diff --git a/lib/wrench.js b/lib/wrench.js index 1ddd91d..c509bcf 100644 --- a/lib/wrench.js +++ b/lib/wrench.js @@ -55,6 +55,70 @@ exports.readdirSyncRecursive = function(baseDir) { return fileList; }; +/* wrench.readdirRecursive("directory_path", function(error, files) {}); + * + * Recursively dives through directories and read the contents of all the + * children directories. + * + * Asynchronous, so returns results/error in callback. + * Callback receives the of files in currently recursed directory. + * When no more directories are left, callback is called with null for all arguments. + * + */ +exports.readdirRecursive = function(baseDir, fn) { + baseDir = baseDir.replace(/\/$/, ''); + + var waitCount = 0; + + function readdirRecursive(curDir) { + var files = [], + curFiles, + nextDirs, + prependcurDir = function(fname){ + return _path.join(curDir, fname); + }; + + waitCount++; + fs.readdir(curDir, function(e, curFiles) { + waitCount--; + + curFiles = curFiles.map(prependcurDir); + + curFiles.forEach(function(it) { + waitCount++; + + fs.stat(it, function(e, stat) { + waitCount--; + + if (e) { + fn(e); + } else { + if (stat.isDirectory()) { + readdirRecursive(it); + } + } + + if (waitCount == 0) { + fn(null, null); + } + }); + }); + + fn(null, curFiles.map(function(val) { + // convert absolute paths to relative + return val.replace(baseDir + '/', ''); + })); + + if (waitCount == 0) { + fn(null, null); + } + }); + }; + + readdirRecursive(baseDir); +}; + + /* wrench.rmdirSyncRecursive("directory_path", forceDelete, failSilent); * diff --git a/readme.md b/readme.md index e821b19..1462160 100644 --- a/readme.md +++ b/readme.md @@ -18,7 +18,10 @@ Usage ``` javascript var wrench = require('wrench'), util = require('util'); +``` +### Synchronous operations +``` javascript // Recursively create directories, sub-trees and all. wrench.mkdirSyncRecursive(dir, 0777); @@ -43,6 +46,19 @@ while(f.hasNextLine()) { util.puts(x.getNextLine()); } ``` -It should be noted that these are all currently synchronous operations. + +### Asynchronous operations +``` javascript +// Recursively read directories contents +var files = []; +wrench.readdirRecursive('my_directory_name', function(error, curFiles) { + if (files) { + files = files.concat(curFiles); + } else { + // files list contains all the directory contents now + } +}); + +``` Questions, comments? Hit me up. (ryan [at] venodesigns.net | http://twitter.com/ryanmcgrath) diff --git a/tests/mkdirSyncRecursive.js b/tests/mkdir.js similarity index 100% rename from tests/mkdirSyncRecursive.js rename to tests/mkdir.js diff --git a/tests/readdir.js b/tests/readdir.js new file mode 100644 index 0000000..b2d14f0 --- /dev/null +++ b/tests/readdir.js @@ -0,0 +1,57 @@ +var testCase = require('nodeunit').testCase; +var fs = require('fs'); +var wrench = require('../lib/wrench'); +var path = require('path'); +var _und = require("underscore"); + + +function checkResult(test, files) { + var check = [ + 'bar.txt', + 'foo', + 'foo/bar', + 'foo/dolor.md', + 'foo/lorem.txt', + 'foo/bar/ipsum.js' + ]; + + test.equals(files.length, check.length, 'number of paths is correct'); + + _und.each(check, function(it) { + test.ok(_und.include(files, it), 'path ' + it + ' should be returned'); + }); + + test.done(); +} + +module.exports = testCase({ + test_readdirSyncRecursive: function(test) { + var dir = __dirname + '/readdir'; + + test.ok(path.existsSync(dir), 'Folders should exist'); + + var files = wrench.readdirSyncRecursive(dir); + + checkResult(test, files); + }, + + test_readdirRecursive: function(test) { + var dir = __dirname + '/readdir'; + + test.ok(path.existsSync(dir), 'Folders should exist'); + + var allFiles = []; + + wrench.readdirRecursive(dir, function(e, files) { + if (e) throw e; + + if (files) { + allFiles = allFiles.concat(files); + } else { + checkResult(test, allFiles); + } + }); + } +}); + +// vim: et ts=4 sw=4 diff --git a/tests/readdirSyncRecursive.js b/tests/readdirSyncRecursive.js deleted file mode 100644 index afed9a0..0000000 --- a/tests/readdirSyncRecursive.js +++ /dev/null @@ -1,33 +0,0 @@ -var testCase = require('nodeunit').testCase; -var fs = require('fs'); -var wrench = require('../lib/wrench'); -var path = require('path'); -var _und = require("underscore"); - -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'); - for (var filename in files) { - test.ok(_und.include(check, files[filename])); - } - - test.done(); - } -}); - -// vim: et ts=4 sw=4 diff --git a/tests/runner.js b/tests/runner.js index b353d1f..a5cc8f7 100644 --- a/tests/runner.js +++ b/tests/runner.js @@ -2,6 +2,6 @@ // will run all the tests module.exports = { - group_mkdirSyncRecursive : require('./mkdirSyncRecursive'), - group_readdirSyncRecursive : require('./readdirSyncRecursive') + group_mkdir: require('./mkdir'), + group_readdir: require('./readdir') };