diff --git a/package.json b/package.json index 93f44e0a3..14534ce51 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "globals": "^16.5.0", "js-yaml": "^5.2.2", "knip": "^6.23.0", - "minimatch": "^10.0.0", "nx": "^22.0.0", "oxfmt": "^0.59.0", "oxlint": "^1.51.0", diff --git a/scripts/affected.ts b/scripts/affected.ts index 2450a4566..0405af9dc 100644 --- a/scripts/affected.ts +++ b/scripts/affected.ts @@ -1,7 +1,7 @@ import { getBaseCommit, getChangedFiles, git } from "@rnx-kit/tools-git"; import * as yaml from "js-yaml"; -import { Minimatch } from "minimatch"; import * as fs from "node:fs"; +import * as path from "node:path"; type MatchChangedFiles = { "any-glob-to-any-file": string[] }; type Match = { "changed-files": MatchChangedFiles[] }; @@ -21,12 +21,23 @@ function loadLabels(): Record { return yaml.load(yml) as Record; } +/** + * Makes a glob pattern match dotfiles, emulating minimatch's `{ dot: true }`. + * + * `path.matchesGlob` won't match a path segment that starts with a dot against + * `*`/`**`, so we insert an optional dot before every wildcard segment (a `*` + * right after a `/`, or at the very start of the pattern). + */ +function dotAware(pattern: string): string { + const withDot = pattern.replaceAll("/*", "/{.,}*"); + return withDot.startsWith("*") ? `{.,}${withDot}` : withDot; +} + /** * Makes platform specific file path matchers. */ -function makeMatchers(): Record { - const matchers: Record = {}; - const options = { dot: true }; +function makeMatchers(): Record { + const matchers: Record = {}; const labels = loadLabels(); for (const [label, match] of Object.entries(labels)) { @@ -36,7 +47,7 @@ function makeMatchers(): Record { const patterns = match[0]["changed-files"][0]["any-glob-to-any-file"]; const platform = label.split(": ")[1]; - matchers[platform] = patterns.map((m) => new Minimatch(m, options)); + matchers[platform] = patterns.map(dotAware); } return matchers; @@ -70,8 +81,8 @@ function getAffectedPlatforms(targetBranch: string | undefined): string[] { } const affectedPlatforms = new Set(); - for (const [platform, matchers] of Object.entries(platformMatchers)) { - if (matchers.some((m) => changedFiles.some((f) => m.match(f)))) { + for (const [platform, patterns] of Object.entries(platformMatchers)) { + if (patterns.some((p) => changedFiles.some((f) => path.matchesGlob(f, p)))) { affectedPlatforms.add(platform); } } diff --git a/yarn.lock b/yarn.lock index dbc16976f..193fcafc2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2508,7 +2508,6 @@ __metadata: globals: "npm:^16.5.0" js-yaml: "npm:^5.2.2" knip: "npm:^6.23.0" - minimatch: "npm:^10.0.0" nx: "npm:^22.0.0" oxfmt: "npm:^0.59.0" oxlint: "npm:^1.51.0" @@ -11675,7 +11674,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^10.0.0, minimatch@npm:^10.0.3, minimatch@npm:^10.1.1, minimatch@npm:^10.2.2, minimatch@npm:^10.2.5": +"minimatch@npm:^10.0.3, minimatch@npm:^10.1.1, minimatch@npm:^10.2.2, minimatch@npm:^10.2.5": version: 10.2.5 resolution: "minimatch@npm:10.2.5" dependencies: