move.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. 'use strict'
  2. const fs = require('graceful-fs')
  3. const path = require('path')
  4. const copy = require('../copy').copy
  5. const remove = require('../remove').remove
  6. const mkdirp = require('../mkdirs').mkdirp
  7. const pathExists = require('../path-exists').pathExists
  8. const stat = require('../util/stat')
  9. function move (src, dest, opts, cb) {
  10. if (typeof opts === 'function') {
  11. cb = opts
  12. opts = {}
  13. }
  14. const overwrite = opts.overwrite || opts.clobber || false
  15. stat.checkPaths(src, dest, 'move', (err, stats) => {
  16. if (err) return cb(err)
  17. const { srcStat } = stats
  18. stat.checkParentPaths(src, srcStat, dest, 'move', err => {
  19. if (err) return cb(err)
  20. mkdirp(path.dirname(dest), err => {
  21. if (err) return cb(err)
  22. return doRename(src, dest, overwrite, cb)
  23. })
  24. })
  25. })
  26. }
  27. function doRename (src, dest, overwrite, cb) {
  28. if (overwrite) {
  29. return remove(dest, err => {
  30. if (err) return cb(err)
  31. return rename(src, dest, overwrite, cb)
  32. })
  33. }
  34. pathExists(dest, (err, destExists) => {
  35. if (err) return cb(err)
  36. if (destExists) return cb(new Error('dest already exists.'))
  37. return rename(src, dest, overwrite, cb)
  38. })
  39. }
  40. function rename (src, dest, overwrite, cb) {
  41. fs.rename(src, dest, err => {
  42. if (!err) return cb()
  43. if (err.code !== 'EXDEV') return cb(err)
  44. return moveAcrossDevice(src, dest, overwrite, cb)
  45. })
  46. }
  47. function moveAcrossDevice (src, dest, overwrite, cb) {
  48. const opts = {
  49. overwrite,
  50. errorOnExist: true
  51. }
  52. copy(src, dest, opts, err => {
  53. if (err) return cb(err)
  54. return remove(src, cb)
  55. })
  56. }
  57. module.exports = move