diff --git a/lib/move/__tests__/move.test.js b/lib/move/__tests__/move.test.js index c1cc2a9e..fd905472 100644 --- a/lib/move/__tests__/move.test.js +++ b/lib/move/__tests__/move.test.js @@ -1,6 +1,6 @@ 'use strict' -const fs = require('graceful-fs') +const fs = require('../../fs') const os = require('os') const fse = require('../../') const path = require('path') @@ -12,14 +12,12 @@ const { differentDevice, ifCrossDeviceEnabled } = require('./cross-device-utils' const describeIfWindows = process.platform === 'win32' ? describe : describe.skip function createAsyncErrFn (errCode) { - const fn = function (...args) { + async function fn () { fn.callCount++ - const callback = args.pop() - setTimeout(() => { - const err = new Error() - err.code = errCode - callback(err) - }, 10) + const err = new Error() + err.code = errCode + + return Promise.reject(err) } fn.callCount = 0 return fn diff --git a/lib/move/index.js b/lib/move/index.js index fcee73c4..5a2f1ccd 100644 --- a/lib/move/index.js +++ b/lib/move/index.js @@ -1,6 +1,6 @@ 'use strict' -const u = require('universalify').fromCallback +const u = require('universalify').fromPromise module.exports = { move: u(require('./move')), moveSync: require('./move-sync') diff --git a/lib/move/move.js b/lib/move/move.js index 5c4d74f9..992bd0fc 100644 --- a/lib/move/move.js +++ b/lib/move/move.js @@ -1,76 +1,59 @@ 'use strict' -const fs = require('graceful-fs') +const fs = require('../fs') const path = require('path') -const copy = require('../copy').copy -const remove = require('../remove').remove -const mkdirp = require('../mkdirs').mkdirp -const pathExists = require('../path-exists').pathExists +const { copy } = require('../copy') +const { remove } = require('../remove') +const { mkdirp } = require('../mkdirs') +const { pathExists } = require('../path-exists') const stat = require('../util/stat') -function move (src, dest, opts, cb) { - if (typeof opts === 'function') { - cb = opts - opts = {} - } +async function move (src, dest, opts = {}) { + const overwrite = opts.overwrite || opts.clobber || false - opts = opts || {} + const { srcStat, isChangingCase = false } = await stat.checkPaths(src, dest, 'move', opts) - const overwrite = opts.overwrite || opts.clobber || false + await stat.checkParentPaths(src, srcStat, dest, 'move') - stat.checkPaths(src, dest, 'move', opts, (err, stats) => { - if (err) return cb(err) - const { srcStat, isChangingCase = false } = stats - stat.checkParentPaths(src, srcStat, dest, 'move', err => { - if (err) return cb(err) - if (isParentRoot(dest)) return doRename(src, dest, overwrite, isChangingCase, cb) - mkdirp(path.dirname(dest), err => { - if (err) return cb(err) - return doRename(src, dest, overwrite, isChangingCase, cb) - }) - }) - }) -} + // If the parent of dest is not root, make sure it exists before proceeding + const destParent = path.dirname(dest) + const parsedParentPath = path.parse(destParent) + if (parsedParentPath.root !== destParent) { + await mkdirp(destParent) + } -function isParentRoot (dest) { - const parent = path.dirname(dest) - const parsedPath = path.parse(parent) - return parsedPath.root === parent + return doRename(src, dest, overwrite, isChangingCase) } -function doRename (src, dest, overwrite, isChangingCase, cb) { - if (isChangingCase) return rename(src, dest, overwrite, cb) - if (overwrite) { - return remove(dest, err => { - if (err) return cb(err) - return rename(src, dest, overwrite, cb) - }) +async function doRename (src, dest, overwrite, isChangingCase) { + if (!isChangingCase) { + if (overwrite) { + await remove(dest) + } else if (await pathExists(dest)) { + throw new Error('dest already exists.') + } } - pathExists(dest, (err, destExists) => { - if (err) return cb(err) - if (destExists) return cb(new Error('dest already exists.')) - return rename(src, dest, overwrite, cb) - }) -} -function rename (src, dest, overwrite, cb) { - fs.rename(src, dest, err => { - if (!err) return cb() - if (err.code !== 'EXDEV') return cb(err) - return moveAcrossDevice(src, dest, overwrite, cb) - }) + try { + // Try w/ rename first, and try copy + remove if EXDEV + await fs.rename(src, dest) + } catch (err) { + if (err.code !== 'EXDEV') { + throw err + } + await moveAcrossDevice(src, dest, overwrite) + } } -function moveAcrossDevice (src, dest, overwrite, cb) { +async function moveAcrossDevice (src, dest, overwrite) { const opts = { overwrite, errorOnExist: true, preserveTimestamps: true } - copy(src, dest, opts, err => { - if (err) return cb(err) - return remove(src, cb) - }) + + await copy(src, dest, opts) + return remove(src) } module.exports = move