changed the way copyDirRecursive works.

- paths needed to be normalized
- using 'preserve' instead of 'forceDelete'. it makes more sense to let users decide if they want to keep the existing folders/subfolders then to ask them if they want to 'forceDelete' the old ones. The default operation will be to keep existing folders.
- added (and fixed) 'inflateSymLinks'. It's a new option that allows users do decide if they want to copy symlinks from original folder as new folders or just copy the symlink.
This commit is contained in:
refaelos 2013-05-22 10:37:47 +03:00
parent fee7f769ae
commit d32c9f46bc

View file

@ -12,7 +12,8 @@
*/ */
var fs = require("fs"), var fs = require("fs"),
_path = require("path"); _path = require("path"),
mkdirp = require("mkdirp");
/* wrench.readdirSyncRecursive("directory_path"); /* wrench.readdirSyncRecursive("directory_path");
@ -166,7 +167,7 @@ exports.rmdirSyncRecursive = function(path, failSilent) {
*/ */
exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) { exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) {
try { try {
if(fs.statSync(newDirLocation).isDirectory()) { if(fs.statSync(newDirLocation).isDirectory()) {
if(typeof opts !== 'undefined' && opts.forceDelete) { if(typeof opts !== 'undefined' && opts.forceDelete) {
exports.rmdirSyncRecursive(newDirLocation); exports.rmdirSyncRecursive(newDirLocation);
} else { } else {
@ -292,7 +293,7 @@ exports.chownSyncRecursive = function(sourceDir, uid, gid) {
*/ */
exports.rmdirRecursive = function rmdirRecursive(dir, failSilent, clbk){ exports.rmdirRecursive = function rmdirRecursive(dir, failSilent, clbk){
fs.readdir(dir, function(err, files){ fs.readdir(dir, function(err, files){
if(err && typeof failSilent === 'boolean' && !failSilent) if(err && typeof failSilent === 'boolean' && !failSilent)
return clbk(err); return clbk(err);
if(typeof failSilent === 'function') if(typeof failSilent === 'function')
@ -328,53 +329,63 @@ exports.copyDirRecursive = function copyDirRecursive(srcDir, newDir, opts, clbk)
if (typeof opts === 'function') if (typeof opts === 'function')
clbk = opts; clbk = opts;
srcDir = _path.normalize(srcDir);
newDir = _path.normalize(newDir);
var handleFile = function(file, newFile, clbk) {
fs.readFile(file, function (err, data) {
fs.writeFile(newFile, data, clbk);
});
};
var handleSymlink = function(file, newFile, clbk) {
fs.readlink(file, function (err, link) {
if (!opts.inflateSymlinks) {
fs.symlink(link, newFile, clbk);
} else {
fs.lstat(srcDir + '/' + link, function (err, stats) {
if (stats.isDirectory()) {
copyDirRecursive(srcDir + '/' + link, newFile, opts, clbk);
} else {
handleFile(srcDir + '/' + link, newFile, clbk);
}
});
}
});
};
var copyDirRecInner = function() { var copyDirRecInner = function() {
fs.stat(srcDir, function (err1, srcDirStat) { fs.readdir(srcDir, function (err, files) {
if (err1) return clbk(err1); if (err) return clbk(err);
fs.readdir(srcDir, function (err, files) { (function copyFiles(err) {
if (err) return clbk(err); if (err) return clbk(err);
(function copyFiles(err) {
if (err) return clbk(err);
var filename = files.shift(); var filename = files.shift();
if (filename === null || typeof filename == 'undefined') {
return clbk(); while (filename && opts.excludeHiddenUnix && /^\./.test(filename)) {
filename = files.shift();
}
if (filename === null || typeof filename == 'undefined') {
return clbk();
}
var file = srcDir + '/' + filename,
newFile = newDir + '/' + filename;
fs.stat(file, function (err, fileStat) {
if (fileStat.isDirectory()) {
copyDirRecursive(file, newFile, opts, copyFiles);
}
else if (fileStat.isSymbolicLink()) {
handleSymlink(file, newFile, copyFiles);
}
else {
handleFile(file, newFile, copyFiles);
} }
if (opts.excludeHiddenUnix && /^\./.test(filename)) });
return clbk(); })();
var file = srcDir + '/' + filename,
newFile = newDir + '/' + filename;
fs.stat(file, function (err, fileStat) {
if (fileStat.isDirectory())
copyDirRecursive(file, newFile, opts, copyFiles);
else if (fileStat.isSymbolicLink()) {
fs.readlink(file, function (err, link) {
if (!opts.inflateSymlinks) {
fs.symlink(link, newFile, copyFiles);
} else {
fs.lstat(srcDir + '/' + link, function (err, stats) {
if (stats.isDirectory()) {
copyDirRecursive(srcDir + '/' + link, newFile, opts, copyFiles);
} else {
fs.readFile(srcDir + '/' + link, function (err, data) {
fs.writeFile(newFile, data, copyFiles);
});
}
});
}
});
}
else
fs.readFile(file, function (err, data) {
fs.writeFile(newFile, data, copyFiles);
});
});
})();
});
}); });
}; };
@ -388,9 +399,14 @@ exports.copyDirRecursive = function copyDirRecursive(srcDir, newDir, opts, clbk)
copyDirRecInner(); copyDirRecInner();
} }
} else { } else {
fs.mkdir(newDir, srcDirStat.mode, function(err){ fs.stat(srcDir, function (err, srcDirStat) {
if (err) return clbk(err); if (err) {
copyDirRecInner(); clbk(new Error('The source directory (probably) doesn\'t exist. error: ' + err));
}
mkdirp(newDir, srcDirStat.mode, function(err){
if (err) return clbk(err);
copyDirRecInner();
});
}); });
} }
}); });