Skip to content

Commit

Permalink
Fix: skip dot files and ignored dirs on traverse (fixes #1077, relate…
Browse files Browse the repository at this point in the history
…d to #814)
  • Loading branch information
Vitaly Puzrin committed Jul 12, 2014
1 parent b8f2a61 commit 5e601fb
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 44 deletions.
46 changes: 24 additions & 22 deletions lib/cli-engine.js
Expand Up @@ -155,40 +155,42 @@ CLIEngine.prototype = {
executeOnFiles: function(files) {

var results = [],
processed = [],
configHelper = new Config(this.options),
ignoredPaths = IgnoredPaths.load(this.options);
ignoredPaths = IgnoredPaths.load(this.options),
exclude = ignoredPaths.contains.bind(ignoredPaths);

traverse({
files: files
files: files,
exclude: this.options.ignore ? exclude : false
}, function(filename) {

debug("Processing " + filename);

if (path.extname(filename) === ".js") {

var shouldIgnore = this.options.ignore ? ignoredPaths.contains(filename) : false;

if (!shouldIgnore) {
results.push(processFile(filename, configHelper));
} else if (files.indexOf(filename) > -1) {

debug("Ignoring " + filename);

// only warn for files explicitly passes on the command line
results.push({
filePath: filename,
messages: [
{
fatal: false,
message: "File ignored because of your .eslintignore file. Use --no-ignore to override."
}
]
});
}
processed.push(filename);
results.push(processFile(filename, configHelper));
}

}.bind(this));

// only warn for files explicitly passes on the command line
if (this.options.ignore) {
files.forEach(function(file) {
if (path.extname(file) === ".js" && processed.indexOf(file) === -1) {
results.push({
filePath: file,
messages: [
{
fatal: false,
message: "File ignored because of your .eslintignore file. Use --no-ignore to override."
}
]
});
}
});
}

return {
results: results
};
Expand Down
49 changes: 27 additions & 22 deletions lib/util/traverse.js
Expand Up @@ -11,55 +11,51 @@

var fs = require("fs"),
path = require("path"),
minimatch = require("minimatch");
debug = require("debug");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

/**
* Determines if a file or directory should be excluded from traversal.
* @param {string} name The path name to check.
* @param {string[]} exclude The paths to exclude.
* @returns {boolean} True if the file should be excluded, false if not.
* @private
*/
function isExcluded(name, exclude) {
return exclude.some(function(exclusion) {
return minimatch(name, exclusion);
});
}
debug = debug("eslint:traverse");

/**
* Walks a path recursively calling the callback on each file.
* @param {string} name The file or directory path.
* @param {string[]} exclude Array of glob patterns to exclude.
* @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, exclude, callback){

var stat;
var stat, basename;

try {
stat = fs.statSync(name);
} catch (ex){
/* istanbul ignore next too hard to make fs.stat fail */
return [];
return;
}

function traverse(dir, stack){
stack.push(dir);

fs.readdirSync(path.join.apply(path, stack)).forEach(function(file){
var filePath, stat;

// skip all hidded things (dirs, files, links)
if (file[0] === ".") {
return;
}

fs.readdirSync(path.join.apply(path, stack)).forEach(function(file){
var filePath = path.join.apply(path, stack.concat([file])),
stat = fs.statSync(filePath);
filePath = path.join.apply(path, stack.concat([file]));
stat = fs.statSync(filePath);

//if this file or directory is excluded from linting, skip over it.
if (isExcluded(filePath, exclude)) {
if (exclude && exclude(filePath)) {
//console.log("Ignoring " + filePath);
debug("Ignoring " + filePath);
return;
}

Expand All @@ -72,12 +68,21 @@ function walk(name, exclude, callback){
stack.pop();
}

basename = path.basename(name);

// don't ignore cases like 'eslint ./'
if ((basename !== "." && basename !== ".." && basename[0] === ".") ||
(exclude && exclude(name))) {

debug("Ignoring " + name);
return;
}

if (stat.isFile()) {
callback(name);
} else {
traverse(name, []);
}

}

/**
Expand All @@ -91,7 +96,7 @@ function walk(name, exclude, callback){
module.exports = function traverse(options, callback) {

var files = options.files,
exclude = options.exclude || [];
exclude = options.exclude;

files.forEach(function(file) {
walk(file, exclude, callback);
Expand Down
Empty file.
Empty file.
1 change: 1 addition & 0 deletions tests/fixtures/traverse/found.js
@@ -0,0 +1 @@
'test.js'
60 changes: 60 additions & 0 deletions tests/lib/traverse.js
@@ -0,0 +1,60 @@
/**
* @fileoverview Tests for traverse.
*/

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

var assert = require("chai").assert,
path = require("path"),
traverse = require("../../lib/util/traverse");


//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

describe("traverse", function() {

it("should ignore dot files and dirs", function() {
traverse(
{ files: [ path.resolve(__dirname, "..", "fixtures", "traverse") ] },
function(file) {
assert.notEqual(file.indexOf("."), -1);
}
);
});

it("should ignore files by exclude option", function() {
var files = [];

traverse(
{
files: [ path.resolve(__dirname, "..", "fixtures", "traverse") ],
exclude: function() {
return true;
}
},
function(file) {
files.push(file);
}
);

assert.equal(files.length, 0);
});

it("should find normal files", function() {
var files = [];

traverse(
{ files: [ path.resolve(__dirname, "..", "fixtures", "traverse") ] },
function(file) {
files.push(file);
}
);

assert.notEqual(files.length, 0);
});

});

0 comments on commit 5e601fb

Please sign in to comment.