new features in copyDirRecursive #55

Closed
refaelos wants to merge 7 commits from master into master
2 changed files with 97 additions and 46 deletions

View file

@ -12,7 +12,8 @@
*/
var fs = require("fs"),
_path = require("path");
_path = require("path"),
mkdirp = require("mkdirp");
/* wrench.readdirSyncRecursive("directory_path");
@ -166,7 +167,7 @@ exports.rmdirSyncRecursive = function(path, failSilent) {
*/
exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) {
try {
if(fs.statSync(newDirLocation).isDirectory()) {
if(fs.statSync(newDirLocation).isDirectory()) {
if(typeof opts !== 'undefined' && opts.forceDelete) {
exports.rmdirSyncRecursive(newDirLocation);
} else {
@ -202,6 +203,8 @@ exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) {
var contents = fs.readFileSync(srcFile);
fs.writeFileSync(destFile, contents);
var stat = fs.lstatSync(srcFile);
fs.chmodSync(destFile, stat.mode);
};
if(currFile.isDirectory()) {
@ -289,12 +292,21 @@ exports.chownSyncRecursive = function(sourceDir, uid, gid) {
* Recursively dives through directories and obliterates everything about it.
*/
exports.rmdirRecursive = function rmdirRecursive(dir, failSilent, clbk){
if (clbk === null || typeof clbk == 'undefined') {
clbk = function(err) {};
}
fs.readdir(dir, function(err, files){
if(err && typeof failSilent === 'boolean' && !failSilent)
return clbk(err);
if(err) {
if (typeof failSilent === 'boolean' && failSilent) {
return clbk(null);
} else {
return clbk(err);
}
}
if(typeof failSilent === 'function')
clbk = failSilent;
if(typeof failSilent === 'function')
clbk = failSilent;
(function rmFile(err){
if (err) return clbk(err);
@ -315,59 +327,97 @@ exports.rmdirRecursive = function rmdirRecursive(dir, failSilent, clbk){
});
};
/* wrench.copyDirRecursive("directory_to_copy", "new_location", {forceDelete: bool}, callback);
/* wrench.copyDirRecursive("directory_to_copy", "new_location", {preserve: bool, inflateSymlinks:bool, excludeHiddenUnix:bool }, callback);
*
* Recursively dives through a directory and moves all its files to a new
* location. Specify forceDelete to force directory overwrite.
* location.
*
* Note: Directories should be passed to this function without a trailing slash.
*/
exports.copyDirRecursive = function copyDirRecursive(srcDir, newDir, opts, clbk) {
fs.stat(newDir, function(err, newDirStat){
if(!err) {
if(typeof opts !== 'undefined' && typeof opts !== 'function' && opts.forceDelete)
return exports.rmdirRecursive(newDir, function(err){
copyDirRecursive.apply(this, arguments);
});
else
return clbk(new Error('You are trying to delete a directory that already exists. Specify forceDelete in an options object to override this.'));
}
if(typeof opts === 'function')
clbk = opts;
if (typeof opts === 'function')
clbk = opts;
srcDir = _path.normalize(srcDir);
newDir = _path.normalize(newDir);
fs.stat(srcDir, function(err, srcDirStat){
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() {
fs.readdir(srcDir, function (err, files) {
if (err) return clbk(err);
fs.mkdir(newDir, srcDirStat.mode, function(err){
(function copyFiles(err) {
if (err) return clbk(err);
fs.readdir(srcDir, function(err, files){
var filename = files.shift();
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);
}
});
})();
});
};
fs.stat(newDir, function(err, newDirStat){
if (!err) {
if ((typeof opts !== 'undefined' && typeof opts !== 'function' && !opts.preserve) && (newDirStat.isDirectory())) {
return exports.rmdirRecursive(newDir, function(err){
copyDirRecursive(srcDir, newDir, opts, clbk);
});
} else {
copyDirRecInner();
}
} else {
fs.stat(srcDir, function (err, srcDirStat) {
if (err) {
clbk(new Error('The source directory (probably) doesn\'t exist. error: ' + err));
}
mkdirp(newDir, srcDirStat.mode, function(err){
if (err) return clbk(err);
(function copyFiles(err){
if (err) return clbk(err);
var filename = files.shift();
if (filename === null || typeof filename == 'undefined')
return clbk(null);
var file = srcDir+'/'+filename,
newFile = newDir+'/'+filename;
fs.stat(file, function(err, fileStat){
if (fileStat.isDirectory())
copyDirRecursive(file, newFile, copyFiles);
else if (fileStat.isSymbolicLink())
fs.readlink(file, function(err, link){
fs.symlink(link, newFile, copyFiles);
});
else
fs.readFile(file, function(err, data){
fs.writeFile(newFile, data, copyFiles);
});
});
})();
copyDirRecInner();
});
});
});
}
});
};

View file

@ -18,6 +18,7 @@
},
"dependencies": {
"mkdirp": "*"
},
"devDependencies": {