|
8 | 8 | // TAP summary, and always discards the sandbox. Selection stays useful on its own as |
9 | 9 | // "run these, in this order"; dryRun turns the prediction into measured evidence. |
10 | 10 | import { execFileSync, spawnSync } from "node:child_process"; |
11 | | -import { existsSync, mkdtempSync, readFileSync, rmSync, statSync } from "node:fs"; |
| 11 | +import { existsSync, mkdtempSync, readFileSync, realpathSync, rmSync, statSync } from "node:fs"; |
12 | 12 | import { tmpdir } from "node:os"; |
13 | 13 | import { join } from "node:path"; |
14 | 14 | import { build as buildAtlas, impact, load as loadAtlas } from "./atlas.js"; |
@@ -134,6 +134,12 @@ export function dryRun(root, { tests, timeoutMs = 120000 } = {}) { |
134 | 134 | const msg = /** @type {{stderr?: Buffer}} */ (e).stderr?.toString().trim() || String(e); |
135 | 135 | return { ok: false, reason: `git worktree add failed: ${msg}` }; |
136 | 136 | } |
| 137 | + // node --test reports each failure's `location:` as a canonical (realpath'd) path. |
| 138 | + // On platforms where tmpdir() itself is a symlink (macOS: /var → /private/var), the |
| 139 | + // raw `wt` path won't string-match those locations, so per-file attribution below |
| 140 | + // must compare against the canonicalized worktree root. On Linux (no symlink) this |
| 141 | + // is a no-op. |
| 142 | + const wtReal = realpathSync(wt); |
137 | 143 | // Runner policy: always `node --test <files...>` — a custom package test script |
138 | 144 | // (jest, vitest, …) is a WHOLE-SUITE command that can't be scoped per-file safely, |
139 | 145 | // which would defeat minimal selection. We still run node --test and say so, so a |
@@ -196,7 +202,7 @@ export function dryRun(root, { tests, timeoutMs = 120000 } = {}) { |
196 | 202 | let attributable = true; |
197 | 203 | for (const block of (run.stdout ?? "").split(/^not ok /m).slice(1)) { |
198 | 204 | const file = block.split("\n").map(locFile).find(Boolean); |
199 | | - const t = file && tests.find((c) => file === join(wt, String(c))); |
| 205 | + const t = file && tests.find((c) => file === join(wtReal, String(c))); |
200 | 206 | if (t) perFile[String(t)] = "fail"; |
201 | 207 | else attributable = false; |
202 | 208 | } |
|
0 commit comments