From 9432b67f76ddd7b8a73d37e8a041a9ff25822f0c Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Mon, 14 Nov 2022 20:20:17 +0100 Subject: [PATCH] fix: throw error for first unmatched pattern (#16533) * fix: throw error for first unmatched pattern * Update lib/eslint/eslint-helpers.js Co-authored-by: Nicholas C. Zakas Co-authored-by: Nicholas C. Zakas --- lib/eslint/eslint-helpers.js | 52 +++++++++++++++------------------ tests/lib/eslint/flat-eslint.js | 25 ++++++++++++++++ 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/lib/eslint/eslint-helpers.js b/lib/eslint/eslint-helpers.js index 9f2f5e8c31e..bf91700ba35 100644 --- a/lib/eslint/eslint-helpers.js +++ b/lib/eslint/eslint-helpers.js @@ -76,7 +76,7 @@ class UnmatchedSearchPatternsError extends Error { constructor({ basePath, unmatchedPatterns, patterns, rawPatterns }) { super(`No files matching '${rawPatterns}' in '${basePath}' were found.`); this.basePath = basePath; - this.patternsToCheck = unmatchedPatterns; + this.unmatchedPatterns = unmatchedPatterns; this.patterns = patterns; this.rawPatterns = rawPatterns; } @@ -337,49 +337,43 @@ async function globSearch({ } /** - * Checks to see if there are any ignored results for a given search. This - * happens either when there are unmatched patterns during a search or if - * a search returns no results. + * Throws an error for unmatched patterns. The error will only contain information about the first one. + * Checks to see if there are any ignored results for a given search. * @param {Object} options The options for this function. * @param {string} options.basePath The directory to search. * @param {Array} options.patterns An array of glob patterns * that were used in the original search. * @param {Array} options.rawPatterns An array of glob patterns * as the user inputted them. Used for errors. - * @param {Array} options.patternsToCheck An array of glob patterns - * to use for this check. - * @returns {void} - * @throws {NoFilesFoundError} If there is a pattern that doesn't match - * any files and `errorOnUnmatchedPattern` is true. - * @throws {AllFilesIgnoredError} If there is a pattern that matches files - * when there are no ignores. + * @param {Array} options.unmatchedPatterns A non-empty array of glob patterns + * that were unmatched in the original search. + * @returns {void} Always throws an error. + * @throws {NoFilesFoundError} If the first unmatched pattern + * doesn't match any files even when there are no ignores. + * @throws {AllFilesIgnoredError} If the first unmatched pattern + * matches some files when there are no ignores. */ -async function checkForIgnoredResults({ +async function throwErrorForUnmatchedPatterns({ basePath, patterns, rawPatterns, - patternsToCheck = patterns + unmatchedPatterns }) { - for (const pattern of patternsToCheck) { + const pattern = unmatchedPatterns[0]; + const rawPattern = rawPatterns[patterns.indexOf(pattern)]; - const patternHasMatch = await globMatch({ - basePath, - pattern - }); + const patternHasMatch = await globMatch({ + basePath, + pattern + }); - if (patternHasMatch) { - throw new AllFilesIgnoredError( - rawPatterns[patterns.indexOf(pattern)] - ); - } + if (patternHasMatch) { + throw new AllFilesIgnoredError(rawPattern); } // if we get here there are truly no matches - throw new NoFilesFoundError( - rawPatterns[patterns.indexOf(patternsToCheck[0])], - true - ); + throw new NoFilesFoundError(rawPattern, true); } /** @@ -446,9 +440,9 @@ async function globMultiSearch({ searches, configs, errorOnUnmatchedPattern }) { if (errorOnUnmatchedPattern) { - await checkForIgnoredResults({ + await throwErrorForUnmatchedPatterns({ ...currentSearch, - patternsToCheck: error.patternsToCheck + unmatchedPatterns: error.unmatchedPatterns }); } diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index 570bab2ada1..8f5b1024fbb 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -863,6 +863,31 @@ describe("FlatESLint", () => { }, /All files matched by 'subdir2\/\*\.js' are ignored/u); }); + it("should always throw an error for the first unmatched file pattern", async () => { + eslint = new FlatESLint({ + cwd: getFixturePath("example-app2"), + overrideConfig: { + ignores: ["subdir1/*.js", "subdir2/*.js"] + } + }); + + await assert.rejects(async () => { + await eslint.lintFiles(["doesnotexist1/*.js", "doesnotexist2/*.js"]); + }, /No files matching 'doesnotexist1\/\*\.js' were found/u); + + await assert.rejects(async () => { + await eslint.lintFiles(["doesnotexist1/*.js", "subdir1/*.js"]); + }, /No files matching 'doesnotexist1\/\*\.js' were found/u); + + await assert.rejects(async () => { + await eslint.lintFiles(["subdir1/*.js", "doesnotexist1/*.js"]); + }, /All files matched by 'subdir1\/\*\.js' are ignored/u); + + await assert.rejects(async () => { + await eslint.lintFiles(["subdir1/*.js", "subdir2/*.js"]); + }, /All files matched by 'subdir1\/\*\.js' are ignored/u); + }); + it("should not throw an error for an ignored file pattern when errorOnUnmatchedPattern is false", async () => { eslint = new FlatESLint({ cwd: getFixturePath("example-app2"),