Skip to content

Commit

Permalink
Breaking: migrate from minimatch to node-ignore (fixes eslint#2365)
Browse files Browse the repository at this point in the history
  • Loading branch information
gronke committed Jan 4, 2016
1 parent 2efd8fd commit a974856
Show file tree
Hide file tree
Showing 23 changed files with 815 additions and 278 deletions.
8 changes: 5 additions & 3 deletions docs/user-guide/configuring.md
Expand Up @@ -558,18 +558,20 @@ You can tell ESLint to ignore specific files and directories by creating an `.es

When ESLint is run, it looks in the current working directory to find an `.eslintignore` file before determining which files to lint. If this file is found, then those preferences are applied when traversing directories. Only one `.eslintignore` file can be used at a time, so `.eslintignore` files other than the one in the current working directory will not be used.

Globs are matched using [minimatch](https://github.com/isaacs/minimatch), so a number of features are available:
Globs are matched using [node-ignore](https://github.com/kaelzhang/node-ignore), so a number of features are available:

* Lines beginning with `#` are treated as comments and do not affect ignore patterns.
* Paths are relative to `.eslintignore` location or the current working directory. This also influences paths passed via `--ignore-pattern`.
* Ignore patterns behave according to the `.gitignore` [specification](http://git-scm.com/docs/gitignore)
* Lines preceded by `!` are negated patterns that re-include a pattern that was ignored by an earlier pattern.
* Brace expansion can refer to multiple files in a pattern. For example, `file.{js,ts,coffee}` will ignore `file.js`, `file.ts`, and `file.coffee`.

In addition to any patterns in a `.eslintignore` file, ESLint always ignores files in `node_modules/**` and `bower_components/**`.
In addition to any patterns in a `.eslintignore` file, ESLint always ignores files in `/node_modules/**` and `/bower_components/**`.

For example, placing the following `.eslintignore` file in the current working directory will ignore all of `node_modules`, `bower_components`, any files with the extensions `.ts.js` or `.coffee.js` extension that might have been transpiled, and anything in the `build/` directory except `build/index.js`:

```text
# node_modules and bower_components ignored by default
# /node_modules and /bower_components ignored by default
# Ignore files compiled from TypeScript and CoffeeScript
**/*.{ts,coffee}.js
Expand Down
76 changes: 56 additions & 20 deletions lib/cli-engine.js
Expand Up @@ -22,6 +22,7 @@ var fs = require("fs"),

assign = require("object-assign"),
debug = require("debug"),
glob = require("glob"),
shell = require("shelljs"),

rules = require("./rules"),
Expand Down Expand Up @@ -76,7 +77,6 @@ var DEFAULT_PARSER = require("../conf/eslint.json").parser;
// Private
//------------------------------------------------------------------------------


var defaultOptions = {
configFile: null,
baseConfig: false,
Expand All @@ -97,6 +97,7 @@ var defaultOptions = {
cacheFile: ".eslintcache",
fix: false,
allowInlineConfig: true,
warnIgnoredByDefault: true,
cwd: process.cwd()
},
loadedPlugins = Object.create(null);
Expand Down Expand Up @@ -287,7 +288,7 @@ function createIgnoreResult(filePath) {
{
fatal: false,
severity: 1,
message: "File ignored because of your .eslintignore file. Use --no-ignore to override."
message: "File ignored because of a matching ignore pattern. Use --no-ignore to override."
}
],
errorCount: 0,
Expand Down Expand Up @@ -391,13 +392,16 @@ function getCacheFile(cacheFile, cwd) {
*/
function CLIEngine(options) {

options = assign(defaultOptions, options || {});
options.cwd = options.cwd || process.cwd();

/**
* Stored options for this instance
* @type {Object}
*/
this.options = assign(defaultOptions, options);
this.options = assign(Object.create(defaultOptions), options || {});


var cacheFile = getCacheFile(this.options.cacheLocation || this.options.cacheFile, this.options.cwd);

/**
Expand Down Expand Up @@ -537,13 +541,25 @@ CLIEngine.prototype = {
options = this.options,
fileCache = this._fileCache,
configHelper = new Config(options),
ignoredPaths = new IgnoredPaths(options),
globOptions,
stats,
startTime,
prevConfig; // the previous configuration used

startTime = Date.now();

patterns = this.resolveFileGlobPatterns(patterns);
globOptions = {
nodir: true
};

var cwd = options.cwd || process.cwd;
patterns = this.resolveFileGlobPatterns(patterns.map(function(pattern) {
if (pattern.indexOf("/") !== 0) {
return path.join(cwd, pattern);
}
return pattern;
}));

/**
* Calculates the hash of the config file used to validate a given file
Expand Down Expand Up @@ -575,11 +591,31 @@ CLIEngine.prototype = {
* Executes the linter on a file defined by the `filename`. Skips
* unsupported file extensions and any files that are already linted.
* @param {string} filename The resolved filename of the file to be linted
* @param {boolean} warnIgnored always warn when a file is ignored
* @returns {void}
*/
function executeOnFile(filename) {
function executeOnFile(filename, warnIgnored) {
var hashOfConfig;

if (options.ignore !== false) {

if (ignoredPaths.contains(filename, "custom")) {
if (warnIgnored) {
results.push(createIgnoreResult(filename));
}
return;
}

if (ignoredPaths.contains(filename, "default")) {
if (options.warnIgnoredByDefault || warnIgnored) {
results.push(createIgnoreResult(filename));
}
return;
}

}

filename = path.resolve(filename);
if (processed[filename]) {
return;
}
Expand Down Expand Up @@ -639,18 +675,19 @@ CLIEngine.prototype = {
results.push(res);
}

// Lint each desired file
globUtil.listFilesToProcess(patterns, options).forEach(executeOnFile);
patterns.forEach(function(pattern) {

// only warn for files explicitly passed on the command line
if (options.ignore) {
patterns.forEach(function(file) {
var fullPath = path.resolve(file);
if (shell.test("-f", fullPath) && !processed[fullPath]) {
results.push(createIgnoreResult(file));
}
});
}
var file = path.resolve(pattern);

if (shell.test("-f", file)) {
executeOnFile(fs.realpathSync(pattern), !shell.test("-d", file));
} else {
glob.sync(pattern, globOptions).forEach(function(globMatch) {
executeOnFile(globMatch, false);
});
}

});

stats = calculateStatsPerRun(results);

Expand Down Expand Up @@ -680,10 +717,9 @@ CLIEngine.prototype = {
stats,
options = this.options,
configHelper = new Config(options),
ignoredPaths = IgnoredPaths.load(options),
exclude = ignoredPaths.contains.bind(ignoredPaths);
ignoredPaths = new IgnoredPaths(options);

if (filename && options.ignore && exclude(filename)) {
if (filename && (options.ignore !== false) && ignoredPaths.contains(filename)) {
results.push(createIgnoreResult(filename));
} else {
results.push(processText(text, configHelper, filename, options.fix, options.allowInlineConfig));
Expand Down Expand Up @@ -719,7 +755,7 @@ CLIEngine.prototype = {
var ignoredPaths;

if (this.options.ignore) {
ignoredPaths = IgnoredPaths.load(this.options);
ignoredPaths = new IgnoredPaths(this.options);
return ignoredPaths.contains(filePath);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/file-finder.js
Expand Up @@ -45,7 +45,7 @@ function getDirectoryEntries(directory) {
*/
function FileFinder(files, cwd) {
this.fileNames = Array.isArray(files) ? files : [files];
this.cwd = cwd;
this.cwd = cwd || process.cwd();
this.cache = {};
}

Expand Down

0 comments on commit a974856

Please sign in to comment.