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