diff options
Diffstat (limited to 'deps/npm/node_modules/tar/lib/mkdir.js')
-rw-r--r-- | deps/npm/node_modules/tar/lib/mkdir.js | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/deps/npm/node_modules/tar/lib/mkdir.js b/deps/npm/node_modules/tar/lib/mkdir.js index aed398fcdcd..a0719e6c36e 100644 --- a/deps/npm/node_modules/tar/lib/mkdir.js +++ b/deps/npm/node_modules/tar/lib/mkdir.js @@ -8,6 +8,7 @@ const mkdirp = require('mkdirp') const fs = require('fs') const path = require('path') const chownr = require('chownr') +const normPath = require('./normalize-windows-path.js') class SymlinkError extends Error { constructor (symlink, path) { @@ -33,7 +34,20 @@ class CwdError extends Error { } } +const cGet = (cache, key) => cache.get(normPath(key)) +const cSet = (cache, key, val) => cache.set(normPath(key), val) + +const checkCwd = (dir, cb) => { + fs.stat(dir, (er, st) => { + if (er || !st.isDirectory()) + er = new CwdError(dir, er && er.code || 'ENOTDIR') + cb(er) + }) +} + module.exports = (dir, opt, cb) => { + dir = normPath(dir) + // if there's any overlap between mask and mode, // then we'll need an explicit chmod const umask = opt.umask @@ -49,13 +63,13 @@ module.exports = (dir, opt, cb) => { const preserve = opt.preserve const unlink = opt.unlink const cache = opt.cache - const cwd = opt.cwd + const cwd = normPath(opt.cwd) const done = (er, created) => { if (er) cb(er) else { - cache.set(dir, true) + cSet(cache, dir, true) if (created && doChown) chownr(created, uid, gid, er => done(er)) else if (needChmod) @@ -65,22 +79,17 @@ module.exports = (dir, opt, cb) => { } } - if (cache && cache.get(dir) === true) + if (cache && cGet(cache, dir) === true) return done() - if (dir === cwd) { - return fs.stat(dir, (er, st) => { - if (er || !st.isDirectory()) - er = new CwdError(dir, er && er.code || 'ENOTDIR') - done(er) - }) - } + if (dir === cwd) + return checkCwd(dir, done) if (preserve) return mkdirp(dir, {mode}).then(made => done(null, made), done) - const sub = path.relative(cwd, dir) - const parts = sub.split(/\/|\\/) + const sub = normPath(path.relative(cwd, dir)) + const parts = sub.split('/') mkdir_(cwd, parts, mode, cache, unlink, cwd, null, done) } @@ -88,22 +97,19 @@ const mkdir_ = (base, parts, mode, cache, unlink, cwd, created, cb) => { if (!parts.length) return cb(null, created) const p = parts.shift() - const part = base + '/' + p - if (cache.get(part)) + const part = normPath(path.resolve(base + '/' + p)) + if (cGet(cache, part)) return mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb)) } const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => { if (er) { - if (er.path && path.dirname(er.path) === cwd && - (er.code === 'ENOTDIR' || er.code === 'ENOENT')) - return cb(new CwdError(cwd, er.code)) - fs.lstat(part, (statEr, st) => { - if (statEr) + if (statEr) { + statEr.path = statEr.path && normPath(statEr.path) cb(statEr) - else if (st.isDirectory()) + } else if (st.isDirectory()) mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) else if (unlink) { fs.unlink(part, er => { @@ -122,7 +128,21 @@ const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => { } } +const checkCwdSync = dir => { + let ok = false + let code = 'ENOTDIR' + try { + ok = fs.statSync(dir).isDirectory() + } catch (er) { + code = er.code + } finally { + if (!ok) + throw new CwdError(dir, code) + } +} + module.exports.sync = (dir, opt) => { + dir = normPath(dir) // if there's any overlap between mask and mode, // then we'll need an explicit chmod const umask = opt.umask @@ -138,64 +158,51 @@ module.exports.sync = (dir, opt) => { const preserve = opt.preserve const unlink = opt.unlink const cache = opt.cache - const cwd = opt.cwd + const cwd = normPath(opt.cwd) const done = (created) => { - cache.set(dir, true) + cSet(cache, dir, true) if (created && doChown) chownr.sync(created, uid, gid) if (needChmod) fs.chmodSync(dir, mode) } - if (cache && cache.get(dir) === true) + if (cache && cGet(cache, dir) === true) return done() if (dir === cwd) { - let ok = false - let code = 'ENOTDIR' - try { - ok = fs.statSync(dir).isDirectory() - } catch (er) { - code = er.code - } finally { - if (!ok) - throw new CwdError(dir, code) - } - done() - return + checkCwdSync(cwd) + return done() } if (preserve) return done(mkdirp.sync(dir, mode)) - const sub = path.relative(cwd, dir) - const parts = sub.split(/\/|\\/) + const sub = normPath(path.relative(cwd, dir)) + const parts = sub.split('/') let created = null for (let p = parts.shift(), part = cwd; p && (part += '/' + p); p = parts.shift()) { - if (cache.get(part)) + part = normPath(path.resolve(part)) + if (cGet(cache, part)) continue try { fs.mkdirSync(part, mode) created = created || part - cache.set(part, true) + cSet(cache, part, true) } catch (er) { - if (er.path && path.dirname(er.path) === cwd && - (er.code === 'ENOTDIR' || er.code === 'ENOENT')) - return new CwdError(cwd, er.code) - const st = fs.lstatSync(part) if (st.isDirectory()) { - cache.set(part, true) + cSet(cache, part, true) continue } else if (unlink) { fs.unlinkSync(part) fs.mkdirSync(part, mode) created = created || part - cache.set(part, true) + cSet(cache, part, true) continue } else if (st.isSymbolicLink()) return new SymlinkError(part, part + '/' + parts.join('/')) |