@descent-vtt/spec-graph 0.9.7 → 0.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,60 @@
3
3
  Notable changes, newest first. Versions follow [semver](https://semver.org):
4
4
  a patch fixes behaviour without asking anything of a repository that upgrades.
5
5
 
6
+ ## 0.9.8
7
+
8
+ A plain name such as `docs/vendor` reads a directory the default list skips,
9
+ as `docs/vendor/` does, where it found nothing; and spec-core is at 56c7e54,
10
+ which refuses braces that name no path, such as `{./,docs}`, where they read
11
+ as every path. A repository whose patterns name neither sees nothing change.
12
+
13
+ ### Changed
14
+
15
+ - **spec-core 56c7e54: a refusal of braces names the alternative that names
16
+ no path.** `{/,docs}`, `{//,docs}` and `{.,docs}` stop the run on
17
+ `invalid glob "{/,docs}": the braces expand to "/", which names no path`
18
+ and the like, where they said `the pattern names no path` of a pattern
19
+ that names `docs`; `{,docs}`, `{docs,}` and `{}` stop it on
20
+ `the braces expand to an empty pattern`. The exit `2` is as it was, and a
21
+ pattern without braces is refused in the words it was (ADR-0022).
22
+
23
+ ### Fixed
24
+
25
+ - **spec-core 56c7e54: a brace alternative that names no path is refused,
26
+ as the same text written alone is.** `./` alone stopped the run, but
27
+ `{./,docs}` read every path: inside braces its slash was read first, as
28
+ the contents of `.`. As a pattern to check it read every Markdown file in
29
+ the repository; as an `--ignore` it took every one out and stopped on
30
+ `no specifications matched`; as a `--history` pattern it made every
31
+ document a record, whose links are checked and whose open items are
32
+ nobody's; and as an `--ignore-ref` it passed over every reference target,
33
+ so no reference was reported broken. `{docs,./}`, `{.//,docs}` and `.{/,docs}` did the same.
34
+ Each now stops the run with exit `2` on
35
+ `invalid glob "{./,docs}": the braces expand to "./", which names no path`,
36
+ from the configuration as from the command line. Outside braces, `/./` and
37
+ `/.//` are refused as `/.` is, `the pattern names no path`, where as a
38
+ pattern they found nothing and as an `--ignore` or `--history` pattern
39
+ matched nothing. A `./` inside an alternative that names a path is dropped
40
+ as before: `docs/{./,adr}` and `{./docs,specs}` read what they read
41
+ (ADR-0022). No configuration in this repository, its fixtures or the rest
42
+ of the family writes such a pattern, and over them every `check` format
43
+ and every graph export is byte for byte what 0.9.7 wrote.
44
+ - **A plain name for a directory the walk skips reads that directory.**
45
+ `spec-graph check docs/vendor` and `spec-graph check vendor` found nothing
46
+ and stopped with exit `2`, where `docs/vendor/` read the directory: a name
47
+ with no slash at its end may be a file, so its walk started in the directory
48
+ above, and that walk pruned `vendor` on its way in. The default list now
49
+ gives way to the directory a pattern names outright, as it gives way to one a
50
+ pattern starts inside - `docs/vendor`, `vendor/dist`, or a literal a brace
51
+ expands to, `docs/{vendor,drafts}` - and the rest of the list is still
52
+ pruned inside it. A file of that name is read as the file, as before; every
53
+ directory no pattern names is skipped, and a negated name names none. A
54
+ bare `--ignore` name still prunes it at any depth, and a path `--ignore`
55
+ still takes it out where it takes it out of a walk passing through
56
+ (ADR-0022). No configuration in this repository, its fixtures or the rest of
57
+ the family names such a directory, and over them every `check` format and
58
+ every graph export is byte for byte what 0.9.7 wrote.
59
+
6
60
  ## 0.9.7
7
61
 
8
62
  spec-core at f9ce375. A `/` ending a brace alternative means what it means
package/README.md CHANGED
@@ -870,21 +870,25 @@ recorded on a Windows checkout holds in Linux CI:
870
870
  | `docs\adr\*.md` | the same as `docs/adr/*.md`: a `\` is a separator |
871
871
 
872
872
  A class never matches a `/`, and a pattern that cannot mean a path under the
873
- root — an unclosed `[` or `{`, `..`, a lone `.`, an empty one — stops the run
874
- with exit `2` and names the pattern, wherever it was written. So does an
873
+ root — an unclosed `[` or `{`, `..`, a lone `.` or `./`, an empty one, or
874
+ braces that give one of them, `{./,docs}` — stops the run with exit `2` and
875
+ names the pattern, wherever it was written. So does an
875
876
  extended glob, `+(a|b)`: write `{a,b}`. So does one too large to compile:
876
877
  braces that expand to more than 256 patterns, or a pattern past 65,536
877
878
  automaton states. A parenthesis with no `|` in its group
878
879
  is itself, so `C++(notes).md` names that file. A `..` typed below the root,
879
880
  `spec-graph "../*.md"` from `docs/deep`, is resolved against where you typed
880
881
  it. A bare `--ignore` name, `--ignore drafts`, still prunes that directory at
881
- any depth, even where a pattern starts inside it.
882
+ any depth, even where a pattern starts inside it or names it.
882
883
 
883
884
  The walk never enters `.git`, `.hg`, `.svn`, `.cache`, `.next`, `.nuxt`,
884
885
  `.turbo`, `.venv`, `node_modules`, `bower_components`, `vendor`, `dist`,
885
886
  `build`, `out`, `target`, `coverage` or `__pycache__` on its way to what the
886
887
  patterns name. Unlike an `--ignore`, these yield to a pattern that starts inside
887
888
  one: `vendor/specs/*.md` is read from there, whatever the other patterns reach.
889
+ They yield to a plain name for one as well: `vendor` and `docs/vendor` read
890
+ those directories as `vendor/` and `docs/vendor/` do, or the file, where one
891
+ of them is a file.
888
892
 
889
893
  `--ignore-ref` is matched against reference targets rather than paths: a bare
890
894
  pattern names one target exactly, case is ignored on every host, a `\` escapes
@@ -1104,9 +1108,9 @@ tools share, whose code is copied into `src/vendor/` and checked by hash rather
1104
1108
  than installed. So the whole package is auditable in an afternoon — and nothing
1105
1109
  in the pipeline can take longer than its input.
1106
1110
 
1107
- **Verified, not just covered.** 1,790 tests; 99.3% statement and 99.7% line
1111
+ **Verified, not just covered.** 1,799 tests; 99.3% statement and 99.7% line
1108
1112
  coverage. Coverage says a line ran, so the suite is also held to a mutation
1109
- score - 96.32% over 8,242 mutants, measured by CI's full sweep, and a build
1113
+ score - 96.33% over 8,250 mutants, measured by CI's full sweep, and a build
1110
1114
  fails under 93 - because a vocabulary entry or a boundary
1111
1115
  condition can be weakened by an ordinary-looking refactor without a single test
1112
1116
  going red. [ADR-0007](https://github.com/DescentVTT/spec-graph/blob/main/docs/adr/0007-mutation-testing.md) is straight about what
package/dist/glob.js CHANGED
@@ -279,7 +279,7 @@ export async function walkFiles(options) {
279
279
  // a typo or an unset variable, and was an ignore that ignored nothing.
280
280
  const bare = (pattern) => pattern.length > 0 && !isGlob(pattern) && !pattern.includes('/');
281
281
  const named = new Set(ignores.filter(bare));
282
- const ignoredNames = new Set([...DEFAULT_IGNORED_DIRECTORIES, ...named]);
282
+ const skippedByDefault = new Set(DEFAULT_IGNORED_DIRECTORIES);
283
283
  const ignoreList = pathList(ignores.filter((pattern) => !bare(pattern)));
284
284
  const excluded = (path) => ignoreList.match(path);
285
285
  // Only walk the directories the patterns can possibly reach: each pattern's
@@ -289,11 +289,29 @@ export async function walkFiles(options) {
289
289
  // Markdown file in `node_modules`. No positive pattern at all walks nothing,
290
290
  // which is the answer.
291
291
  const bases = new Set();
292
+ // The paths a positive pattern names outright: `docs/vendor`, or each literal
293
+ // a brace expands to. Such a name may be a file, so its walk starts in the
294
+ // directory above, which pruned `vendor` on its way in: `docs/vendor` found
295
+ // nothing where `docs/vendor/` read the directory. The default list gives way
296
+ // to the directory a pattern names as it gives way to one a pattern starts
297
+ // inside. A negated name adds none, for the reason it adds no base.
298
+ const literals = new Set();
292
299
  for (const entry of patterns.entries) {
293
300
  if (entry.negated)
294
301
  continue;
295
302
  for (const base of entry.glob.bases)
296
303
  bases.add(base);
304
+ // The dialect is what knows a literal when it reads one, so each pattern
305
+ // is compiled a second time to be told of them. That glob is thrown away:
306
+ // the reading answered here decides nothing, and a mutant that changes it
307
+ // is equivalent.
308
+ parseGlob(entry.glob.source, {
309
+ ...PATH,
310
+ literal: (path) => {
311
+ literals.add(path);
312
+ return 'either';
313
+ },
314
+ });
297
315
  }
298
316
  // Every base is walked, even one inside another, because the outer walk
299
317
  // prunes `vendor` and the rest of the default list on its way down, and a
@@ -327,7 +345,9 @@ export async function walkFiles(options) {
327
345
  if (entry.isDirectory()) {
328
346
  // Pruning a whole subtree is an optimisation; a pattern that only
329
347
  // matches the files inside it is still honoured when they are filtered.
330
- if (ignoredNames.has(entry.name) || excluded(child))
348
+ // A bare `--ignore` name prunes a directory a pattern names as well:
349
+ // only the default list gives way.
350
+ if (named.has(entry.name) || (skippedByDefault.has(entry.name) && !literals.has(child)) || excluded(child))
331
351
  continue;
332
352
  await walk(child);
333
353
  continue;
package/dist/glob.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"glob.js","sourceRoot":"","sources":["../src/glob.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pattern matching and directory walking.\n *\n * The patterns are the `path` dialect every spec-* tool reads, from spec-core:\n * `**`, `*`, `?`, `{a,b}`, `[abc]` and `[!a-z]`, matched against whole\n * repository-relative POSIX paths by an automaton that cannot backtrack, with\n * case respected on every host (ADR-0022). What stays here is spec-graph's own:\n * how a list with `!` entries in it reads, which directories a walk never\n * enters, and how a reference target - which is not a path - is matched.\n */\n\nimport { readdir, stat } from 'node:fs/promises';\n\nimport { isAbsolutePath, joinPosix, toPosix } from './paths.js';\nimport {\n compileGlob as compileFamilyGlob,\n GlobError,\n isGlobSyntax,\n parseGlob,\n parseGlobList,\n type Glob,\n type GlobList,\n type GlobOptions as FamilyGlobOptions,\n type RegexMatcher,\n} from './vendor/spec-core/pattern/index.js';\n\n/** Directories skipped unless a pattern explicitly names them. */\nexport const DEFAULT_IGNORED_DIRECTORIES: readonly string[] = Object.freeze([\n '.git',\n '.hg',\n '.svn',\n '.cache',\n '.next',\n '.nuxt',\n '.turbo',\n '.venv',\n 'node_modules',\n 'bower_components',\n 'vendor',\n 'dist',\n 'build',\n 'out',\n 'target',\n 'coverage',\n '__pycache__',\n]);\n\n/** Files larger than this are skipped: a specification is not a binary. */\nexport const MAX_FILE_SIZE = 4 * 1024 * 1024;\n\nexport interface WalkedFile {\n /** Repository-relative POSIX path. */\n readonly path: string;\n /** Absolute host path, for reading. */\n readonly absolute: string;\n readonly size: number;\n}\n\nexport interface WalkOptions {\n readonly root: string;\n readonly patterns: readonly string[];\n readonly ignore?: readonly string[] | undefined;\n readonly maxFileSize?: number | undefined;\n /** Follow directory symlinks. Off by default: cycles are real. */\n readonly followSymlinks?: boolean | undefined;\n}\n\n/**\n * How a path pattern is read everywhere in spec-graph.\n *\n * A literal names a file or a directory and everything beneath it, which is\n * what `--ignore docs/drafts` has always meant. A `\\` is a separator, because a\n * pattern typed on a Windows shell arrives with them and spec-graph has always\n * read them that way; it cannot also be an escape.\n */\nconst PATH: FamilyGlobOptions = { dialect: 'path', caseSensitive: true, literal: 'either', backslash: 'separator' };\n\n/** True when the string contains glob syntax rather than being a literal path. */\nexport function isGlob(pattern: string): boolean {\n return isGlobSyntax(pattern);\n}\n\n/**\n * Compiles a glob to an anchored regular expression, in the dialect spec-graph\n * read before it adopted spec-core's.\n *\n * @deprecated Nothing matches with this. It stays for callers who want a\n * `RegExp`, and as the record of the old reading that `tests/glob.test.ts`\n * holds every difference against, each one named in ADR-0022. It no longer\n * folds case on Windows alone: an answer must not depend on the host.\n */\nexport function globToRegExp(pattern: string): RegExp {\n return new RegExp(`^${globSource(pattern)}$`);\n}\n\nexport interface GlobOptions {\n /** Fold case. Off unless asked for, on every host. */\n readonly ignoreCase?: boolean | undefined;\n}\n\n/**\n * Compiles one glob to a matcher over whole repository-relative paths.\n *\n * A pattern with no glob syntax names that path and nothing beneath it; a bare\n * directory meaning its contents is a reading of {@link createGlobMatcher}'s.\n * Throws a `GlobError` that names the glob as it was written.\n *\n * Matching is linear in the path whatever the pattern. It was not always: a\n * glob's stars are not nested, but each is a `[^/]*` to `RegExp`, and a subject\n * that fails is divided between them every way there is - `*-*-*-x` took two\n * minutes over a 10,000-character reference target (ADR-0017).\n */\nexport function compileGlob(pattern: string, options: GlobOptions = {}): RegexMatcher {\n // `literal: 'file'` is the dialect's reading of any value but `directory`\n // and `either`, so a mutant that blanks it reads the same. It is spelled out\n // because what an unknown value means is spec-core's to change.\n const glob = compileFamilyGlob(pattern, { ...PATH, literal: 'file', caseSensitive: options.ignoreCase !== true });\n return { test: (path) => glob.match(path), size: glob.automaton.kinds.length };\n}\n\n/** The expression a glob stood for before 0.9.0, before anchors and flags. */\nfunction globSource(pattern: string): string {\n let source = '';\n let i = 0;\n const braces: number[] = [];\n\n while (i < pattern.length) {\n const ch = pattern[i] as string;\n\n if (ch === '*') {\n const doubled = pattern[i + 1] === '*';\n if (doubled) {\n const slashAfter = pattern[i + 2] === '/';\n // `a/**/b` must also match `a/b`, so the separator is folded in.\n source += slashAfter ? '(?:.*/)?' : '.*';\n i += slashAfter ? 3 : 2;\n } else {\n source += '[^/]*';\n i += 1;\n }\n continue;\n }\n\n if (ch === '?') {\n source += '[^/]';\n i += 1;\n continue;\n }\n\n if (ch === '[') {\n const close = pattern.indexOf(']', i + 1);\n if (close === -1) {\n source += '\\\\[';\n i += 1;\n continue;\n }\n const body = pattern.slice(i + 1, close);\n source += `[${body.startsWith('!') ? `^${escapeClass(body.slice(1))}` : escapeClass(body)}]`;\n i = close + 1;\n continue;\n }\n\n if (ch === '{') {\n braces.push(source.length);\n source += '(?:';\n i += 1;\n continue;\n }\n if (ch === '}' && braces.length > 0) {\n braces.pop();\n source += ')';\n i += 1;\n continue;\n }\n if (ch === ',' && braces.length > 0) {\n source += '|';\n i += 1;\n continue;\n }\n\n source += ch.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&');\n i += 1;\n }\n\n // Otherwise reported as an unmatched parenthesis, in a glob that has none.\n if (braces.length > 0) throw new Error(`invalid glob \"${pattern}\": unclosed \"{\"`);\n return source;\n}\n\nfunction escapeClass(body: string): string {\n return body.replace(/[\\\\^\\]]/g, '\\\\$&');\n}\n\nexport interface GlobMatcher {\n (path: string): boolean;\n}\n\n/** Compiles a list of path patterns, or throws naming the one that is not a glob. */\nfunction pathList(patterns: readonly string[]): GlobList {\n const parsed = parseGlobList(patterns, PATH);\n if (!parsed.ok) throw new Error(`invalid glob ${parsed.error}`);\n return parsed.list;\n}\n\n/**\n * Builds a matcher from include patterns, honouring `!` negations.\n *\n * Later patterns win, so `docs/**\\/*.md` followed by `!docs/drafts/**` reads the\n * way a `.gitignore` does. A pattern with no glob syntax in it names a file, or\n * a directory and everything beneath it; `docs/` names only what is beneath.\n */\nexport function createGlobMatcher(patterns: readonly string[]): GlobMatcher {\n const list = pathList(patterns);\n return (path: string): boolean => list.match(path);\n}\n\n/**\n * Builds a predicate over reference *targets*, not paths.\n *\n * Separate from {@link createGlobMatcher} on purpose. That one is\n * path-oriented: a bare name there is a directory and everything under it. A\n * reference target has no such structure - `trap 55` is a name, not a location\n * - so a bare pattern matches it literally and nothing else.\n *\n * Case is ignored, on every platform, because a citation's spelling is the\n * author's and not the filesystem's. The fold is simple case mapping, one code\n * point at a time and without a locale, so every host gives the same answer:\n * U+00B5 (micro sign) and U+03BC (mu) stay two targets, as they have been since\n * a Windows-only `i` flag made them one there (ADR-0017).\n *\n * A target is text a document holds rather than a path on this host, and two\n * things follow. A `\\` escapes the character after it: there is no Windows\n * separator to allow for. And a `.` or `..` segment is text: in a path the\n * dialect drops the one and refuses the other as climbing out of the root, but\n * `../../notes/gone.md` is a link somebody wrote and may want left alone.\n */\nexport function createReferenceFilter(patterns: readonly string[]): (target: string) => boolean {\n // A blank pattern reaches the dialect, which refuses it, as every pattern\n // spec-graph reads is refused when it names nothing. It used to be dropped,\n // so an unset variable in `--ignore-ref \"$TAGS\"` went unnoticed.\n const globs: Glob[] = patterns.map((pattern) => {\n const literalDots = pattern\n .trim()\n .split('/')\n .map((segment) => (segment === '.' ? '\\\\.' : segment === '..' ? '\\\\.\\\\.' : segment))\n .join('/');\n // Every option spelled out, though the dialect reads `{}` the same way\n // today: its defaults are spec-core's to change, and this reading is\n // spec-graph's to keep. A mutant that drops one is equivalent until then.\n const parsed = parseGlob(literalDots, { dialect: 'path', caseSensitive: false, literal: 'file' });\n if (!parsed.ok) throw new GlobError(pattern, parsed.error);\n return parsed.glob;\n });\n return (target: string): boolean => {\n const value = target.trim();\n return globs.some((glob) => glob.match(value));\n };\n}\n\n/**\n * The literal directory a pattern's matches all sit under, or `''` for the root.\n *\n * `{docs,specs}/**` has two, and this is the directory they share; the walk\n * itself starts at each.\n */\nexport function globBase(pattern: string): string {\n const { glob } = pathList([pattern]).entries[0] as { readonly glob: Glob };\n const bases = glob.bases.map((base) => base.split('/'));\n const shared = bases[0] as string[];\n let length = shared.length;\n for (const base of bases) {\n let same = 0;\n // `<=` would read one past the end, where both sides are undefined and\n // equal, and slice the same prefix: an equivalent mutant, left untested.\n while (same < length && base[same] === shared[same]) same += 1;\n length = same;\n }\n return shared.slice(0, length).join('/');\n}\n\n/**\n * Whether a base names directories that exist with exactly that spelling.\n *\n * A walk starts where a pattern's literal prefix points rather than at the\n * root, and on a filesystem that ignores case, `readdir('Docs')` lists `docs`.\n * Every file under it would come back spelled `Docs/...` - a node id, a\n * baseline key - and `Docs/**` would find it on Windows and macOS and nothing\n * on Linux. Asking each parent for the name gives git's answer on every host. A\n * base with an empty segment is rooted at `/`, which is never inside the root.\n */\nasync function spelledAsOnDisk(root: string, base: string): Promise<boolean> {\n if (base.length === 0) return true;\n let directory = root;\n for (const segment of base.split('/')) {\n let names: string[];\n try {\n names = await readdir(directory);\n } catch {\n // Answering `true` here would change nothing a test can see: the walk\n // would then read a directory beneath this one, fail the same way, and\n // find nothing.\n return false;\n }\n if (!names.includes(segment)) return false;\n directory = `${directory}/${segment}`;\n }\n return true;\n}\n\n/**\n * Walks the tree and returns every file matching the patterns.\n *\n * Directories are pruned as early as possible: a repository with a 2 GB\n * `node_modules` should cost nothing to scan.\n */\nexport async function walkFiles(options: WalkOptions): Promise<WalkedFile[]> {\n const root = toPosix(options.root).replace(/\\/+$/, '');\n const patterns = pathList(options.patterns);\n const maxSize = options.maxFileSize ?? MAX_FILE_SIZE;\n\n // Ignores come in two shapes and both are documented. A bare name prunes any\n // directory called that, at any depth, the way a `.gitignore` line does.\n // Anything carrying a separator or glob syntax is matched against the\n // repository-relative path, which is what `--ignore \"docs/drafts/**\"` means -\n // and treating that as a directory name silently excluded nothing at all.\n // A mutant that defaults this to `['Stryker was here']` prunes directories of\n // that name, which no repository has: equivalent, and left untested.\n const ignores = options.ignore ?? [];\n // The empty pattern is no directory's name, so it goes to the dialect, which\n // refuses it as it refuses an empty include: a pattern that names nothing is\n // a typo or an unset variable, and was an ignore that ignored nothing.\n const bare = (pattern: string): boolean => pattern.length > 0 && !isGlob(pattern) && !pattern.includes('/');\n const named = new Set(ignores.filter(bare));\n const ignoredNames = new Set([...DEFAULT_IGNORED_DIRECTORIES, ...named]);\n const ignoreList = pathList(ignores.filter((pattern) => !bare(pattern)));\n const excluded = (path: string): boolean => ignoreList.match(path);\n\n // Only walk the directories the patterns can possibly reach: each pattern's\n // literal prefix, one per brace alternative. A negated pattern adds none: it\n // takes files back, and starting a walk at its prefix would enter what the\n // walk skips - `!node_modules/**/*.txt` beside `**/*.md` would read every\n // Markdown file in `node_modules`. No positive pattern at all walks nothing,\n // which is the answer.\n const bases = new Set<string>();\n for (const entry of patterns.entries) {\n if (entry.negated) continue;\n for (const base of entry.glob.bases) bases.add(base);\n }\n // Every base is walked, even one inside another, because the outer walk\n // prunes `vendor` and the rest of the default list on its way down, and a\n // pattern that starts inside one of those is read from there. Dropping the\n // inner base as already covered meant `docs/**/*.md` beside\n // `docs/vendor/specs/*.md` found less than the second pattern alone. A bare\n // `--ignore` name is not overruled that way: it is the user's, and prunes at\n // any depth, a pattern's own starting point included - so `--ignore adr`\n // still takes out `adr/`, which the default `adr/**/*.md` starts inside.\n const startable = (base: string): boolean => !base.split('/').some((segment) => named.has(segment));\n const out = new Map<string, WalkedFile>();\n // Where two walks overlap, whichever reaches a directory first reads it and\n // the other stops there. Reading it twice would find the same files under\n // the same keys, so the two mutants that drop this are equivalent.\n const visited = new Set<string>();\n\n const walk = async (relative: string): Promise<void> => {\n const absolute = relative.length === 0 ? root : `${root}/${relative}`;\n if (visited.has(absolute)) return;\n visited.add(absolute);\n\n let entries;\n try {\n entries = await readdir(absolute, { withFileTypes: true });\n } catch {\n // An unreadable directory is not a reason to fail the whole run.\n return;\n }\n\n for (const entry of entries) {\n const child = relative.length === 0 ? entry.name : `${relative}/${entry.name}`;\n\n if (entry.isDirectory()) {\n // Pruning a whole subtree is an optimisation; a pattern that only\n // matches the files inside it is still honoured when they are filtered.\n if (ignoredNames.has(entry.name) || excluded(child)) continue;\n await walk(child);\n continue;\n }\n\n if (entry.isSymbolicLink()) {\n if (!options.followSymlinks) continue;\n try {\n const info = await stat(`${root}/${child}`);\n if (info.isDirectory()) {\n await walk(child);\n continue;\n }\n if (!patterns.match(child) || excluded(child) || info.size > maxSize) continue;\n out.set(child, { path: child, absolute: `${root}/${child}`, size: info.size });\n } catch {\n // A link to nothing has nothing to read.\n }\n continue;\n }\n\n if (!entry.isFile()) continue;\n if (!patterns.match(child) || excluded(child)) continue;\n\n try {\n const info = await stat(`${root}/${child}`);\n if (info.size > maxSize) continue;\n out.set(child, { path: child, absolute: `${root}/${child}`, size: info.size });\n } catch {\n // Gone between the listing and the look: there is nothing to read.\n }\n }\n };\n\n for (const base of bases) if (startable(base) && (await spelledAsOnDisk(root, base))) await walk(base);\n\n // No two paths are equal, since they are the keys of `out`, so the order\n // needs only `<`, and `<=` would read the same.\n return [...out.values()].sort((a, b) => (a.path < b.path ? -1 : 1));\n}\n\n/**\n * Resolves a repository-relative path against the root, in POSIX form.\n *\n * An absolute path already names one place, and joining it under the root names\n * another: `--baseline /tmp/b.json` read `<root>/tmp/b.json`, found nothing\n * there, and accepted nothing without saying so.\n */\nexport function underRoot(root: string, relative: string): string {\n if (isAbsolutePath(relative)) return toPosix(relative);\n return joinPosix(toPosix(root), relative);\n}\n"]}
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../src/glob.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pattern matching and directory walking.\n *\n * The patterns are the `path` dialect every spec-* tool reads, from spec-core:\n * `**`, `*`, `?`, `{a,b}`, `[abc]` and `[!a-z]`, matched against whole\n * repository-relative POSIX paths by an automaton that cannot backtrack, with\n * case respected on every host (ADR-0022). What stays here is spec-graph's own:\n * how a list with `!` entries in it reads, which directories a walk never\n * enters, and how a reference target - which is not a path - is matched.\n */\n\nimport { readdir, stat } from 'node:fs/promises';\n\nimport { isAbsolutePath, joinPosix, toPosix } from './paths.js';\nimport {\n compileGlob as compileFamilyGlob,\n GlobError,\n isGlobSyntax,\n parseGlob,\n parseGlobList,\n type Glob,\n type GlobList,\n type GlobOptions as FamilyGlobOptions,\n type RegexMatcher,\n} from './vendor/spec-core/pattern/index.js';\n\n/** Directories skipped unless a pattern explicitly names them. */\nexport const DEFAULT_IGNORED_DIRECTORIES: readonly string[] = Object.freeze([\n '.git',\n '.hg',\n '.svn',\n '.cache',\n '.next',\n '.nuxt',\n '.turbo',\n '.venv',\n 'node_modules',\n 'bower_components',\n 'vendor',\n 'dist',\n 'build',\n 'out',\n 'target',\n 'coverage',\n '__pycache__',\n]);\n\n/** Files larger than this are skipped: a specification is not a binary. */\nexport const MAX_FILE_SIZE = 4 * 1024 * 1024;\n\nexport interface WalkedFile {\n /** Repository-relative POSIX path. */\n readonly path: string;\n /** Absolute host path, for reading. */\n readonly absolute: string;\n readonly size: number;\n}\n\nexport interface WalkOptions {\n readonly root: string;\n readonly patterns: readonly string[];\n readonly ignore?: readonly string[] | undefined;\n readonly maxFileSize?: number | undefined;\n /** Follow directory symlinks. Off by default: cycles are real. */\n readonly followSymlinks?: boolean | undefined;\n}\n\n/**\n * How a path pattern is read everywhere in spec-graph.\n *\n * A literal names a file or a directory and everything beneath it, which is\n * what `--ignore docs/drafts` has always meant. A `\\` is a separator, because a\n * pattern typed on a Windows shell arrives with them and spec-graph has always\n * read them that way; it cannot also be an escape.\n */\nconst PATH: FamilyGlobOptions = { dialect: 'path', caseSensitive: true, literal: 'either', backslash: 'separator' };\n\n/** True when the string contains glob syntax rather than being a literal path. */\nexport function isGlob(pattern: string): boolean {\n return isGlobSyntax(pattern);\n}\n\n/**\n * Compiles a glob to an anchored regular expression, in the dialect spec-graph\n * read before it adopted spec-core's.\n *\n * @deprecated Nothing matches with this. It stays for callers who want a\n * `RegExp`, and as the record of the old reading that `tests/glob.test.ts`\n * holds every difference against, each one named in ADR-0022. It no longer\n * folds case on Windows alone: an answer must not depend on the host.\n */\nexport function globToRegExp(pattern: string): RegExp {\n return new RegExp(`^${globSource(pattern)}$`);\n}\n\nexport interface GlobOptions {\n /** Fold case. Off unless asked for, on every host. */\n readonly ignoreCase?: boolean | undefined;\n}\n\n/**\n * Compiles one glob to a matcher over whole repository-relative paths.\n *\n * A pattern with no glob syntax names that path and nothing beneath it; a bare\n * directory meaning its contents is a reading of {@link createGlobMatcher}'s.\n * Throws a `GlobError` that names the glob as it was written.\n *\n * Matching is linear in the path whatever the pattern. It was not always: a\n * glob's stars are not nested, but each is a `[^/]*` to `RegExp`, and a subject\n * that fails is divided between them every way there is - `*-*-*-x` took two\n * minutes over a 10,000-character reference target (ADR-0017).\n */\nexport function compileGlob(pattern: string, options: GlobOptions = {}): RegexMatcher {\n // `literal: 'file'` is the dialect's reading of any value but `directory`\n // and `either`, so a mutant that blanks it reads the same. It is spelled out\n // because what an unknown value means is spec-core's to change.\n const glob = compileFamilyGlob(pattern, { ...PATH, literal: 'file', caseSensitive: options.ignoreCase !== true });\n return { test: (path) => glob.match(path), size: glob.automaton.kinds.length };\n}\n\n/** The expression a glob stood for before 0.9.0, before anchors and flags. */\nfunction globSource(pattern: string): string {\n let source = '';\n let i = 0;\n const braces: number[] = [];\n\n while (i < pattern.length) {\n const ch = pattern[i] as string;\n\n if (ch === '*') {\n const doubled = pattern[i + 1] === '*';\n if (doubled) {\n const slashAfter = pattern[i + 2] === '/';\n // `a/**/b` must also match `a/b`, so the separator is folded in.\n source += slashAfter ? '(?:.*/)?' : '.*';\n i += slashAfter ? 3 : 2;\n } else {\n source += '[^/]*';\n i += 1;\n }\n continue;\n }\n\n if (ch === '?') {\n source += '[^/]';\n i += 1;\n continue;\n }\n\n if (ch === '[') {\n const close = pattern.indexOf(']', i + 1);\n if (close === -1) {\n source += '\\\\[';\n i += 1;\n continue;\n }\n const body = pattern.slice(i + 1, close);\n source += `[${body.startsWith('!') ? `^${escapeClass(body.slice(1))}` : escapeClass(body)}]`;\n i = close + 1;\n continue;\n }\n\n if (ch === '{') {\n braces.push(source.length);\n source += '(?:';\n i += 1;\n continue;\n }\n if (ch === '}' && braces.length > 0) {\n braces.pop();\n source += ')';\n i += 1;\n continue;\n }\n if (ch === ',' && braces.length > 0) {\n source += '|';\n i += 1;\n continue;\n }\n\n source += ch.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&');\n i += 1;\n }\n\n // Otherwise reported as an unmatched parenthesis, in a glob that has none.\n if (braces.length > 0) throw new Error(`invalid glob \"${pattern}\": unclosed \"{\"`);\n return source;\n}\n\nfunction escapeClass(body: string): string {\n return body.replace(/[\\\\^\\]]/g, '\\\\$&');\n}\n\nexport interface GlobMatcher {\n (path: string): boolean;\n}\n\n/** Compiles a list of path patterns, or throws naming the one that is not a glob. */\nfunction pathList(patterns: readonly string[]): GlobList {\n const parsed = parseGlobList(patterns, PATH);\n if (!parsed.ok) throw new Error(`invalid glob ${parsed.error}`);\n return parsed.list;\n}\n\n/**\n * Builds a matcher from include patterns, honouring `!` negations.\n *\n * Later patterns win, so `docs/**\\/*.md` followed by `!docs/drafts/**` reads the\n * way a `.gitignore` does. A pattern with no glob syntax in it names a file, or\n * a directory and everything beneath it; `docs/` names only what is beneath.\n */\nexport function createGlobMatcher(patterns: readonly string[]): GlobMatcher {\n const list = pathList(patterns);\n return (path: string): boolean => list.match(path);\n}\n\n/**\n * Builds a predicate over reference *targets*, not paths.\n *\n * Separate from {@link createGlobMatcher} on purpose. That one is\n * path-oriented: a bare name there is a directory and everything under it. A\n * reference target has no such structure - `trap 55` is a name, not a location\n * - so a bare pattern matches it literally and nothing else.\n *\n * Case is ignored, on every platform, because a citation's spelling is the\n * author's and not the filesystem's. The fold is simple case mapping, one code\n * point at a time and without a locale, so every host gives the same answer:\n * U+00B5 (micro sign) and U+03BC (mu) stay two targets, as they have been since\n * a Windows-only `i` flag made them one there (ADR-0017).\n *\n * A target is text a document holds rather than a path on this host, and two\n * things follow. A `\\` escapes the character after it: there is no Windows\n * separator to allow for. And a `.` or `..` segment is text: in a path the\n * dialect drops the one and refuses the other as climbing out of the root, but\n * `../../notes/gone.md` is a link somebody wrote and may want left alone.\n */\nexport function createReferenceFilter(patterns: readonly string[]): (target: string) => boolean {\n // A blank pattern reaches the dialect, which refuses it, as every pattern\n // spec-graph reads is refused when it names nothing. It used to be dropped,\n // so an unset variable in `--ignore-ref \"$TAGS\"` went unnoticed.\n const globs: Glob[] = patterns.map((pattern) => {\n const literalDots = pattern\n .trim()\n .split('/')\n .map((segment) => (segment === '.' ? '\\\\.' : segment === '..' ? '\\\\.\\\\.' : segment))\n .join('/');\n // Every option spelled out, though the dialect reads `{}` the same way\n // today: its defaults are spec-core's to change, and this reading is\n // spec-graph's to keep. A mutant that drops one is equivalent until then.\n const parsed = parseGlob(literalDots, { dialect: 'path', caseSensitive: false, literal: 'file' });\n if (!parsed.ok) throw new GlobError(pattern, parsed.error);\n return parsed.glob;\n });\n return (target: string): boolean => {\n const value = target.trim();\n return globs.some((glob) => glob.match(value));\n };\n}\n\n/**\n * The literal directory a pattern's matches all sit under, or `''` for the root.\n *\n * `{docs,specs}/**` has two, and this is the directory they share; the walk\n * itself starts at each.\n */\nexport function globBase(pattern: string): string {\n const { glob } = pathList([pattern]).entries[0] as { readonly glob: Glob };\n const bases = glob.bases.map((base) => base.split('/'));\n const shared = bases[0] as string[];\n let length = shared.length;\n for (const base of bases) {\n let same = 0;\n // `<=` would read one past the end, where both sides are undefined and\n // equal, and slice the same prefix: an equivalent mutant, left untested.\n while (same < length && base[same] === shared[same]) same += 1;\n length = same;\n }\n return shared.slice(0, length).join('/');\n}\n\n/**\n * Whether a base names directories that exist with exactly that spelling.\n *\n * A walk starts where a pattern's literal prefix points rather than at the\n * root, and on a filesystem that ignores case, `readdir('Docs')` lists `docs`.\n * Every file under it would come back spelled `Docs/...` - a node id, a\n * baseline key - and `Docs/**` would find it on Windows and macOS and nothing\n * on Linux. Asking each parent for the name gives git's answer on every host. A\n * base with an empty segment is rooted at `/`, which is never inside the root.\n */\nasync function spelledAsOnDisk(root: string, base: string): Promise<boolean> {\n if (base.length === 0) return true;\n let directory = root;\n for (const segment of base.split('/')) {\n let names: string[];\n try {\n names = await readdir(directory);\n } catch {\n // Answering `true` here would change nothing a test can see: the walk\n // would then read a directory beneath this one, fail the same way, and\n // find nothing.\n return false;\n }\n if (!names.includes(segment)) return false;\n directory = `${directory}/${segment}`;\n }\n return true;\n}\n\n/**\n * Walks the tree and returns every file matching the patterns.\n *\n * Directories are pruned as early as possible: a repository with a 2 GB\n * `node_modules` should cost nothing to scan.\n */\nexport async function walkFiles(options: WalkOptions): Promise<WalkedFile[]> {\n const root = toPosix(options.root).replace(/\\/+$/, '');\n const patterns = pathList(options.patterns);\n const maxSize = options.maxFileSize ?? MAX_FILE_SIZE;\n\n // Ignores come in two shapes and both are documented. A bare name prunes any\n // directory called that, at any depth, the way a `.gitignore` line does.\n // Anything carrying a separator or glob syntax is matched against the\n // repository-relative path, which is what `--ignore \"docs/drafts/**\"` means -\n // and treating that as a directory name silently excluded nothing at all.\n // A mutant that defaults this to `['Stryker was here']` prunes directories of\n // that name, which no repository has: equivalent, and left untested.\n const ignores = options.ignore ?? [];\n // The empty pattern is no directory's name, so it goes to the dialect, which\n // refuses it as it refuses an empty include: a pattern that names nothing is\n // a typo or an unset variable, and was an ignore that ignored nothing.\n const bare = (pattern: string): boolean => pattern.length > 0 && !isGlob(pattern) && !pattern.includes('/');\n const named = new Set(ignores.filter(bare));\n const skippedByDefault = new Set(DEFAULT_IGNORED_DIRECTORIES);\n const ignoreList = pathList(ignores.filter((pattern) => !bare(pattern)));\n const excluded = (path: string): boolean => ignoreList.match(path);\n\n // Only walk the directories the patterns can possibly reach: each pattern's\n // literal prefix, one per brace alternative. A negated pattern adds none: it\n // takes files back, and starting a walk at its prefix would enter what the\n // walk skips - `!node_modules/**/*.txt` beside `**/*.md` would read every\n // Markdown file in `node_modules`. No positive pattern at all walks nothing,\n // which is the answer.\n const bases = new Set<string>();\n // The paths a positive pattern names outright: `docs/vendor`, or each literal\n // a brace expands to. Such a name may be a file, so its walk starts in the\n // directory above, which pruned `vendor` on its way in: `docs/vendor` found\n // nothing where `docs/vendor/` read the directory. The default list gives way\n // to the directory a pattern names as it gives way to one a pattern starts\n // inside. A negated name adds none, for the reason it adds no base.\n const literals = new Set<string>();\n for (const entry of patterns.entries) {\n if (entry.negated) continue;\n for (const base of entry.glob.bases) bases.add(base);\n // The dialect is what knows a literal when it reads one, so each pattern\n // is compiled a second time to be told of them. That glob is thrown away:\n // the reading answered here decides nothing, and a mutant that changes it\n // is equivalent.\n parseGlob(entry.glob.source, {\n ...PATH,\n literal: (path) => {\n literals.add(path);\n return 'either';\n },\n });\n }\n // Every base is walked, even one inside another, because the outer walk\n // prunes `vendor` and the rest of the default list on its way down, and a\n // pattern that starts inside one of those is read from there. Dropping the\n // inner base as already covered meant `docs/**/*.md` beside\n // `docs/vendor/specs/*.md` found less than the second pattern alone. A bare\n // `--ignore` name is not overruled that way: it is the user's, and prunes at\n // any depth, a pattern's own starting point included - so `--ignore adr`\n // still takes out `adr/`, which the default `adr/**/*.md` starts inside.\n const startable = (base: string): boolean => !base.split('/').some((segment) => named.has(segment));\n const out = new Map<string, WalkedFile>();\n // Where two walks overlap, whichever reaches a directory first reads it and\n // the other stops there. Reading it twice would find the same files under\n // the same keys, so the two mutants that drop this are equivalent.\n const visited = new Set<string>();\n\n const walk = async (relative: string): Promise<void> => {\n const absolute = relative.length === 0 ? root : `${root}/${relative}`;\n if (visited.has(absolute)) return;\n visited.add(absolute);\n\n let entries;\n try {\n entries = await readdir(absolute, { withFileTypes: true });\n } catch {\n // An unreadable directory is not a reason to fail the whole run.\n return;\n }\n\n for (const entry of entries) {\n const child = relative.length === 0 ? entry.name : `${relative}/${entry.name}`;\n\n if (entry.isDirectory()) {\n // Pruning a whole subtree is an optimisation; a pattern that only\n // matches the files inside it is still honoured when they are filtered.\n // A bare `--ignore` name prunes a directory a pattern names as well:\n // only the default list gives way.\n if (named.has(entry.name) || (skippedByDefault.has(entry.name) && !literals.has(child)) || excluded(child)) continue;\n await walk(child);\n continue;\n }\n\n if (entry.isSymbolicLink()) {\n if (!options.followSymlinks) continue;\n try {\n const info = await stat(`${root}/${child}`);\n if (info.isDirectory()) {\n await walk(child);\n continue;\n }\n if (!patterns.match(child) || excluded(child) || info.size > maxSize) continue;\n out.set(child, { path: child, absolute: `${root}/${child}`, size: info.size });\n } catch {\n // A link to nothing has nothing to read.\n }\n continue;\n }\n\n if (!entry.isFile()) continue;\n if (!patterns.match(child) || excluded(child)) continue;\n\n try {\n const info = await stat(`${root}/${child}`);\n if (info.size > maxSize) continue;\n out.set(child, { path: child, absolute: `${root}/${child}`, size: info.size });\n } catch {\n // Gone between the listing and the look: there is nothing to read.\n }\n }\n };\n\n for (const base of bases) if (startable(base) && (await spelledAsOnDisk(root, base))) await walk(base);\n\n // No two paths are equal, since they are the keys of `out`, so the order\n // needs only `<`, and `<=` would read the same.\n return [...out.values()].sort((a, b) => (a.path < b.path ? -1 : 1));\n}\n\n/**\n * Resolves a repository-relative path against the root, in POSIX form.\n *\n * An absolute path already names one place, and joining it under the root names\n * another: `--baseline /tmp/b.json` read `<root>/tmp/b.json`, found nothing\n * there, and accepted nothing without saying so.\n */\nexport function underRoot(root: string, relative: string): string {\n if (isAbsolutePath(relative)) return toPosix(relative);\n return joinPosix(toPosix(root), relative);\n}\n"]}
@@ -29,6 +29,8 @@
29
29
  * - Braces expand first, and each alternative reads as it would written on
30
30
  * its own: `{src/,lib}` is `src/` or `lib`, and a trailing `/` means the
31
31
  * directory's contents - in an exclusion, the directory and its contents.
32
+ * One that names no path, `{./,lib}` or `{,lib}`, is refused, as `./` and
33
+ * the empty pattern are.
32
34
  * - Case is the caller's decision, stated every time. A result must not
33
35
  * depend on the host it ran on.
34
36
  * - A malformed pattern is an error, never a literal. An unclosed `[` or `{`,
@@ -29,6 +29,8 @@
29
29
  * - Braces expand first, and each alternative reads as it would written on
30
30
  * its own: `{src/,lib}` is `src/` or `lib`, and a trailing `/` means the
31
31
  * directory's contents - in an exclusion, the directory and its contents.
32
+ * One that names no path, `{./,lib}` or `{,lib}`, is refused, as `./` and
33
+ * the empty pattern are.
32
34
  * - Case is the caller's decision, stated every time. A result must not
33
35
  * depend on the host it ran on.
34
36
  * - A malformed pattern is an error, never a literal. An unclosed `[` or `{`,
@@ -104,6 +106,12 @@ function build(source, options) {
104
106
  return expanded;
105
107
  const alternatives = [];
106
108
  for (const text of expanded) {
109
+ // Refused before its trailing slash is read, which would make `./` the
110
+ // contents of `.`, every path: `{./,a}` is refused as `./` alone is.
111
+ // Each text the braces give is shorter than the pattern, so only a
112
+ // pattern without braces is its own text.
113
+ if (namesNoPath(text))
114
+ return text === pattern ? 'the pattern names no path' : bracesNamingNoPath(text);
107
115
  const parsed = parseAlternative(trailingSlash(text, options.dialect), escapes);
108
116
  if (parsed === GLOBSTAR_IN_NAME)
109
117
  return `${GLOBSTAR_IN_NAME}: ${globstarAdvice(written)}`;
@@ -253,6 +261,17 @@ function classEnd(pattern, open, escapes) {
253
261
  return -1;
254
262
  }
255
263
  /* ---------------------------------------------------------------- segments */
264
+ /** Whether a pattern's text names no path: nothing in it but `/` and `.` segments. */
265
+ function namesNoPath(text) {
266
+ return text.split('/').every((part) => part === '' || part === '.');
267
+ }
268
+ /**
269
+ * The refusal of an alternative the braces give that names no path, naming
270
+ * it as it was expanded, so that `.{/,a}` is told `./`, the text refused.
271
+ */
272
+ function bracesNamingNoPath(text) {
273
+ return text === '' ? 'the braces expand to an empty pattern' : `the braces expand to "${text}", which names no path`;
274
+ }
256
275
  /**
257
276
  * What a trailing slash means, read on each alternative the braces give, so
258
277
  * that `{src/,lib}` reads `src/` as `src/` alone reads: the directory's
@@ -261,17 +280,21 @@ function classEnd(pattern, open, escapes) {
261
280
  * In an exclusion `build/` excludes what `build` does. Git's rule is that a
262
281
  * trailing slash matches only a directory, and a directory is excluded with
263
282
  * everything in it; a matcher that sees only a path cannot tell a directory
264
- * from a file, so the slash is dropped, and it anchors nothing. An
265
- * alternative that is only slashes names the root, which `parseAlternative`
266
- * refuses as naming no path.
283
+ * from a file, so the slash is dropped, and it anchors nothing.
267
284
  *
268
- * The whole run of slashes is taken, so that `{//,a}` is refused as `{/,a}`
269
- * is; taken lazily it is the whole run all the same, since it ends the text.
285
+ * Only ever given a text that names a path, so a name is left. The whole run
286
+ * of slashes is taken, but one slash would read the same, since
287
+ * `parseAlternative` drops the empty segments the rest leave; and taken
288
+ * lazily it is the whole run all the same, since it ends the text.
270
289
  */
271
290
  function trailingSlash(text, dialect) {
272
291
  const name = text.replace(/\/+$/, '');
273
- return name === text || name === '' || dialect === 'gitignore' ? name : `${name}/**`;
292
+ return name === text || dialect === 'gitignore' ? name : `${name}/**`;
274
293
  }
294
+ /**
295
+ * The segments of a text that names a path - `build` refuses one that does
296
+ * not - so at least one segment is left.
297
+ */
275
298
  function parseAlternative(text, escapes) {
276
299
  const segments = [];
277
300
  const raw = text.split('/');
@@ -290,8 +313,6 @@ function parseAlternative(text, escapes) {
290
313
  return tokens;
291
314
  segments.push({ kind: 'name', tokens });
292
315
  }
293
- if (segments.length === 0)
294
- return 'the pattern names no path';
295
316
  return { segments, slashed: raw.filter((part) => part !== '' && part !== '.').length > 1 };
296
317
  }
297
318
  const EXTGLOB = 'extended globs such as "+(a|b)" are not supported: write alternatives as "{a,b}", and a literal parenthesis as "[(]"';
@@ -1 +1 @@
1
- {"version":3,"file":"glob.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/pattern/glob.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Globs, in the three dialects the spec-* tools speak, compiled to one kind of\n * automaton.\n *\n * The syntax is the part people type: `*`, `**`, `?`, `[abc]`, `[!a-z]`,\n * `{a,b}`, and `\\` to escape. What differs between the tools is not the\n * syntax but what a pattern is matched against, and those differences are\n * deliberate, so each has a name (docs/adr/0003-glob-dialects.md):\n *\n * - `path` - the whole repository-relative path, anchored at the root. A\n * pattern with no glob syntax names a file, a directory, or either, as the\n * caller says; `src/auth` may cover `src/auth/login.ts`.\n * - `ripgrep` - as ripgrep's `-g`: a pattern with no `/` is matched against\n * the last segment at any depth, so `*.ts` matches `src/deep/a.ts`; one with\n * a `/` is matched against the whole path.\n * - `gitignore` - as an exclusion list reads: a pattern matches a path or any\n * directory above it, so `tests` excludes everything under any `tests`; one\n * with a `/` other than a trailing one is anchored at the root, and a\n * leading `/` only anchors.\n *\n * Shared by all three:\n *\n * - `**` is a globstar only as a whole segment. `a/**\\/b` matches `a/b` and\n * `a/x/y/b`; a trailing `/**` matches everything inside a directory and not\n * the directory itself. Two stars inside a name, `**.md`, are refused: the\n * tools read it three ways, and the quiet reading narrowed their scope. The\n * refusal writes the two patterns it may have meant from the one written.\n * - `*`, `?` and classes never match `/`, and `*` matches a leading dot.\n * - Braces expand first, and each alternative reads as it would written on\n * its own: `{src/,lib}` is `src/` or `lib`, and a trailing `/` means the\n * directory's contents - in an exclusion, the directory and its contents.\n * - Case is the caller's decision, stated every time. A result must not\n * depend on the host it ran on.\n * - A malformed pattern is an error, never a literal. An unclosed `[` or `{`,\n * an extended glob, a `..` - each is refused with a reason, because a typo\n * read as a literal is a scope that silently matches nothing. An extended\n * glob is a group holding a `|`, `+(a|b)`: without one, `C++(notes).md` is\n * a name with parentheses in it, as ripgrep and `.gitignore` read it.\n */\n\nimport {\n AutomatonTooLarge,\n Builder,\n findWitness,\n Matcher,\n WITNESS_BUDGET,\n type Automaton,\n type Fragment,\n type Witness,\n} from './automaton.js';\nimport { ANY, classSet, literalSet, SEPARATOR, type CodeRange } from './charset.js';\n\nexport type GlobDialect = 'path' | 'ripgrep' | 'gitignore';\n\n/** How a `path` pattern with no glob syntax is read. */\nexport type LiteralReading = 'file' | 'directory' | 'either';\n\nexport interface GlobOptions {\n readonly dialect: GlobDialect;\n /** Whether `A` and `a` differ. No default: the caller decides, every time. */\n readonly caseSensitive: boolean;\n /**\n * `path` dialect only: how a pattern with no glob syntax is read - as a\n * file, as a directory and everything beneath it, or as either. A function\n * is asked per literal path, for a caller that knows the tree. `either` when\n * unset. A trailing `/`, on the pattern or on one of its brace alternatives,\n * always means a directory's contents, and is never asked about.\n */\n readonly literal?: LiteralReading | ((path: string) => LiteralReading) | undefined;\n /**\n * `escape` (the default): `\\` escapes the next character, and a `\\` before a\n * letter or digit is refused as a Windows separator typed by mistake.\n * `separator`: every `\\` is a `/`, for patterns typed on a Windows shell.\n */\n readonly backslash?: 'escape' | 'separator' | undefined;\n}\n\nexport interface Glob {\n readonly source: string;\n readonly dialect: GlobDialect;\n readonly caseSensitive: boolean;\n /**\n * The directories a walk must enter to find every match: one per\n * alternative, the leading literal segments. `''` for an alternative that\n * can match at any depth.\n */\n readonly bases: readonly string[];\n readonly automaton: Automaton;\n /** Whether a canonical path - POSIX, no `.`, no empty or trailing segment - matches. */\n match(path: string): boolean;\n}\n\nexport type GlobParse = { readonly ok: true; readonly glob: Glob } | { readonly ok: false; readonly error: string };\n\nexport class GlobError extends Error {\n readonly source: string;\n constructor(source: string, reason: string) {\n super(`invalid glob \"${source}\": ${reason}`);\n this.name = 'GlobError';\n this.source = source;\n }\n}\n\n/** More alternatives than this is a pattern nobody meant. */\nexport const MAX_ALTERNATIVES = 256;\n\ntype Token =\n | { readonly kind: 'literal'; readonly point: number }\n | { readonly kind: 'any' }\n | { readonly kind: 'star' }\n | { readonly kind: 'class'; readonly negated: boolean; readonly ranges: readonly CodeRange[] };\n\ntype Segment = { readonly kind: 'globstar' } | { readonly kind: 'name'; readonly tokens: readonly Token[] };\n\ninterface Alternative {\n readonly segments: readonly Segment[];\n /** Written with a `/` somewhere other than at its end. */\n readonly slashed: boolean;\n}\n\n/** Whether a string uses glob syntax at all. */\nexport function isGlobSyntax(source: string): boolean {\n return /[*?[\\]{}]/.test(source);\n}\n\n/**\n * Parses and compiles a glob, or says why it cannot: malformed, or too large\n * to compile, past {@link MAX_ALTERNATIVES} alternatives or `MAX_STATES`\n * states. It throws only what a `literal` function throws.\n */\nexport function parseGlob(source: string, options: GlobOptions): GlobParse {\n const result = build(source, options);\n return typeof result === 'string' ? { ok: false, error: result } : { ok: true, glob: result };\n}\n\n/**\n * Parses and compiles a glob, throwing {@link GlobError} for every reason\n * {@link parseGlob} gives, and what a `literal` function throws.\n */\nexport function compileGlob(source: string, options: GlobOptions): Glob {\n const result = build(source, options);\n if (typeof result === 'string') throw new GlobError(source, result);\n return result;\n}\n\nfunction build(source: string, options: GlobOptions): Glob | string {\n const escapes = options.backslash !== 'separator';\n let pattern = source.trim();\n if (!escapes) pattern = pattern.replace(/\\\\/g, '/');\n const written = pattern;\n if (pattern.length === 0) return 'the pattern is empty';\n if (pattern.startsWith('!')) return 'a negated pattern is a list entry, not a glob; narrow the positive pattern';\n if (/(?:^|[^\\\\])[?*+@!]\\([^)]*\\|/.test(pattern)) return EXTGLOB;\n while (pattern.startsWith('./')) pattern = pattern.slice(2);\n\n // A leading slash roots a pattern at the filesystem's root in the path and\n // ripgrep dialects, and only anchors it at the repository root in gitignore.\n let rooted = false;\n let anchored = false;\n if (pattern.startsWith('/')) {\n if (options.dialect === 'gitignore') anchored = true;\n else rooted = true;\n pattern = pattern.replace(/^\\/+/, '');\n }\n if (pattern.length === 0) return 'the pattern names the root itself, not a path under it';\n\n const expanded = expandBraces(pattern, escapes);\n if (typeof expanded === 'string') return expanded;\n\n const alternatives: Alternative[] = [];\n for (const text of expanded) {\n const parsed = parseAlternative(trailingSlash(text, options.dialect), escapes);\n if (parsed === GLOBSTAR_IN_NAME) return `${GLOBSTAR_IN_NAME}: ${globstarAdvice(written)}`;\n if (typeof parsed === 'string') return parsed;\n alternatives.push(parsed);\n }\n\n const builder = new Builder();\n const fragments: Fragment[] = [];\n const bases: string[] = [];\n let automaton: Automaton;\n try {\n for (const alternative of alternatives) {\n const compiled = compileAlternative(builder, alternative, options, rooted, anchored);\n fragments.push(compiled.fragment);\n bases.push(compiled.base);\n }\n automaton = builder.finish(builder.either(fragments), options.caseSensitive);\n } catch (error) {\n // A pattern too large to compile is refused with a reason, as a malformed\n // one is. Anything else - a caller's literal reading that throws - is the\n // caller's failure, not the pattern's, and goes on up.\n if (error instanceof AutomatonTooLarge) return error.message;\n throw error;\n }\n let matcher: Matcher | null = null;\n return {\n source,\n dialect: options.dialect,\n caseSensitive: options.caseSensitive,\n bases: [...new Set(bases)],\n automaton,\n match(path: string): boolean {\n matcher ??= new Matcher(automaton);\n return matcher.test(path);\n },\n };\n}\n\n/* ------------------------------------------------------------------ braces */\n\n/**\n * Expands `{a,b}` groups into the patterns they stand for, or says why the\n * pattern is malformed.\n *\n * Classes and escapes are skipped while looking for braces and commas, so\n * `{[,]x,y}` is two alternatives, `[,]x` and `y`. A lone `}` is a literal: it\n * cannot be read as anything else. An unclosed `{` is an error.\n *\n * Here and in the two functions after it, a loop that reads one step past\n * the end reads `''`, which none of them acts on, and `classEnd` answers -1\n * or an index past the `[`, so `close > 0` and `close >= 0` read the same.\n * `open` is set by the `{` that any `}` read here closes, so its first value\n * is never read.\n */\nfunction expandBraces(pattern: string, escapes: boolean): string[] | string {\n let depth = 0;\n let open = -1;\n for (let i = 0; i < pattern.length; i += 1) {\n const ch = pattern.charAt(i);\n if (ch === '\\\\' && escapes) {\n i += 1;\n continue;\n }\n if (ch === '[') {\n const close = classEnd(pattern, i, escapes);\n if (close > 0) i = close;\n continue;\n }\n if (ch === '{') {\n if (depth === 0) open = i;\n depth += 1;\n continue;\n }\n if (ch !== '}' || depth === 0) continue;\n depth -= 1;\n if (depth > 0) continue;\n const prefix = pattern.slice(0, open);\n const suffix = pattern.slice(i + 1);\n const results: string[] = [];\n for (const option of splitOptions(pattern.slice(open + 1, i), escapes)) {\n const expanded = expandBraces(`${prefix}${option}${suffix}`, escapes);\n if (typeof expanded === 'string') return expanded;\n results.push(...expanded);\n if (results.length > MAX_ALTERNATIVES) return `the braces expand to more than ${MAX_ALTERNATIVES} patterns`;\n }\n return results;\n }\n if (depth > 0) return 'a \"{\" is never closed';\n return [pattern];\n}\n\n/** Splits a brace body on its top-level commas. */\nfunction splitOptions(body: string, escapes: boolean): string[] {\n const parts: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < body.length; i += 1) {\n const ch = body.charAt(i);\n if (ch === '\\\\' && escapes) {\n i += 1;\n } else if (ch === '[') {\n const close = classEnd(body, i, escapes);\n if (close > 0) i = close;\n } else if (ch === '{') {\n depth += 1;\n } else if (ch === '}') {\n depth -= 1;\n } else if (ch === ',' && depth === 0) {\n parts.push(body.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(body.slice(start));\n return parts;\n}\n\n/** The index of the `]` closing a class opened at `open`, or -1 when none does within the segment. */\nfunction classEnd(pattern: string, open: number, escapes: boolean): number {\n let i = open + 1;\n if (pattern.charAt(i) === '!' || pattern.charAt(i) === '^') i += 1;\n // The first member is always a member, even `]`.\n if (pattern.charAt(i) === ']') i += 1;\n for (; i < pattern.length; i += 1) {\n const ch = pattern.charAt(i);\n if (ch === '\\\\' && escapes) {\n i += 1;\n continue;\n }\n if (ch === '/') return -1;\n if (ch === ']') return i;\n }\n return -1;\n}\n\n/* ---------------------------------------------------------------- segments */\n\n/**\n * What a trailing slash means, read on each alternative the braces give, so\n * that `{src/,lib}` reads `src/` as `src/` alone reads: the directory's\n * contents, `src/**`, and not a literal that may be the directory itself.\n *\n * In an exclusion `build/` excludes what `build` does. Git's rule is that a\n * trailing slash matches only a directory, and a directory is excluded with\n * everything in it; a matcher that sees only a path cannot tell a directory\n * from a file, so the slash is dropped, and it anchors nothing. An\n * alternative that is only slashes names the root, which `parseAlternative`\n * refuses as naming no path.\n *\n * The whole run of slashes is taken, so that `{//,a}` is refused as `{/,a}`\n * is; taken lazily it is the whole run all the same, since it ends the text.\n */\nfunction trailingSlash(text: string, dialect: GlobDialect): string {\n const name = text.replace(/\\/+$/, '');\n return name === text || name === '' || dialect === 'gitignore' ? name : `${name}/**`;\n}\n\nfunction parseAlternative(text: string, escapes: boolean): Alternative | string {\n const segments: Segment[] = [];\n const raw = text.split('/');\n for (const part of raw) {\n if (part === '' || part === '.') continue;\n if (part === '..') return 'a pattern cannot climb out of its root with \"..\"';\n if (part === '**') {\n if (segments[segments.length - 1]?.kind !== 'globstar') segments.push({ kind: 'globstar' });\n continue;\n }\n const tokens = tokenize(part, escapes);\n if (typeof tokens === 'string') return tokens;\n segments.push({ kind: 'name', tokens });\n }\n if (segments.length === 0) return 'the pattern names no path';\n return { segments, slashed: raw.filter((part) => part !== '' && part !== '.').length > 1 };\n}\n\nconst EXTGLOB = 'extended globs such as \"+(a|b)\" are not supported: write alternatives as \"{a,b}\", and a literal parenthesis as \"[(]\"';\nconst GLOBSTAR_IN_NAME = '\"**\" means any number of directories only as a whole segment';\n\n/**\n * The two patterns a writer of `**` inside a name may have meant, built from\n * what they wrote. Each run of stars that is not a whole segment becomes, for\n * any depth, a globstar segment with a star kept on each side where a name\n * went on - `docs/**.md` to `docs/**\\/*.md`, `src/a**` to `src/a*\\/**`,\n * `a**b` to `a*\\/**\\/*b` - and for one level a single star. Everything else\n * stays as written, braces and classes included, and a globstar that was a\n * whole segment stays one.\n *\n * Only `/` is taken for a boundary. A run beside a brace, `{**.md,x}`, is\n * given a star on that side too, which keeps the advice a pattern that\n * compiles whatever the braces expand to.\n *\n * `written` holds a `\\` only where it escapes: in the `separator` reading\n * each one is already a `/`.\n */\nfunction globstarAdvice(written: string): string {\n let deep = '';\n let flat = '';\n let at = 0;\n // One step past the end reads `''` and appends nothing, so the bound could\n // be one further and give the same advice.\n while (at < written.length) {\n const ch = written.charAt(at);\n let next = at + 1;\n if (ch === '\\\\') {\n next = at + 2;\n } else if (ch === '[') {\n // A class is copied as written. `classEnd` answers an index past the\n // `[`, or -1 for one never closed, so `close >= 0` reads the same; and\n // stopping one short of the `]` copies the class all the same, since\n // its last member and the `]` after it are never a run of stars.\n const close = classEnd(written, at, true);\n if (close > 0) next = close + 1;\n } else if (ch === '*') {\n while (written.charAt(next) === '*') next += 1;\n const before = at > 0 && written.charAt(at - 1) !== '/';\n const after = next < written.length && written.charAt(next) !== '/';\n if (next - at > 2 || (next - at === 2 && (before || after))) {\n deep += `${before ? '*/' : ''}**${after ? '/*' : ''}`;\n flat += '*';\n at = next;\n continue;\n }\n }\n deep += written.slice(at, next);\n flat += written.slice(at, next);\n at = next;\n }\n return `write \"${deep}\" for any depth, or \"${flat}\" for one level`;\n}\n\nfunction tokenize(segment: string, escapes: boolean): Token[] | string {\n const tokens: Token[] = [];\n const chars = Array.from(segment);\n for (let i = 0; i < chars.length; i += 1) {\n const ch = chars[i] as string;\n if (ch === '\\\\' && escapes) {\n const next = chars[i + 1];\n if (next === undefined || /[A-Za-z0-9]/.test(next)) {\n return '\"\\\\\" escapes glob syntax; separate directories with \"/\"';\n }\n tokens.push({ kind: 'literal', point: next.codePointAt(0) as number });\n i += 1;\n } else if (ch === '*') {\n // Two stars inside a name are refused rather than read as one. The\n // tools this replaces read `docs/**.md` three ways - recursive, one\n // level, and as ripgrep does - and reading it as one level silently\n // dropped every nested document from a run that used to include them.\n if (chars[i + 1] === '*') return GLOBSTAR_IN_NAME;\n tokens.push({ kind: 'star' });\n } else if (ch === '?') {\n tokens.push({ kind: 'any' });\n } else if (ch === '[') {\n const parsed = readClass(chars, i, escapes);\n if (typeof parsed === 'string') return parsed;\n tokens.push(parsed.token);\n i = parsed.end;\n } else {\n tokens.push({ kind: 'literal', point: ch.codePointAt(0) as number });\n }\n }\n return tokens;\n}\n\nfunction readClass(chars: readonly string[], open: number, escapes: boolean): { token: Token; end: number } | string {\n let i = open + 1;\n let negated = false;\n if (chars[i] === '!' || chars[i] === '^') {\n negated = true;\n i += 1;\n }\n const ranges: CodeRange[] = [];\n let first = true;\n for (; i < chars.length; i += 1) {\n const ch = chars[i] as string;\n if (ch === ']' && !first) return { token: { kind: 'class', negated, ranges }, end: i };\n first = false;\n let low = ch;\n if (ch === '\\\\' && escapes && chars[i + 1] !== undefined) {\n i += 1;\n low = chars[i] as string;\n }\n let high = low;\n if (chars[i + 1] === '-' && chars[i + 2] !== undefined && chars[i + 2] !== ']') {\n i += 2;\n high = chars[i] as string;\n if (high === '\\\\' && escapes && chars[i + 1] !== undefined) {\n i += 1;\n high = chars[i] as string;\n }\n }\n const from = low.codePointAt(0) as number;\n const to = high.codePointAt(0) as number;\n if (to < from) return `the range \"${low}-${high}\" runs backwards`;\n ranges.push([from, to]);\n }\n return 'a \"[\" is never closed';\n}\n\n/* --------------------------------------------------------------- compiling */\n\nfunction literalText(segments: readonly Segment[]): string | null {\n const names: string[] = [];\n for (const segment of segments) {\n if (segment.kind !== 'name') return null;\n let name = '';\n for (const token of segment.tokens) {\n if (token.kind !== 'literal') return null;\n name += String.fromCodePoint(token.point);\n }\n names.push(name);\n }\n return names.join('/');\n}\n\n/** One segment name: at least one character, none of them `/`. */\nfunction name(b: Builder): Fragment {\n return b.plus(b.char(ANY));\n}\n\n/** Zero or more whole directories: `(name/)*`. */\nfunction anyDirectories(b: Builder): Fragment {\n return b.star(b.sequence([name(b), b.char(SEPARATOR)]));\n}\n\n/** One or more whole segments below a path: `/name(/name)*`. */\nfunction beneath(b: Builder): Fragment {\n return b.sequence([b.char(SEPARATOR), name(b), b.star(b.sequence([b.char(SEPARATOR), name(b)]))]);\n}\n\nfunction tokens(b: Builder, list: readonly Token[]): Fragment {\n return b.sequence(\n list.map((token) => {\n switch (token.kind) {\n case 'literal':\n return b.char(literalSet(token.point));\n case 'any':\n return b.char(ANY);\n case 'star':\n return b.star(b.char(ANY));\n case 'class':\n return b.char(classSet(token.ranges, token.negated));\n }\n }),\n );\n}\n\nfunction segmentsFragment(b: Builder, segments: readonly Segment[]): Fragment {\n const parts: Fragment[] = [];\n segments.forEach((segment, i) => {\n const last = i === segments.length - 1;\n if (segment.kind === 'globstar') {\n // Inside a path a globstar is any number of whole directories, the\n // separator after them included; at its end, at least one segment.\n parts.push(last ? b.sequence([name(b), b.star(b.sequence([b.char(SEPARATOR), name(b)]))]) : anyDirectories(b));\n return;\n }\n parts.push(tokens(b, segment.tokens));\n if (!last) parts.push(b.char(SEPARATOR));\n });\n return b.sequence(parts);\n}\n\nfunction compileAlternative(\n b: Builder,\n alternative: Alternative,\n options: GlobOptions,\n rooted: boolean,\n anchored: boolean,\n): { fragment: Fragment; base: string } {\n const { segments } = alternative;\n const body = segmentsFragment(b, segments);\n const root = rooted ? '/' : '';\n const literal = literalText(segments);\n const leading = leadingLiteral(segments);\n\n if (options.dialect === 'gitignore') {\n const floating = !anchored && !alternative.slashed;\n const parts = [body, b.optional(beneath(b))];\n if (floating) parts.unshift(anyDirectories(b));\n const base = literal !== null ? leading.slice(0, -1) : leading;\n return { fragment: b.sequence(parts), base: floating ? '' : base.join('/') };\n }\n\n if (options.dialect === 'ripgrep' && !rooted && !alternative.slashed) {\n return { fragment: b.sequence([anyDirectories(b), body]), base: '' };\n }\n\n const parts = rooted ? [b.char(SEPARATOR), body] : [body];\n if (options.dialect === 'path' && literal !== null) {\n const reading = typeof options.literal === 'function' ? options.literal(root + literal) : options.literal ?? 'either';\n if (reading === 'directory') {\n parts.push(beneath(b));\n return { fragment: b.sequence(parts), base: root + literal };\n }\n if (reading === 'either') parts.push(b.optional(beneath(b)));\n }\n // A literal path may be a file, whose base is the directory holding it.\n const base = literal !== null ? leading.slice(0, -1) : leading;\n return { fragment: b.sequence(parts), base: root + base.join('/') };\n}\n\nfunction leadingLiteral(segments: readonly Segment[]): string[] {\n const out: string[] = [];\n for (const segment of segments) {\n const text = literalText([segment]);\n if (text === null) break;\n out.push(text);\n }\n return out;\n}\n\n/* ---------------------------------------------------------------- questions */\n\nfunction assertComparable(globs: readonly Glob[]): void {\n for (const glob of globs) {\n if (!glob.caseSensitive) throw new Error(`\"${glob.source}\" ignores case; scopes are compared case-sensitively`);\n }\n}\n\n/**\n * A shortest path every glob in `include` matches and no glob in `exclude`\n * does: the file two scopes would both write, less what either protects.\n * `none` is a proof that there is no such path. Case-sensitive globs only.\n */\nexport function globWitness(\n include: readonly Glob[],\n exclude: readonly Glob[] = [],\n budget: number = WITNESS_BUDGET,\n): Witness {\n assertComparable([...include, ...exclude]);\n return findWitness(\n include.map((glob) => glob.automaton),\n exclude.map((glob) => glob.automaton),\n budget,\n );\n}\n\n/**\n * Whether every path `inner` matches is matched by one of `outer`: `true`,\n * `false`, or `undecided` when the search met its budget.\n */\nexport function globCovers(\n outer: readonly Glob[],\n inner: Glob,\n budget: number = WITNESS_BUDGET,\n): boolean | 'undecided' {\n const witness = globWitness([inner], outer, budget);\n return witness.kind === 'undecided' ? 'undecided' : witness.kind === 'none';\n}\n\n/* -------------------------------------------------------------------- lists */\n\nexport interface GlobList {\n /** Whether a path is in: the last entry that matches it decides, and a `!` entry takes it out. */\n match(path: string): boolean;\n readonly entries: readonly { readonly negated: boolean; readonly glob: Glob }[];\n}\n\nexport type GlobListParse = { readonly ok: true; readonly list: GlobList } | { readonly ok: false; readonly error: string };\n\n/**\n * A list of patterns read the way a `.gitignore` reads: in order, each entry\n * deciding the paths it matches, a leading `!` taking them back out.\n */\nexport function parseGlobList(patterns: readonly string[], options: GlobOptions): GlobListParse {\n const entries: { negated: boolean; glob: Glob }[] = [];\n for (const pattern of patterns) {\n const trimmed = pattern.trim();\n const negated = trimmed.startsWith('!');\n const parsed = parseGlob(negated ? trimmed.slice(1) : trimmed, options);\n if (!parsed.ok) return { ok: false, error: `\"${pattern}\": ${parsed.error}` };\n entries.push({ negated, glob: parsed.glob });\n }\n return {\n ok: true,\n list: {\n entries,\n match(path: string): boolean {\n let included = false;\n for (const entry of entries) if (entry.glob.match(path)) included = !entry.negated;\n return included;\n },\n },\n };\n}\n"]}
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/pattern/glob.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Globs, in the three dialects the spec-* tools speak, compiled to one kind of\n * automaton.\n *\n * The syntax is the part people type: `*`, `**`, `?`, `[abc]`, `[!a-z]`,\n * `{a,b}`, and `\\` to escape. What differs between the tools is not the\n * syntax but what a pattern is matched against, and those differences are\n * deliberate, so each has a name (docs/adr/0003-glob-dialects.md):\n *\n * - `path` - the whole repository-relative path, anchored at the root. A\n * pattern with no glob syntax names a file, a directory, or either, as the\n * caller says; `src/auth` may cover `src/auth/login.ts`.\n * - `ripgrep` - as ripgrep's `-g`: a pattern with no `/` is matched against\n * the last segment at any depth, so `*.ts` matches `src/deep/a.ts`; one with\n * a `/` is matched against the whole path.\n * - `gitignore` - as an exclusion list reads: a pattern matches a path or any\n * directory above it, so `tests` excludes everything under any `tests`; one\n * with a `/` other than a trailing one is anchored at the root, and a\n * leading `/` only anchors.\n *\n * Shared by all three:\n *\n * - `**` is a globstar only as a whole segment. `a/**\\/b` matches `a/b` and\n * `a/x/y/b`; a trailing `/**` matches everything inside a directory and not\n * the directory itself. Two stars inside a name, `**.md`, are refused: the\n * tools read it three ways, and the quiet reading narrowed their scope. The\n * refusal writes the two patterns it may have meant from the one written.\n * - `*`, `?` and classes never match `/`, and `*` matches a leading dot.\n * - Braces expand first, and each alternative reads as it would written on\n * its own: `{src/,lib}` is `src/` or `lib`, and a trailing `/` means the\n * directory's contents - in an exclusion, the directory and its contents.\n * One that names no path, `{./,lib}` or `{,lib}`, is refused, as `./` and\n * the empty pattern are.\n * - Case is the caller's decision, stated every time. A result must not\n * depend on the host it ran on.\n * - A malformed pattern is an error, never a literal. An unclosed `[` or `{`,\n * an extended glob, a `..` - each is refused with a reason, because a typo\n * read as a literal is a scope that silently matches nothing. An extended\n * glob is a group holding a `|`, `+(a|b)`: without one, `C++(notes).md` is\n * a name with parentheses in it, as ripgrep and `.gitignore` read it.\n */\n\nimport {\n AutomatonTooLarge,\n Builder,\n findWitness,\n Matcher,\n WITNESS_BUDGET,\n type Automaton,\n type Fragment,\n type Witness,\n} from './automaton.js';\nimport { ANY, classSet, literalSet, SEPARATOR, type CodeRange } from './charset.js';\n\nexport type GlobDialect = 'path' | 'ripgrep' | 'gitignore';\n\n/** How a `path` pattern with no glob syntax is read. */\nexport type LiteralReading = 'file' | 'directory' | 'either';\n\nexport interface GlobOptions {\n readonly dialect: GlobDialect;\n /** Whether `A` and `a` differ. No default: the caller decides, every time. */\n readonly caseSensitive: boolean;\n /**\n * `path` dialect only: how a pattern with no glob syntax is read - as a\n * file, as a directory and everything beneath it, or as either. A function\n * is asked per literal path, for a caller that knows the tree. `either` when\n * unset. A trailing `/`, on the pattern or on one of its brace alternatives,\n * always means a directory's contents, and is never asked about.\n */\n readonly literal?: LiteralReading | ((path: string) => LiteralReading) | undefined;\n /**\n * `escape` (the default): `\\` escapes the next character, and a `\\` before a\n * letter or digit is refused as a Windows separator typed by mistake.\n * `separator`: every `\\` is a `/`, for patterns typed on a Windows shell.\n */\n readonly backslash?: 'escape' | 'separator' | undefined;\n}\n\nexport interface Glob {\n readonly source: string;\n readonly dialect: GlobDialect;\n readonly caseSensitive: boolean;\n /**\n * The directories a walk must enter to find every match: one per\n * alternative, the leading literal segments. `''` for an alternative that\n * can match at any depth.\n */\n readonly bases: readonly string[];\n readonly automaton: Automaton;\n /** Whether a canonical path - POSIX, no `.`, no empty or trailing segment - matches. */\n match(path: string): boolean;\n}\n\nexport type GlobParse = { readonly ok: true; readonly glob: Glob } | { readonly ok: false; readonly error: string };\n\nexport class GlobError extends Error {\n readonly source: string;\n constructor(source: string, reason: string) {\n super(`invalid glob \"${source}\": ${reason}`);\n this.name = 'GlobError';\n this.source = source;\n }\n}\n\n/** More alternatives than this is a pattern nobody meant. */\nexport const MAX_ALTERNATIVES = 256;\n\ntype Token =\n | { readonly kind: 'literal'; readonly point: number }\n | { readonly kind: 'any' }\n | { readonly kind: 'star' }\n | { readonly kind: 'class'; readonly negated: boolean; readonly ranges: readonly CodeRange[] };\n\ntype Segment = { readonly kind: 'globstar' } | { readonly kind: 'name'; readonly tokens: readonly Token[] };\n\ninterface Alternative {\n readonly segments: readonly Segment[];\n /** Written with a `/` somewhere other than at its end. */\n readonly slashed: boolean;\n}\n\n/** Whether a string uses glob syntax at all. */\nexport function isGlobSyntax(source: string): boolean {\n return /[*?[\\]{}]/.test(source);\n}\n\n/**\n * Parses and compiles a glob, or says why it cannot: malformed, or too large\n * to compile, past {@link MAX_ALTERNATIVES} alternatives or `MAX_STATES`\n * states. It throws only what a `literal` function throws.\n */\nexport function parseGlob(source: string, options: GlobOptions): GlobParse {\n const result = build(source, options);\n return typeof result === 'string' ? { ok: false, error: result } : { ok: true, glob: result };\n}\n\n/**\n * Parses and compiles a glob, throwing {@link GlobError} for every reason\n * {@link parseGlob} gives, and what a `literal` function throws.\n */\nexport function compileGlob(source: string, options: GlobOptions): Glob {\n const result = build(source, options);\n if (typeof result === 'string') throw new GlobError(source, result);\n return result;\n}\n\nfunction build(source: string, options: GlobOptions): Glob | string {\n const escapes = options.backslash !== 'separator';\n let pattern = source.trim();\n if (!escapes) pattern = pattern.replace(/\\\\/g, '/');\n const written = pattern;\n if (pattern.length === 0) return 'the pattern is empty';\n if (pattern.startsWith('!')) return 'a negated pattern is a list entry, not a glob; narrow the positive pattern';\n if (/(?:^|[^\\\\])[?*+@!]\\([^)]*\\|/.test(pattern)) return EXTGLOB;\n while (pattern.startsWith('./')) pattern = pattern.slice(2);\n\n // A leading slash roots a pattern at the filesystem's root in the path and\n // ripgrep dialects, and only anchors it at the repository root in gitignore.\n let rooted = false;\n let anchored = false;\n if (pattern.startsWith('/')) {\n if (options.dialect === 'gitignore') anchored = true;\n else rooted = true;\n pattern = pattern.replace(/^\\/+/, '');\n }\n if (pattern.length === 0) return 'the pattern names the root itself, not a path under it';\n\n const expanded = expandBraces(pattern, escapes);\n if (typeof expanded === 'string') return expanded;\n\n const alternatives: Alternative[] = [];\n for (const text of expanded) {\n // Refused before its trailing slash is read, which would make `./` the\n // contents of `.`, every path: `{./,a}` is refused as `./` alone is.\n // Each text the braces give is shorter than the pattern, so only a\n // pattern without braces is its own text.\n if (namesNoPath(text)) return text === pattern ? 'the pattern names no path' : bracesNamingNoPath(text);\n const parsed = parseAlternative(trailingSlash(text, options.dialect), escapes);\n if (parsed === GLOBSTAR_IN_NAME) return `${GLOBSTAR_IN_NAME}: ${globstarAdvice(written)}`;\n if (typeof parsed === 'string') return parsed;\n alternatives.push(parsed);\n }\n\n const builder = new Builder();\n const fragments: Fragment[] = [];\n const bases: string[] = [];\n let automaton: Automaton;\n try {\n for (const alternative of alternatives) {\n const compiled = compileAlternative(builder, alternative, options, rooted, anchored);\n fragments.push(compiled.fragment);\n bases.push(compiled.base);\n }\n automaton = builder.finish(builder.either(fragments), options.caseSensitive);\n } catch (error) {\n // A pattern too large to compile is refused with a reason, as a malformed\n // one is. Anything else - a caller's literal reading that throws - is the\n // caller's failure, not the pattern's, and goes on up.\n if (error instanceof AutomatonTooLarge) return error.message;\n throw error;\n }\n let matcher: Matcher | null = null;\n return {\n source,\n dialect: options.dialect,\n caseSensitive: options.caseSensitive,\n bases: [...new Set(bases)],\n automaton,\n match(path: string): boolean {\n matcher ??= new Matcher(automaton);\n return matcher.test(path);\n },\n };\n}\n\n/* ------------------------------------------------------------------ braces */\n\n/**\n * Expands `{a,b}` groups into the patterns they stand for, or says why the\n * pattern is malformed.\n *\n * Classes and escapes are skipped while looking for braces and commas, so\n * `{[,]x,y}` is two alternatives, `[,]x` and `y`. A lone `}` is a literal: it\n * cannot be read as anything else. An unclosed `{` is an error.\n *\n * Here and in the two functions after it, a loop that reads one step past\n * the end reads `''`, which none of them acts on, and `classEnd` answers -1\n * or an index past the `[`, so `close > 0` and `close >= 0` read the same.\n * `open` is set by the `{` that any `}` read here closes, so its first value\n * is never read.\n */\nfunction expandBraces(pattern: string, escapes: boolean): string[] | string {\n let depth = 0;\n let open = -1;\n for (let i = 0; i < pattern.length; i += 1) {\n const ch = pattern.charAt(i);\n if (ch === '\\\\' && escapes) {\n i += 1;\n continue;\n }\n if (ch === '[') {\n const close = classEnd(pattern, i, escapes);\n if (close > 0) i = close;\n continue;\n }\n if (ch === '{') {\n if (depth === 0) open = i;\n depth += 1;\n continue;\n }\n if (ch !== '}' || depth === 0) continue;\n depth -= 1;\n if (depth > 0) continue;\n const prefix = pattern.slice(0, open);\n const suffix = pattern.slice(i + 1);\n const results: string[] = [];\n for (const option of splitOptions(pattern.slice(open + 1, i), escapes)) {\n const expanded = expandBraces(`${prefix}${option}${suffix}`, escapes);\n if (typeof expanded === 'string') return expanded;\n results.push(...expanded);\n if (results.length > MAX_ALTERNATIVES) return `the braces expand to more than ${MAX_ALTERNATIVES} patterns`;\n }\n return results;\n }\n if (depth > 0) return 'a \"{\" is never closed';\n return [pattern];\n}\n\n/** Splits a brace body on its top-level commas. */\nfunction splitOptions(body: string, escapes: boolean): string[] {\n const parts: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < body.length; i += 1) {\n const ch = body.charAt(i);\n if (ch === '\\\\' && escapes) {\n i += 1;\n } else if (ch === '[') {\n const close = classEnd(body, i, escapes);\n if (close > 0) i = close;\n } else if (ch === '{') {\n depth += 1;\n } else if (ch === '}') {\n depth -= 1;\n } else if (ch === ',' && depth === 0) {\n parts.push(body.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(body.slice(start));\n return parts;\n}\n\n/** The index of the `]` closing a class opened at `open`, or -1 when none does within the segment. */\nfunction classEnd(pattern: string, open: number, escapes: boolean): number {\n let i = open + 1;\n if (pattern.charAt(i) === '!' || pattern.charAt(i) === '^') i += 1;\n // The first member is always a member, even `]`.\n if (pattern.charAt(i) === ']') i += 1;\n for (; i < pattern.length; i += 1) {\n const ch = pattern.charAt(i);\n if (ch === '\\\\' && escapes) {\n i += 1;\n continue;\n }\n if (ch === '/') return -1;\n if (ch === ']') return i;\n }\n return -1;\n}\n\n/* ---------------------------------------------------------------- segments */\n\n/** Whether a pattern's text names no path: nothing in it but `/` and `.` segments. */\nfunction namesNoPath(text: string): boolean {\n return text.split('/').every((part) => part === '' || part === '.');\n}\n\n/**\n * The refusal of an alternative the braces give that names no path, naming\n * it as it was expanded, so that `.{/,a}` is told `./`, the text refused.\n */\nfunction bracesNamingNoPath(text: string): string {\n return text === '' ? 'the braces expand to an empty pattern' : `the braces expand to \"${text}\", which names no path`;\n}\n\n/**\n * What a trailing slash means, read on each alternative the braces give, so\n * that `{src/,lib}` reads `src/` as `src/` alone reads: the directory's\n * contents, `src/**`, and not a literal that may be the directory itself.\n *\n * In an exclusion `build/` excludes what `build` does. Git's rule is that a\n * trailing slash matches only a directory, and a directory is excluded with\n * everything in it; a matcher that sees only a path cannot tell a directory\n * from a file, so the slash is dropped, and it anchors nothing.\n *\n * Only ever given a text that names a path, so a name is left. The whole run\n * of slashes is taken, but one slash would read the same, since\n * `parseAlternative` drops the empty segments the rest leave; and taken\n * lazily it is the whole run all the same, since it ends the text.\n */\nfunction trailingSlash(text: string, dialect: GlobDialect): string {\n const name = text.replace(/\\/+$/, '');\n return name === text || dialect === 'gitignore' ? name : `${name}/**`;\n}\n\n/**\n * The segments of a text that names a path - `build` refuses one that does\n * not - so at least one segment is left.\n */\nfunction parseAlternative(text: string, escapes: boolean): Alternative | string {\n const segments: Segment[] = [];\n const raw = text.split('/');\n for (const part of raw) {\n if (part === '' || part === '.') continue;\n if (part === '..') return 'a pattern cannot climb out of its root with \"..\"';\n if (part === '**') {\n if (segments[segments.length - 1]?.kind !== 'globstar') segments.push({ kind: 'globstar' });\n continue;\n }\n const tokens = tokenize(part, escapes);\n if (typeof tokens === 'string') return tokens;\n segments.push({ kind: 'name', tokens });\n }\n return { segments, slashed: raw.filter((part) => part !== '' && part !== '.').length > 1 };\n}\n\nconst EXTGLOB = 'extended globs such as \"+(a|b)\" are not supported: write alternatives as \"{a,b}\", and a literal parenthesis as \"[(]\"';\nconst GLOBSTAR_IN_NAME = '\"**\" means any number of directories only as a whole segment';\n\n/**\n * The two patterns a writer of `**` inside a name may have meant, built from\n * what they wrote. Each run of stars that is not a whole segment becomes, for\n * any depth, a globstar segment with a star kept on each side where a name\n * went on - `docs/**.md` to `docs/**\\/*.md`, `src/a**` to `src/a*\\/**`,\n * `a**b` to `a*\\/**\\/*b` - and for one level a single star. Everything else\n * stays as written, braces and classes included, and a globstar that was a\n * whole segment stays one.\n *\n * Only `/` is taken for a boundary. A run beside a brace, `{**.md,x}`, is\n * given a star on that side too, which keeps the advice a pattern that\n * compiles whatever the braces expand to.\n *\n * `written` holds a `\\` only where it escapes: in the `separator` reading\n * each one is already a `/`.\n */\nfunction globstarAdvice(written: string): string {\n let deep = '';\n let flat = '';\n let at = 0;\n // One step past the end reads `''` and appends nothing, so the bound could\n // be one further and give the same advice.\n while (at < written.length) {\n const ch = written.charAt(at);\n let next = at + 1;\n if (ch === '\\\\') {\n next = at + 2;\n } else if (ch === '[') {\n // A class is copied as written. `classEnd` answers an index past the\n // `[`, or -1 for one never closed, so `close >= 0` reads the same; and\n // stopping one short of the `]` copies the class all the same, since\n // its last member and the `]` after it are never a run of stars.\n const close = classEnd(written, at, true);\n if (close > 0) next = close + 1;\n } else if (ch === '*') {\n while (written.charAt(next) === '*') next += 1;\n const before = at > 0 && written.charAt(at - 1) !== '/';\n const after = next < written.length && written.charAt(next) !== '/';\n if (next - at > 2 || (next - at === 2 && (before || after))) {\n deep += `${before ? '*/' : ''}**${after ? '/*' : ''}`;\n flat += '*';\n at = next;\n continue;\n }\n }\n deep += written.slice(at, next);\n flat += written.slice(at, next);\n at = next;\n }\n return `write \"${deep}\" for any depth, or \"${flat}\" for one level`;\n}\n\nfunction tokenize(segment: string, escapes: boolean): Token[] | string {\n const tokens: Token[] = [];\n const chars = Array.from(segment);\n for (let i = 0; i < chars.length; i += 1) {\n const ch = chars[i] as string;\n if (ch === '\\\\' && escapes) {\n const next = chars[i + 1];\n if (next === undefined || /[A-Za-z0-9]/.test(next)) {\n return '\"\\\\\" escapes glob syntax; separate directories with \"/\"';\n }\n tokens.push({ kind: 'literal', point: next.codePointAt(0) as number });\n i += 1;\n } else if (ch === '*') {\n // Two stars inside a name are refused rather than read as one. The\n // tools this replaces read `docs/**.md` three ways - recursive, one\n // level, and as ripgrep does - and reading it as one level silently\n // dropped every nested document from a run that used to include them.\n if (chars[i + 1] === '*') return GLOBSTAR_IN_NAME;\n tokens.push({ kind: 'star' });\n } else if (ch === '?') {\n tokens.push({ kind: 'any' });\n } else if (ch === '[') {\n const parsed = readClass(chars, i, escapes);\n if (typeof parsed === 'string') return parsed;\n tokens.push(parsed.token);\n i = parsed.end;\n } else {\n tokens.push({ kind: 'literal', point: ch.codePointAt(0) as number });\n }\n }\n return tokens;\n}\n\nfunction readClass(chars: readonly string[], open: number, escapes: boolean): { token: Token; end: number } | string {\n let i = open + 1;\n let negated = false;\n if (chars[i] === '!' || chars[i] === '^') {\n negated = true;\n i += 1;\n }\n const ranges: CodeRange[] = [];\n let first = true;\n for (; i < chars.length; i += 1) {\n const ch = chars[i] as string;\n if (ch === ']' && !first) return { token: { kind: 'class', negated, ranges }, end: i };\n first = false;\n let low = ch;\n if (ch === '\\\\' && escapes && chars[i + 1] !== undefined) {\n i += 1;\n low = chars[i] as string;\n }\n let high = low;\n if (chars[i + 1] === '-' && chars[i + 2] !== undefined && chars[i + 2] !== ']') {\n i += 2;\n high = chars[i] as string;\n if (high === '\\\\' && escapes && chars[i + 1] !== undefined) {\n i += 1;\n high = chars[i] as string;\n }\n }\n const from = low.codePointAt(0) as number;\n const to = high.codePointAt(0) as number;\n if (to < from) return `the range \"${low}-${high}\" runs backwards`;\n ranges.push([from, to]);\n }\n return 'a \"[\" is never closed';\n}\n\n/* --------------------------------------------------------------- compiling */\n\nfunction literalText(segments: readonly Segment[]): string | null {\n const names: string[] = [];\n for (const segment of segments) {\n if (segment.kind !== 'name') return null;\n let name = '';\n for (const token of segment.tokens) {\n if (token.kind !== 'literal') return null;\n name += String.fromCodePoint(token.point);\n }\n names.push(name);\n }\n return names.join('/');\n}\n\n/** One segment name: at least one character, none of them `/`. */\nfunction name(b: Builder): Fragment {\n return b.plus(b.char(ANY));\n}\n\n/** Zero or more whole directories: `(name/)*`. */\nfunction anyDirectories(b: Builder): Fragment {\n return b.star(b.sequence([name(b), b.char(SEPARATOR)]));\n}\n\n/** One or more whole segments below a path: `/name(/name)*`. */\nfunction beneath(b: Builder): Fragment {\n return b.sequence([b.char(SEPARATOR), name(b), b.star(b.sequence([b.char(SEPARATOR), name(b)]))]);\n}\n\nfunction tokens(b: Builder, list: readonly Token[]): Fragment {\n return b.sequence(\n list.map((token) => {\n switch (token.kind) {\n case 'literal':\n return b.char(literalSet(token.point));\n case 'any':\n return b.char(ANY);\n case 'star':\n return b.star(b.char(ANY));\n case 'class':\n return b.char(classSet(token.ranges, token.negated));\n }\n }),\n );\n}\n\nfunction segmentsFragment(b: Builder, segments: readonly Segment[]): Fragment {\n const parts: Fragment[] = [];\n segments.forEach((segment, i) => {\n const last = i === segments.length - 1;\n if (segment.kind === 'globstar') {\n // Inside a path a globstar is any number of whole directories, the\n // separator after them included; at its end, at least one segment.\n parts.push(last ? b.sequence([name(b), b.star(b.sequence([b.char(SEPARATOR), name(b)]))]) : anyDirectories(b));\n return;\n }\n parts.push(tokens(b, segment.tokens));\n if (!last) parts.push(b.char(SEPARATOR));\n });\n return b.sequence(parts);\n}\n\nfunction compileAlternative(\n b: Builder,\n alternative: Alternative,\n options: GlobOptions,\n rooted: boolean,\n anchored: boolean,\n): { fragment: Fragment; base: string } {\n const { segments } = alternative;\n const body = segmentsFragment(b, segments);\n const root = rooted ? '/' : '';\n const literal = literalText(segments);\n const leading = leadingLiteral(segments);\n\n if (options.dialect === 'gitignore') {\n const floating = !anchored && !alternative.slashed;\n const parts = [body, b.optional(beneath(b))];\n if (floating) parts.unshift(anyDirectories(b));\n const base = literal !== null ? leading.slice(0, -1) : leading;\n return { fragment: b.sequence(parts), base: floating ? '' : base.join('/') };\n }\n\n if (options.dialect === 'ripgrep' && !rooted && !alternative.slashed) {\n return { fragment: b.sequence([anyDirectories(b), body]), base: '' };\n }\n\n const parts = rooted ? [b.char(SEPARATOR), body] : [body];\n if (options.dialect === 'path' && literal !== null) {\n const reading = typeof options.literal === 'function' ? options.literal(root + literal) : options.literal ?? 'either';\n if (reading === 'directory') {\n parts.push(beneath(b));\n return { fragment: b.sequence(parts), base: root + literal };\n }\n if (reading === 'either') parts.push(b.optional(beneath(b)));\n }\n // A literal path may be a file, whose base is the directory holding it.\n const base = literal !== null ? leading.slice(0, -1) : leading;\n return { fragment: b.sequence(parts), base: root + base.join('/') };\n}\n\nfunction leadingLiteral(segments: readonly Segment[]): string[] {\n const out: string[] = [];\n for (const segment of segments) {\n const text = literalText([segment]);\n if (text === null) break;\n out.push(text);\n }\n return out;\n}\n\n/* ---------------------------------------------------------------- questions */\n\nfunction assertComparable(globs: readonly Glob[]): void {\n for (const glob of globs) {\n if (!glob.caseSensitive) throw new Error(`\"${glob.source}\" ignores case; scopes are compared case-sensitively`);\n }\n}\n\n/**\n * A shortest path every glob in `include` matches and no glob in `exclude`\n * does: the file two scopes would both write, less what either protects.\n * `none` is a proof that there is no such path. Case-sensitive globs only.\n */\nexport function globWitness(\n include: readonly Glob[],\n exclude: readonly Glob[] = [],\n budget: number = WITNESS_BUDGET,\n): Witness {\n assertComparable([...include, ...exclude]);\n return findWitness(\n include.map((glob) => glob.automaton),\n exclude.map((glob) => glob.automaton),\n budget,\n );\n}\n\n/**\n * Whether every path `inner` matches is matched by one of `outer`: `true`,\n * `false`, or `undecided` when the search met its budget.\n */\nexport function globCovers(\n outer: readonly Glob[],\n inner: Glob,\n budget: number = WITNESS_BUDGET,\n): boolean | 'undecided' {\n const witness = globWitness([inner], outer, budget);\n return witness.kind === 'undecided' ? 'undecided' : witness.kind === 'none';\n}\n\n/* -------------------------------------------------------------------- lists */\n\nexport interface GlobList {\n /** Whether a path is in: the last entry that matches it decides, and a `!` entry takes it out. */\n match(path: string): boolean;\n readonly entries: readonly { readonly negated: boolean; readonly glob: Glob }[];\n}\n\nexport type GlobListParse = { readonly ok: true; readonly list: GlobList } | { readonly ok: false; readonly error: string };\n\n/**\n * A list of patterns read the way a `.gitignore` reads: in order, each entry\n * deciding the paths it matches, a leading `!` taking them back out.\n */\nexport function parseGlobList(patterns: readonly string[], options: GlobOptions): GlobListParse {\n const entries: { negated: boolean; glob: Glob }[] = [];\n for (const pattern of patterns) {\n const trimmed = pattern.trim();\n const negated = trimmed.startsWith('!');\n const parsed = parseGlob(negated ? trimmed.slice(1) : trimmed, options);\n if (!parsed.ok) return { ok: false, error: `\"${pattern}\": ${parsed.error}` };\n entries.push({ negated, glob: parsed.glob });\n }\n return {\n ok: true,\n list: {\n entries,\n match(path: string): boolean {\n let included = false;\n for (const entry of entries) if (entry.glob.match(path)) included = !entry.negated;\n return included;\n },\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descent-vtt/spec-graph",
3
- "version": "0.9.7",
3
+ "version": "0.9.8",
4
4
  "description": "Turn Markdown specs into a verifiable relational graph. Catches ghost handovers, stale premises and broken references in CI.",
5
5
  "keywords": [
6
6
  "adr",