Repository: eslint/eslint
File: lib/eslint/eslint-helpers.js (JavaScript)

Code before:
                return false;
            }

            /*
             * Optimization: We need to track when patterns are left unmatched
             * and so we use `unmatchedPatterns` to do that. There is a bit of
             * complexity here because the same file can be matched by more than
             * one pattern. So, when we start, we actually need to test every
             * pattern against every file. Once we know there are no remaining
             * unmatched patterns, then we can switch to just looking for the
             * first matching pattern for improved speed.
             */
            const matchesPattern = unmatchedPatterns.size > 0
                ? matchers.reduce((previousValue, matcher) => {
                    const pathMatches = matcher.match(relativePath);

                    // update unmatched patterns for potential errors
                    if (pathMatches) {
                        unmatchedPatterns.delete(matcher.pattern);
                    }

                    return pathMatches || previousValue;
                }, false)
                : matchers.some(matcher => matcher.match(relativePath));

            return matchesPattern && !configs.isFileIgnored(entry.path);
        }

    })).map(entry => entry.path);

    // now check to see if we have any unmatched patterns
    if (errorOnUnmatchedPattern && unmatchedPatterns.size > 0) {
        throw new UnmatchedSearchPatternsErrror({
            basePath,
            unmatchedPatterns: [...unmatchedPatterns].map(
                pattern => relativeToPatterns.get(pattern)
            ),
            patterns,
            rawPatterns
        });
    }

    return filePaths;
}

/**
 * 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.
 * @param {Object} options The options for this function.
 * @param {string} options.basePath The directory to search.

Review comment (bug):
Here, if the file is ignored, it still removes patterns from `unmatchedPatterns`, which seems wrong because when there are multiple patterns and at least one matches some non-ignored files, patterns that match only ignored files will not be reported.

For example, run:

```
eslint "lib/*.js" "tools/*.js" --ignore-pattern "tools/*.js"
```

In flat config mode, this command exits with 0 because `"lib/*.js"` matches something, although `"tools/*.js"` does not (it matches only ignored files).

In eslintrc mode, the same command exits with 1:

```
Oops! Something went wrong! :(

ESLint: 8.26.0

You are linting "tools/*.js", but all of the files matching the glob pattern "tools/*.js" are ignored.

...
```

I think that eslintrc behavior is correct and that flat eslint should work the same.

Code after:
                return false;
            }

            /*
             * Optimization: We need to track when patterns are left unmatched
             * and so we use `unmatchedPatterns` to do that. There is a bit of
             * complexity here because the same file can be matched by more than
             * one pattern. So, when we start, we actually need to test every
             * pattern against every file. Once we know there are no remaining
             * unmatched patterns, then we can switch to just looking for the
             * first matching pattern for improved speed.
             */
            const matchesPattern = unmatchedPatterns.size > 0
                ? matchers.reduce((previousValue, matcher) => {
                    const pathMatches = matcher.match(relativePath);

                    /*
                     * We updated the unmatched patterns set only if the path
                     * matches and the file isn't ignored. If the file is
                     * ignored, that means there wasn't a match for the
                     * pattern so it should not be removed.
                     *
                     * Performance note: isFileIgnored() aggressively caches
                     * results so there is no performance penalty for calling
                     * it twice with the same argument.
                     */
                    if (pathMatches && !configs.isFileIgnored(entry.path)) {
                        unmatchedPatterns.delete(matcher.pattern);
                    }

                    return pathMatches || previousValue;
                }, false)
                : matchers.some(matcher => matcher.match(relativePath));

            return matchesPattern && !configs.isFileIgnored(entry.path);
        }

    })).map(entry => entry.path);

    // now check to see if we have any unmatched patterns
    if (errorOnUnmatchedPattern && unmatchedPatterns.size > 0) {
        throw new UnmatchedSearchPatternsError({
            basePath,
            unmatchedPatterns: [...unmatchedPatterns].map(
                pattern => relativeToPatterns.get(pattern)
            ),
            patterns,
            rawPatterns
        });
    }