Closed nedredmond closed 1 year ago
I solved this locally:
// picomatch does does inclusive disjunctions (ORs) by default,
// so we need to do some extra work to get conjunctive (AND) matches.
if (globsList.length > 1 && matchAllGlobs) {
// conjunctive glob match
const matchers = globsList.map((glob) => picomatch(glob));
filters.push((path) => matchers.every((matcher) => matcher(path)));
} else {
// disjunctive glob match
filters.push((path) => picomatch(globsList)(path));
}
Would love to see a built-in solution.
I see that this is exactly how it's handled in micromatch
, which I wasn't aware of before I made this issue! I'll go ahead and close it.
micromatch.all = (str, patterns, options) => {
if (typeof str !== 'string') {
throw new TypeError(`Expected a string: "${util.inspect(str)}"`);
}
return [].concat(patterns).every(p => picomatch(p, options)(str));
};
As the documentation says,
isMatch
will match any of the provided globs when provided an array. This creates an issue for a use case in which an array of negative matchers are provided.For example, if a developer wanted to match a path without given matches, each glob would negate the other (unless a path had all of the strings):
picomatch(["!(**/__tests__/**)", "!(**/dist/**)"])
The above would match any path with
/__tests__/
in it as long as it did not also have/dist/
, and vice versa, and ends up matching all files (since test files don't often end up in dist directories).Of course, we could change this to a single (but more difficult to write and grok) glob, but it would be more intuitive to use a "match all" option-- a function like
isMatchAll()
or an option likematchAll: true
.