add readdirSyncRecursive, normalize tabs, add tests/runner #11

Merged
millermedeiros merged 2 commits from master into master 2012-01-14 12:13:08 -08:00
9 changed files with 149 additions and 66 deletions

View file

@ -11,7 +11,50 @@
* ~ Ryan McGrath (ryan [at] venodesigns.net) * ~ Ryan McGrath (ryan [at] venodesigns.net)
*/ */
var fs = require("fs"); var fs = require("fs"),
_path = require("path");
/* wrench.readdirSyncRecursive("directory_path");
*
* Recursively dives through directories and read the contents of all the
* children directories.
*/
exports.readdirSyncRecursive = function(baseDir) {
baseDir = baseDir.replace(/\/$/, '');
var readdirSyncRecursive = function(baseDir) {
var files = [],
curFiles,
nextDirs,
isDir = function(fname){
return fs.statSync( _path.join(baseDir, fname) ).isDirectory();
},
prependBaseDir = function(fname){
return _path.join(baseDir, fname);
};
curFiles = fs.readdirSync(baseDir);
nextDirs = curFiles.filter(isDir);
curFiles = curFiles.map(prependBaseDir);
files = files.concat( curFiles );
while (nextDirs.length) {
files = files.concat( readdirSyncRecursive( _path.join(baseDir, nextDirs.shift()) ) );
}
return files;
};
// convert absolute paths to relative
var fileList = readdirSyncRecursive(baseDir).map(function(val){
return val.replace(baseDir + '/', '');
});
return fileList;
};
/* wrench.rmdirSyncRecursive("directory_path", forceDelete, failSilent); /* wrench.rmdirSyncRecursive("directory_path", forceDelete, failSilent);
* *
@ -20,14 +63,14 @@ var fs = require("fs");
* Asynchronous version. :\ * Asynchronous version. :\
*/ */
exports.rmdirSyncRecursive = function(path, failSilent) { exports.rmdirSyncRecursive = function(path, failSilent) {
var files; var files;
try { try {
files = fs.readdirSync(path); files = fs.readdirSync(path);
} catch (err) { } catch (err) {
if(failSilent) return; if(failSilent) return;
throw new Error(err.message); throw new Error(err.message);
} }
/* Loop through and delete everything in the sub-tree after checking it */ /* Loop through and delete everything in the sub-tree after checking it */
for(var i = 0; i < files.length; i++) { for(var i = 0; i < files.length; i++) {
@ -57,7 +100,7 @@ exports.rmdirSyncRecursive = function(path, failSilent) {
* Note: Directories should be passed to this function without a trailing slash. * Note: Directories should be passed to this function without a trailing slash.
*/ */
exports.copyDirSyncRecursive = function(sourceDir, newDirLocation) { exports.copyDirSyncRecursive = function(sourceDir, newDirLocation) {
/* Copying over something is... tricky. The user should know what they're doing at this point, so... /* Copying over something is... tricky. The user should know what they're doing at this point, so...
* blow any existing directory away! * blow any existing directory away!
*/ */
try { try {
@ -65,13 +108,13 @@ exports.copyDirSyncRecursive = function(sourceDir, newDirLocation) {
} catch(e) { } } catch(e) { }
/* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */ /* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
var checkDir = fs.statSync(sourceDir); var checkDir = fs.statSync(sourceDir);
fs.mkdirSync(newDirLocation, checkDir.mode); fs.mkdirSync(newDirLocation, checkDir.mode);
var files = fs.readdirSync(sourceDir); var files = fs.readdirSync(sourceDir);
for(var i = 0; i < files.length; i++) { for(var i = 0; i < files.length; i++) {
var currFile = fs.statSync(sourceDir + "/" + files[i]); var currFile = fs.statSync(sourceDir + "/" + files[i]);
if(currFile.isDirectory()) { if(currFile.isDirectory()) {
/* Create a new directory in our copied version... */ /* Create a new directory in our copied version... */
@ -85,8 +128,8 @@ exports.copyDirSyncRecursive = function(sourceDir, newDirLocation) {
} else { } else {
/* At this point, we've hit a file actually worth copying... so copy it on over. */ /* At this point, we've hit a file actually worth copying... so copy it on over. */
var contents = fs.readFileSync(sourceDir + "/" + files[i]); var contents = fs.readFileSync(sourceDir + "/" + files[i]);
fs.writeFileSync(newDirLocation + "/" + files[i], contents); fs.writeFileSync(newDirLocation + "/" + files[i], contents);
} }
} }
}; };
@ -100,8 +143,8 @@ exports.copyDirSyncRecursive = function(sourceDir, newDirLocation) {
exports.chmodSyncRecursive = function(sourceDir, filemode) { exports.chmodSyncRecursive = function(sourceDir, filemode) {
var files = fs.readdirSync(sourceDir); var files = fs.readdirSync(sourceDir);
for(var i = 0; i < files.length; i++) { for(var i = 0; i < files.length; i++) {
var currFile = fs.statSync(sourceDir + "/" + files[i]); var currFile = fs.statSync(sourceDir + "/" + files[i]);
if(currFile.isDirectory()) { if(currFile.isDirectory()) {
/* ...and recursion this thing right on back. */ /* ...and recursion this thing right on back. */
@ -109,7 +152,7 @@ exports.chmodSyncRecursive = function(sourceDir, filemode) {
} else { } else {
/* At this point, we've hit a file actually worth copying... so copy it on over. */ /* At this point, we've hit a file actually worth copying... so copy it on over. */
fs.chmod(sourceDir + "/" + files[i], filemode); fs.chmod(sourceDir + "/" + files[i], filemode);
} }
} }
/* Finally, chmod the parent directory */ /* Finally, chmod the parent directory */
@ -127,8 +170,8 @@ exports.chmodSyncRecursive = function(sourceDir, filemode) {
exports.chownSyncRecursive = function(sourceDir, uid, gid) { exports.chownSyncRecursive = function(sourceDir, uid, gid) {
var files = fs.readdirSync(sourceDir); var files = fs.readdirSync(sourceDir);
for(var i = 0; i < files.length; i++) { for(var i = 0; i < files.length; i++) {
var currFile = fs.statSync(sourceDir + "/" + files[i]); var currFile = fs.statSync(sourceDir + "/" + files[i]);
if(currFile.isDirectory()) { if(currFile.isDirectory()) {
/* ...and recursion this thing right on back. */ /* ...and recursion this thing right on back. */
@ -136,7 +179,7 @@ exports.chownSyncRecursive = function(sourceDir, uid, gid) {
} else { } else {
/* At this point, we've hit a file actually worth chowning... so own it. */ /* At this point, we've hit a file actually worth chowning... so own it. */
fs.chownSync(sourceDir + "/" + files[i], uid, gid); fs.chownSync(sourceDir + "/" + files[i], uid, gid);
} }
} }
/* Finally, chown the parent directory */ /* Finally, chown the parent directory */
@ -220,64 +263,64 @@ exports.copyDirRecursive = function copyDirRecursive(srcDir, newDir, clbk) {
}; };
var mkdirSyncRecursive = function(path, mode) { var mkdirSyncRecursive = function(path, mode) {
var self = this; var self = this;
try { try {
fs.mkdirSync(path, mode); fs.mkdirSync(path, mode);
} catch(err) { } catch(err) {
if(err.code == "ENOENT") { if(err.code == "ENOENT") {
var slashIdx = path.lastIndexOf("/"); var slashIdx = path.lastIndexOf("/");
if(slashIdx > 0) { if(slashIdx > 0) {
var parentPath = path.substring(0, slashIdx); var parentPath = path.substring(0, slashIdx);
mkdirSyncRecursive(parentPath, mode); mkdirSyncRecursive(parentPath, mode);
mkdirSyncRecursive(path, mode); mkdirSyncRecursive(path, mode);
} else { } else {
throw err; throw err;
} }
} else if(err.code == "EEXIST") { } else if(err.code == "EEXIST") {
return; return;
} else { } else {
throw err; throw err;
} }
} }
}; };
exports.mkdirSyncRecursive = mkdirSyncRecursive; exports.mkdirSyncRecursive = mkdirSyncRecursive;
exports.LineReader = function(filename, bufferSize) { exports.LineReader = function(filename, bufferSize) {
this.bufferSize = bufferSize || 8192; this.bufferSize = bufferSize || 8192;
this.buffer = ""; this.buffer = "";
this.fd = fs.openSync(filename, "r"); this.fd = fs.openSync(filename, "r");
this.currentPosition = 0; this.currentPosition = 0;
} };
exports.LineReader.prototype = { exports.LineReader.prototype = {
getBufferAndSetCurrentPosition: function(position) { getBufferAndSetCurrentPosition: function(position) {
var res = fs.readSync(this.fd, this.bufferSize, position, "ascii"); var res = fs.readSync(this.fd, this.bufferSize, position, "ascii");
this.buffer += res[0]; this.buffer += res[0];
if(res[1] === 0) return -1; if(res[1] === 0) return -1;
this.currentPosition = position + res[1]; this.currentPosition = position + res[1];
return this.currentPosition; return this.currentPosition;
}, },
hasNextLine: function() { hasNextLine: function() {
while(this.buffer.indexOf('\n') === -1) { while(this.buffer.indexOf('\n') === -1) {
this.getBufferAndSetCurrentPosition(this.currentPosition); this.getBufferAndSetCurrentPosition(this.currentPosition);
if(this.currentPosition === -1) return false; if(this.currentPosition === -1) return false;
} }
if(this.buffer.indexOf("\n") > -1) return true; if(this.buffer.indexOf("\n") > -1) return true;
return false; return false;
}, },
getNextLine: function() { getNextLine: function() {
var lineEnd = this.buffer.indexOf("\n"), var lineEnd = this.buffer.indexOf("\n"),
result = this.buffer.substring(0, lineEnd); result = this.buffer.substring(0, lineEnd);
this.buffer = this.buffer.substring(result.length + 1, this.buffer.length); this.buffer = this.buffer.substring(result.length + 1, this.buffer.length);
return result; return result;
} }
}; };
// vim: et ts=4 sw=4 // vim: et ts=4 sw=4

View file

@ -25,6 +25,9 @@ wrench.mkdirSyncRecursive(dir, 0777);
// Recursively delete the entire sub-tree of a directory, then kill the directory // Recursively delete the entire sub-tree of a directory, then kill the directory
wrench.rmdirSyncRecursive('my_directory_name', failSilently); wrench.rmdirSyncRecursive('my_directory_name', failSilently);
// Recursively read directories contents.
wrench.readdirSyncRecursive('my_directory_name');
// Recursively chmod the entire sub-tree of a directory // Recursively chmod the entire sub-tree of a directory
wrench.chmodSyncRecursive('my_directory_name', 0755); wrench.chmodSyncRecursive('my_directory_name', 0755);

View file

@ -4,7 +4,7 @@ var wrench = require('wrench');
var path = require('path'); var path = require('path');
module.exports = testCase({ module.exports = testCase({
testMkdirSyncRecursive: function(test) { test_mkdirSyncRecursive: function(test) {
var dir = __dirname + '/_tmp/foo/bar'; var dir = __dirname + '/_tmp/foo/bar';
test.equals(path.existsSync(dir), false, 'Dir shouldn\'t exist - clean it up manually?'); test.equals(path.existsSync(dir), false, 'Dir shouldn\'t exist - clean it up manually?');

0
tests/readdir/bar.txt Normal file
View file

View file

View file

View file

View file

@ -0,0 +1,30 @@
var testCase = require('nodeunit').testCase;
var fs = require('fs');
var wrench = require('wrench');
var path = require('path');
module.exports = testCase({
test_readdirSyncRecursive: function(test) {
var dir = __dirname + '/readdir';
test.equals(path.existsSync(dir), true, 'Folders should exist');
var check = [
'bar.txt',
'foo',
'foo/bar',
'foo/dolor.md',
'foo/lorem.txt',
'foo/bar/ipsum.js'
];
var files = wrench.readdirSyncRecursive(dir);
test.equals(files.length, check.length, 'number of paths is correct');
test.deepEqual(files, check, 'list shows all files and folders');
test.done();
}
});
// vim: et ts=4 sw=4

7
tests/runner.js Normal file
View file

@ -0,0 +1,7 @@
// `nodeunit tests/runner`
// will run all the tests
module.exports = {
group_mkdirSyncRecursive : require('./mkdirSyncRecursive'),
group_readdirSyncRecursive : require('./readdirSyncRecursive')
};