move-sync.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. 'use strict'
  2. const fs = require('graceful-fs')
  3. const path = require('path')
  4. const copySync = require('../copy').copySync
  5. const removeSync = require('../remove').removeSync
  6. const mkdirpSync = require('../mkdirs').mkdirpSync
  7. const stat = require('../util/stat')
  8. function moveSync (src, dest, opts) {
  9. opts = opts || {}
  10. const overwrite = opts.overwrite || opts.clobber || false
  11. const { srcStat, isChangingCase = false } = stat.checkPathsSync(src, dest, 'move', opts)
  12. stat.checkParentPathsSync(src, srcStat, dest, 'move')
  13. if (!isParentRoot(dest)) mkdirpSync(path.dirname(dest))
  14. return doRename(src, dest, overwrite, isChangingCase)
  15. }
  16. function isParentRoot (dest) {
  17. const parent = path.dirname(dest)
  18. const parsedPath = path.parse(parent)
  19. return parsedPath.root === parent
  20. }
  21. function doRename (src, dest, overwrite, isChangingCase) {
  22. if (isChangingCase) return rename(src, dest, overwrite)
  23. if (overwrite) {
  24. removeSync(dest)
  25. return rename(src, dest, overwrite)
  26. }
  27. if (fs.existsSync(dest)) throw new Error('dest already exists.')
  28. return rename(src, dest, overwrite)
  29. }
  30. function rename (src, dest, overwrite) {
  31. try {
  32. fs.renameSync(src, dest)
  33. } catch (err) {
  34. if (err.code !== 'EXDEV') throw err
  35. return moveAcrossDevice(src, dest, overwrite)
  36. }
  37. }
  38. function moveAcrossDevice (src, dest, overwrite) {
  39. const opts = {
  40. overwrite,
  41. errorOnExist: true
  42. }
  43. copySync(src, dest, opts)
  44. return removeSync(src)
  45. }
  46. module.exports = moveSync