| 'use strict' |
| module.exports = move |
| |
| var nodeFs = require('fs') |
| var rimraf = require('rimraf') |
| var validate = require('aproba') |
| var copy = require('copy-concurrently') |
| var RunQueue = require('run-queue') |
| var extend = Object.assign || require('util')._extend |
| |
| function promisify (Promise, fn) { |
| return function () { |
| var args = [].slice.call(arguments) |
| return new Promise(function (resolve, reject) { |
| return fn.apply(null, args.concat(function (err, value) { |
| if (err) { |
| reject(err) |
| } else { |
| resolve(value) |
| } |
| })) |
| }) |
| } |
| } |
| |
| function move (from, to, opts) { |
| validate('SSO|SS', arguments) |
| opts = extend({}, opts || {}) |
| |
| var Promise = opts.Promise || global.Promise |
| var fs = opts.fs || nodeFs |
| var rimrafAsync = promisify(Promise, rimraf) |
| var renameAsync = promisify(Promise, fs.rename) |
| |
| opts.top = from |
| |
| var queue = new RunQueue({ |
| maxConcurrency: opts.maxConcurrency, |
| Promise: Promise |
| }) |
| opts.queue = queue |
| opts.recurseWith = rename |
| |
| queue.add(0, rename, [from, to, opts]) |
| |
| return queue.run().then(function () { |
| return remove(from) |
| }, function (err) { |
| // if the target already exists don't clobber it |
| if (err.code === 'EEXIST' || err.code === 'EPERM') { |
| return passThroughError() |
| } else { |
| return remove(to).then(passThroughError, passThroughError) |
| } |
| function passThroughError () { |
| return Promise.reject(err) |
| } |
| }) |
| |
| function remove (target) { |
| var opts = { |
| unlink: fs.unlink, |
| chmod: fs.chmod, |
| stat: fs.stat, |
| lstat: fs.lstat, |
| rmdir: fs.rmdir, |
| readdir: fs.readdir, |
| glob: false |
| } |
| return rimrafAsync(target, opts) |
| } |
| |
| function rename (from, to, opts, done) { |
| return renameAsync(from, to).catch(function (err) { |
| if (err.code !== 'EXDEV') { |
| return Promise.reject(err) |
| } else { |
| return remove(to).then(function () { |
| return copy.item(from, to, opts) |
| }) |
| } |
| }) |
| } |
| } |