"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/fs-extra/lib/move/index.js" (11 Apr 2017, 3973 Bytes) of package /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // most of this code was written by Andrew Kelley
    2 // licensed under the BSD license: see
    3 // https://github.com/andrewrk/node-mv/blob/master/package.json
    4 
    5 // this needs a cleanup
    6 
    7 var fs = require('graceful-fs')
    8 var ncp = require('../copy/ncp')
    9 var path = require('path')
   10 var rimraf = require('rimraf')
   11 var mkdirp = require('../mkdirs').mkdirs
   12 
   13 function mv (source, dest, options, callback) {
   14   if (typeof options === 'function') {
   15     callback = options
   16     options = {}
   17   }
   18 
   19   var shouldMkdirp = ('mkdirp' in options) ? options.mkdirp : true
   20   var clobber = ('clobber' in options) ? options.clobber : false
   21 
   22   var limit = options.limit || 16
   23 
   24   if (shouldMkdirp) {
   25     mkdirs()
   26   } else {
   27     doRename()
   28   }
   29 
   30   function mkdirs () {
   31     mkdirp(path.dirname(dest), function (err) {
   32       if (err) return callback(err)
   33       doRename()
   34     })
   35   }
   36 
   37   function doRename () {
   38     if (clobber) {
   39       fs.rename(source, dest, function (err) {
   40         if (!err) return callback()
   41 
   42         if (err.code === 'ENOTEMPTY' || err.code === 'EEXIST') {
   43           rimraf(dest, function (err) {
   44             if (err) return callback(err)
   45             options.clobber = false // just clobbered it, no need to do it again
   46             mv(source, dest, options, callback)
   47           })
   48           return
   49         }
   50 
   51         // weird Windows shit
   52         if (err.code === 'EPERM') {
   53           setTimeout(function () {
   54             rimraf(dest, function (err) {
   55               if (err) return callback(err)
   56               options.clobber = false
   57               mv(source, dest, options, callback)
   58             })
   59           }, 200)
   60           return
   61         }
   62 
   63         if (err.code !== 'EXDEV') return callback(err)
   64         moveAcrossDevice(source, dest, clobber, limit, callback)
   65       })
   66     } else {
   67       fs.link(source, dest, function (err) {
   68         if (err) {
   69           if (err.code === 'EXDEV' || err.code === 'EISDIR' || err.code === 'EPERM') {
   70             moveAcrossDevice(source, dest, clobber, limit, callback)
   71             return
   72           }
   73           callback(err)
   74           return
   75         }
   76         fs.unlink(source, callback)
   77       })
   78     }
   79   }
   80 }
   81 
   82 function moveAcrossDevice (source, dest, clobber, limit, callback) {
   83   fs.stat(source, function (err, stat) {
   84     if (err) {
   85       callback(err)
   86       return
   87     }
   88 
   89     if (stat.isDirectory()) {
   90       moveDirAcrossDevice(source, dest, clobber, limit, callback)
   91     } else {
   92       moveFileAcrossDevice(source, dest, clobber, limit, callback)
   93     }
   94   })
   95 }
   96 
   97 function moveFileAcrossDevice (source, dest, clobber, limit, callback) {
   98   var outFlags = clobber ? 'w' : 'wx'
   99   var ins = fs.createReadStream(source)
  100   var outs = fs.createWriteStream(dest, {flags: outFlags})
  101 
  102   ins.on('error', function (err) {
  103     ins.destroy()
  104     outs.destroy()
  105     outs.removeListener('close', onClose)
  106 
  107     // may want to create a directory but `out` line above
  108     // creates an empty file for us: See #108
  109     // don't care about error here
  110     fs.unlink(dest, function () {
  111       // note: `err` here is from the input stream errror
  112       if (err.code === 'EISDIR' || err.code === 'EPERM') {
  113         moveDirAcrossDevice(source, dest, clobber, limit, callback)
  114       } else {
  115         callback(err)
  116       }
  117     })
  118   })
  119 
  120   outs.on('error', function (err) {
  121     ins.destroy()
  122     outs.destroy()
  123     outs.removeListener('close', onClose)
  124     callback(err)
  125   })
  126 
  127   outs.once('close', onClose)
  128   ins.pipe(outs)
  129 
  130   function onClose () {
  131     fs.unlink(source, callback)
  132   }
  133 }
  134 
  135 function moveDirAcrossDevice (source, dest, clobber, limit, callback) {
  136   var options = {
  137     stopOnErr: true,
  138     clobber: false,
  139     limit: limit
  140   }
  141 
  142   function startNcp () {
  143     ncp(source, dest, options, function (errList) {
  144       if (errList) return callback(errList[0])
  145       rimraf(source, callback)
  146     })
  147   }
  148 
  149   if (clobber) {
  150     rimraf(dest, function (err) {
  151       if (err) return callback(err)
  152       startNcp()
  153     })
  154   } else {
  155     startNcp()
  156   }
  157 }
  158 
  159 module.exports = {
  160   move: mv
  161 }