summaryrefslogtreecommitdiff
path: root/tools/eslint/lib/util/traverse.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/eslint/lib/util/traverse.js')
-rw-r--r--tools/eslint/lib/util/traverse.js105
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);
+ });
+
+};