forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			118 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			118 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict' | ||
|  | 
 | ||
|  | const fs = require('graceful-fs') | ||
|  | const path = require('path') | ||
|  | const copySync = require('../copy-sync').copySync | ||
|  | const removeSync = require('../remove').removeSync | ||
|  | const mkdirpSync = require('../mkdirs').mkdirsSync | ||
|  | const buffer = require('../util/buffer') | ||
|  | 
 | ||
|  | function moveSync (src, dest, options) { | ||
|  |   options = options || {} | ||
|  |   const overwrite = options.overwrite || options.clobber || false | ||
|  | 
 | ||
|  |   src = path.resolve(src) | ||
|  |   dest = path.resolve(dest) | ||
|  | 
 | ||
|  |   if (src === dest) return fs.accessSync(src) | ||
|  | 
 | ||
|  |   if (isSrcSubdir(src, dest)) throw new Error(`Cannot move '${src}' into itself '${dest}'.`) | ||
|  | 
 | ||
|  |   mkdirpSync(path.dirname(dest)) | ||
|  |   tryRenameSync() | ||
|  | 
 | ||
|  |   function tryRenameSync () { | ||
|  |     if (overwrite) { | ||
|  |       try { | ||
|  |         return fs.renameSync(src, dest) | ||
|  |       } catch (err) { | ||
|  |         if (err.code === 'ENOTEMPTY' || err.code === 'EEXIST' || err.code === 'EPERM') { | ||
|  |           removeSync(dest) | ||
|  |           options.overwrite = false // just overwriteed it, no need to do it again
 | ||
|  |           return moveSync(src, dest, options) | ||
|  |         } | ||
|  | 
 | ||
|  |         if (err.code !== 'EXDEV') throw err | ||
|  |         return moveSyncAcrossDevice(src, dest, overwrite) | ||
|  |       } | ||
|  |     } else { | ||
|  |       try { | ||
|  |         fs.linkSync(src, dest) | ||
|  |         return fs.unlinkSync(src) | ||
|  |       } catch (err) { | ||
|  |         if (err.code === 'EXDEV' || err.code === 'EISDIR' || err.code === 'EPERM' || err.code === 'ENOTSUP') { | ||
|  |           return moveSyncAcrossDevice(src, dest, overwrite) | ||
|  |         } | ||
|  |         throw err | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function moveSyncAcrossDevice (src, dest, overwrite) { | ||
|  |   const stat = fs.statSync(src) | ||
|  | 
 | ||
|  |   if (stat.isDirectory()) { | ||
|  |     return moveDirSyncAcrossDevice(src, dest, overwrite) | ||
|  |   } else { | ||
|  |     return moveFileSyncAcrossDevice(src, dest, overwrite) | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function moveFileSyncAcrossDevice (src, dest, overwrite) { | ||
|  |   const BUF_LENGTH = 64 * 1024 | ||
|  |   const _buff = buffer(BUF_LENGTH) | ||
|  | 
 | ||
|  |   const flags = overwrite ? 'w' : 'wx' | ||
|  | 
 | ||
|  |   const fdr = fs.openSync(src, 'r') | ||
|  |   const stat = fs.fstatSync(fdr) | ||
|  |   const fdw = fs.openSync(dest, flags, stat.mode) | ||
|  |   let pos = 0 | ||
|  | 
 | ||
|  |   while (pos < stat.size) { | ||
|  |     const bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos) | ||
|  |     fs.writeSync(fdw, _buff, 0, bytesRead) | ||
|  |     pos += bytesRead | ||
|  |   } | ||
|  | 
 | ||
|  |   fs.closeSync(fdr) | ||
|  |   fs.closeSync(fdw) | ||
|  |   return fs.unlinkSync(src) | ||
|  | } | ||
|  | 
 | ||
|  | function moveDirSyncAcrossDevice (src, dest, overwrite) { | ||
|  |   const options = { | ||
|  |     overwrite: false | ||
|  |   } | ||
|  | 
 | ||
|  |   if (overwrite) { | ||
|  |     removeSync(dest) | ||
|  |     tryCopySync() | ||
|  |   } else { | ||
|  |     tryCopySync() | ||
|  |   } | ||
|  | 
 | ||
|  |   function tryCopySync () { | ||
|  |     copySync(src, dest, options) | ||
|  |     return removeSync(src) | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | // return true if dest is a subdir of src, otherwise false.
 | ||
|  | // extract dest base dir and check if that is the same as src basename
 | ||
|  | function isSrcSubdir (src, dest) { | ||
|  |   try { | ||
|  |     return fs.statSync(src).isDirectory() && | ||
|  |            src !== dest && | ||
|  |            dest.indexOf(src) > -1 && | ||
|  |            dest.split(path.dirname(src) + path.sep)[1].split(path.sep)[0] === path.basename(src) | ||
|  |   } catch (e) { | ||
|  |     return false | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = { | ||
|  |   moveSync | ||
|  | } |