From 1713d0758b083f3840d724505f997a7cb20ff384 Mon Sep 17 00:00:00 2001 From: ncraley Date: Fri, 20 Dec 2019 15:42:18 -0500 Subject: [PATCH] New: Add no-error-on-unmatched-pattern flag (fixes #10587) (#12377) 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 | 1 + lib/cli-engine/file-enumerator.js | 22 +++--- 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, 103 insertions(+), 10 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 c8871b07d2f..89f42744eb3 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 0b1c76bac68..22336a91de2 100644 --- a/lib/cli-engine/cli-engine.js +++ b/lib/cli-engine/cli-engine.js @@ -576,6 +576,7 @@ class CLIEngine { cwd: options.cwd, extensions: options.extensions, globInputPaths: options.globInputPaths, + errorOnUnmatchedPattern: options.errorOnUnmatchedPattern, ignore: options.ignore }); const lintResultCache = diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js index b5a082b71a6..c67e01aef9b 100644 --- a/lib/cli-engine/file-enumerator.js +++ b/lib/cli-engine/file-enumerator.js @@ -190,6 +190,7 @@ class FileEnumerator { configArrayFactory = new CascadingConfigArrayFactory({ cwd }), extensions = [".js"], globInputPaths = true, + errorOnUnmatchedPattern = true, ignore = true } = {}) { internalSlotsMap.set(this, { @@ -208,6 +209,7 @@ class FileEnumerator { "u" ), globInputPaths, + errorOnUnmatchedPattern, ignoreFlag: ignore }); } @@ -226,7 +228,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]; @@ -265,14 +267,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);