Projekt

Obecné

Profil

Stáhnout (1.97 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
'use strict'
2
module.exports = move
3
4
var nodeFs = require('fs')
5
var rimraf = require('rimraf')
6
var validate = require('aproba')
7
var copy = require('copy-concurrently')
8
var RunQueue = require('run-queue')
9
var extend = Object.assign || require('util')._extend
10
11
function promisify (Promise, fn) {
12
  return function () {
13
    var args = [].slice.call(arguments)
14
    return new Promise(function (resolve, reject) {
15
      return fn.apply(null, args.concat(function (err, value) {
16
        if (err) {
17
          reject(err)
18
        } else {
19
          resolve(value)
20
        }
21
      }))
22
    })
23
  }
24
}
25
26
function move (from, to, opts) {
27
  validate('SSO|SS', arguments)
28
  opts = extend({}, opts || {})
29
30
  var Promise = opts.Promise || global.Promise
31
  var fs = opts.fs || nodeFs
32
  var rimrafAsync = promisify(Promise, rimraf)
33
  var renameAsync = promisify(Promise, fs.rename)
34
35
  opts.top = from
36
37
  var queue = new RunQueue({
38
    maxConcurrency: opts.maxConcurrency,
39
    Promise: Promise
40
  })
41
  opts.queue = queue
42
  opts.recurseWith = rename
43
44
  queue.add(0, rename, [from, to, opts])
45
46
  return queue.run().then(function () {
47
    return remove(from)
48
  }, function (err) {
49
    // if the target already exists don't clobber it
50
    if (err.code === 'EEXIST' || err.code === 'EPERM') {
51
      return passThroughError()
52
    } else {
53
      return remove(to).then(passThroughError, passThroughError)
54
    }
55
    function passThroughError () {
56
      return Promise.reject(err)
57
    }
58
  })
59
60
  function remove (target) {
61
    var opts = {
62
      unlink: fs.unlink,
63
      chmod: fs.chmod,
64
      stat: fs.stat,
65
      lstat: fs.lstat,
66
      rmdir: fs.rmdir,
67
      readdir: fs.readdir,
68
      glob: false
69
    }
70
    return rimrafAsync(target, opts)
71
  }
72
73
  function rename (from, to, opts, done) {
74
    return renameAsync(from, to).catch(function (err) {
75
      if (err.code !== 'EXDEV') {
76
        return Promise.reject(err)
77
      } else {
78
        return remove(to).then(function () {
79
          return copy.item(from, to, opts)
80
        })
81
      }
82
    })
83
  }
84
}