headlamp 0.1.6 → 0.1.9
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/README.md +47 -2
- package/dist/cli.cjs +432 -264
- package/dist/cli.cjs.map +4 -4
- package/dist/index.js +436 -265
- package/dist/index.js.map +4 -4
- package/package.json +10 -4
- package/scripts/build.mjs +117 -0
- package/scripts/postinstall.mjs +13 -0
- package/scripts/print-publish-log.mjs +29 -0
package/dist/index.js
CHANGED
|
@@ -52,6 +52,7 @@ var init_args = __esm({
|
|
|
52
52
|
coverage: (coverageValue) => ({ type: "coverage", coverageValue }),
|
|
53
53
|
coverageUi: (value) => ({ type: "coverageUi", value }),
|
|
54
54
|
coverageAbortOnFailure: (value) => ({ type: "coverageAbortOnFailure", value }),
|
|
55
|
+
onlyFailures: (value) => ({ type: "onlyFailures", value }),
|
|
55
56
|
jestArg: (value) => ({ type: "jestArg", value }),
|
|
56
57
|
jestArgs: (values) => ({ type: "jestArgs", values }),
|
|
57
58
|
vitestArg: (value) => ({ type: "vitestArg", value }),
|
|
@@ -67,7 +68,8 @@ var init_args = __esm({
|
|
|
67
68
|
coverageMode: (value) => ({ type: "coverageMode", value }),
|
|
68
69
|
coverageMaxFiles: (value) => ({ type: "coverageMaxFiles", value }),
|
|
69
70
|
coverageMaxHotspots: (value) => ({ type: "coverageMaxHotspots", value }),
|
|
70
|
-
coveragePageFit: (value) => ({ type: "coveragePageFit", value })
|
|
71
|
+
coveragePageFit: (value) => ({ type: "coveragePageFit", value }),
|
|
72
|
+
changed: (value) => ({ type: "changed", value })
|
|
71
73
|
};
|
|
72
74
|
Some = (value) => ({ _tag: "some", value });
|
|
73
75
|
None = { _tag: "none" };
|
|
@@ -204,6 +206,18 @@ var init_args = __esm({
|
|
|
204
206
|
"--coverage.pageFit",
|
|
205
207
|
(_flag, lookahead) => step([ActionBuilders.coveragePageFit(isTruthy(String(lookahead)))], true)
|
|
206
208
|
),
|
|
209
|
+
// --onlyFailures flag (boolean)
|
|
210
|
+
rule.eq("--onlyFailures", () => step([ActionBuilders.onlyFailures(true)])),
|
|
211
|
+
rule.startsWith(
|
|
212
|
+
"--onlyFailures=",
|
|
213
|
+
(value) => step([
|
|
214
|
+
ActionBuilders.onlyFailures(isTruthy((value.split("=")[1] ?? "").trim().toLowerCase()))
|
|
215
|
+
])
|
|
216
|
+
),
|
|
217
|
+
rule.withLookahead(
|
|
218
|
+
"--onlyFailures",
|
|
219
|
+
(_flag, lookahead) => step([ActionBuilders.onlyFailures(isTruthy(String(lookahead)))], true)
|
|
220
|
+
),
|
|
207
221
|
rule.withLookahead(
|
|
208
222
|
"--testPathPattern",
|
|
209
223
|
(flag, lookahead) => step([ActionBuilders.jestArgs([flag, lookahead])], true)
|
|
@@ -264,6 +278,18 @@ var init_args = __esm({
|
|
|
264
278
|
"--coverage.root=",
|
|
265
279
|
(value) => step([ActionBuilders.coverageRoot((value.split("=")[1] ?? "").trim())])
|
|
266
280
|
),
|
|
281
|
+
// --changed flag: selects changed files via git (all|staged|unstaged)
|
|
282
|
+
rule.eq("--changed", () => step([ActionBuilders.changed("all")])),
|
|
283
|
+
rule.startsWith("--changed=", (value) => {
|
|
284
|
+
const raw = (value.split("=")[1] ?? "").trim().toLowerCase();
|
|
285
|
+
const mode = raw === "staged" ? "staged" : raw === "unstaged" ? "unstaged" : "all";
|
|
286
|
+
return step([ActionBuilders.changed(mode)]);
|
|
287
|
+
}),
|
|
288
|
+
rule.withLookahead("--changed", (_flag, lookahead) => {
|
|
289
|
+
const raw = String(lookahead).trim().toLowerCase();
|
|
290
|
+
const mode = raw === "staged" ? "staged" : raw === "unstaged" ? "unstaged" : "all";
|
|
291
|
+
return step([ActionBuilders.changed(mode)], true);
|
|
292
|
+
}),
|
|
267
293
|
rule.withLookahead(
|
|
268
294
|
"-t",
|
|
269
295
|
(flag, lookahead) => step(
|
|
@@ -338,6 +364,8 @@ var init_args = __esm({
|
|
|
338
364
|
return { vitest: [], jest: [], coverage: false, coverageUi: action.value };
|
|
339
365
|
case "coverageAbortOnFailure":
|
|
340
366
|
return { vitest: [], jest: [], coverage: false, coverageAbortOnFailure: action.value };
|
|
367
|
+
case "onlyFailures":
|
|
368
|
+
return { vitest: [], jest: [], coverage: false, onlyFailures: action.value };
|
|
341
369
|
case "jestArgs":
|
|
342
370
|
return { vitest: [], jest: action.values, coverage: false };
|
|
343
371
|
case "selectionHint":
|
|
@@ -366,6 +394,8 @@ var init_args = __esm({
|
|
|
366
394
|
return { vitest: [], jest: [], coverage: false, coverageMaxHotspots: action.value };
|
|
367
395
|
case "coveragePageFit":
|
|
368
396
|
return { vitest: [], jest: [], coverage: false, coveragePageFit: action.value };
|
|
397
|
+
case "changed":
|
|
398
|
+
return { vitest: [], jest: [], coverage: false, changed: action.value };
|
|
369
399
|
case "jestArg":
|
|
370
400
|
return { vitest: [], jest: [action.value], coverage: false };
|
|
371
401
|
case "vitestArg":
|
|
@@ -405,7 +435,9 @@ var init_args = __esm({
|
|
|
405
435
|
}
|
|
406
436
|
return {
|
|
407
437
|
...next,
|
|
438
|
+
...right.changed !== void 0 || left.changed !== void 0 ? { changed: right.changed ?? left.changed } : {},
|
|
408
439
|
...right.coverageAbortOnFailure !== void 0 || left.coverageAbortOnFailure !== void 0 ? { coverageAbortOnFailure: right.coverageAbortOnFailure ?? left.coverageAbortOnFailure } : {},
|
|
440
|
+
...right.onlyFailures !== void 0 || left.onlyFailures !== void 0 ? { onlyFailures: right.onlyFailures ?? left.onlyFailures } : {},
|
|
409
441
|
...right.coverageDetail !== void 0 || left.coverageDetail !== void 0 ? { coverageDetail: right.coverageDetail ?? left.coverageDetail } : {},
|
|
410
442
|
...right.coverageShowCode !== void 0 || left.coverageShowCode !== void 0 ? { coverageShowCode: right.coverageShowCode ?? left.coverageShowCode } : {},
|
|
411
443
|
...right.coverageMode !== void 0 || left.coverageMode !== void 0 ? { coverageMode: right.coverageMode ?? left.coverageMode } : {},
|
|
@@ -429,6 +461,7 @@ var init_args = __esm({
|
|
|
429
461
|
let collectCoverage = false;
|
|
430
462
|
let coverageUi = "both";
|
|
431
463
|
let coverageAbortOnFailure = false;
|
|
464
|
+
let onlyFailures = false;
|
|
432
465
|
let coverageShowCode = Boolean(process.stdout.isTTY);
|
|
433
466
|
let coverageMode = "auto";
|
|
434
467
|
const coverageMaxFilesLocalInit = void 0;
|
|
@@ -446,6 +479,7 @@ var init_args = __esm({
|
|
|
446
479
|
collectCoverage ||= contrib.coverage;
|
|
447
480
|
coverageUi = contrib.coverageUi ?? coverageUi;
|
|
448
481
|
coverageAbortOnFailure = contrib.coverageAbortOnFailure ?? coverageAbortOnFailure;
|
|
482
|
+
onlyFailures = contrib.onlyFailures ?? onlyFailures;
|
|
449
483
|
coverageShowCode = contrib.coverageShowCode ?? coverageShowCode;
|
|
450
484
|
const coverageDetailComputed = contrib.coverageDetail ?? (contrib.selection ? "auto" : void 0);
|
|
451
485
|
coverageMode = contrib.coverageMode ?? (contrib.selection ? "compact" : "auto");
|
|
@@ -479,6 +513,7 @@ var init_args = __esm({
|
|
|
479
513
|
collectCoverage,
|
|
480
514
|
coverageUi,
|
|
481
515
|
coverageAbortOnFailure,
|
|
516
|
+
onlyFailures,
|
|
482
517
|
selectionSpecified: Boolean(contrib.selection),
|
|
483
518
|
selectionPaths: [...contrib.selectionPaths ?? []],
|
|
484
519
|
includeGlobs,
|
|
@@ -490,7 +525,8 @@ var init_args = __esm({
|
|
|
490
525
|
...coverageMaxHotspotsLocal !== void 0 ? { coverageMaxHotspots: coverageMaxHotspotsLocal } : {},
|
|
491
526
|
coveragePageFit,
|
|
492
527
|
...contrib.editorCmd !== void 0 ? { editorCmd: contrib.editorCmd } : {},
|
|
493
|
-
...contrib.workspaceRoot !== void 0 ? { workspaceRoot: contrib.workspaceRoot } : {}
|
|
528
|
+
...contrib.workspaceRoot !== void 0 ? { workspaceRoot: contrib.workspaceRoot } : {},
|
|
529
|
+
...contrib.changed !== void 0 ? { changed: contrib.changed } : {}
|
|
494
530
|
};
|
|
495
531
|
return out;
|
|
496
532
|
};
|
|
@@ -557,7 +593,7 @@ var init_TimeoutError = __esm({
|
|
|
557
593
|
|
|
558
594
|
// node_modules/es-toolkit/dist/promise/delay.mjs
|
|
559
595
|
function delay(ms, { signal } = {}) {
|
|
560
|
-
return new Promise((
|
|
596
|
+
return new Promise((resolve9, reject) => {
|
|
561
597
|
const abortError = () => {
|
|
562
598
|
reject(new AbortError());
|
|
563
599
|
};
|
|
@@ -570,7 +606,7 @@ function delay(ms, { signal } = {}) {
|
|
|
570
606
|
}
|
|
571
607
|
const timeoutId = setTimeout(() => {
|
|
572
608
|
signal?.removeEventListener("abort", abortHandler);
|
|
573
|
-
|
|
609
|
+
resolve9();
|
|
574
610
|
}, ms);
|
|
575
611
|
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
576
612
|
});
|
|
@@ -635,11 +671,11 @@ var init_exec = __esm({
|
|
|
635
671
|
child.stderr?.on("data", (chunk) => {
|
|
636
672
|
stderr += String(chunk);
|
|
637
673
|
});
|
|
638
|
-
const exec = new Promise((
|
|
674
|
+
const exec = new Promise((resolve9, reject) => {
|
|
639
675
|
child.on("error", reject);
|
|
640
676
|
child.on(
|
|
641
677
|
"close",
|
|
642
|
-
(code) => Number(code) === 0 ?
|
|
678
|
+
(code) => Number(code) === 0 ? resolve9(stdout) : reject(new Error(stderr || `exit ${code}`))
|
|
643
679
|
);
|
|
644
680
|
});
|
|
645
681
|
try {
|
|
@@ -659,7 +695,7 @@ var init_exec = __esm({
|
|
|
659
695
|
throw caughtError;
|
|
660
696
|
}
|
|
661
697
|
};
|
|
662
|
-
runExitCode = async (cmd, args, opts = {}) => new Promise((
|
|
698
|
+
runExitCode = async (cmd, args, opts = {}) => new Promise((resolve9, reject) => {
|
|
663
699
|
const child = spawn(cmd, [...args], {
|
|
664
700
|
cwd: opts.cwd,
|
|
665
701
|
env: opts.env,
|
|
@@ -668,9 +704,9 @@ var init_exec = __esm({
|
|
|
668
704
|
windowsHide: true
|
|
669
705
|
});
|
|
670
706
|
child.on("error", reject);
|
|
671
|
-
child.on("close", (code) =>
|
|
707
|
+
child.on("close", (code) => resolve9(Number(code)));
|
|
672
708
|
});
|
|
673
|
-
runWithCapture = async (cmd, args, opts) => new Promise((
|
|
709
|
+
runWithCapture = async (cmd, args, opts) => new Promise((resolve9, reject) => {
|
|
674
710
|
const child = spawn(cmd, [...args], {
|
|
675
711
|
cwd: opts.cwd,
|
|
676
712
|
env: opts.env,
|
|
@@ -686,7 +722,7 @@ var init_exec = __esm({
|
|
|
686
722
|
buf += String(chunk);
|
|
687
723
|
});
|
|
688
724
|
child.on("error", reject);
|
|
689
|
-
child.on("close", (code) =>
|
|
725
|
+
child.on("close", (code) => resolve9({ code: Number(code), output: buf }));
|
|
690
726
|
});
|
|
691
727
|
}
|
|
692
728
|
});
|
|
@@ -1097,8 +1133,8 @@ var require_utils = __commonJS({
|
|
|
1097
1133
|
}
|
|
1098
1134
|
return output;
|
|
1099
1135
|
};
|
|
1100
|
-
exports.basename = (
|
|
1101
|
-
const segs =
|
|
1136
|
+
exports.basename = (path11, { windows } = {}) => {
|
|
1137
|
+
const segs = path11.split(windows ? /[\\/]/ : "/");
|
|
1102
1138
|
const last = segs[segs.length - 1];
|
|
1103
1139
|
if (last === "") {
|
|
1104
1140
|
return segs[segs.length - 2];
|
|
@@ -4688,8 +4724,75 @@ var compositeBarPct = (summary, hotspots) => {
|
|
|
4688
4724
|
// src/lib/coverage-print.ts
|
|
4689
4725
|
init_env_utils();
|
|
4690
4726
|
init_exec();
|
|
4691
|
-
import * as
|
|
4727
|
+
import * as path8 from "node:path";
|
|
4692
4728
|
import * as fsSync2 from "node:fs";
|
|
4729
|
+
|
|
4730
|
+
// src/lib/relevance.ts
|
|
4731
|
+
init_args();
|
|
4732
|
+
init_fast_related();
|
|
4733
|
+
import * as path7 from "node:path";
|
|
4734
|
+
var normalizeAbs = (inputPath) => path7.resolve(inputPath).replace(/\\/g, "/");
|
|
4735
|
+
var compareBooleanDesc = (left, right) => {
|
|
4736
|
+
if (left === right) {
|
|
4737
|
+
return 0;
|
|
4738
|
+
}
|
|
4739
|
+
return right ? 1 : -1;
|
|
4740
|
+
};
|
|
4741
|
+
var compareNumberAsc = (left, right) => left - right;
|
|
4742
|
+
var compareStringAsc = (left, right) => left.localeCompare(right);
|
|
4743
|
+
var fileFailed = (file) => Boolean(
|
|
4744
|
+
(file.status ?? "") === "failed" || (file.testResults ?? []).some((assertion) => (assertion.status ?? "") === "failed")
|
|
4745
|
+
);
|
|
4746
|
+
var composeComparators = (...comparators) => (left, right) => {
|
|
4747
|
+
for (const cmp of comparators) {
|
|
4748
|
+
const result = cmp(left, right);
|
|
4749
|
+
if (result !== 0) {
|
|
4750
|
+
return result;
|
|
4751
|
+
}
|
|
4752
|
+
}
|
|
4753
|
+
return 0;
|
|
4754
|
+
};
|
|
4755
|
+
var comparatorForRank = (rankByPath) => {
|
|
4756
|
+
const rankOrInf = (absPath) => rankByPath.has(absPath) ? rankByPath.get(absPath) : Number.POSITIVE_INFINITY;
|
|
4757
|
+
return composeComparators(
|
|
4758
|
+
(left, right) => compareBooleanDesc(fileFailed(left), fileFailed(right)),
|
|
4759
|
+
(left, right) => compareNumberAsc(
|
|
4760
|
+
rankOrInf(normalizeAbs(left.testFilePath)),
|
|
4761
|
+
rankOrInf(normalizeAbs(right.testFilePath))
|
|
4762
|
+
),
|
|
4763
|
+
(left, right) => compareStringAsc(normalizeAbs(left.testFilePath), normalizeAbs(right.testFilePath))
|
|
4764
|
+
);
|
|
4765
|
+
};
|
|
4766
|
+
var computeDirectnessRank = async (opts) => {
|
|
4767
|
+
const selectionKey = opts.productionSeeds.map((abs) => path7.relative(opts.repoRoot, abs).replace(/\\/g, "/")).sort((left, right) => left.localeCompare(right)).join("|");
|
|
4768
|
+
const related = await cachedRelated({
|
|
4769
|
+
repoRoot: opts.repoRoot,
|
|
4770
|
+
selectionKey,
|
|
4771
|
+
compute: () => findRelatedTestsFast({
|
|
4772
|
+
repoRoot: opts.repoRoot,
|
|
4773
|
+
productionPaths: opts.productionSeeds,
|
|
4774
|
+
testGlobs: DEFAULT_TEST_GLOBS,
|
|
4775
|
+
excludeGlobs: opts.excludeGlobs ?? DEFAULT_EXCLUDE,
|
|
4776
|
+
timeoutMs: 1500
|
|
4777
|
+
})
|
|
4778
|
+
});
|
|
4779
|
+
const out = /* @__PURE__ */ new Map();
|
|
4780
|
+
related.forEach((abs, index) => {
|
|
4781
|
+
out.set(normalizeAbs(abs), index);
|
|
4782
|
+
});
|
|
4783
|
+
return out;
|
|
4784
|
+
};
|
|
4785
|
+
var sortTestResultsWithRank = (rankByPath, results) => results.slice().sort(comparatorForRank(rankByPath));
|
|
4786
|
+
var comparatorForPathRank = (rankByPath) => {
|
|
4787
|
+
const rankOrInf = (absPath) => rankByPath.has(absPath) ? rankByPath.get(absPath) : Number.POSITIVE_INFINITY;
|
|
4788
|
+
return composeComparators(
|
|
4789
|
+
(left, right) => compareNumberAsc(rankOrInf(normalizeAbs(left)), rankOrInf(normalizeAbs(right))),
|
|
4790
|
+
(left, right) => compareStringAsc(normalizeAbs(left), normalizeAbs(right))
|
|
4791
|
+
);
|
|
4792
|
+
};
|
|
4793
|
+
var sortPathsWithRank = (rankByPath, paths) => paths.slice().sort(comparatorForPathRank(rankByPath));
|
|
4794
|
+
|
|
4795
|
+
// src/lib/coverage-print.ts
|
|
4693
4796
|
var printDetailedCoverage = async (opts) => {
|
|
4694
4797
|
const files = opts.map.files().sort((fileA, fileB) => {
|
|
4695
4798
|
const summaryA = opts.map.fileCoverageFor(fileA).toSummary();
|
|
@@ -4699,7 +4802,7 @@ var printDetailedCoverage = async (opts) => {
|
|
|
4699
4802
|
for (const abs of files) {
|
|
4700
4803
|
const fc = opts.map.fileCoverageFor(abs);
|
|
4701
4804
|
const sum = fc.toSummary();
|
|
4702
|
-
const rel =
|
|
4805
|
+
const rel = path8.relative(opts.root, abs).replace(/\\/g, "/");
|
|
4703
4806
|
const blocks = computeUncoveredBlocks(fc);
|
|
4704
4807
|
const misses = missedBranches(fc);
|
|
4705
4808
|
const missFns = missedFunctions(fc);
|
|
@@ -4708,9 +4811,9 @@ var printDetailedCoverage = async (opts) => {
|
|
|
4708
4811
|
const branchesPctText = `${sum.branches.pct.toFixed(1)}%`;
|
|
4709
4812
|
const header = `${ansi.bold(rel)} lines ${tintPct(sum.lines.pct)(
|
|
4710
4813
|
linesPctText
|
|
4711
|
-
)} ${barCell(compositeBarPct(sum, blocks))("".padEnd(14))} funcs ${tintPct(
|
|
4712
|
-
|
|
4713
|
-
)
|
|
4814
|
+
)} ${barCell(compositeBarPct(sum, blocks))("".padEnd(14))} funcs ${tintPct(sum.functions.pct)(
|
|
4815
|
+
funcsPctText
|
|
4816
|
+
)} branches ${tintPct(sum.branches.pct)(branchesPctText)}`;
|
|
4714
4817
|
console.info(header);
|
|
4715
4818
|
const max = opts.limitPerFile === "all" ? Number.POSITIVE_INFINITY : opts.limitPerFile ?? 5;
|
|
4716
4819
|
const compareRangesByLengthDescThenStart = (firstRange, secondRange) => {
|
|
@@ -4737,10 +4840,8 @@ var printDetailedCoverage = async (opts) => {
|
|
|
4737
4840
|
abs,
|
|
4738
4841
|
block.start,
|
|
4739
4842
|
opts.editorCmd
|
|
4740
|
-
)}\x07${
|
|
4741
|
-
const label = ` ${ansi.yellow(`L${block.start}`)}\u2013${ansi.yellow(
|
|
4742
|
-
`L${block.end}`
|
|
4743
|
-
)} ${link}`;
|
|
4843
|
+
)}\x07${path8.basename(abs)}:${block.start}\x1B]8;;\x07`;
|
|
4844
|
+
const label = ` ${ansi.yellow(`L${block.start}`)}\u2013${ansi.yellow(`L${block.end}`)} ${link}`;
|
|
4744
4845
|
console.info(label);
|
|
4745
4846
|
if (opts.showCode && src.length) {
|
|
4746
4847
|
const lines = src.split(/\r?\n/);
|
|
@@ -4760,7 +4861,7 @@ var printDetailedCoverage = async (opts) => {
|
|
|
4760
4861
|
abs,
|
|
4761
4862
|
fn.line,
|
|
4762
4863
|
opts.editorCmd
|
|
4763
|
-
)}\x07${
|
|
4864
|
+
)}\x07${path8.basename(abs)}:${fn.line}\x1B]8;;\x07`;
|
|
4764
4865
|
console.info(` - ${fn.name} @ ${link}`);
|
|
4765
4866
|
}
|
|
4766
4867
|
}
|
|
@@ -4771,12 +4872,8 @@ var printDetailedCoverage = async (opts) => {
|
|
|
4771
4872
|
abs,
|
|
4772
4873
|
br.line,
|
|
4773
4874
|
opts.editorCmd
|
|
4774
|
-
)}\x07${
|
|
4775
|
-
console.info(
|
|
4776
|
-
` - branch#${br.id} @ ${link} missed paths: [${br.zeroPaths.join(
|
|
4777
|
-
", "
|
|
4778
|
-
)}]`
|
|
4779
|
-
);
|
|
4875
|
+
)}\x07${path8.basename(abs)}:${br.line}\x1B]8;;\x07`;
|
|
4876
|
+
console.info(` - branch#${br.id} @ ${link} missed paths: [${br.zeroPaths.join(", ")}]`);
|
|
4780
4877
|
}
|
|
4781
4878
|
}
|
|
4782
4879
|
console.info("");
|
|
@@ -4796,7 +4893,7 @@ var printCompactCoverage = async (opts) => {
|
|
|
4796
4893
|
for (const abs of files.slice(0, fileCap)) {
|
|
4797
4894
|
const fc = opts.map.fileCoverageFor(abs);
|
|
4798
4895
|
const sum = fc.toSummary();
|
|
4799
|
-
const rel =
|
|
4896
|
+
const rel = path8.relative(opts.root, abs).replace(/\\/g, "/");
|
|
4800
4897
|
const compareRangesByLengthDescThenStart = (firstRange, secondRange) => {
|
|
4801
4898
|
const secondLength = secondRange.end - secondRange.start;
|
|
4802
4899
|
const firstLength = firstRange.end - firstRange.start;
|
|
@@ -4810,9 +4907,9 @@ var printCompactCoverage = async (opts) => {
|
|
|
4810
4907
|
const branchesPctText = `${sum.branches.pct.toFixed(1)}%`;
|
|
4811
4908
|
const header = `${ansi.bold(rel)} lines ${tintPct(sum.lines.pct)(
|
|
4812
4909
|
linesPctText
|
|
4813
|
-
)} ${barCell(compositeBarPct(sum, blocks))("".padEnd(14))} funcs ${tintPct(
|
|
4814
|
-
|
|
4815
|
-
)
|
|
4910
|
+
)} ${barCell(compositeBarPct(sum, blocks))("".padEnd(14))} funcs ${tintPct(sum.functions.pct)(
|
|
4911
|
+
funcsPctText
|
|
4912
|
+
)} branches ${tintPct(sum.branches.pct)(branchesPctText)}`;
|
|
4816
4913
|
console.info(header);
|
|
4817
4914
|
const hotspots = blocks.slice(0, maxHotspotsDerived);
|
|
4818
4915
|
if (hotspots.length) {
|
|
@@ -4823,10 +4920,8 @@ var printCompactCoverage = async (opts) => {
|
|
|
4823
4920
|
abs,
|
|
4824
4921
|
hotspot.start,
|
|
4825
4922
|
opts.editorCmd
|
|
4826
|
-
)}\x07${
|
|
4827
|
-
console.info(
|
|
4828
|
-
` - L${hotspot.start}\u2013L${hotspot.end} (${len} lines) ${link}`
|
|
4829
|
-
);
|
|
4923
|
+
)}\x07${path8.basename(abs)}:${hotspot.start}\x1B]8;;\x07`;
|
|
4924
|
+
console.info(` - L${hotspot.start}\u2013L${hotspot.end} (${len} lines) ${link}`);
|
|
4830
4925
|
}
|
|
4831
4926
|
}
|
|
4832
4927
|
const functionsList = missFns.slice(0, maxFunctionsDerived);
|
|
@@ -4838,7 +4933,7 @@ var printCompactCoverage = async (opts) => {
|
|
|
4838
4933
|
abs,
|
|
4839
4934
|
fn.line,
|
|
4840
4935
|
opts.editorCmd
|
|
4841
|
-
)}\x07${
|
|
4936
|
+
)}\x07${path8.basename(abs)}:${fn.line}\x1B]8;;\x07`
|
|
4842
4937
|
);
|
|
4843
4938
|
}
|
|
4844
4939
|
}
|
|
@@ -4853,7 +4948,7 @@ var printCompactCoverage = async (opts) => {
|
|
|
4853
4948
|
abs,
|
|
4854
4949
|
br.line,
|
|
4855
4950
|
opts.editorCmd
|
|
4856
|
-
)}\x07${
|
|
4951
|
+
)}\x07${path8.basename(abs)}:${br.line}\x1B]8;;\x07`
|
|
4857
4952
|
);
|
|
4858
4953
|
}
|
|
4859
4954
|
}
|
|
@@ -4862,9 +4957,7 @@ var printCompactCoverage = async (opts) => {
|
|
|
4862
4957
|
const restBrs = Math.max(0, misses.length - branchesList.length);
|
|
4863
4958
|
if (restHs + restFns + restBrs > 0) {
|
|
4864
4959
|
console.info(
|
|
4865
|
-
ansi.dim(
|
|
4866
|
-
` \u2026 truncated: +${restHs} hotspots, +${restFns} funcs, +${restBrs} branches`
|
|
4867
|
-
)
|
|
4960
|
+
ansi.dim(` \u2026 truncated: +${restHs} hotspots, +${restFns} funcs, +${restBrs} branches`)
|
|
4868
4961
|
);
|
|
4869
4962
|
}
|
|
4870
4963
|
console.info("");
|
|
@@ -4901,7 +4994,7 @@ var shortenPathPreservingFilename = (relPath, maxWidth, opts) => {
|
|
|
4901
4994
|
return { stem: base.slice(0, -ending.length), ext: ending };
|
|
4902
4995
|
}
|
|
4903
4996
|
}
|
|
4904
|
-
const ext2 =
|
|
4997
|
+
const ext2 = path8.extname(base);
|
|
4905
4998
|
return { stem: base.slice(0, -ext2.length), ext: ext2 };
|
|
4906
4999
|
};
|
|
4907
5000
|
const sliceBalanced = (input, width) => {
|
|
@@ -4984,12 +5077,7 @@ var shortenPathPreservingFilename = (relPath, maxWidth, opts) => {
|
|
|
4984
5077
|
const tailParts = tailSrc.map((segment) => segment);
|
|
4985
5078
|
let hidAny = false;
|
|
4986
5079
|
const build = () => {
|
|
4987
|
-
const label2 = joinParts(
|
|
4988
|
-
headParts,
|
|
4989
|
-
tailParts,
|
|
4990
|
-
hideMiddle2 || hidAny,
|
|
4991
|
-
baseLabel
|
|
4992
|
-
);
|
|
5080
|
+
const label2 = joinParts(headParts, tailParts, hideMiddle2 || hidAny, baseLabel);
|
|
4993
5081
|
return { label: label2, width: visibleWidth(label2) };
|
|
4994
5082
|
};
|
|
4995
5083
|
let { label, width } = build();
|
|
@@ -5082,13 +5170,7 @@ var shortenPathPreservingFilename = (relPath, maxWidth, opts) => {
|
|
|
5082
5170
|
return { headRaw: headRaw2, tailRaw: tailRaw2, hideMiddle: hideMiddle2 };
|
|
5083
5171
|
};
|
|
5084
5172
|
let { headRaw, tailRaw, hideMiddle } = buildRaw(headCount, tailCount);
|
|
5085
|
-
let candidate = tryTrimDirsToFit(
|
|
5086
|
-
headRaw,
|
|
5087
|
-
tailRaw,
|
|
5088
|
-
hideMiddle,
|
|
5089
|
-
baseFull,
|
|
5090
|
-
maxWidth
|
|
5091
|
-
);
|
|
5173
|
+
let candidate = tryTrimDirsToFit(headRaw, tailRaw, hideMiddle, baseFull, maxWidth);
|
|
5092
5174
|
if (!candidate) {
|
|
5093
5175
|
return baseFull;
|
|
5094
5176
|
}
|
|
@@ -5097,13 +5179,7 @@ var shortenPathPreservingFilename = (relPath, maxWidth, opts) => {
|
|
|
5097
5179
|
if (headCount + tailCount < total) {
|
|
5098
5180
|
const tryTail = Math.min(tailCount + 1, total - headCount);
|
|
5099
5181
|
({ headRaw, tailRaw, hideMiddle } = buildRaw(headCount, tryTail));
|
|
5100
|
-
const candTail = tryTrimDirsToFit(
|
|
5101
|
-
headRaw,
|
|
5102
|
-
tailRaw,
|
|
5103
|
-
hideMiddle,
|
|
5104
|
-
baseFull,
|
|
5105
|
-
maxWidth
|
|
5106
|
-
);
|
|
5182
|
+
const candTail = tryTrimDirsToFit(headRaw, tailRaw, hideMiddle, baseFull, maxWidth);
|
|
5107
5183
|
if (candTail) {
|
|
5108
5184
|
tailCount = tryTail;
|
|
5109
5185
|
candidate = candTail;
|
|
@@ -5113,13 +5189,7 @@ var shortenPathPreservingFilename = (relPath, maxWidth, opts) => {
|
|
|
5113
5189
|
if (!advanced && headCount + tailCount < total) {
|
|
5114
5190
|
const tryHead = Math.min(headCount + 1, total - tailCount);
|
|
5115
5191
|
({ headRaw, tailRaw, hideMiddle } = buildRaw(tryHead, tailCount));
|
|
5116
|
-
const candHead = tryTrimDirsToFit(
|
|
5117
|
-
headRaw,
|
|
5118
|
-
tailRaw,
|
|
5119
|
-
hideMiddle,
|
|
5120
|
-
baseFull,
|
|
5121
|
-
maxWidth
|
|
5122
|
-
);
|
|
5192
|
+
const candHead = tryTrimDirsToFit(headRaw, tailRaw, hideMiddle, baseFull, maxWidth);
|
|
5123
5193
|
if (candHead) {
|
|
5124
5194
|
headCount = tryHead;
|
|
5125
5195
|
candidate = candHead;
|
|
@@ -5181,7 +5251,7 @@ var buildDistanceMapFromTests = async (executedTestsAbs, rootDir) => {
|
|
|
5181
5251
|
const queue = [];
|
|
5182
5252
|
const seen = /* @__PURE__ */ new Set();
|
|
5183
5253
|
for (const testAbs of executedTestsAbs) {
|
|
5184
|
-
const testPathNormalized =
|
|
5254
|
+
const testPathNormalized = path8.resolve(testAbs).replace(/\\/g, "/");
|
|
5185
5255
|
dist.set(testPathNormalized, 0);
|
|
5186
5256
|
queue.push([testPathNormalized, 0]);
|
|
5187
5257
|
}
|
|
@@ -5200,12 +5270,7 @@ var buildDistanceMapFromTests = async (executedTestsAbs, rootDir) => {
|
|
|
5200
5270
|
const specs = await extractImportSpecs2(currentFile, specsCache);
|
|
5201
5271
|
const nextDistance = currentDistance + 1;
|
|
5202
5272
|
for (const spec of specs) {
|
|
5203
|
-
const resolved = resolveImportWithRoot(
|
|
5204
|
-
currentFile,
|
|
5205
|
-
spec,
|
|
5206
|
-
rootDir,
|
|
5207
|
-
resolutionCache
|
|
5208
|
-
);
|
|
5273
|
+
const resolved = resolveImportWithRoot(currentFile, spec, rootDir, resolutionCache);
|
|
5209
5274
|
const usable = resolved && !resolved.includes("/node_modules/");
|
|
5210
5275
|
if (usable) {
|
|
5211
5276
|
const existing = dist.get(resolved);
|
|
@@ -5220,13 +5285,10 @@ var buildDistanceMapFromTests = async (executedTestsAbs, rootDir) => {
|
|
|
5220
5285
|
return dist;
|
|
5221
5286
|
};
|
|
5222
5287
|
var renderPerFileCompositeTable = async (opts) => {
|
|
5223
|
-
const rel =
|
|
5288
|
+
const rel = path8.relative(opts.root, opts.absPath).replace(/\\/g, "/");
|
|
5224
5289
|
const sum = opts.file.toSummary();
|
|
5225
5290
|
const rowsAvail = typeof process.stdout.rows === "number" && process.stdout.rows > 10 ? process.stdout.rows : 40;
|
|
5226
|
-
const tableBudget = Math.max(
|
|
5227
|
-
14,
|
|
5228
|
-
Math.min(opts.maxRows ?? rowsAvail - 1, rowsAvail + 8)
|
|
5229
|
-
);
|
|
5291
|
+
const tableBudget = Math.max(14, Math.min(opts.maxRows ?? rowsAvail - 1, rowsAvail + 8));
|
|
5230
5292
|
const rowBudget = Math.max(6, tableBudget - 6);
|
|
5231
5293
|
const blocks = computeUncoveredBlocks(opts.file).slice().sort((firstRange, secondRange) => {
|
|
5232
5294
|
const firstLength = firstRange.end - firstRange.start;
|
|
@@ -5270,9 +5332,7 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5270
5332
|
rows.push([
|
|
5271
5333
|
cell(
|
|
5272
5334
|
rel,
|
|
5273
|
-
(padded) => ansi.dim(
|
|
5274
|
-
shortenPathPreservingFilename(rel, padded.length).padEnd(padded.length)
|
|
5275
|
-
)
|
|
5335
|
+
(padded) => ansi.dim(shortenPathPreservingFilename(rel, padded.length).padEnd(padded.length))
|
|
5276
5336
|
),
|
|
5277
5337
|
cell("Totals", ansi.dim),
|
|
5278
5338
|
cell("\u2014", ansi.dim),
|
|
@@ -5291,11 +5351,7 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5291
5351
|
rows.push([
|
|
5292
5352
|
cell(
|
|
5293
5353
|
rel,
|
|
5294
|
-
(padded) => ansi.dim(
|
|
5295
|
-
shortenPathPreservingFilename(rel, padded.length).padEnd(
|
|
5296
|
-
padded.length
|
|
5297
|
-
)
|
|
5298
|
-
)
|
|
5354
|
+
(padded) => ansi.dim(shortenPathPreservingFilename(rel, padded.length).padEnd(padded.length))
|
|
5299
5355
|
),
|
|
5300
5356
|
cell("Hotspots", ansi.dim),
|
|
5301
5357
|
cell("", ansi.dim),
|
|
@@ -5309,14 +5365,8 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5309
5365
|
rows.push([
|
|
5310
5366
|
cell(rel, (padded) => {
|
|
5311
5367
|
const width = padded.length;
|
|
5312
|
-
const display = shortenPathPreservingFilename(rel, width).padEnd(
|
|
5313
|
-
|
|
5314
|
-
);
|
|
5315
|
-
return linkifyPadded(
|
|
5316
|
-
opts.absPath,
|
|
5317
|
-
hotspotRange.start,
|
|
5318
|
-
opts.editorCmd
|
|
5319
|
-
)(display);
|
|
5368
|
+
const display = shortenPathPreservingFilename(rel, width).padEnd(width);
|
|
5369
|
+
return linkifyPadded(opts.absPath, hotspotRange.start, opts.editorCmd)(display);
|
|
5320
5370
|
}),
|
|
5321
5371
|
cell("Hotspot"),
|
|
5322
5372
|
cell(`L${hotspotRange.start}\u2013L${hotspotRange.end}`),
|
|
@@ -5333,11 +5383,7 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5333
5383
|
rows.push([
|
|
5334
5384
|
cell(
|
|
5335
5385
|
rel,
|
|
5336
|
-
(padded) => ansi.dim(
|
|
5337
|
-
shortenPathPreservingFilename(rel, padded.length).padEnd(
|
|
5338
|
-
padded.length
|
|
5339
|
-
)
|
|
5340
|
-
)
|
|
5386
|
+
(padded) => ansi.dim(shortenPathPreservingFilename(rel, padded.length).padEnd(padded.length))
|
|
5341
5387
|
),
|
|
5342
5388
|
cell("Functions", ansi.dim),
|
|
5343
5389
|
cell("", ansi.dim),
|
|
@@ -5351,14 +5397,8 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5351
5397
|
rows.push([
|
|
5352
5398
|
cell(rel, (padded) => {
|
|
5353
5399
|
const width = padded.length;
|
|
5354
|
-
const display = shortenPathPreservingFilename(rel, width).padEnd(
|
|
5355
|
-
|
|
5356
|
-
);
|
|
5357
|
-
return linkifyPadded(
|
|
5358
|
-
opts.absPath,
|
|
5359
|
-
missedFunction.line,
|
|
5360
|
-
opts.editorCmd
|
|
5361
|
-
)(display);
|
|
5400
|
+
const display = shortenPathPreservingFilename(rel, width).padEnd(width);
|
|
5401
|
+
return linkifyPadded(opts.absPath, missedFunction.line, opts.editorCmd)(display);
|
|
5362
5402
|
}),
|
|
5363
5403
|
cell("Func"),
|
|
5364
5404
|
cell(`L${missedFunction.line}`),
|
|
@@ -5375,11 +5415,7 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5375
5415
|
rows.push([
|
|
5376
5416
|
cell(
|
|
5377
5417
|
rel,
|
|
5378
|
-
(padded) => ansi.dim(
|
|
5379
|
-
shortenPathPreservingFilename(rel, padded.length).padEnd(
|
|
5380
|
-
padded.length
|
|
5381
|
-
)
|
|
5382
|
-
)
|
|
5418
|
+
(padded) => ansi.dim(shortenPathPreservingFilename(rel, padded.length).padEnd(padded.length))
|
|
5383
5419
|
),
|
|
5384
5420
|
cell("Branches", ansi.dim),
|
|
5385
5421
|
cell("", ansi.dim),
|
|
@@ -5393,14 +5429,8 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5393
5429
|
rows.push([
|
|
5394
5430
|
cell(rel, (padded) => {
|
|
5395
5431
|
const width = padded.length;
|
|
5396
|
-
const display = shortenPathPreservingFilename(rel, width).padEnd(
|
|
5397
|
-
|
|
5398
|
-
);
|
|
5399
|
-
return linkifyPadded(
|
|
5400
|
-
opts.absPath,
|
|
5401
|
-
missedBranch.line,
|
|
5402
|
-
opts.editorCmd
|
|
5403
|
-
)(display);
|
|
5432
|
+
const display = shortenPathPreservingFilename(rel, width).padEnd(width);
|
|
5433
|
+
return linkifyPadded(opts.absPath, missedBranch.line, opts.editorCmd)(display);
|
|
5404
5434
|
}),
|
|
5405
5435
|
cell("Branch"),
|
|
5406
5436
|
cell(`L${missedBranch.line}`),
|
|
@@ -5408,9 +5438,7 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5408
5438
|
cell(""),
|
|
5409
5439
|
cell(""),
|
|
5410
5440
|
cell(""),
|
|
5411
|
-
cell(
|
|
5412
|
-
`#${missedBranch.id} missed [${missedBranch.zeroPaths.join(", ")}]`
|
|
5413
|
-
)
|
|
5441
|
+
cell(`#${missedBranch.id} missed [${missedBranch.zeroPaths.join(", ")}]`)
|
|
5414
5442
|
]);
|
|
5415
5443
|
}
|
|
5416
5444
|
}
|
|
@@ -5430,9 +5458,7 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5430
5458
|
rows.push([
|
|
5431
5459
|
cell(rel, (padded) => {
|
|
5432
5460
|
const width = padded.length;
|
|
5433
|
-
const display = shortenPathPreservingFilename(rel, width).padEnd(
|
|
5434
|
-
width
|
|
5435
|
-
);
|
|
5461
|
+
const display = shortenPathPreservingFilename(rel, width).padEnd(width);
|
|
5436
5462
|
return linkifyPadded(opts.absPath, ln, opts.editorCmd)(display);
|
|
5437
5463
|
}),
|
|
5438
5464
|
cell("Line"),
|
|
@@ -5445,16 +5471,7 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5445
5471
|
]);
|
|
5446
5472
|
}
|
|
5447
5473
|
while (rows.length < target) {
|
|
5448
|
-
rows.push([
|
|
5449
|
-
cell(""),
|
|
5450
|
-
cell(""),
|
|
5451
|
-
cell(""),
|
|
5452
|
-
cell(""),
|
|
5453
|
-
cell(""),
|
|
5454
|
-
cell(""),
|
|
5455
|
-
cell(""),
|
|
5456
|
-
cell("")
|
|
5457
|
-
]);
|
|
5474
|
+
rows.push([cell(""), cell(""), cell(""), cell(""), cell(""), cell(""), cell(""), cell("")]);
|
|
5458
5475
|
}
|
|
5459
5476
|
}
|
|
5460
5477
|
}
|
|
@@ -5462,20 +5479,17 @@ var renderPerFileCompositeTable = async (opts) => {
|
|
|
5462
5479
|
console.info(table);
|
|
5463
5480
|
const sep = ansi.gray(
|
|
5464
5481
|
"\u2500".repeat(
|
|
5465
|
-
Math.max(
|
|
5466
|
-
20,
|
|
5467
|
-
typeof process.stdout.columns === "number" ? process.stdout.columns : 100
|
|
5468
|
-
)
|
|
5482
|
+
Math.max(20, typeof process.stdout.columns === "number" ? process.stdout.columns : 100)
|
|
5469
5483
|
)
|
|
5470
5484
|
);
|
|
5471
5485
|
console.info(sep);
|
|
5472
5486
|
};
|
|
5473
5487
|
var printPerFileCompositeTables = async (opts) => {
|
|
5474
5488
|
const selectionAbs = (opts.selectionPaths ?? []).map(
|
|
5475
|
-
(selPath) =>
|
|
5489
|
+
(selPath) => path8.resolve(selPath).replace(/\\/g, "/")
|
|
5476
5490
|
);
|
|
5477
5491
|
const changedAbs = (opts.changedFiles ?? []).map(
|
|
5478
|
-
(chgPath) =>
|
|
5492
|
+
(chgPath) => path8.resolve(chgPath).replace(/\\/g, "/")
|
|
5479
5493
|
);
|
|
5480
5494
|
const tokenizeForSimilarity = (filePathForTokens) => new Set(
|
|
5481
5495
|
filePathForTokens.toLowerCase().replace(/[^a-z0-9/_\-.]/g, " ").split(/[/_.-]+/).filter(Boolean)
|
|
@@ -5491,15 +5505,15 @@ var printPerFileCompositeTables = async (opts) => {
|
|
|
5491
5505
|
return intersectionCount / unionSize;
|
|
5492
5506
|
};
|
|
5493
5507
|
const isSameDirOrChild = (firstAbs, secondAbs) => {
|
|
5494
|
-
const dirA =
|
|
5495
|
-
const dirB =
|
|
5508
|
+
const dirA = path8.dirname(firstAbs).replace(/\\/g, "/");
|
|
5509
|
+
const dirB = path8.dirname(secondAbs).replace(/\\/g, "/");
|
|
5496
5510
|
return dirA === dirB || dirB.startsWith(`${dirA}/`) || dirA.startsWith(`${dirB}/`);
|
|
5497
5511
|
};
|
|
5498
5512
|
const selectionTokens = selectionAbs.map(tokenizeForSimilarity);
|
|
5499
5513
|
const changedTokens = changedAbs.map(tokenizeForSimilarity);
|
|
5500
|
-
const executedTestsAbs = (opts.executedTests ?? []).map((testPath) =>
|
|
5514
|
+
const executedTestsAbs = (opts.executedTests ?? []).map((testPath) => path8.resolve(testPath).replace(/\\/g, "/")).filter((absPath) => absPath.length > 0);
|
|
5501
5515
|
const testTokens = executedTestsAbs.map(tokenizeForSimilarity);
|
|
5502
|
-
const allMapFilesAbs = opts.map.files().map((absPath) =>
|
|
5516
|
+
const allMapFilesAbs = opts.map.files().map((absPath) => path8.resolve(absPath).replace(/\\/g, "/"));
|
|
5503
5517
|
const uncoveredCandidates = allMapFilesAbs.filter((absPath) => {
|
|
5504
5518
|
const sum = opts.map.fileCoverageFor(absPath).toSummary();
|
|
5505
5519
|
return !(sum.lines.pct >= 100 && sum.functions.pct >= 100 && sum.branches.pct >= 100);
|
|
@@ -5516,33 +5530,24 @@ var printPerFileCompositeTables = async (opts) => {
|
|
|
5516
5530
|
const selectionSetAbs = new Set(selectionAbs);
|
|
5517
5531
|
const scored = await Promise.all(
|
|
5518
5532
|
candidates.map(async (abs) => {
|
|
5519
|
-
const rel =
|
|
5533
|
+
const rel = path8.relative(opts.root, abs).replace(/\\/g, "/");
|
|
5520
5534
|
const sum = opts.map.fileCoverageFor(abs).toSummary();
|
|
5521
5535
|
const pct = Number.isFinite(sum.lines.pct) ? sum.lines.pct : 0;
|
|
5522
|
-
const absNorm =
|
|
5536
|
+
const absNorm = path8.resolve(abs).replace(/\\/g, "/");
|
|
5523
5537
|
const selfTokens = tokenizeForSimilarity(absNorm);
|
|
5524
5538
|
const selSim = Math.max(
|
|
5525
5539
|
0,
|
|
5526
|
-
...selectionTokens.map(
|
|
5527
|
-
(selectionTokenSet) => jaccard(selfTokens, selectionTokenSet)
|
|
5528
|
-
)
|
|
5540
|
+
...selectionTokens.map((selectionTokenSet) => jaccard(selfTokens, selectionTokenSet))
|
|
5529
5541
|
);
|
|
5530
5542
|
const chgSim = Math.max(
|
|
5531
5543
|
0,
|
|
5532
|
-
...changedTokens.map(
|
|
5533
|
-
(changedTokenSet) => jaccard(selfTokens, changedTokenSet)
|
|
5534
|
-
)
|
|
5535
|
-
);
|
|
5536
|
-
const tstSim = Math.max(
|
|
5537
|
-
0,
|
|
5538
|
-
...testTokens.map((tset) => jaccard(selfTokens, tset))
|
|
5544
|
+
...changedTokens.map((changedTokenSet) => jaccard(selfTokens, changedTokenSet))
|
|
5539
5545
|
);
|
|
5546
|
+
const tstSim = Math.max(0, ...testTokens.map((tset) => jaccard(selfTokens, tset)));
|
|
5540
5547
|
const nearSelection = selectionAbs.some(
|
|
5541
5548
|
(selectionPath) => isSameDirOrChild(absNorm, selectionPath)
|
|
5542
5549
|
);
|
|
5543
|
-
const nearChanged = changedAbs.some(
|
|
5544
|
-
(changedPath) => isSameDirOrChild(absNorm, changedPath)
|
|
5545
|
-
);
|
|
5550
|
+
const nearChanged = changedAbs.some((changedPath) => isSameDirOrChild(absNorm, changedPath));
|
|
5546
5551
|
const related = selSim > 0 || chgSim > 0 || nearSelection || nearChanged;
|
|
5547
5552
|
const distance = selectionSetAbs.has(absNorm) ? 0 : distFromTests.get(absNorm) ?? INF;
|
|
5548
5553
|
let group = 6;
|
|
@@ -5566,9 +5571,12 @@ var printPerFileCompositeTables = async (opts) => {
|
|
|
5566
5571
|
return { abs: absNorm, rel, linesPct: pct, group, score, distance };
|
|
5567
5572
|
})
|
|
5568
5573
|
);
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5574
|
+
const prodSeeds = selectionAbs.length > 0 ? selectionAbs : changedAbs;
|
|
5575
|
+
const rank = await computeDirectnessRank({ repoRoot: opts.root, productionSeeds: prodSeeds });
|
|
5576
|
+
let files = sortPathsWithRank(
|
|
5577
|
+
rank,
|
|
5578
|
+
scored.map((s) => s.abs)
|
|
5579
|
+
);
|
|
5572
5580
|
if (selectionAbs.length > 0) {
|
|
5573
5581
|
const selectionSet = new Set(selectionAbs);
|
|
5574
5582
|
const selectedHead = files.filter((filePath) => selectionSet.has(filePath));
|
|
@@ -5592,7 +5600,7 @@ var printPerFileCompositeTables = async (opts) => {
|
|
|
5592
5600
|
|
|
5593
5601
|
// src/lib/jest-bridge.ts
|
|
5594
5602
|
var import_json5 = __toESM(require_lib(), 1);
|
|
5595
|
-
import * as
|
|
5603
|
+
import * as path9 from "node:path";
|
|
5596
5604
|
import * as fs4 from "node:fs";
|
|
5597
5605
|
import * as util from "node:util";
|
|
5598
5606
|
var extractBridgePath = (raw, cwd) => {
|
|
@@ -5603,7 +5611,7 @@ var extractBridgePath = (raw, cwd) => {
|
|
|
5603
5611
|
return null;
|
|
5604
5612
|
}
|
|
5605
5613
|
const jsonPath = matches[matches.length - 1][1].trim().replace(/^["'`]|["'`]$/g, "");
|
|
5606
|
-
return
|
|
5614
|
+
return path9.isAbsolute(jsonPath) ? jsonPath : path9.resolve(cwd, jsonPath);
|
|
5607
5615
|
};
|
|
5608
5616
|
var drawRule = (label) => {
|
|
5609
5617
|
const width = Math.max(
|
|
@@ -6251,7 +6259,7 @@ var buildStackSection = (mergedForStack, ctx, fallbackLoc) => {
|
|
|
6251
6259
|
const loc = deepestProjectLoc(mergedForStack, ctx.projectHint);
|
|
6252
6260
|
if (loc) {
|
|
6253
6261
|
const href = preferredEditorHref(loc.file, loc.line, ctx.editorCmd);
|
|
6254
|
-
out.push(` ${ansi.dim("at")} ${osc8(`${
|
|
6262
|
+
out.push(` ${ansi.dim("at")} ${osc8(`${path9.basename(loc.file)}:${loc.line}`, href)}`);
|
|
6255
6263
|
}
|
|
6256
6264
|
out.push("");
|
|
6257
6265
|
return out;
|
|
@@ -6291,6 +6299,7 @@ var formatJestOutputVitest = (raw, opts) => {
|
|
|
6291
6299
|
const projectHint = new RegExp(
|
|
6292
6300
|
`(${cwd.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")})|(/gigworx-node/)`
|
|
6293
6301
|
);
|
|
6302
|
+
const onlyFailures = Boolean(opts?.onlyFailures);
|
|
6294
6303
|
const lines = raw.split(/\r?\n/);
|
|
6295
6304
|
const out = [];
|
|
6296
6305
|
const seenFailures = /* @__PURE__ */ new Set();
|
|
@@ -6378,8 +6387,10 @@ var formatJestOutputVitest = (raw, opts) => {
|
|
|
6378
6387
|
continue;
|
|
6379
6388
|
}
|
|
6380
6389
|
seenFiles.add(rel);
|
|
6381
|
-
|
|
6382
|
-
|
|
6390
|
+
if (!(onlyFailures && badge === "PASS")) {
|
|
6391
|
+
const pill = badge === "PASS" ? colorTokens.passPill("PASS") : colorTokens.failPill("FAIL");
|
|
6392
|
+
out.push(`${pill} ${ansi.white(rel)}`);
|
|
6393
|
+
}
|
|
6383
6394
|
lineIndex += 1;
|
|
6384
6395
|
continue;
|
|
6385
6396
|
}
|
|
@@ -6492,14 +6503,21 @@ function renderVitestFromJestJSON(data, opts) {
|
|
|
6492
6503
|
`(${cwd.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")})|(/gigworx-node/)`
|
|
6493
6504
|
);
|
|
6494
6505
|
const ctx = { projectHint, editorCmd: opts?.editorCmd, showStacks: true };
|
|
6506
|
+
const onlyFailures = Boolean(opts?.onlyFailures);
|
|
6495
6507
|
const out = [];
|
|
6496
|
-
|
|
6497
|
-
|
|
6508
|
+
if (!onlyFailures) {
|
|
6509
|
+
out.push(renderRunLine(cwd));
|
|
6510
|
+
out.push("");
|
|
6511
|
+
}
|
|
6498
6512
|
for (const file of data.testResults) {
|
|
6499
6513
|
const rel = file.testFilePath.replace(/\\/g, "/").replace(`${cwd}/`, "");
|
|
6500
6514
|
const failed = file.testResults.filter((assertion) => assertion.status === "failed");
|
|
6501
|
-
|
|
6502
|
-
|
|
6515
|
+
if (!onlyFailures) {
|
|
6516
|
+
out.push(...buildPerFileOverview(rel, file.testResults));
|
|
6517
|
+
}
|
|
6518
|
+
if (!(onlyFailures && failed.length === 0)) {
|
|
6519
|
+
out.push(buildFileBadgeLine(rel, failed.length));
|
|
6520
|
+
}
|
|
6503
6521
|
if (file.failureMessage && failed.length === 0) {
|
|
6504
6522
|
const lines = file.failureMessage.split(/\r?\n/);
|
|
6505
6523
|
const details = linesFromDetails(file.failureDetails);
|
|
@@ -6530,7 +6548,7 @@ function renderVitestFromJestJSON(data, opts) {
|
|
|
6530
6548
|
const deepestLoc = deepestProjectLoc(mergedForStack, projectHint);
|
|
6531
6549
|
const locLink = deepestLoc && (() => {
|
|
6532
6550
|
const href = preferredEditorHref(deepestLoc.file, deepestLoc.line, opts?.editorCmd);
|
|
6533
|
-
const base = `${
|
|
6551
|
+
const base = `${path9.basename(deepestLoc.file)}:${deepestLoc.line}`;
|
|
6534
6552
|
return osc8(base, href);
|
|
6535
6553
|
})();
|
|
6536
6554
|
const headerLine = `${ansi.white(header)}${locLink ? ` ${ansi.dim(`(${locLink})`)}` : ""}`;
|
|
@@ -6578,7 +6596,7 @@ ${footer}`;
|
|
|
6578
6596
|
init_env_utils();
|
|
6579
6597
|
init_exec();
|
|
6580
6598
|
init_args();
|
|
6581
|
-
import * as
|
|
6599
|
+
import * as path10 from "node:path";
|
|
6582
6600
|
import * as os2 from "node:os";
|
|
6583
6601
|
import * as fsSync3 from "node:fs";
|
|
6584
6602
|
import * as fs5 from "node:fs/promises";
|
|
@@ -6587,10 +6605,6 @@ import * as Reports from "istanbul-reports";
|
|
|
6587
6605
|
import { createCoverageMap as createCoverageMap2 } from "istanbul-lib-coverage";
|
|
6588
6606
|
var jestBin = "./node_modules/.bin/jest";
|
|
6589
6607
|
var babelNodeBin = "./node_modules/.bin/babel-node";
|
|
6590
|
-
var moduleSpecifierForRequire = (
|
|
6591
|
-
// @ts-ignore
|
|
6592
|
-
typeof __filename !== "undefined" ? __filename : import.meta.url
|
|
6593
|
-
);
|
|
6594
6608
|
var registerSignalHandlersOnce = () => {
|
|
6595
6609
|
let handled = false;
|
|
6596
6610
|
const on = (sig) => {
|
|
@@ -6608,7 +6622,6 @@ Received ${sig}, exiting...
|
|
|
6608
6622
|
};
|
|
6609
6623
|
var isDebug = () => Boolean(process.env.TEST_CLI_DEBUG);
|
|
6610
6624
|
var mergeLcov = async () => {
|
|
6611
|
-
const jestLcovPath = "coverage/jest/lcov.info";
|
|
6612
6625
|
const vitestLcovPath = "coverage/vitest/lcov.info";
|
|
6613
6626
|
const mergedOutPath = "coverage/lcov.info";
|
|
6614
6627
|
const readOrEmpty = async (filePath) => {
|
|
@@ -6619,7 +6632,7 @@ var mergeLcov = async () => {
|
|
|
6619
6632
|
}
|
|
6620
6633
|
};
|
|
6621
6634
|
let vitestContent = "";
|
|
6622
|
-
|
|
6635
|
+
const jestParts = [];
|
|
6623
6636
|
try {
|
|
6624
6637
|
vitestContent = await readOrEmpty(vitestLcovPath);
|
|
6625
6638
|
} catch (readVitestError) {
|
|
@@ -6627,20 +6640,46 @@ var mergeLcov = async () => {
|
|
|
6627
6640
|
console.info(`read vitest lcov failed: ${String(readVitestError)}`);
|
|
6628
6641
|
}
|
|
6629
6642
|
}
|
|
6643
|
+
const collectLcovs = (dir) => {
|
|
6644
|
+
const out = [];
|
|
6645
|
+
try {
|
|
6646
|
+
const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
|
|
6647
|
+
for (const entry of entries) {
|
|
6648
|
+
const full = path10.join(dir, entry.name);
|
|
6649
|
+
if (entry.isDirectory()) {
|
|
6650
|
+
out.push(...collectLcovs(full));
|
|
6651
|
+
} else if (entry.isFile() && entry.name === "lcov.info") {
|
|
6652
|
+
out.push(full);
|
|
6653
|
+
}
|
|
6654
|
+
}
|
|
6655
|
+
} catch {
|
|
6656
|
+
}
|
|
6657
|
+
return out;
|
|
6658
|
+
};
|
|
6630
6659
|
try {
|
|
6631
|
-
|
|
6660
|
+
const jestRoot = path10.join("coverage", "jest");
|
|
6661
|
+
const candidates = [path10.join(jestRoot, "lcov.info"), ...collectLcovs(jestRoot)].map((candidatePath) => path10.resolve(candidatePath)).filter((absolutePath, index, arr) => arr.indexOf(absolutePath) === index);
|
|
6662
|
+
for (const filePath of candidates) {
|
|
6663
|
+
try {
|
|
6664
|
+
const content = await readOrEmpty(filePath);
|
|
6665
|
+
if (content.trim()) {
|
|
6666
|
+
jestParts.push(content.trim());
|
|
6667
|
+
}
|
|
6668
|
+
} catch {
|
|
6669
|
+
}
|
|
6670
|
+
}
|
|
6632
6671
|
} catch (readJestError) {
|
|
6633
6672
|
if (isDebug()) {
|
|
6634
|
-
console.info(`
|
|
6673
|
+
console.info(`scan jest lcov failed: ${String(readJestError)}`);
|
|
6635
6674
|
}
|
|
6636
6675
|
}
|
|
6637
|
-
if (!vitestContent &&
|
|
6676
|
+
if (!vitestContent && jestParts.length === 0) {
|
|
6638
6677
|
if (isDebug()) {
|
|
6639
6678
|
console.info("No coverage outputs found to merge.");
|
|
6640
6679
|
}
|
|
6641
6680
|
return;
|
|
6642
6681
|
}
|
|
6643
|
-
const merged = [vitestContent.trim(),
|
|
6682
|
+
const merged = [vitestContent.trim(), ...jestParts].filter(Boolean).join("\n");
|
|
6644
6683
|
if (merged.length > 0) {
|
|
6645
6684
|
await (await import("node:fs/promises")).mkdir("coverage", { recursive: true });
|
|
6646
6685
|
await (await import("node:fs/promises")).writeFile(mergedOutPath, `${merged}
|
|
@@ -6653,23 +6692,40 @@ var mergeLcov = async () => {
|
|
|
6653
6692
|
}
|
|
6654
6693
|
};
|
|
6655
6694
|
var emitMergedCoverage = async (ui, opts) => {
|
|
6656
|
-
const jestJson = path9.join("coverage", "jest", "coverage-final.json");
|
|
6657
|
-
const jSize = fsSync3.existsSync(jestJson) ? fsSync3.statSync(jestJson).size : -1;
|
|
6658
|
-
const jestSizeLabel = jSize >= 0 ? `${jSize} bytes` : "missing";
|
|
6659
|
-
if (isDebug()) {
|
|
6660
|
-
console.info(`Coverage JSON probe \u2192 jest: ${jestSizeLabel}`);
|
|
6661
|
-
}
|
|
6662
|
-
const jestData = await readCoverageJson(jestJson);
|
|
6663
|
-
const jestFilesCount = Object.keys(jestData).length;
|
|
6664
|
-
if (isDebug()) {
|
|
6665
|
-
console.info(`Decoded coverage entries \u2192 jest: ${jestFilesCount}`);
|
|
6666
|
-
}
|
|
6667
6695
|
const map = createCoverageMap2({});
|
|
6668
|
-
|
|
6696
|
+
const listJsons = (dir) => {
|
|
6697
|
+
const out = [];
|
|
6669
6698
|
try {
|
|
6670
|
-
|
|
6699
|
+
const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
|
|
6700
|
+
for (const entry of entries) {
|
|
6701
|
+
const full = path10.join(dir, entry.name);
|
|
6702
|
+
if (entry.isDirectory()) {
|
|
6703
|
+
out.push(...listJsons(full));
|
|
6704
|
+
} else if (entry.isFile() && entry.name === "coverage-final.json") {
|
|
6705
|
+
out.push(full);
|
|
6706
|
+
}
|
|
6707
|
+
}
|
|
6708
|
+
} catch {
|
|
6709
|
+
}
|
|
6710
|
+
return out;
|
|
6711
|
+
};
|
|
6712
|
+
const coverageRoot = path10.join("coverage", "jest");
|
|
6713
|
+
const jsonCandidates = [
|
|
6714
|
+
path10.join(coverageRoot, "coverage-final.json"),
|
|
6715
|
+
...listJsons(coverageRoot)
|
|
6716
|
+
].map((candidatePath) => path10.resolve(candidatePath)).filter((absolutePath, index, arr) => {
|
|
6717
|
+
const isFirst = arr.indexOf(absolutePath) === index;
|
|
6718
|
+
const exists = fsSync3.existsSync(absolutePath);
|
|
6719
|
+
return isFirst && exists;
|
|
6720
|
+
});
|
|
6721
|
+
for (const jsonPath of jsonCandidates) {
|
|
6722
|
+
try {
|
|
6723
|
+
const data = await readCoverageJson(jsonPath);
|
|
6724
|
+
if (Object.keys(data).length) {
|
|
6725
|
+
map.merge(data);
|
|
6726
|
+
}
|
|
6671
6727
|
} catch (mergeJestError) {
|
|
6672
|
-
console.warn(`Failed merging jest coverage JSON: ${String(mergeJestError)}`);
|
|
6728
|
+
console.warn(`Failed merging jest coverage JSON @ ${jsonPath}: ${String(mergeJestError)}`);
|
|
6673
6729
|
}
|
|
6674
6730
|
}
|
|
6675
6731
|
if (map.files().length === 0) {
|
|
@@ -6719,7 +6775,7 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
6719
6775
|
executedTests: opts.executedTests ?? []
|
|
6720
6776
|
});
|
|
6721
6777
|
const context = LibReport.createContext({
|
|
6722
|
-
dir:
|
|
6778
|
+
dir: path10.resolve("coverage", "merged"),
|
|
6723
6779
|
coverageMap: filteredMap,
|
|
6724
6780
|
defaultSummarizer: "nested"
|
|
6725
6781
|
});
|
|
@@ -6787,8 +6843,8 @@ var emitMergedCoverage = async (ui, opts) => {
|
|
|
6787
6843
|
for (const reporter of reporters) {
|
|
6788
6844
|
reporter.execute(context);
|
|
6789
6845
|
}
|
|
6790
|
-
const textPath =
|
|
6791
|
-
const summaryPath =
|
|
6846
|
+
const textPath = path10.resolve("coverage", "merged", "coverage.txt");
|
|
6847
|
+
const summaryPath = path10.resolve("coverage", "merged", "coverage-summary.txt");
|
|
6792
6848
|
const filesToPrint = [];
|
|
6793
6849
|
if (fsSync3.existsSync(textPath)) {
|
|
6794
6850
|
filesToPrint.push(textPath);
|
|
@@ -6859,6 +6915,7 @@ var program = async () => {
|
|
|
6859
6915
|
collectCoverage,
|
|
6860
6916
|
coverageUi,
|
|
6861
6917
|
coverageAbortOnFailure,
|
|
6918
|
+
onlyFailures,
|
|
6862
6919
|
selectionSpecified,
|
|
6863
6920
|
selectionPaths,
|
|
6864
6921
|
includeGlobs,
|
|
@@ -6870,17 +6927,43 @@ var program = async () => {
|
|
|
6870
6927
|
coverageMode,
|
|
6871
6928
|
coverageMaxFiles: coverageMaxFilesArg,
|
|
6872
6929
|
coverageMaxHotspots: coverageMaxHotspotsArg,
|
|
6873
|
-
coveragePageFit
|
|
6930
|
+
coveragePageFit,
|
|
6931
|
+
changed
|
|
6874
6932
|
} = deriveArgs(argv);
|
|
6875
|
-
|
|
6933
|
+
const getChangedFiles = async (mode, cwd) => {
|
|
6934
|
+
const collect = async (cmd, args) => {
|
|
6935
|
+
try {
|
|
6936
|
+
const out = await runText(cmd, args, {
|
|
6937
|
+
cwd,
|
|
6938
|
+
env: safeEnv(process.env, {}),
|
|
6939
|
+
timeoutMs: 4e3
|
|
6940
|
+
});
|
|
6941
|
+
return out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
6942
|
+
} catch {
|
|
6943
|
+
return [];
|
|
6944
|
+
}
|
|
6945
|
+
};
|
|
6946
|
+
const staged = mode === "staged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB", "--cached"]) : [];
|
|
6947
|
+
const unstagedTracked = mode === "unstaged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB"]) : [];
|
|
6948
|
+
const untracked = mode === "unstaged" || mode === "all" ? await collect("git", ["ls-files", "--others", "--exclude-standard"]) : [];
|
|
6949
|
+
const rels = Array.from(/* @__PURE__ */ new Set([...staged, ...unstagedTracked, ...untracked]));
|
|
6950
|
+
return rels.map((rel) => path10.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
|
|
6951
|
+
};
|
|
6952
|
+
const repoRootForChanged = workspaceRoot ?? await findRepoRoot();
|
|
6953
|
+
const changedSelectionAbs = changed ? await getChangedFiles(changed, repoRootForChanged) : [];
|
|
6954
|
+
const selectionPathsAugmented = changedSelectionAbs.length ? Array.from(/* @__PURE__ */ new Set([...selectionPaths, ...changedSelectionAbs])) : selectionPaths;
|
|
6955
|
+
const selectionSpecifiedAugmented = Boolean(selectionSpecified || changedSelectionAbs.length > 0);
|
|
6956
|
+
console.info(
|
|
6957
|
+
`Selection \u2192 specified=${selectionSpecifiedAugmented} paths=${selectionPathsAugmented.length}`
|
|
6958
|
+
);
|
|
6876
6959
|
const { jest } = argsForDiscovery(["run"], jestArgs);
|
|
6877
|
-
const selectionLooksLikeTest =
|
|
6960
|
+
const selectionLooksLikeTest = selectionPathsAugmented.some(
|
|
6878
6961
|
(pathText) => /\.(test|spec)\.[tj]sx?$/i.test(pathText) || /(^|\/)tests?\//i.test(pathText)
|
|
6879
6962
|
);
|
|
6880
|
-
const selectionLooksLikePath =
|
|
6963
|
+
const selectionLooksLikePath = selectionPathsAugmented.some(
|
|
6881
6964
|
(pathText) => /[\\/]/.test(pathText) || /\.(m?[tj]sx?)$/i.test(pathText)
|
|
6882
6965
|
);
|
|
6883
|
-
const selectionHasPaths =
|
|
6966
|
+
const selectionHasPaths = selectionPathsAugmented.length > 0;
|
|
6884
6967
|
const repoRootForDiscovery = workspaceRoot ?? await findRepoRoot();
|
|
6885
6968
|
const expandProductionSelections = async (tokens, repoRoot) => {
|
|
6886
6969
|
const results = /* @__PURE__ */ new Set();
|
|
@@ -6889,18 +6972,18 @@ var program = async () => {
|
|
|
6889
6972
|
if (!token) {
|
|
6890
6973
|
continue;
|
|
6891
6974
|
}
|
|
6892
|
-
const isAbs =
|
|
6975
|
+
const isAbs = path10.isAbsolute(token);
|
|
6893
6976
|
const looksLikeRelPath = /[\\/]/.test(token);
|
|
6894
6977
|
let candidateFromRoot;
|
|
6895
6978
|
if (token.startsWith("/")) {
|
|
6896
|
-
candidateFromRoot =
|
|
6979
|
+
candidateFromRoot = path10.join(repoRoot, token.slice(1));
|
|
6897
6980
|
} else if (looksLikeRelPath) {
|
|
6898
|
-
candidateFromRoot =
|
|
6981
|
+
candidateFromRoot = path10.join(repoRoot, token);
|
|
6899
6982
|
} else {
|
|
6900
6983
|
candidateFromRoot = void 0;
|
|
6901
6984
|
}
|
|
6902
6985
|
const tryPushIfProd = (absPath) => {
|
|
6903
|
-
const norm =
|
|
6986
|
+
const norm = path10.resolve(absPath).replace(/\\/g, "/");
|
|
6904
6987
|
const isTest = /(^|\/)tests?\//i.test(norm) || /\.(test|spec)\.[tj]sx?$/i.test(norm);
|
|
6905
6988
|
if (!isTest && fsSync3.existsSync(norm)) {
|
|
6906
6989
|
results.add(norm);
|
|
@@ -6922,7 +7005,7 @@ var program = async () => {
|
|
|
6922
7005
|
}),
|
|
6923
7006
|
timeoutMs: 4e3
|
|
6924
7007
|
});
|
|
6925
|
-
const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) =>
|
|
7008
|
+
const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) => path10.resolve(repoRoot, rel).replace(/\\/g, "/")).filter(
|
|
6926
7009
|
(abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/") && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
|
|
6927
7010
|
);
|
|
6928
7011
|
matches.forEach((abs) => results.add(abs));
|
|
@@ -6931,20 +7014,20 @@ var program = async () => {
|
|
|
6931
7014
|
}
|
|
6932
7015
|
return Array.from(results);
|
|
6933
7016
|
};
|
|
6934
|
-
const initialProdSelections =
|
|
7017
|
+
const initialProdSelections = selectionPathsAugmented.filter(
|
|
6935
7018
|
(pathText) => (/[\\/]/.test(pathText) || /\.(m?[tj]sx?)$/i.test(pathText)) && !/(^|\/)tests?\//i.test(pathText) && !/\.(test|spec)\.[tj]sx?$/i.test(pathText)
|
|
6936
7019
|
);
|
|
6937
|
-
const expandedProdSelections = initialProdSelections.length ? initialProdSelections : await expandProductionSelections(
|
|
7020
|
+
const expandedProdSelections = initialProdSelections.length ? initialProdSelections : await expandProductionSelections(selectionPathsAugmented, repoRootForDiscovery);
|
|
6938
7021
|
const selectionIncludesProdPaths = expandedProdSelections.length > 0;
|
|
6939
7022
|
console.info(
|
|
6940
7023
|
`Selection classify \u2192 looksLikePath=${selectionLooksLikePath} looksLikeTest=${selectionLooksLikeTest} prodPaths=${selectionIncludesProdPaths}`
|
|
6941
7024
|
);
|
|
6942
|
-
const stripPathTokens = (args) => args.filter((token) => !
|
|
7025
|
+
const stripPathTokens = (args) => args.filter((token) => !selectionPathsAugmented.includes(token));
|
|
6943
7026
|
const jestDiscoveryArgs = selectionIncludesProdPaths ? stripPathTokens(jest) : jest;
|
|
6944
7027
|
const projectConfigs = [];
|
|
6945
7028
|
try {
|
|
6946
|
-
const baseCfg =
|
|
6947
|
-
const tsCfg =
|
|
7029
|
+
const baseCfg = path10.resolve("jest.config.js");
|
|
7030
|
+
const tsCfg = path10.resolve("jest.ts.config.js");
|
|
6948
7031
|
if (fsSync3.existsSync(baseCfg)) {
|
|
6949
7032
|
projectConfigs.push(baseCfg);
|
|
6950
7033
|
}
|
|
@@ -6961,7 +7044,7 @@ var program = async () => {
|
|
|
6961
7044
|
);
|
|
6962
7045
|
const prodSelections2 = expandedProdSelections;
|
|
6963
7046
|
for (const cfg of projectConfigs) {
|
|
6964
|
-
const cfgCwd =
|
|
7047
|
+
const cfgCwd = path10.dirname(cfg);
|
|
6965
7048
|
const allTests = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
|
|
6966
7049
|
cwd: cfgCwd
|
|
6967
7050
|
});
|
|
@@ -6974,7 +7057,7 @@ var program = async () => {
|
|
|
6974
7057
|
});
|
|
6975
7058
|
} catch (err) {
|
|
6976
7059
|
if (isDebug()) {
|
|
6977
|
-
console.warn(`direct selection failed for project ${
|
|
7060
|
+
console.warn(`direct selection failed for project ${path10.basename(cfg)}: ${String(err)}`);
|
|
6978
7061
|
}
|
|
6979
7062
|
}
|
|
6980
7063
|
perProjectFiles.set(cfg, directPerProject);
|
|
@@ -6986,7 +7069,7 @@ var program = async () => {
|
|
|
6986
7069
|
)} | related=${selectionIncludesProdPaths} | cwd=${repoRootForDiscovery}`
|
|
6987
7070
|
);
|
|
6988
7071
|
for (const cfg of projectConfigs) {
|
|
6989
|
-
const cfgCwd =
|
|
7072
|
+
const cfgCwd = path10.dirname(cfg);
|
|
6990
7073
|
const files = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
|
|
6991
7074
|
cwd: cfgCwd
|
|
6992
7075
|
});
|
|
@@ -6996,18 +7079,18 @@ var program = async () => {
|
|
|
6996
7079
|
const perProjectFiltered = /* @__PURE__ */ new Map();
|
|
6997
7080
|
for (const cfg of projectConfigs) {
|
|
6998
7081
|
const files = perProjectFiles.get(cfg) ?? [];
|
|
6999
|
-
const selectionTestPaths =
|
|
7082
|
+
const selectionTestPaths = selectionPathsAugmented.filter(
|
|
7000
7083
|
(pathToken) => /\.(test|spec)\.[tj]sx?$/i.test(pathToken) || /(^|\/)tests?\//i.test(pathToken)
|
|
7001
7084
|
);
|
|
7002
7085
|
const candidates = selectionHasPaths && selectionLooksLikeTest ? selectionTestPaths : files;
|
|
7003
7086
|
const absFiles = candidates.map(
|
|
7004
|
-
(candidatePath) =>
|
|
7087
|
+
(candidatePath) => path10.isAbsolute(candidatePath) ? candidatePath : path10.join(repoRootForDiscovery, candidatePath)
|
|
7005
7088
|
).map((absolutePath) => absolutePath.replace(/\\/g, "/"));
|
|
7006
7089
|
const onlyOwned = await filterCandidatesForProject(
|
|
7007
7090
|
cfg,
|
|
7008
7091
|
jestDiscoveryArgs,
|
|
7009
7092
|
absFiles,
|
|
7010
|
-
|
|
7093
|
+
path10.dirname(cfg)
|
|
7011
7094
|
);
|
|
7012
7095
|
perProjectFiltered.set(cfg, onlyOwned);
|
|
7013
7096
|
}
|
|
@@ -7019,7 +7102,7 @@ var program = async () => {
|
|
|
7019
7102
|
if (selectionHasPaths && prodSelections.length > 0) {
|
|
7020
7103
|
console.info(`rg related \u2192 prodSelections=${prodSelections.length} (starting)`);
|
|
7021
7104
|
const repoRootForRefinement = workspaceRoot ?? await findRepoRoot();
|
|
7022
|
-
const selectionKey = prodSelections.map((absPath) =>
|
|
7105
|
+
const selectionKey = prodSelections.map((absPath) => path10.relative(repoRootForRefinement, absPath).replace(/\\/g, "/")).sort((firstPath, secondPath) => firstPath.localeCompare(secondPath)).join("|");
|
|
7023
7106
|
const { cachedRelated: cachedRelated2, findRelatedTestsFast: findRelatedTestsFast2, DEFAULT_TEST_GLOBS: DEFAULT_TEST_GLOBS2 } = await Promise.resolve().then(() => (init_fast_related(), fast_related_exports));
|
|
7024
7107
|
const { DEFAULT_EXCLUDE: DEFAULT_EXCLUDE2 } = await Promise.resolve().then(() => (init_args(), args_exports));
|
|
7025
7108
|
const rgMatches = await cachedRelated2({
|
|
@@ -7049,7 +7132,7 @@ var program = async () => {
|
|
|
7049
7132
|
cfg,
|
|
7050
7133
|
jestDiscoveryArgs,
|
|
7051
7134
|
rgCandidates,
|
|
7052
|
-
|
|
7135
|
+
path10.dirname(cfg)
|
|
7053
7136
|
);
|
|
7054
7137
|
perProjectFromRg.set(cfg, owned);
|
|
7055
7138
|
}
|
|
@@ -7064,9 +7147,9 @@ var program = async () => {
|
|
|
7064
7147
|
} else {
|
|
7065
7148
|
const repoRootForScan = repoRootForDiscovery;
|
|
7066
7149
|
const toSeeds = (abs) => {
|
|
7067
|
-
const rel =
|
|
7150
|
+
const rel = path10.relative(repoRootForScan, abs).replace(/\\/g, "/");
|
|
7068
7151
|
const withoutExt = rel.replace(/\.(m?[tj]sx?)$/i, "");
|
|
7069
|
-
const base =
|
|
7152
|
+
const base = path10.basename(withoutExt);
|
|
7070
7153
|
const segs = withoutExt.split("/");
|
|
7071
7154
|
const tail2 = segs.slice(-2).join("/");
|
|
7072
7155
|
return Array.from(new Set([withoutExt, base, tail2].filter(Boolean)));
|
|
@@ -7081,8 +7164,8 @@ var program = async () => {
|
|
|
7081
7164
|
}
|
|
7082
7165
|
};
|
|
7083
7166
|
const resolveLocalImport = (fromFile, spec) => {
|
|
7084
|
-
const baseDir =
|
|
7085
|
-
const cand =
|
|
7167
|
+
const baseDir = path10.dirname(fromFile);
|
|
7168
|
+
const cand = path10.resolve(baseDir, spec);
|
|
7086
7169
|
const exts = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
7087
7170
|
for (const ext of exts) {
|
|
7088
7171
|
const full = ext ? `${cand}${ext}` : cand;
|
|
@@ -7091,7 +7174,7 @@ var program = async () => {
|
|
|
7091
7174
|
}
|
|
7092
7175
|
}
|
|
7093
7176
|
for (const ext of exts) {
|
|
7094
|
-
const full =
|
|
7177
|
+
const full = path10.join(cand, `index${ext}`);
|
|
7095
7178
|
if (fsSync3.existsSync(full)) {
|
|
7096
7179
|
return full;
|
|
7097
7180
|
}
|
|
@@ -7145,7 +7228,7 @@ var program = async () => {
|
|
|
7145
7228
|
cfg,
|
|
7146
7229
|
jestDiscoveryArgs,
|
|
7147
7230
|
keptCandidates,
|
|
7148
|
-
|
|
7231
|
+
path10.dirname(cfg)
|
|
7149
7232
|
);
|
|
7150
7233
|
perProjectFromScan.set(cfg, owned);
|
|
7151
7234
|
}
|
|
@@ -7172,9 +7255,9 @@ var program = async () => {
|
|
|
7172
7255
|
if (effectiveJestFiles.length === 0) {
|
|
7173
7256
|
const repoRoot = repoRootForRefinement;
|
|
7174
7257
|
const seeds = prodSelections.map(
|
|
7175
|
-
(abs) =>
|
|
7258
|
+
(abs) => path10.relative(repoRoot, abs).replace(/\\/g, "/").replace(/\.(m?[tj]sx?)$/i, "")
|
|
7176
7259
|
).flatMap((rel) => {
|
|
7177
|
-
const base =
|
|
7260
|
+
const base = path10.basename(rel);
|
|
7178
7261
|
const segments = rel.split("/");
|
|
7179
7262
|
return Array.from(new Set([rel, base, segments.slice(-2).join("/")].filter(Boolean)));
|
|
7180
7263
|
});
|
|
@@ -7187,8 +7270,8 @@ var program = async () => {
|
|
|
7187
7270
|
}
|
|
7188
7271
|
};
|
|
7189
7272
|
const resolveLocalImport = (fromFile, spec) => {
|
|
7190
|
-
const baseDir =
|
|
7191
|
-
const candidate =
|
|
7273
|
+
const baseDir = path10.dirname(fromFile);
|
|
7274
|
+
const candidate = path10.resolve(baseDir, spec);
|
|
7192
7275
|
const extensions = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
|
|
7193
7276
|
for (const ext of extensions) {
|
|
7194
7277
|
const fullPath = ext ? `${candidate}${ext}` : candidate;
|
|
@@ -7197,7 +7280,7 @@ var program = async () => {
|
|
|
7197
7280
|
}
|
|
7198
7281
|
}
|
|
7199
7282
|
for (const ext of extensions) {
|
|
7200
|
-
const fullPath =
|
|
7283
|
+
const fullPath = path10.join(candidate, `index${ext}`);
|
|
7201
7284
|
if (fsSync3.existsSync(fullPath)) {
|
|
7202
7285
|
return fullPath;
|
|
7203
7286
|
}
|
|
@@ -7316,8 +7399,8 @@ var program = async () => {
|
|
|
7316
7399
|
}
|
|
7317
7400
|
}
|
|
7318
7401
|
const jestDecision = decideShouldRunJest([], effectiveJestFiles, {
|
|
7319
|
-
selectionSpecified,
|
|
7320
|
-
selectionPaths
|
|
7402
|
+
selectionSpecified: selectionSpecifiedAugmented,
|
|
7403
|
+
selectionPaths: selectionPathsAugmented
|
|
7321
7404
|
});
|
|
7322
7405
|
const { shouldRunJest } = jestDecision;
|
|
7323
7406
|
const jestCount = effectiveJestFiles.length;
|
|
@@ -7335,45 +7418,63 @@ var program = async () => {
|
|
|
7335
7418
|
}
|
|
7336
7419
|
console.info(`Run plan \u2192 Jest maybe=${shouldRunJest} (projects=${projectConfigs.length})`);
|
|
7337
7420
|
let jestExitCode = 0;
|
|
7421
|
+
const allBridgeJson = [];
|
|
7338
7422
|
const executedTestFilesSet = /* @__PURE__ */ new Set();
|
|
7339
7423
|
if (shouldRunJest) {
|
|
7340
7424
|
console.info("Starting Jest (no Vitest targets)\u2026");
|
|
7341
7425
|
await runJestBootstrap();
|
|
7342
7426
|
const jestRunArgs = selectionIncludesProdPaths ? stripPathTokens(jestArgs) : jestArgs;
|
|
7427
|
+
const sanitizedJestRunArgs = jestRunArgs.filter(
|
|
7428
|
+
(arg) => !/^--coverageDirectory(?:=|$)/.test(String(arg))
|
|
7429
|
+
);
|
|
7343
7430
|
const projectsToRun = projectConfigs.filter(
|
|
7344
7431
|
(cfg) => (perProjectFiltered.get(cfg) ?? []).length > 0
|
|
7345
7432
|
);
|
|
7346
|
-
const totalProjectsToRun = projectsToRun.length;
|
|
7347
7433
|
const stripFooter = (text) => {
|
|
7348
7434
|
const lines = text.split("\n");
|
|
7349
7435
|
const idx = lines.findIndex((ln) => /^Test Files\s/.test(stripAnsiSimple(ln)));
|
|
7350
7436
|
return idx >= 0 ? lines.slice(0, idx).join("\n").trimEnd() : text;
|
|
7351
7437
|
};
|
|
7438
|
+
const prodSeedsForRun = (() => {
|
|
7439
|
+
const changedAbs = (changedSelectionAbs ?? []).map(
|
|
7440
|
+
(absPath) => path10.resolve(absPath).replace(/\\/g, "/")
|
|
7441
|
+
);
|
|
7442
|
+
const selAbs = selectionPathsAugmented.map(
|
|
7443
|
+
(pathToken) => path10.resolve(pathToken).replace(/\\/g, "/")
|
|
7444
|
+
);
|
|
7445
|
+
return (changedAbs.length ? changedAbs : selAbs).filter(
|
|
7446
|
+
(abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
|
|
7447
|
+
);
|
|
7448
|
+
})();
|
|
7449
|
+
const repoRootForRank = repoRootForDiscovery;
|
|
7450
|
+
const fileRank = await computeDirectnessRank({
|
|
7451
|
+
repoRoot: repoRootForRank,
|
|
7452
|
+
productionSeeds: prodSeedsForRun
|
|
7453
|
+
});
|
|
7352
7454
|
for (let projIndex = 0; projIndex < projectsToRun.length; projIndex += 1) {
|
|
7353
7455
|
const cfg = projectsToRun[projIndex];
|
|
7354
|
-
const isLastProject = projIndex === totalProjectsToRun - 1;
|
|
7355
7456
|
const files = perProjectFiltered.get(cfg) ?? [];
|
|
7356
7457
|
if (files.length === 0) {
|
|
7357
|
-
console.info(`Project ${
|
|
7458
|
+
console.info(`Project ${path10.basename(cfg)}: 0 matching tests after filter; skipping.`);
|
|
7358
7459
|
continue;
|
|
7359
7460
|
}
|
|
7360
7461
|
files.forEach(
|
|
7361
|
-
(absTestPath) => executedTestFilesSet.add(
|
|
7462
|
+
(absTestPath) => executedTestFilesSet.add(path10.resolve(absTestPath).replace(/\\/g, "/"))
|
|
7362
7463
|
);
|
|
7363
|
-
const outJson =
|
|
7464
|
+
const outJson = path10.join(
|
|
7364
7465
|
os2.tmpdir(),
|
|
7365
7466
|
`jest-bridge-${Date.now()}-${Math.random().toString(36).slice(2)}.json`
|
|
7366
7467
|
);
|
|
7367
|
-
const reporterPath =
|
|
7468
|
+
const reporterPath = path10.resolve("scripts/jest-vitest-bridge.cjs");
|
|
7368
7469
|
try {
|
|
7369
7470
|
if (!fsSync3.existsSync(reporterPath)) {
|
|
7370
|
-
fsSync3.mkdirSync(
|
|
7471
|
+
fsSync3.mkdirSync(path10.dirname(reporterPath), { recursive: true });
|
|
7371
7472
|
fsSync3.writeFileSync(reporterPath, JEST_BRIDGE_REPORTER_SOURCE, "utf8");
|
|
7372
7473
|
}
|
|
7373
7474
|
} catch (ensureReporterError) {
|
|
7374
7475
|
console.warn(`Unable to ensure jest bridge reporter: ${String(ensureReporterError)}`);
|
|
7375
7476
|
}
|
|
7376
|
-
const selectedFilesForCoverage =
|
|
7477
|
+
const selectedFilesForCoverage = selectionPathsAugmented.filter((pathToken) => /[\\/]/.test(pathToken)).filter((pathToken) => !looksLikeTestPath(pathToken)).map((pathToken) => path10.relative(repoRootForDiscovery, pathToken).replace(/\\\\/g, "/")).filter((rel) => rel && !/^\.+\//.test(rel)).map((rel) => rel.startsWith("./") ? rel : `./${rel}`);
|
|
7377
7478
|
const coverageFromArgs = [];
|
|
7378
7479
|
for (const relPath of selectedFilesForCoverage) {
|
|
7379
7480
|
coverageFromArgs.push("--collectCoverageFrom", relPath);
|
|
@@ -7387,14 +7488,17 @@ var program = async () => {
|
|
|
7387
7488
|
"--config",
|
|
7388
7489
|
cfg,
|
|
7389
7490
|
"--runTestsByPath",
|
|
7390
|
-
|
|
7391
|
-
reporterPath,
|
|
7491
|
+
`--reporters=${reporterPath}`,
|
|
7392
7492
|
"--silent",
|
|
7393
7493
|
"--colors",
|
|
7394
7494
|
"--json",
|
|
7395
7495
|
"--outputFile",
|
|
7396
7496
|
outJson,
|
|
7397
|
-
...
|
|
7497
|
+
...sanitizedJestRunArgs,
|
|
7498
|
+
...collectCoverage ? [
|
|
7499
|
+
"--coverageDirectory",
|
|
7500
|
+
path10.join("coverage", "jest", path10.basename(cfg).replace(/[^a-zA-Z0-9_.-]+/g, "_"))
|
|
7501
|
+
] : [],
|
|
7398
7502
|
...coverageFromArgs,
|
|
7399
7503
|
"--passWithNoTests",
|
|
7400
7504
|
...files
|
|
@@ -7420,10 +7524,24 @@ var program = async () => {
|
|
|
7420
7524
|
const jsonText = fsSync3.readFileSync(outJson, "utf8");
|
|
7421
7525
|
const parsed = JSON.parse(jsonText);
|
|
7422
7526
|
const bridge = coerceJestJsonToBridge(parsed);
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7527
|
+
allBridgeJson.push(bridge);
|
|
7528
|
+
try {
|
|
7529
|
+
const reordered = {
|
|
7530
|
+
...bridge,
|
|
7531
|
+
testResults: sortTestResultsWithRank(fileRank, bridge.testResults).reverse()
|
|
7532
|
+
};
|
|
7533
|
+
pretty = renderVitestFromJestJSON(reordered, {
|
|
7534
|
+
cwd: repoRootForDiscovery,
|
|
7535
|
+
...editorCmd !== void 0 ? { editorCmd } : {},
|
|
7536
|
+
onlyFailures
|
|
7537
|
+
});
|
|
7538
|
+
} catch {
|
|
7539
|
+
pretty = renderVitestFromJestJSON(bridge, {
|
|
7540
|
+
cwd: repoRootForDiscovery,
|
|
7541
|
+
...editorCmd !== void 0 ? { editorCmd } : {},
|
|
7542
|
+
onlyFailures
|
|
7543
|
+
});
|
|
7544
|
+
}
|
|
7427
7545
|
if (debug) {
|
|
7428
7546
|
const preview = pretty.split("\n").slice(0, 3).join("\n");
|
|
7429
7547
|
console.info(`pretty preview (json):
|
|
@@ -7438,7 +7556,8 @@ ${preview}${pretty.includes("\n") ? "\n\u2026" : ""}`);
|
|
|
7438
7556
|
}
|
|
7439
7557
|
const renderOpts = {
|
|
7440
7558
|
cwd: repoRootForDiscovery,
|
|
7441
|
-
...editorCmd !== void 0 ? { editorCmd } : {}
|
|
7559
|
+
...editorCmd !== void 0 ? { editorCmd } : {},
|
|
7560
|
+
onlyFailures
|
|
7442
7561
|
};
|
|
7443
7562
|
pretty = formatJestOutputVitest(output, renderOpts);
|
|
7444
7563
|
if (debug) {
|
|
@@ -7447,9 +7566,7 @@ ${preview}${pretty.includes("\n") ? "\n\u2026" : ""}`);
|
|
|
7447
7566
|
${preview}${pretty.includes("\n") ? "\n\u2026" : ""}`);
|
|
7448
7567
|
}
|
|
7449
7568
|
}
|
|
7450
|
-
|
|
7451
|
-
pretty = stripFooter(pretty);
|
|
7452
|
-
}
|
|
7569
|
+
pretty = stripFooter(pretty);
|
|
7453
7570
|
if (pretty.trim().length > 0) {
|
|
7454
7571
|
process.stdout.write(pretty.endsWith("\n") ? pretty : `${pretty}
|
|
7455
7572
|
`);
|
|
@@ -7461,15 +7578,70 @@ ${preview}${pretty.includes("\n") ? "\n\u2026" : ""}`);
|
|
|
7461
7578
|
} else {
|
|
7462
7579
|
console.info("Jest run skipped based on selection and thresholds.");
|
|
7463
7580
|
}
|
|
7464
|
-
if (
|
|
7465
|
-
|
|
7581
|
+
if (allBridgeJson.length > 0) {
|
|
7582
|
+
const agg = allBridgeJson.map((bridge) => bridge.aggregated);
|
|
7583
|
+
const sum = (select) => agg.reduce((total, item) => total + (select(item) || 0), 0);
|
|
7584
|
+
const startTime = Math.min(
|
|
7585
|
+
...allBridgeJson.map((bridge) => Number(bridge.startTime || Date.now()))
|
|
7586
|
+
);
|
|
7587
|
+
const unified = {
|
|
7588
|
+
startTime,
|
|
7589
|
+
testResults: allBridgeJson.flatMap((bridge) => bridge.testResults),
|
|
7590
|
+
aggregated: {
|
|
7591
|
+
numTotalTestSuites: sum((item) => item.numTotalTestSuites),
|
|
7592
|
+
numPassedTestSuites: sum((item) => item.numPassedTestSuites),
|
|
7593
|
+
numFailedTestSuites: sum((item) => item.numFailedTestSuites),
|
|
7594
|
+
numTotalTests: sum((item) => item.numTotalTests),
|
|
7595
|
+
numPassedTests: sum((item) => item.numPassedTests),
|
|
7596
|
+
numFailedTests: sum((item) => item.numFailedTests),
|
|
7597
|
+
numPendingTests: sum((item) => item.numPendingTests),
|
|
7598
|
+
numTodoTests: sum((item) => item.numTodoTests),
|
|
7599
|
+
startTime,
|
|
7600
|
+
success: agg.every((item) => Boolean(item.success)),
|
|
7601
|
+
runTimeMs: sum((item) => Number(item.runTimeMs ?? 0))
|
|
7602
|
+
}
|
|
7603
|
+
};
|
|
7604
|
+
try {
|
|
7605
|
+
const prodSeeds = (() => {
|
|
7606
|
+
const changedAbs = (changedSelectionAbs ?? []).map(
|
|
7607
|
+
(absPath) => path10.resolve(absPath).replace(/\\/g, "/")
|
|
7608
|
+
);
|
|
7609
|
+
const selAbs = selectionPathsAugmented.map(
|
|
7610
|
+
(pathToken) => path10.resolve(pathToken).replace(/\\/g, "/")
|
|
7611
|
+
);
|
|
7612
|
+
return (changedAbs.length ? changedAbs : selAbs).filter(
|
|
7613
|
+
(abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
|
|
7614
|
+
);
|
|
7615
|
+
})();
|
|
7616
|
+
const unifiedRank = await computeDirectnessRank({
|
|
7617
|
+
repoRoot: repoRootForDiscovery,
|
|
7618
|
+
productionSeeds: prodSeeds
|
|
7619
|
+
});
|
|
7620
|
+
const ordered = sortTestResultsWithRank(unifiedRank, unified.testResults).reverse();
|
|
7621
|
+
unified.testResults = ordered;
|
|
7622
|
+
} catch {
|
|
7623
|
+
}
|
|
7624
|
+
const text = renderVitestFromJestJSON(unified, {
|
|
7625
|
+
cwd: repoRootForDiscovery,
|
|
7626
|
+
...editorCmd !== void 0 ? { editorCmd } : {},
|
|
7627
|
+
onlyFailures
|
|
7628
|
+
});
|
|
7629
|
+
if (text.trim().length > 0) {
|
|
7630
|
+
process.stdout.write(text.endsWith("\n") ? text : `${text}
|
|
7631
|
+
`);
|
|
7632
|
+
}
|
|
7633
|
+
}
|
|
7634
|
+
const finalExitCode = jestExitCode;
|
|
7635
|
+
if (collectCoverage && shouldRunJest && coverageAbortOnFailure && finalExitCode !== 0) {
|
|
7636
|
+
process.exit(finalExitCode);
|
|
7637
|
+
return;
|
|
7466
7638
|
}
|
|
7467
7639
|
if (collectCoverage && shouldRunJest) {
|
|
7468
7640
|
await mergeLcov();
|
|
7469
7641
|
const repoRoot = workspaceRoot ?? await findRepoRoot();
|
|
7470
7642
|
const mergedOptsBase = {
|
|
7471
|
-
selectionSpecified,
|
|
7472
|
-
selectionPaths,
|
|
7643
|
+
selectionSpecified: selectionSpecifiedAugmented,
|
|
7644
|
+
selectionPaths: selectionPathsAugmented,
|
|
7473
7645
|
includeGlobs,
|
|
7474
7646
|
excludeGlobs,
|
|
7475
7647
|
workspaceRoot: repoRoot,
|
|
@@ -7484,7 +7656,6 @@ ${preview}${pretty.includes("\n") ? "\n\u2026" : ""}`);
|
|
|
7484
7656
|
};
|
|
7485
7657
|
await emitMergedCoverage(coverageUi, mergedOptsBase);
|
|
7486
7658
|
}
|
|
7487
|
-
const finalExitCode = jestExitCode;
|
|
7488
7659
|
process.exit(finalExitCode);
|
|
7489
7660
|
};
|
|
7490
7661
|
export {
|