Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/chatty-ravens-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'steiger': patch
---

Improve glob filtering performance by replacing micromatch with picomatch.
4 changes: 2 additions & 2 deletions packages/steiger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
"globby": "^14.0.2",
"immer": "^10.1.1",
"lodash-es": "^4.17.21",
"micromatch": "^4.0.8",
"patronum": "^2.3.0",
"picocolors": "^1.1.1",
"picomatch": "^4.0.3",
"prexit": "^2.3.0",
"yargs": "^17.7.2",
"zod": "^3.24.1",
Expand All @@ -66,7 +66,7 @@
"@steiger/types": "workspace:*",
"@total-typescript/ts-reset": "^0.6.1",
"@types/lodash-es": "^4.17.12",
"@types/micromatch": "^4.0.9",
"@types/picomatch": "^4.0.1",
"@types/yargs": "^17.0.33",
"memfs": "^4.17.0",
"tsup": "^8.3.5",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isNegatedGlob } from './utilities'
import micromatch from 'micromatch'
import picomatch from 'picomatch'

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

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

function filterAccordingToGlobs(path: string) {
const matchesInclusionPatterns =
!thereAreInclusions || inclusions.some((pattern) => micromatch.isMatch(path, pattern))
let isIgnored = false
const isIncluded = thereAreInclusions ? picomatch(inclusions, picomatchOptions) : () => true

const positiveExclusionPatterns =
(thereAreExclusions && exclusions.filter((pattern) => !isNegatedGlob(pattern))) || []
const reInclusionPatterns =
(thereAreExclusions && exclusions.filter((pattern) => isNegatedGlob(pattern)).map((pattern) => pattern.slice(1))) ||
[]

const isPositivelyExcluded = picomatch(positiveExclusionPatterns, picomatchOptions)
const isReIncluded = picomatch(reInclusionPatterns, picomatchOptions)

function filterAccordingToGlobs(path: string) {
if (inclusionsEmpty) {
return false
}

const matchesInclusionPatterns = isIncluded(path)
let isIgnored = false

if (matchesInclusionPatterns && thereAreExclusions) {
isIgnored = exclusions
.filter((pattern) => !isNegatedGlob(pattern))
.some((pattern) => micromatch.isMatch(path, pattern))

// If the path is ignored, check for any negated patterns that would include it back
if (isIgnored) {
const isNegated = exclusions.some(
(ignorePattern) => isNegatedGlob(ignorePattern) && micromatch.isMatch(path, ignorePattern.slice(1)),
)

isIgnored = !isNegated
}
isIgnored = isPositivelyExcluded(path) && !isReIncluded(path)
}

return matchesInclusionPatterns && !isIgnored
Expand Down
43 changes: 18 additions & 25 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading