Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(util): Replace micromatch with picomatch to fix issues with negated globs #11287

Merged
merged 4 commits into from Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -60,7 +60,7 @@
"jest-watch-typeahead": "^0.6.0",
"jquery": "^3.2.1",
"lerna": "^4.0.0",
"micromatch": "^4.0.2",
"micromatch": "^4.0.4",
danez marked this conversation as resolved.
Show resolved Hide resolved
"mlh-tsd": "^0.14.1",
"mock-fs": "^4.4.1",
"node-notifier": "^9.0.0",
Expand Down
5 changes: 3 additions & 2 deletions packages/jest-util/package.json
Expand Up @@ -19,12 +19,13 @@
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"is-ci": "^3.0.0",
"micromatch": "^4.0.2"
"picomatch": "^2.2.3"
},
"devDependencies": {
"@types/graceful-fs": "^4.1.2",
"@types/is-ci": "^2.0.0",
"@types/micromatch": "^4.0.0"
"@types/micromatch": "^4.0.1",
Copy link
Member

@SimenB SimenB Apr 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need this one?

"@types/picomatch": "^2.2.1"
},
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
Expand Down
26 changes: 26 additions & 0 deletions packages/jest-util/src/__tests__/globsToMatcher.test.ts
Expand Up @@ -70,3 +70,29 @@ it('works like micromatch with empty globs', () => {
micromatch(['some-module.test.js'], globs).length > 0,
);
});

it('works like micromatch with pure negated extglobs', () => {
const globs = ['**/*.js', '!(some-module.test.js)'];
const matcher = globsToMatcher(globs);

expect(matcher('some-module.js')).toBe(
micromatch(['some-module.js'], globs).length > 0,
);

expect(matcher('some-module.test.js')).toBe(
micromatch(['some-module.test.js'], globs).length > 0,
);
});

it('works like micromatch with negated extglobs', () => {
const globs = ['**/*.js', '!(tests|coverage)/*.js'];
const matcher = globsToMatcher(globs);

expect(matcher('some-module.js')).toBe(
micromatch(['some-module.js'], globs).length > 0,
);

expect(matcher('tests/some-module.test.js')).toBe(
micromatch(['tests/some-module.test.js'], globs).length > 0,
);
});
20 changes: 10 additions & 10 deletions packages/jest-util/src/globsToMatcher.ts
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import micromatch = require('micromatch');
import picomatch = require('picomatch');
import type {Config} from '@jest/types';
import replacePathSepForGlob from './replacePathSepForGlob';

Expand All @@ -16,15 +16,15 @@ const globsToMatchersMap = new Map<
{isMatch: Matcher; negated: boolean}
>();

const micromatchOptions = {dot: true};
const picomatchOptions = {dot: true};

/**
* Converts a list of globs into a function that matches a path against the
* globs.
*
* Every time micromatch is called, it will parse the glob strings and turn
* them into regexp instances. Instead of calling micromatch repeatedly with
* the same globs, we can use this function which will build the micromatch
* Every time picomatch is called, it will parse the glob strings and turn
* them into regexp instances. Instead of calling picomatch repeatedly with
* the same globs, we can use this function which will build the picomatch
* matchers ahead of time and then have an optimized path for determining
* whether an individual path matches.
*
Expand All @@ -44,13 +44,13 @@ export default function globsToMatcher(globs: Array<Config.Glob>): Matcher {

const matchers = globs.map(glob => {
if (!globsToMatchersMap.has(glob)) {
// Matchers that are negated have different behavior than matchers that
// are not negated, so we need to store this information ahead of time.
const {negated} = micromatch.scan(glob, micromatchOptions);
const isMatch = picomatch(glob, picomatchOptions, true);

const matcher = {
isMatch: micromatch.matcher(glob, micromatchOptions),
negated,
isMatch,
// Matchers that are negated have different behavior than matchers that
// are not negated, so we need to store this information ahead of time.
negated: isMatch.state.negated || !!isMatch.state.negatedExtglob,
danez marked this conversation as resolved.
Show resolved Hide resolved
};

globsToMatchersMap.set(glob, matcher);
Expand Down
33 changes: 29 additions & 4 deletions yarn.lock
Expand Up @@ -2581,7 +2581,7 @@ __metadata:
jest-watch-typeahead: ^0.6.0
jquery: ^3.2.1
lerna: ^4.0.0
micromatch: ^4.0.2
micromatch: ^4.0.4
mlh-tsd: ^0.14.1
mock-fs: ^4.4.1
node-notifier: ^9.0.0
Expand Down Expand Up @@ -4690,7 +4690,7 @@ __metadata:
languageName: node
linkType: hard

"@types/micromatch@npm:^4.0.0":
"@types/micromatch@npm:^4.0.0, @types/micromatch@npm:^4.0.1":
version: 4.0.1
resolution: "@types/micromatch@npm:4.0.1"
dependencies:
Expand Down Expand Up @@ -4780,6 +4780,13 @@ __metadata:
languageName: node
linkType: hard

"@types/picomatch@npm:^2.2.1":
version: 2.2.1
resolution: "@types/picomatch@npm:2.2.1"
checksum: 6da30597711a4f8688a04d07cfa462324c4e62d96d9b6075d5da580c1512b818af3c574cde3a60f36dd5d4d6c8186cb6d42ad85e8d8fa204176246dda641251d
languageName: node
linkType: hard

"@types/prettier@npm:*, @types/prettier@npm:^2.0.0, @types/prettier@npm:^2.1.5":
version: 2.2.2
resolution: "@types/prettier@npm:2.2.2"
Expand Down Expand Up @@ -14008,12 +14015,13 @@ fsevents@^1.2.7:
"@jest/types": ^27.0.0-next.7
"@types/graceful-fs": ^4.1.2
"@types/is-ci": ^2.0.0
"@types/micromatch": ^4.0.0
"@types/micromatch": ^4.0.1
"@types/node": "*"
"@types/picomatch": ^2.2.1
chalk: ^4.0.0
graceful-fs: ^4.2.4
is-ci: ^3.0.0
micromatch: ^4.0.2
picomatch: ^2.2.3
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -15872,6 +15880,16 @@ fsevents@^1.2.7:
languageName: node
linkType: hard

"micromatch@npm:^4.0.4":
danez marked this conversation as resolved.
Show resolved Hide resolved
version: 4.0.4
resolution: "micromatch@npm:4.0.4"
dependencies:
braces: ^3.0.1
picomatch: ^2.2.3
checksum: bc522ad93c086aa176f50fea2dc8060a8f7d7a621c811cf9ba02a1912577cc100190508166d721231465f10a575a40ec8a1bffc23bbc2c0108fcbf02e4be04ed
languageName: node
linkType: hard

"miller-rabin@npm:^4.0.0":
version: 4.0.1
resolution: "miller-rabin@npm:4.0.1"
Expand Down Expand Up @@ -17866,6 +17884,13 @@ fsevents@^1.2.7:
languageName: node
linkType: hard

"picomatch@npm:^2.2.3":
version: 2.2.3
resolution: "picomatch@npm:2.2.3"
checksum: f8c9323bc3b21ff448e81dd32277135d781abae5d53a1415d69a4ce6317a2c11404d449c550110b8fa402c07d5e80ff0e2657f263a312517cc809e9010d25791
languageName: node
linkType: hard

"pify@npm:^2.0.0, pify@npm:^2.3.0":
version: 2.3.0
resolution: "pify@npm:2.3.0"
Expand Down