Skip to content
This repository has been archived by the owner on Jun 19, 2019. It is now read-only.

Improved file filtering for copyDirSyncRecursive #57

Merged
merged 4 commits into from
Oct 15, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 90 additions & 28 deletions lib/wrench.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ exports.readdirRecursive = function(baseDir, fn) {





/* wrench.rmdirSyncRecursive("directory_path", forceDelete, failSilent);
*
* Recursively dives through directories and obliterates everything about it. This is a
Expand Down Expand Up @@ -156,6 +158,62 @@ exports.rmdirSyncRecursive = function(path, failSilent) {
return fs.rmdirSync(path);
};



function isFileIncluded(opts, dir, filename) {

function isMatch(filter) {
if (typeof filter === 'function') {
return filter(filename, dir) === true;
}
else {
// Maintain backwards compatibility and use just the filename
return filename.match(filter);
}
}

if (opts.include || opts.exclude) {
if (opts.exclude) {
if (isMatch(opts.exclude)) {
return false;
}
}

if (opts.include) {
if (isMatch(opts.include)) {
return true;
}
else {
return false;
}
}

return true;
}
else if (opts.filter) {
var filter = opts.filter;

if (!opts.whitelist) {
// if !opts.whitelist is false every file or directory
// which does match opts.filter will be ignored
return isMatch(filter) ? false : true;
} else {
// if opts.whitelist is true every file or directory
// which doesn't match opts.filter will be ignored
return !isMatch(filter) ? false : true;
}
}

return true;
}

exports.copyFileSync = function(srcFile, destFile, preserveFiles) {
if (preserveFiles && fs.existsSync(destFile)) return;

var contents = fs.readFileSync(srcFile);
fs.writeFileSync(destFile, contents);
};

/* wrench.copyDirSyncRecursive("directory_to_copy", "new_directory_location", opts);
*
* Recursively dives through a directory and moves all its files to a new location. This is a
Expand All @@ -165,14 +223,16 @@ exports.rmdirSyncRecursive = function(path, failSilent) {
* Note: Directories should be passed to this function without a trailing slash.
*/
exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) {
opts = opts || {};

try {
if(fs.statSync(newDirLocation).isDirectory()) {
if(typeof opts !== 'undefined' && opts.forceDelete) {
exports.rmdirSyncRecursive(newDirLocation);
} else {
return new Error('You are trying to delete a directory that already exists. Specify forceDelete in the opts argument to override this. Bailing~');
}
}
if(fs.statSync(newDirLocation).isDirectory()) {
if(typeof opts !== 'undefined' && opts.forceDelete) {
exports.rmdirSyncRecursive(newDirLocation);
} else {
return new Error('You are trying to delete a directory that already exists. Specify forceDelete in the opts argument to override this. Bailing~');
}
}
} catch(e) { }

/* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
Expand All @@ -185,23 +245,25 @@ exports.copyDirSyncRecursive = function(sourceDir, newDirLocation, opts) {
}

var files = fs.readdirSync(sourceDir);
var hasFilter = opts.filter || opts.include || opts.exclude;
var preserveFiles = opts.preserveFiles === true;

for(var i = 0; i < files.length; i++) {
// ignores all files or directories which match the RegExp in opts.filter
if(typeof opts !== 'undefined') {
if(!opts.whitelist && opts.filter && files[i].match(opts.filter)) continue;
// if opts.whitelist is true every file or directory which doesn't match opts.filter will be ignored
if(opts.whitelist && opts.filter && !files[i].match(opts.filter)) continue;
if(typeof opts !== 'undefined') {
if (hasFilter) {
if (!isFileIncluded(opts, sourceDir, files[i])) {
continue;
}
}

if (opts.excludeHiddenUnix && /^\./.test(files[i])) continue;
}

var currFile = fs.lstatSync(_path.join(sourceDir, files[i]));

var fCopyFile = function(srcFile, destFile) {
if(typeof opts !== 'undefined' && opts.preserveFiles && fs.existsSync(destFile)) return;

var contents = fs.readFileSync(srcFile);
fs.writeFileSync(destFile, contents);
exports.copyFileSync(srcFile, destFile, preserveFiles);
};

if(currFile.isDirectory()) {
Expand Down Expand Up @@ -291,10 +353,10 @@ exports.chownSyncRecursive = function(sourceDir, uid, gid) {
exports.rmdirRecursive = function rmdirRecursive(dir, failSilent, clbk){
fs.readdir(dir, function(err, files){
if(err && typeof failSilent === 'boolean' && !failSilent)
return clbk(err);
return clbk(err);

if(typeof failSilent === 'function')
clbk = failSilent;
if(typeof failSilent === 'function')
clbk = failSilent;

(function rmFile(err){
if (err) return clbk(err);
Expand Down Expand Up @@ -325,16 +387,16 @@ exports.rmdirRecursive = function rmdirRecursive(dir, failSilent, clbk){
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 !== '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;

fs.stat(srcDir, function(err, srcDirStat){
if (err) return clbk(err);
Expand Down
8 changes: 7 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,16 @@ wrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end
excludeHiddenUnix: bool, // Whether to copy hidden Unix files or not (preceding .)
preserveFiles: bool, // If we're overwriting something and the file already exists, keep the existing
inflateSymlinks: bool, // Whether to follow symlinks or not when copying files
filter: regexp, // A filter to match files against; if matches, do nothing (exclude).
filter: regexpOrFunction, // A filter to match files against; if matches, do nothing (exclude).
whitelist: bool, // if true every file or directory which doesn't match filter will be ignored
include: regexpOrFunction, // An include filter (either a regexp or a function)
exclude: regexpOrFunction // An exclude filter (either a regexp or a function)
});

// Note: If a RegExp is provided then then it will be matched against the filename. If a function is
// provided then the signature should be the following:
// function(filename, dir) { return result; }

// Read lines in from a file until you hit the end
var f = new wrench.LineReader('x.txt');
while(f.hasNextLine()) {
Expand Down