diff options
Diffstat (limited to 'node_modules/fs-extra/lib')
-rw-r--r-- | node_modules/fs-extra/lib/ensure/file.js | 11 | ||||
-rw-r--r-- | node_modules/fs-extra/lib/fs/index.js | 44 | ||||
-rw-r--r-- | node_modules/fs-extra/lib/json/index.js | 4 | ||||
-rw-r--r-- | node_modules/fs-extra/lib/move/index.js | 82 | ||||
-rw-r--r-- | node_modules/fs-extra/lib/remove/rimraf.js | 22 |
5 files changed, 116 insertions, 47 deletions
diff --git a/node_modules/fs-extra/lib/ensure/file.js b/node_modules/fs-extra/lib/ensure/file.js index 962c21cb3..67eed3017 100644 --- a/node_modules/fs-extra/lib/ensure/file.js +++ b/node_modules/fs-extra/lib/ensure/file.js @@ -14,9 +14,8 @@ function createFile (file, callback) { }) } - pathExists(file, (err, fileExists) => { - if (err) return callback(err) - if (fileExists) return callback() + fs.stat(file, (err, stats) => { // eslint-disable-line handle-callback-err + if (!err && stats.isFile()) return callback() const dir = path.dirname(file) pathExists(dir, (err, dirExists) => { if (err) return callback(err) @@ -30,7 +29,11 @@ function createFile (file, callback) { } function createFileSync (file) { - if (fs.existsSync(file)) return + let stats + try { + stats = fs.statSync(file) + } catch (e) {} + if (stats && stats.isFile()) return const dir = path.dirname(file) if (!fs.existsSync(dir)) { diff --git a/node_modules/fs-extra/lib/fs/index.js b/node_modules/fs-extra/lib/fs/index.js index e20ae762a..551ca6a09 100644 --- a/node_modules/fs-extra/lib/fs/index.js +++ b/node_modules/fs-extra/lib/fs/index.js @@ -21,7 +21,6 @@ const api = [ 'lstat', 'mkdir', 'open', - 'read', 'readFile', 'readdir', 'readlink', @@ -33,7 +32,6 @@ const api = [ 'truncate', 'unlink', 'utimes', - 'write', 'writeFile' ] // fs.mkdtemp() was added in Node.js v5.10.0, so check if it exists @@ -59,3 +57,45 @@ exports.exists = function (filename, callback) { return fs.exists(filename, resolve) }) } + +// fs.read() & fs.write need special treatment due to multiple callback args + +exports.read = function (fd, buffer, offset, length, position, callback) { + if (typeof callback === 'function') { + return fs.read(fd, buffer, offset, length, position, callback) + } + return new Promise((resolve, reject) => { + fs.read(fd, buffer, offset, length, position, (err, bytesRead, buffer) => { + if (err) return reject(err) + resolve({ bytesRead, buffer }) + }) + }) +} + +// Function signature can be +// fs.write(fd, buffer[, offset[, length[, position]]], callback) +// OR +// fs.write(fd, string[, position[, encoding]], callback) +// so we need to handle both cases +exports.write = function (fd, buffer, a, b, c, callback) { + if (typeof arguments[arguments.length - 1] === 'function') { + return fs.write(fd, buffer, a, b, c, callback) + } + + // Check for old, depricated fs.write(fd, string[, position[, encoding]], callback) + if (typeof buffer === 'string') { + return new Promise((resolve, reject) => { + fs.write(fd, buffer, a, b, (err, bytesWritten, buffer) => { + if (err) return reject(err) + resolve({ bytesWritten, buffer }) + }) + }) + } + + return new Promise((resolve, reject) => { + fs.write(fd, buffer, a, b, c, (err, bytesWritten, buffer) => { + if (err) return reject(err) + resolve({ bytesWritten, buffer }) + }) + }) +} diff --git a/node_modules/fs-extra/lib/json/index.js b/node_modules/fs-extra/lib/json/index.js index 717d48f41..bae68d45a 100644 --- a/node_modules/fs-extra/lib/json/index.js +++ b/node_modules/fs-extra/lib/json/index.js @@ -3,11 +3,11 @@ const u = require('universalify').fromCallback const jsonFile = require('./jsonfile') -jsonFile.outputJsonSync = require('./output-json-sync') jsonFile.outputJson = u(require('./output-json')) +jsonFile.outputJsonSync = require('./output-json-sync') // aliases -jsonFile.outputJSONSync = jsonFile.outputJSONSync jsonFile.outputJSON = jsonFile.outputJson +jsonFile.outputJSONSync = jsonFile.outputJsonSync jsonFile.writeJSON = jsonFile.writeJson jsonFile.writeJSONSync = jsonFile.writeJsonSync jsonFile.readJSON = jsonFile.readJson diff --git a/node_modules/fs-extra/lib/move/index.js b/node_modules/fs-extra/lib/move/index.js index e5eb2c101..eeeb30fe3 100644 --- a/node_modules/fs-extra/lib/move/index.js +++ b/node_modules/fs-extra/lib/move/index.js @@ -13,40 +13,35 @@ const path = require('path') const remove = require('../remove').remove const mkdirp = require('../mkdirs').mkdirs -function move (source, dest, options, callback) { +function move (src, dest, options, callback) { if (typeof options === 'function') { callback = options options = {} } - const shouldMkdirp = ('mkdirp' in options) ? options.mkdirp : true const overwrite = options.overwrite || options.clobber || false - if (shouldMkdirp) { - mkdirs() - } else { - doRename() - } - - function mkdirs () { + isSrcSubdir(src, dest, (err, itIs) => { + if (err) return callback(err) + if (itIs) return callback(new Error(`Cannot move '${src}' to a subdirectory of itself, '${dest}'.`)) mkdirp(path.dirname(dest), err => { if (err) return callback(err) doRename() }) - } + }) function doRename () { - if (path.resolve(source) === path.resolve(dest)) { - fs.access(source, callback) + if (path.resolve(src) === path.resolve(dest)) { + fs.access(src, callback) } else if (overwrite) { - fs.rename(source, dest, err => { + fs.rename(src, dest, err => { if (!err) return callback() if (err.code === 'ENOTEMPTY' || err.code === 'EEXIST') { remove(dest, err => { if (err) return callback(err) options.overwrite = false // just overwriteed it, no need to do it again - move(source, dest, options, callback) + move(src, dest, options, callback) }) return } @@ -57,49 +52,44 @@ function move (source, dest, options, callback) { remove(dest, err => { if (err) return callback(err) options.overwrite = false - move(source, dest, options, callback) + move(src, dest, options, callback) }) }, 200) return } if (err.code !== 'EXDEV') return callback(err) - moveAcrossDevice(source, dest, overwrite, callback) + moveAcrossDevice(src, dest, overwrite, callback) }) } else { - fs.link(source, dest, err => { + fs.link(src, dest, err => { if (err) { if (err.code === 'EXDEV' || err.code === 'EISDIR' || err.code === 'EPERM' || err.code === 'ENOTSUP') { - moveAcrossDevice(source, dest, overwrite, callback) - return + return moveAcrossDevice(src, dest, overwrite, callback) } - callback(err) - return + return callback(err) } - fs.unlink(source, callback) + return fs.unlink(src, callback) }) } } } -function moveAcrossDevice (source, dest, overwrite, callback) { - fs.stat(source, (err, stat) => { - if (err) { - callback(err) - return - } +function moveAcrossDevice (src, dest, overwrite, callback) { + fs.stat(src, (err, stat) => { + if (err) return callback(err) if (stat.isDirectory()) { - moveDirAcrossDevice(source, dest, overwrite, callback) + moveDirAcrossDevice(src, dest, overwrite, callback) } else { - moveFileAcrossDevice(source, dest, overwrite, callback) + moveFileAcrossDevice(src, dest, overwrite, callback) } }) } -function moveFileAcrossDevice (source, dest, overwrite, callback) { +function moveFileAcrossDevice (src, dest, overwrite, callback) { const flags = overwrite ? 'w' : 'wx' - const ins = fs.createReadStream(source) + const ins = fs.createReadStream(src) const outs = fs.createWriteStream(dest, { flags }) ins.on('error', err => { @@ -113,7 +103,7 @@ function moveFileAcrossDevice (source, dest, overwrite, callback) { fs.unlink(dest, () => { // note: `err` here is from the input stream errror if (err.code === 'EISDIR' || err.code === 'EPERM') { - moveDirAcrossDevice(source, dest, overwrite, callback) + moveDirAcrossDevice(src, dest, overwrite, callback) } else { callback(err) } @@ -131,11 +121,11 @@ function moveFileAcrossDevice (source, dest, overwrite, callback) { ins.pipe(outs) function onClose () { - fs.unlink(source, callback) + fs.unlink(src, callback) } } -function moveDirAcrossDevice (source, dest, overwrite, callback) { +function moveDirAcrossDevice (src, dest, overwrite, callback) { const options = { overwrite: false } @@ -150,13 +140,31 @@ function moveDirAcrossDevice (source, dest, overwrite, callback) { } function startNcp () { - ncp(source, dest, options, err => { + ncp(src, dest, options, err => { if (err) return callback(err) - remove(source, callback) + remove(src, callback) }) } } +// return true if dest is a subdir of src, otherwise false. +// extract dest base dir and check if that is the same as src basename +function isSrcSubdir (src, dest, cb) { + fs.stat(src, (err, st) => { + if (err) return cb(err) + if (st.isDirectory()) { + const baseDir = dest.split(path.dirname(src) + path.sep)[1] + if (baseDir) { + const destBasename = baseDir.split(path.sep)[0] + if (destBasename) return cb(null, src !== dest && dest.indexOf(src) > -1 && destBasename === path.basename(src)) + return cb(null, false) + } + return cb(null, false) + } + return cb(null, false) + }) +} + module.exports = { move: u(move) } diff --git a/node_modules/fs-extra/lib/remove/rimraf.js b/node_modules/fs-extra/lib/remove/rimraf.js index 28d4aeb08..15924c37f 100644 --- a/node_modules/fs-extra/lib/remove/rimraf.js +++ b/node_modules/fs-extra/lib/remove/rimraf.js @@ -42,7 +42,7 @@ function rimraf (p, options, cb) { rimraf_(p, options, function CB (er) { if (er) { - if (isWindows && (er.code === 'EBUSY' || er.code === 'ENOTEMPTY' || er.code === 'EPERM') && + if ((er.code === 'EBUSY' || er.code === 'ENOTEMPTY' || er.code === 'EPERM') && busyTries < options.maxBusyTries) { busyTries++ let time = busyTries * 100 @@ -289,7 +289,25 @@ function rmkidsSync (p, options) { assert(p) assert(options) options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) - options.rmdirSync(p, options) + + // We only end up here once we got ENOTEMPTY at least once, and + // at this point, we are guaranteed to have removed all the kids. + // So, we know that it won't be ENOENT or ENOTDIR or anything else. + // try really hard to delete stuff on windows, because it has a + // PROFOUNDLY annoying habit of not closing handles promptly when + // files are deleted, resulting in spurious ENOTEMPTY errors. + const retries = isWindows ? 100 : 1 + let i = 0 + do { + let threw = true + try { + const ret = options.rmdirSync(p, options) + threw = false + return ret + } finally { + if (++i < retries && threw) continue // eslint-disable-line + } + } while (true) } module.exports = rimraf |