Skip to content

Commit dbc1677

Browse files
authored
chore: replace micromatch with picomatch (#208)
1 parent fdaa41b commit dbc1677

File tree

5 files changed

+77
-45
lines changed

5 files changed

+77
-45
lines changed

.changeset/chatty-ravens-prove.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'steiger': patch
3+
---
4+
5+
Improve glob filtering performance by replacing micromatch with picomatch.

packages/steiger/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@
5050
"globby": "^14.0.2",
5151
"immer": "^10.1.1",
5252
"lodash-es": "^4.17.21",
53-
"micromatch": "^4.0.8",
5453
"patronum": "^2.3.0",
5554
"picocolors": "^1.1.1",
55+
"picomatch": "^4.0.3",
5656
"prexit": "^2.3.0",
5757
"yargs": "^17.7.2",
5858
"zod": "^3.24.1",
@@ -66,7 +66,7 @@
6666
"@steiger/types": "workspace:*",
6767
"@total-typescript/ts-reset": "^0.6.1",
6868
"@types/lodash-es": "^4.17.12",
69-
"@types/micromatch": "^4.0.9",
69+
"@types/picomatch": "^4.0.1",
7070
"@types/yargs": "^17.0.33",
7171
"memfs": "^4.17.0",
7272
"tsup": "^8.3.5",

packages/steiger/src/shared/globs/create-filter-according-to-globs.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,40 @@ describe('createFilterAccordingToGlobs', () => {
214214
expect(filteredFiles).toEqual(expected)
215215
})
216216

217+
it('should correctly handle brace expansion in inclusion patterns', () => {
218+
const files = ['/src/shared/lib/feature-a.ts', '/src/shared/lib/feature-a.tsx', '/src/shared/lib/feature-a.js']
219+
220+
const expected = ['/src/shared/lib/feature-a.ts', '/src/shared/lib/feature-a.tsx']
221+
222+
const filter = createFilterAccordingToGlobs({
223+
inclusions: ['**/*.{ts,tsx}'],
224+
})
225+
226+
const filteredFiles = files.filter(filter)
227+
228+
expect(filteredFiles).toEqual(expected)
229+
})
230+
231+
it('should correctly handle brace expansion in negated exclusion patterns', () => {
232+
const files = [
233+
'/src/shared/lib/keep.ts',
234+
'/src/shared/lib/keep.tsx',
235+
'/src/shared/lib/keep.js',
236+
'/src/shared/lib/remove.ts',
237+
'/src/shared/lib/remove.tsx',
238+
]
239+
240+
const expected = ['/src/shared/lib/keep.ts', '/src/shared/lib/keep.tsx', '/src/shared/lib/keep.js']
241+
242+
const filter = createFilterAccordingToGlobs({
243+
exclusions: ['**/*.{ts,tsx}', '!**/keep.{ts,tsx}'],
244+
})
245+
246+
const filteredFiles = files.filter(filter)
247+
248+
expect(filteredFiles).toEqual(expected)
249+
})
250+
217251
it('should correctly handle folder paths', () => {
218252
const files = [
219253
'/src/shared/ui/styles.css',

packages/steiger/src/shared/globs/create-filter-according-to-globs.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { isNegatedGlob } from './utilities'
2-
import micromatch from 'micromatch'
2+
import picomatch from 'picomatch'
33

4-
// ! Don't use platform specific path separators in the glob patterns for globby/micromatch
4+
// ! Don't use platform specific path separators in the glob patterns for globby/picomatch
55
// as it only works with forward slashes!
66

77
interface ApplyGlobsOptions {
@@ -13,29 +13,29 @@ export function createFilterAccordingToGlobs({ inclusions, exclusions }: ApplyGl
1313
const thereAreInclusions = Array.isArray(inclusions)
1414
const thereAreExclusions = Array.isArray(exclusions)
1515
const inclusionsEmpty = thereAreInclusions && inclusions.length === 0
16+
const picomatchOptions = { posixSlashes: true }
1617

17-
function filterAccordingToGlobs(path: string) {
18-
const matchesInclusionPatterns =
19-
!thereAreInclusions || inclusions.some((pattern) => micromatch.isMatch(path, pattern))
20-
let isIgnored = false
18+
const isIncluded = thereAreInclusions ? picomatch(inclusions, picomatchOptions) : () => true
19+
20+
const positiveExclusionPatterns =
21+
(thereAreExclusions && exclusions.filter((pattern) => !isNegatedGlob(pattern))) || []
22+
const reInclusionPatterns =
23+
(thereAreExclusions && exclusions.filter((pattern) => isNegatedGlob(pattern)).map((pattern) => pattern.slice(1))) ||
24+
[]
25+
26+
const isPositivelyExcluded = picomatch(positiveExclusionPatterns, picomatchOptions)
27+
const isReIncluded = picomatch(reInclusionPatterns, picomatchOptions)
2128

29+
function filterAccordingToGlobs(path: string) {
2230
if (inclusionsEmpty) {
2331
return false
2432
}
2533

34+
const matchesInclusionPatterns = isIncluded(path)
35+
let isIgnored = false
36+
2637
if (matchesInclusionPatterns && thereAreExclusions) {
27-
isIgnored = exclusions
28-
.filter((pattern) => !isNegatedGlob(pattern))
29-
.some((pattern) => micromatch.isMatch(path, pattern))
30-
31-
// If the path is ignored, check for any negated patterns that would include it back
32-
if (isIgnored) {
33-
const isNegated = exclusions.some(
34-
(ignorePattern) => isNegatedGlob(ignorePattern) && micromatch.isMatch(path, ignorePattern.slice(1)),
35-
)
36-
37-
isIgnored = !isNegated
38-
}
38+
isIgnored = isPositivelyExcluded(path) && !isReIncluded(path)
3939
}
4040

4141
return matchesInclusionPatterns && !isIgnored

pnpm-lock.yaml

Lines changed: 18 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)