diff options
Diffstat (limited to 'tools/eslint/lib/util/traverse.js')
-rw-r--r-- | tools/eslint/lib/util/traverse.js | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/tools/eslint/lib/util/traverse.js b/tools/eslint/lib/util/traverse.js new file mode 100644 index 0000000000..ba5520e341 --- /dev/null +++ b/tools/eslint/lib/util/traverse.js @@ -0,0 +1,105 @@ +/** + * @fileoverview Simple directory traversal logic. + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +var fs = require("fs"), + path = require("path"), + debug = require("debug"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +debug = debug("eslint:traverse"); + +/** + * Walks a path recursively calling the callback on each file. + * @param {string} name The file or directory path. + * @param {string[]} extensions The file extensions that should cause the callback + * to be called. + * @param {Function} exclude The function to check if file/path should be excluded. + * @param {Function} callback The function to call on each file. + * @returns {void} + * @private + */ +function walk(name, extensions, exclude, callback) { + + var stat, basename; + + stat = fs.statSync(name); + + function traverse(dir, stack) { + stack.push(dir); + + fs.readdirSync(path.join.apply(path, stack)).forEach(function(file) { + var filePath, fileStat; + + // skip all hidded things (dirs, files, links) + if (file[0] === ".") { + return; + } + + filePath = path.join.apply(path, stack.concat([file])); + fileStat = fs.statSync(filePath); + + // if this file or directory is excluded from linting, skip over it. + if (exclude && exclude(filePath)) { + // console.log("Ignoring " + filePath); + debug("Ignoring " + filePath); + return; + } + + // only call callback for files with correct extensions + if (fileStat.isFile() && extensions.indexOf(path.extname(filePath)) > -1) { + callback(filePath); + } else if (fileStat.isDirectory()) { + traverse(file, stack); + } + }); + stack.pop(); + } + + basename = path.basename(name); + + // don't ignore cases like 'eslint ./' + if ((basename !== "." && basename !== ".." && basename[0] === ".") || + (exclude && exclude(name))) { + + debug("Ignoring " + name); + return; + } + + // always call callback for any files that are passed on the command line + if (stat.isFile()) { + callback(name); + } else { + traverse(name, []); + } +} + +/** + * Traverses multiple directories and calls a callback on each file. + * @param {Object} options The option for the traversal. + * param {string[]} options.files An array of file and directory paths to traverse. + * param {Function} options.exclude The function to check if file/path should be excluded. + * @param {Function} callback A function to call for each file. + * @returns {void} + */ +module.exports = function traverse(options, callback) { + + var files = options.files, + exclude = options.exclude, + extensions = options.extensions; + + files.forEach(function(file) { + walk(file, extensions, exclude, callback); + }); + +}; |