diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-05-24 15:10:37 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-05-24 15:11:17 +0200 |
commit | 7a3df06eb573d36142bd1a8e03c5ce8752d300b3 (patch) | |
tree | 70bfaea8884c374876f607774850a3a51c0cb381 /node_modules/fs-extra/lib/move/index.js | |
parent | aca1143cb9eed16cf37f04e475e4257418dd18ac (diff) |
fix build issues and add typedoc
Diffstat (limited to 'node_modules/fs-extra/lib/move/index.js')
-rw-r--r-- | node_modules/fs-extra/lib/move/index.js | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/node_modules/fs-extra/lib/move/index.js b/node_modules/fs-extra/lib/move/index.js new file mode 100644 index 000000000..e5eb2c101 --- /dev/null +++ b/node_modules/fs-extra/lib/move/index.js @@ -0,0 +1,162 @@ +'use strict' + +// most of this code was written by Andrew Kelley +// licensed under the BSD license: see +// https://github.com/andrewrk/node-mv/blob/master/package.json + +// this needs a cleanup + +const u = require('universalify').fromCallback +const fs = require('graceful-fs') +const ncp = require('../copy/ncp') +const path = require('path') +const remove = require('../remove').remove +const mkdirp = require('../mkdirs').mkdirs + +function move (source, 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 () { + mkdirp(path.dirname(dest), err => { + if (err) return callback(err) + doRename() + }) + } + + function doRename () { + if (path.resolve(source) === path.resolve(dest)) { + fs.access(source, callback) + } else if (overwrite) { + fs.rename(source, 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) + }) + return + } + + // weird Windows shit + if (err.code === 'EPERM') { + setTimeout(() => { + remove(dest, err => { + if (err) return callback(err) + options.overwrite = false + move(source, dest, options, callback) + }) + }, 200) + return + } + + if (err.code !== 'EXDEV') return callback(err) + moveAcrossDevice(source, dest, overwrite, callback) + }) + } else { + fs.link(source, dest, err => { + if (err) { + if (err.code === 'EXDEV' || err.code === 'EISDIR' || err.code === 'EPERM' || err.code === 'ENOTSUP') { + moveAcrossDevice(source, dest, overwrite, callback) + return + } + callback(err) + return + } + fs.unlink(source, callback) + }) + } + } +} + +function moveAcrossDevice (source, dest, overwrite, callback) { + fs.stat(source, (err, stat) => { + if (err) { + callback(err) + return + } + + if (stat.isDirectory()) { + moveDirAcrossDevice(source, dest, overwrite, callback) + } else { + moveFileAcrossDevice(source, dest, overwrite, callback) + } + }) +} + +function moveFileAcrossDevice (source, dest, overwrite, callback) { + const flags = overwrite ? 'w' : 'wx' + const ins = fs.createReadStream(source) + const outs = fs.createWriteStream(dest, { flags }) + + ins.on('error', err => { + ins.destroy() + outs.destroy() + outs.removeListener('close', onClose) + + // may want to create a directory but `out` line above + // creates an empty file for us: See #108 + // don't care about error here + fs.unlink(dest, () => { + // note: `err` here is from the input stream errror + if (err.code === 'EISDIR' || err.code === 'EPERM') { + moveDirAcrossDevice(source, dest, overwrite, callback) + } else { + callback(err) + } + }) + }) + + outs.on('error', err => { + ins.destroy() + outs.destroy() + outs.removeListener('close', onClose) + callback(err) + }) + + outs.once('close', onClose) + ins.pipe(outs) + + function onClose () { + fs.unlink(source, callback) + } +} + +function moveDirAcrossDevice (source, dest, overwrite, callback) { + const options = { + overwrite: false + } + + if (overwrite) { + remove(dest, err => { + if (err) return callback(err) + startNcp() + }) + } else { + startNcp() + } + + function startNcp () { + ncp(source, dest, options, err => { + if (err) return callback(err) + remove(source, callback) + }) + } +} + +module.exports = { + move: u(move) +} |