move-sync.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  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. preserveTimestamps: true
  43. }
  44. copySync(src, dest, opts)
  45. return removeSync(src)
  46. }
  47. module.exports = moveSync