Skip to content

Commit

Permalink
New: Add no-error-on-unmatched-pattern flag (fixes eslint#10587)
Browse files Browse the repository at this point in the history
Add flag to prevent errors when a pattern or --ext is not matched
  • Loading branch information
ncraley committed Oct 4, 2019
1 parent 3642342 commit 612610e
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 13 deletions.
5 changes: 5 additions & 0 deletions docs/user-guide/command-line-interface.md
Expand Up @@ -79,6 +79,7 @@ Caching:
Miscellaneous:
--init Run config initialization wizard - default: false
--env-info Output execution environment information - default: false
--no-error-on-unmatched-pattern Prevent errors when pattern is unmatched - default: false
--debug Output debugging information
-h, --help Show help
-v, --version Output the version number
Expand Down Expand Up @@ -451,6 +452,10 @@ The resulting configuration file will be created in the current directory.

This option outputs information about the execution environment, including the version of Node, npm, and local and global installations of ESLint. The ESLint team may ask for this information to help solve bugs.

#### `--no-error-on-unmatched-pattern`

This option prevents errors when a quoted glob pattern or `--ext` is unmatched. This will not prevent errors when your shell can't match a glob.

#### `--debug`

This option outputs debugging information to the console. This information is useful when you're seeing a problem and having a hard time pinpointing it. The ESLint team may ask for this debugging information to help solve bugs.
Expand Down
3 changes: 2 additions & 1 deletion lib/cli-engine/cli-engine.js
Expand Up @@ -563,7 +563,8 @@ class CLIEngine {
extensions: options.extensions,
globInputPaths: options.globInputPaths,
ignore: options.ignore,
ignoredPaths
ignoredPaths,
errorOnUnmatchedPattern: options.errorOnUnmatchedPattern
});
const lintResultCache =
options.cache ? new LintResultCache(cacheFilePath) : null;
Expand Down
26 changes: 15 additions & 11 deletions lib/cli-engine/file-enumerator.js
Expand Up @@ -191,7 +191,8 @@ class FileEnumerator {
extensions = [".js"],
globInputPaths = true,
ignore = true,
ignoredPaths = new IgnoredPaths({ cwd, ignore })
ignoredPaths = new IgnoredPaths({ cwd, ignore }),
errorOnUnmatchedPattern = true
} = {}) {
internalSlotsMap.set(this, {
configArrayFactory,
Expand All @@ -213,7 +214,8 @@ class FileEnumerator {
ignoredPathsWithDotfiles: new IgnoredPaths({
...ignoredPaths.options,
dotfiles: true
})
}),
errorOnUnmatchedPattern
});
}

Expand All @@ -231,7 +233,7 @@ class FileEnumerator {
* @returns {IterableIterator<FileAndConfig>} The found files.
*/
*iterateFiles(patternOrPatterns) {
const { globInputPaths } = internalSlotsMap.get(this);
const { globInputPaths, errorOnUnmatchedPattern } = internalSlotsMap.get(this);
const patterns = Array.isArray(patternOrPatterns)
? patternOrPatterns
: [patternOrPatterns];
Expand Down Expand Up @@ -270,14 +272,16 @@ class FileEnumerator {
}

// Raise an error if any files were not found.
if (!foundRegardlessOfIgnored) {
throw new NoFilesFoundError(
pattern,
!globInputPaths && isGlob(pattern)
);
}
if (!found) {
throw new AllFilesIgnoredError(pattern);
if (errorOnUnmatchedPattern) {
if (!foundRegardlessOfIgnored) {
throw new NoFilesFoundError(
pattern,
!globInputPaths && isGlob(pattern)
);
}
if (!found) {
throw new AllFilesIgnoredError(pattern);
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion lib/cli.js
Expand Up @@ -68,7 +68,8 @@ function translateOptions(cliOptions) {
fixTypes: cliOptions.fixType,
allowInlineConfig: cliOptions.inlineConfig,
reportUnusedDisableDirectives: cliOptions.reportUnusedDisableDirectives,
resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo
resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo,
errorOnUnmatchedPattern: cliOptions.errorOnUnmatchedPattern
};
}

Expand Down
6 changes: 6 additions & 0 deletions lib/options.js
Expand Up @@ -230,6 +230,12 @@ module.exports = optionator({
default: "false",
description: "Output execution environment information"
},
{
option: "error-on-unmatched-pattern",
type: "Boolean",
default: "true",
description: "Prevent errors when pattern is unmatched"
},
{
option: "debug",
type: "Boolean",
Expand Down
3 changes: 3 additions & 0 deletions tests/fixtures/unmatched-patterns/failing.js
@@ -0,0 +1,3 @@
var foo = "bar";
if (foo) {
foo = "bar2";
5 changes: 5 additions & 0 deletions tests/fixtures/unmatched-patterns/passing.js2
@@ -0,0 +1,5 @@
let foo = "bar";

if (foo) {
foo = "bar2";
}
68 changes: 68 additions & 0 deletions tests/lib/cli.js
Expand Up @@ -347,6 +347,74 @@ describe("cli", () => {
});
});

describe("when executing without no-error-on-unmatched-pattern flag", () => {
it("should throw an error on unmatched glob pattern", () => {
const filePath = getFixturePath("unmatched-patterns");
const globPattern = "*.js3";

assert.throws(() => {
cli.execute(`"${filePath}/${globPattern}"`);
}, `No files matching '${filePath}/${globPattern}' were found.`);
});

it("should throw an error on unmatched --ext", () => {
const filePath = getFixturePath("unmatched-patterns");
const extension = ".js3";

assert.throws(() => {
cli.execute(`--ext ${extension} ${filePath}`);
}, `No files matching '${filePath}' were found`);
});
});

describe("when executing with no-error-on-unmatched-pattern flag", () => {
it("should not throw an error on unmatched node glob syntax patterns", () => {
const filePath = getFixturePath("unmatched-patterns");
const exit = cli.execute(`--no-error-on-unmatched-pattern "${filePath}/*.js3"`);

assert.strictEqual(exit, 0);
});

it("should not throw an error on unmatched --ext", () => {
const filePath = getFixturePath("unmatched-patterns");
const exit = cli.execute(`--no-error-on-unmatched-pattern --ext .js3 ${filePath}`);

assert.strictEqual(exit, 0);
});
});

describe("when executing with no-error-on-unmatched-pattern flag and multiple patterns", () => {
it("should not throw an error on multiple unmatched node glob syntax patterns", () => {
const filePath = getFixturePath("unmatched-patterns");
const exit = cli.execute(`--no-error-on-unmatched-pattern ${filePath}/*.js3 ${filePath}/*.js4`);

assert.strictEqual(exit, 0);
});

it("should still throw an error on when a matched pattern has lint errors", () => {
const filePath = getFixturePath("unmatched-patterns");
const exit = cli.execute(`--no-error-on-unmatched-pattern ${filePath}/*.js3 ${filePath}/*.js`);

assert.strictEqual(exit, 1);
});
});

describe("when executing with no-error-on-unmatched-pattern flag and multiple --ext arguments", () => {
it("should not throw an error on multiple unmatched --ext arguments", () => {
const filePath = getFixturePath("unmatched-patterns");
const exit = cli.execute(`--no-error-on-unmatched-pattern --ext .js3 --ext .js4 ${filePath}`);

assert.strictEqual(exit, 0);
});

it("should still throw an error on when a matched pattern has lint errors", () => {
const filePath = getFixturePath("unmatched-patterns");
const exit = cli.execute(`--no-error-on-unmatched-pattern --ext .js3 --ext .js ${filePath}`);

assert.strictEqual(exit, 1);
});
});

describe("when executing with help flag", () => {
it("should print out help", () => {
assert.strictEqual(cli.execute("-h"), 0);
Expand Down

0 comments on commit 612610e

Please sign in to comment.