'use strict'; const fs = require('graceful-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 stat = require('../util/stat'); function move(src, dest, opts, cb) { if (typeof opts === 'function') { cb = opts; opts = {}; } const overwrite = opts.overwrite || opts.clobber || false; stat.checkPaths(src, dest, 'move', (err, stats) => { if (err) return cb(err); const { srcStat } = stats; stat.checkParentPaths(src, srcStat, dest, 'move', (err) => { if (err) return cb(err); mkdirp(path.dirname(dest), (err) => { if (err) return cb(err); return doRename(src, dest, overwrite, cb); }); }); }); } function doRename(src, dest, overwrite, cb) { if (overwrite) { return remove(dest, (err) => { if (err) return cb(err); return rename(src, dest, overwrite, cb); }); } 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); }); } function moveAcrossDevice(src, dest, overwrite, cb) { const opts = { overwrite, errorOnExist: true, }; copy(src, dest, opts, (err) => { if (err) return cb(err); return remove(src, cb); }); } module.exports = move;