2 * @fileoverview Simple directory traversal logic.
3 * @author Nicholas C. Zakas
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 var fs = require("fs"),
13 path = require("path"),
14 debug = require("debug");
16 //------------------------------------------------------------------------------
18 //------------------------------------------------------------------------------
20 debug = debug("eslint:traverse");
23 * Walks a path recursively calling the callback on each file.
24 * @param {string} name The file or directory path.
25 * @param {string[]} extensions The file extensions that should cause the callback
27 * @param {Function} exclude The function to check if file/path should be excluded.
28 * @param {Function} callback The function to call on each file.
32 function walk(name, extensions, exclude, callback) {
36 stat = fs.statSync(name);
38 function traverse(dir, stack) {
41 fs.readdirSync(path.join.apply(path, stack)).forEach(function(file) {
42 var filePath, fileStat;
44 // skip all hidded things (dirs, files, links)
45 if (file[0] === ".") {
49 filePath = path.join.apply(path, stack.concat([file]));
50 fileStat = fs.statSync(filePath);
52 // if this file or directory is excluded from linting, skip over it.
53 if (exclude && exclude(filePath)) {
54 // console.log("Ignoring " + filePath);
55 debug("Ignoring " + filePath);
59 // only call callback for files with correct extensions
60 if (fileStat.isFile() && extensions.indexOf(path.extname(filePath)) > -1) {
62 } else if (fileStat.isDirectory()) {
63 traverse(file, stack);
69 basename = path.basename(name);
71 // don't ignore cases like 'eslint ./'
72 if ((basename !== "." && basename !== ".." && basename[0] === ".") ||
73 (exclude && exclude(name))) {
75 debug("Ignoring " + name);
79 // always call callback for any files that are passed on the command line
88 * Traverses multiple directories and calls a callback on each file.
89 * @param {Object} options The option for the traversal.
90 * param {string[]} options.files An array of file and directory paths to traverse.
91 * param {Function} options.exclude The function to check if file/path should be excluded.
92 * @param {Function} callback A function to call for each file.
95 module.exports = function traverse(options, callback) {
97 var files = options.files,
98 exclude = options.exclude,
99 extensions = options.extensions;
101 files.forEach(function(file) {
102 walk(file, extensions, exclude, callback);