Last active
December 18, 2015 17:39
-
-
Save yuanyan/5819885 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require("fs"); | |
var path = require("path"); | |
// mian code, 请替换路径地址 | |
ncp('./path/to/source', './path/to/dest', function(){ | |
rmrf('./path/to/source'); | |
}) | |
// copy from ncp, 请折叠 | |
function ncp (source, dest, options, callback) { | |
if (!callback) { | |
callback = options; | |
options = {}; | |
} | |
var basePath = process.cwd(), | |
currentPath = path.resolve(basePath, source), | |
targetPath = path.resolve(basePath, dest), | |
filter = options.filter, | |
transform = options.transform, | |
clobber = options.clobber !== false, | |
errs = null, | |
started = 0, | |
finished = 0, | |
running = 0, | |
limit = options.limit || ncp.limit || 16; | |
limit = (limit < 1) ? 1 : (limit > 512) ? 512 : limit; | |
startCopy(currentPath); | |
function startCopy(source) { | |
started++; | |
if (filter) { | |
if (filter instanceof RegExp) { | |
if (!filter.test(source)) { | |
return cb(true); | |
} | |
} | |
else if (typeof filter === 'function') { | |
if (!filter(source)) { | |
return cb(true); | |
} | |
} | |
} | |
return getStats(source); | |
} | |
function defer(fn) { | |
if (typeof(setImmediate) === 'function') | |
return setImmediate(fn); | |
return process.nextTick(fn); | |
} | |
function getStats(source) { | |
if (running >= limit) { | |
return defer(function () { | |
getStats(source); | |
}); | |
} | |
running++; | |
fs.lstat(source, function (err, stats) { | |
var item = {}; | |
if (err) { | |
return onError(err); | |
} | |
// We need to get the mode from the stats object and preserve it. | |
item.name = source; | |
item.mode = stats.mode; | |
if (stats.isDirectory()) { | |
return onDir(item); | |
} | |
else if (stats.isFile()) { | |
return onFile(item); | |
} | |
else if (stats.isSymbolicLink()) { | |
// Symlinks don't really need to know about the mode. | |
return onLink(source); | |
} | |
}); | |
} | |
function onFile(file) { | |
var target = file.name.replace(currentPath, targetPath); | |
isWritable(target, function (writable) { | |
if (writable) { | |
return copyFile(file, target); | |
} | |
if(clobber) | |
rmFile(target, function () { | |
copyFile(file, target); | |
}); | |
}); | |
} | |
function copyFile(file, target) { | |
var readStream = fs.createReadStream(file.name), | |
writeStream = fs.createWriteStream(target, { mode: file.mode }); | |
if(transform) { | |
transform(readStream, writeStream,file); | |
} else { | |
readStream.pipe(writeStream); | |
} | |
readStream.once('end', cb); | |
} | |
function rmFile(file, done) { | |
fs.unlink(file, function (err) { | |
if (err) { | |
return onError(err); | |
} | |
return done(); | |
}); | |
} | |
function onDir(dir) { | |
var target = dir.name.replace(currentPath, targetPath); | |
isWritable(target, function (writable) { | |
if (writable) { | |
return mkDir(dir, target); | |
} | |
copyDir(dir.name); | |
}); | |
} | |
function mkDir(dir, target) { | |
fs.mkdir(target, dir.mode, function (err) { | |
if (err) { | |
return onError(err); | |
} | |
copyDir(dir.name); | |
}); | |
} | |
function copyDir(dir) { | |
fs.readdir(dir, function (err, items) { | |
if (err) { | |
return onError(err); | |
} | |
items.forEach(function (item) { | |
startCopy(dir + '/' + item); | |
}); | |
return cb(); | |
}); | |
} | |
function onLink(link) { | |
var target = link.replace(currentPath, targetPath); | |
fs.readlink(link, function (err, resolvedPath) { | |
if (err) { | |
return onError(err); | |
} | |
checkLink(resolvedPath, target); | |
}); | |
} | |
function checkLink(resolvedPath, target) { | |
isWritable(target, function (writable) { | |
if (writable) { | |
return makeLink(resolvedPath, target); | |
} | |
fs.readlink(target, function (err, targetDest) { | |
if (err) { | |
return onError(err); | |
} | |
if (targetDest === resolvedPath) { | |
return cb(); | |
} | |
return rmFile(target, function () { | |
makeLink(resolvedPath, target); | |
}); | |
}); | |
}); | |
} | |
function makeLink(linkPath, target) { | |
fs.symlink(linkPath, target, function (err) { | |
if (err) { | |
return onError(err); | |
} | |
return cb(); | |
}); | |
} | |
function isWritable(path, done) { | |
fs.lstat(path, function (err, stats) { | |
if (err) { | |
if (err.code === 'ENOENT') return done(true); | |
return done(false); | |
} | |
return done(false); | |
}); | |
} | |
function onError(err) { | |
if (options.stopOnError) { | |
return callback(err); | |
} | |
else if (!errs && options.errs) { | |
errs = fs.createWriteStream(options.errs); | |
} | |
else if (!errs) { | |
errs = []; | |
} | |
if (typeof errs.write === 'undefined') { | |
errs.push(err); | |
} | |
else { | |
errs.write(err.stack + '\n\n'); | |
} | |
return cb(); | |
} | |
function cb(skipped) { | |
if (!skipped) running--; | |
finished++; | |
if ((started === finished) && (running === 0)) { | |
return errs ? callback(errs) : callback(null); | |
} | |
} | |
}; | |
// rm -rf | |
var rmrf = function(dir) { | |
var list = fs.readdirSync(dir); | |
for(var i = 0; i < list.length; i++) { | |
var filename = path.join(dir, list[i]); | |
var stat = fs.statSync(filename); | |
if(stat.isDirectory()) | |
rmrf(filename); | |
else | |
fs.unlinkSync(filename); | |
} | |
fs.rmdirSync(dir); | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
the error
node version