@vzn/vx 0.0.528 → 0.0.529

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.528",
3
+ "version": "0.0.529",
4
4
  "description": "The fastest task runner and build cache for JavaScript monorepos.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -21,10 +21,10 @@
21
21
  "node": ">=18"
22
22
  },
23
23
  "optionalDependencies": {
24
- "@vzn/vx-linux-x64": "0.0.528",
25
- "@vzn/vx-linux-arm64": "0.0.528",
26
- "@vzn/vx-darwin-x64": "0.0.528",
27
- "@vzn/vx-darwin-arm64": "0.0.528"
24
+ "@vzn/vx-linux-x64": "0.0.529",
25
+ "@vzn/vx-linux-arm64": "0.0.529",
26
+ "@vzn/vx-darwin-x64": "0.0.529",
27
+ "@vzn/vx-darwin-arm64": "0.0.529"
28
28
  },
29
29
  "dependencies": {
30
30
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -7,7 +7,13 @@
7
7
 
8
8
  import path from 'node:path'
9
9
  import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync } from 'node:fs'
10
- import { UserError, executablePath, gitSpawnRefusal, xxh3hex } from '../util/index.js'
10
+ import {
11
+ UserError,
12
+ executablePath,
13
+ gitSpawnRefusal,
14
+ isInstalledPath,
15
+ xxh3hex,
16
+ } from '../util/index.js'
11
17
  import { FILE_HASH_RACY_MS, racyWindowMs } from './layer.js'
12
18
 
13
19
  /** Three facts of the repository a directory is in: read off the disk, or one `git rev-parse`. */
@@ -517,7 +523,8 @@ function walkFiles(dir: string, rel = ''): string[] {
517
523
  }
518
524
  const out: string[] = []
519
525
  for (const e of entries) {
520
- if (e.name === '.git') continue
526
+ // Nothing tracks a vendored tree's files; an install there is not one.
527
+ if (e.name === '.git' || e.name === 'node_modules') continue
521
528
  const r = rel === '' ? e.name : `${rel}/${e.name}`
522
529
  if (e.isDirectory()) out.push(...walkFiles(dir, r))
523
530
  else out.push(r)
@@ -562,6 +569,7 @@ function parseLsFilesOutput(
562
569
  if (record.length === 0) continue
563
570
  const m = LS_FILES_STAGE_RE.exec(record)
564
571
  const filePath = m === null ? record : record.slice(m[0].length) // --others: bare path
572
+ if (m === null && isInstalledPath(filePath)) continue
565
573
  files.push(filePath)
566
574
  if (undecodableRecords.size > 0 && undecodableRecords.has(record)) undecodable.push(filePath)
567
575
  if (m === null) continue
@@ -1376,7 +1384,11 @@ export async function startGitEnumeration(
1376
1384
  // is). They come from the status walk, repo-root-relative like the dirty
1377
1385
  // set. Without a status answer the enumeration is the index alone.
1378
1386
  const untracked =
1379
- parsedStatus === null ? [] : [...stripPrefixFromSet(new Set(parsedStatus.untracked), gitPrefix)]
1387
+ parsedStatus === null
1388
+ ? []
1389
+ : [...stripPrefixFromSet(new Set(parsedStatus.untracked), gitPrefix)].filter(
1390
+ (rel) => !isInstalledPath(rel),
1391
+ )
1380
1392
  const listed = untracked.length === 0 ? tracked : tracked.concat(untracked)
1381
1393
  const nested = expandNestedRepos(workspaceRoot, listed, gitlinks)
1382
1394
  const all = nested.files
@@ -58,8 +58,10 @@ export {
58
58
  // re-lock can't bust every cache key the way a tracked source file
59
59
  // would. (Literal pattern, not the workspace `LOCKFILE_NAME` constant:
60
60
  // cache is a leaf module and must not import from workspace.)
61
+ //
62
+ // `node_modules` is not here: the enumeration drops an untracked file
63
+ // under one (`isInstalledPath`), and a tracked one is a source.
61
64
  const ALWAYS_IGNORE = [
62
- '**/node_modules/**',
63
65
  // Defense in depth, and measured as exactly that (item 497): git never
64
66
  // reports a path under `.git`, so dropping this line changes NOTHING on
65
67
  // any route into the input set. Probed three ways with the pattern in
package/src/util/index.ts CHANGED
@@ -43,6 +43,7 @@ export {
43
43
  splitNegations,
44
44
  staticPrefix,
45
45
  anyTaskGlob,
46
+ isInstalledPath,
46
47
  taskGlob,
47
48
  wholeSubtreePrefixes,
48
49
  slashBraceExpansions,
package/src/util/paths.ts CHANGED
@@ -366,6 +366,16 @@ export function slashBraceExpansions(pattern: string): string[] {
366
366
  return [pattern]
367
367
  }
368
368
 
369
+ /**
370
+ * Whether a path git lists as UNTRACKED is an installed dependency: it sits
371
+ * under a `node_modules` directory. Such a file is never an input, and the
372
+ * enumeration drops it. A TRACKED file there (a committed test fixture) is
373
+ * a source like any other: dropped by path, an edit to it was a stale hit.
374
+ */
375
+ export function isInstalledPath(rel: string): boolean {
376
+ return rel.startsWith('node_modules/') || rel.includes('/node_modules/')
377
+ }
378
+
369
379
  // oxlint-disable-next-line no-control-regex
370
380
  const CONTROL = /[\x00-\x1f\x7f-\x9f]/g
371
381
 
@@ -15,6 +15,7 @@ import {
15
15
  UserError,
16
16
  gitSpawnRefusal,
17
17
  isExecutableMissing,
18
+ isInstalledPath,
18
19
  relPosix,
19
20
  taskGlob,
20
21
  } from '../util/index.js'
@@ -234,7 +235,11 @@ export async function affectedChanges(
234
235
 
235
236
  // vx-lock.json (workspace-root metadata) is excluded like a gitignored
236
237
  // file: re-running `vx lock` must not mark every project affected.
237
- const changed = [...diffed, ...untracked].filter((s) => s !== LOCKFILE_NAME)
238
+ // An untracked file under `node_modules` is an install, which the input
239
+ // enumeration drops too (`isInstalledPath`); a tracked one is a source.
240
+ const changed = [...diffed, ...untracked.filter((s) => !isInstalledPath(s))].filter(
241
+ (s) => s !== LOCKFILE_NAME,
242
+ )
238
243
 
239
244
  // A lockfile or workspace-definition change re-keys EVERY task, because the
240
245
  // workspace fingerprint folds those files into every cache key. Mapping