From b1ab66d0361adf560891de6b9db60436d2fd53f8 Mon Sep 17 00:00:00 2001 From: Noel Raley Date: Fri, 4 Oct 2019 19:39:33 -0400 Subject: [PATCH] New: Add no-error-on-unmatched-pattern flag (fixes #10587) Add flag to prevent errors when a pattern or --ext is not matched --- docs/user-guide/command-line-interface.md | 5 ++ lib/cli-engine/cli-engine.js | 3 +- lib/cli-engine/file-enumerator.js | 26 ++++--- lib/cli.js | 3 +- lib/options.js | 6 ++ tests/fixtures/unmatched-patterns/failing.js | 3 + tests/fixtures/unmatched-patterns/passing.js2 | 5 ++ tests/lib/cli.js | 68 +++++++++++++++++++ 8 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 tests/fixtures/unmatched-patterns/failing.js create mode 100644 tests/fixtures/unmatched-patterns/passing.js2 diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md index 8938bc91f24..b290bc50be9 100644 --- a/docs/user-guide/command-line-interface.md +++ b/docs/user-guide/command-line-interface.md @@ -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 @@ -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. diff --git a/lib/cli-engine/cli-engine.js b/lib/cli-engine/cli-engine.js index e768da837d0..0fdd2e29a87 100644 --- a/lib/cli-engine/cli-engine.js +++ b/lib/cli-engine/cli-engine.js @@ -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; diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js index 59083fc4636..fc236842116 100644 --- a/lib/cli-engine/file-enumerator.js +++ b/lib/cli-engine/file-enumerator.js @@ -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, @@ -213,7 +214,8 @@ class FileEnumerator { ignoredPathsWithDotfiles: new IgnoredPaths({ ...ignoredPaths.options, dotfiles: true - }) + }), + errorOnUnmatchedPattern }); } @@ -231,7 +233,7 @@ class FileEnumerator { * @returns {IterableIterator} The found files. */ *iterateFiles(patternOrPatterns) { - const { globInputPaths } = internalSlotsMap.get(this); + const { globInputPaths, errorOnUnmatchedPattern } = internalSlotsMap.get(this); const patterns = Array.isArray(patternOrPatterns) ? patternOrPatterns : [patternOrPatterns]; @@ -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); + } } } diff --git a/lib/cli.js b/lib/cli.js index 18a917cf0b0..944b4b79353 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -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 }; } diff --git a/lib/options.js b/lib/options.js index 83bf9afc22c..98dc04b6eb3 100644 --- a/lib/options.js +++ b/lib/options.js @@ -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", diff --git a/tests/fixtures/unmatched-patterns/failing.js b/tests/fixtures/unmatched-patterns/failing.js new file mode 100644 index 00000000000..e24993ff6f6 --- /dev/null +++ b/tests/fixtures/unmatched-patterns/failing.js @@ -0,0 +1,3 @@ +var foo = "bar"; +if (foo) { + foo = "bar2"; diff --git a/tests/fixtures/unmatched-patterns/passing.js2 b/tests/fixtures/unmatched-patterns/passing.js2 new file mode 100644 index 00000000000..425be7cea23 --- /dev/null +++ b/tests/fixtures/unmatched-patterns/passing.js2 @@ -0,0 +1,5 @@ +let foo = "bar"; + +if (foo) { + foo = "bar2"; +} diff --git a/tests/lib/cli.js b/tests/lib/cli.js index e0f10d5ae4d..6af3b5c838e 100644 --- a/tests/lib/cli.js +++ b/tests/lib/cli.js @@ -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);