diff --git a/lib/utils.js b/lib/utils.js index dd4605e4c..4b699f6ab 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -12,7 +12,8 @@ var async = require('../deps/async'), fs = require('fs'), sys = require('sys'), Script = process.binding('evals').Script, - http = require('http'); + http = require('http'), + path = require('path'); /** @@ -53,33 +54,44 @@ exports.modulePaths = function (paths, callback) { return cb(null, [p]); } if (stats.isDirectory()) { - fs.readdir(p, function (err, files) { - if (err) { - return cb(err); - } - - // filter out any filenames with unsupported extensions - var modules = files.filter(function (filename) { - return extensionPattern.exec(filename); - }); - - // remove extension from module name and prepend the - // directory path - var fullpaths = modules.map(function (filename) { - var mod_name = filename.replace(extensionPattern, ''); - return [p, mod_name].join('/'); - }); - - // sort filenames here, because Array.map changes order - fullpaths.sort(); - - cb(null, fullpaths); + var files = exports.readDirRecursive(p); + + // filter out any filenames with unsupported extensions + var modules = files.filter(function (filename) { + return extensionPattern.exec(filename); + }); + + // remove extension from module name and prepend the + // directory path + var fullpaths = modules.map(function (filename) { + var mod_name = filename.replace(extensionPattern, ''); + return [p, mod_name].join('/'); }); + + // sort filenames here, because Array.map changes order + fullpaths.sort(); + + cb(null, fullpaths); } }); }, callback); }; +exports.readDirRecursive = function(dir) { + var list = []; + fs.readdirSync(dir).forEach(function(entityName) { + var entityPath = path.join(dir, entityName); + if ( fs.statSync(entityPath).isDirectory() ) { + exports.readDirRecursive(entityPath).forEach(function(file) { + list.push(path.join(entityName, file)); + }); + } else { + list.push(entityName); + } + }); + return list; +}; + /** * Evaluates JavaScript files in a sandbox, returning the context. The first * argument can either be a single filename or an array of filenames. If