From b8ae7be2f7a177cde34f3e0bba9c80ff8ceac5eb Mon Sep 17 00:00:00 2001 From: Vladimir Grichina Date: Sat, 18 Feb 2012 00:35:25 +0200 Subject: [PATCH] Added async readdir --- lib/wrench.js | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ readme.md | 19 +++++++++++++- tests/readdir.js | 54 ++++++++++++++++++++++++++++------------ 3 files changed, 121 insertions(+), 16 deletions(-) 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..3540228 100644 --- a/readme.md +++ b/readme.md @@ -19,6 +19,9 @@ Usage var wrench = require('wrench'), util = require('util'); +// Synchronous operations +// + // Recursively create directories, sub-trees and all. wrench.mkdirSyncRecursive(dir, 0777); @@ -42,7 +45,21 @@ var f = new wrench.LineReader('x.txt'); while(f.hasNextLine()) { util.puts(x.getNextLine()); } + + +// Asynchronous operations +// + +// 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 + } +}); + ``` -It should be noted that these are all currently synchronous operations. Questions, comments? Hit me up. (ryan [at] venodesigns.net | http://twitter.com/ryanmcgrath) diff --git a/tests/readdir.js b/tests/readdir.js index afed9a0..b2d14f0 100644 --- a/tests/readdir.js +++ b/tests/readdir.js @@ -4,29 +4,53 @@ 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.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' - ]; + test.ok(path.existsSync(dir), 'Folders should exist'); 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])); - } + checkResult(test, files); + }, - test.done(); + 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); + } + }); } });