@diffci.com/diffci 0.2.0 → 0.2.1
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.
|
@@ -28,7 +28,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
28
28
|
import { tmpdir } from "node:os";
|
|
29
29
|
import { basename, dirname, join, resolve } from "node:path";
|
|
30
30
|
import { observe, isInsideRepository } from "./observe.js";
|
|
31
|
-
import { inferFullCommand } from "./full-command.js";
|
|
31
|
+
import { inferFullCommand, inferSelectedCommand } from "./full-command.js";
|
|
32
32
|
import { submitObservation } from "./submit.js";
|
|
33
33
|
import { formatVerifySavingsSummary, measureCommand, runVerifySavings, writeVerifySavingsReport } from "./verify-savings.js";
|
|
34
34
|
import { auditWorkflows, isNonInterfering } from "./workflow-guard.js";
|
|
@@ -316,10 +316,20 @@ async function runCheck(flags, env) {
|
|
|
316
316
|
console.log(JSON.stringify({ observation, timing: null, reason }, null, 2));
|
|
317
317
|
return 0;
|
|
318
318
|
}
|
|
319
|
+
const selected = inferSelectedCommand(repoPath, observation.result.proposedCommands[0], observation.result.selectedTests);
|
|
320
|
+
if (!selected.command) {
|
|
321
|
+
print(` timing: unavailable (${selected.reason})`);
|
|
322
|
+
if (flags.json === true)
|
|
323
|
+
console.log(JSON.stringify({ observation, timing: null, reason: selected.reason }, null, 2));
|
|
324
|
+
return 0;
|
|
325
|
+
}
|
|
326
|
+
if (selected.command !== observation.result.proposedCommands[0])
|
|
327
|
+
print(` selected command: ${selected.command} (${selected.reason})`);
|
|
319
328
|
print(" running full and selected validation...");
|
|
320
329
|
const savings = runVerifySavings({
|
|
321
330
|
full: inferred.command,
|
|
322
331
|
selectedFromReport: reportPath,
|
|
332
|
+
selectedCommandOverride: selected.command,
|
|
323
333
|
out: savingsPath,
|
|
324
334
|
markdown: markdownPath,
|
|
325
335
|
label: stringFlag(flags, "label") ?? basename(repoPath),
|
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { readRepositoryConfig } from "@diffci.com/core/repo/repo-config";
|
|
4
|
+
/** Preserve the repository's TypeScript test loader for selected node:test files. */
|
|
5
|
+
export function inferSelectedCommand(repoPath, proposed, selectedTests) {
|
|
6
|
+
if (!/^node --test(?:\s|$)/.test(proposed) || !selectedTests.some(path => /\.(?:ts|tsx|mts|cts)$/.test(path))) {
|
|
7
|
+
return { command: proposed, reason: "DiffCI proposed command" };
|
|
8
|
+
}
|
|
9
|
+
const packagePath = join(repoPath, "package.json");
|
|
10
|
+
if (!existsSync(packagePath))
|
|
11
|
+
return { reason: "TypeScript tests require a declared test loader" };
|
|
12
|
+
let script;
|
|
13
|
+
try {
|
|
14
|
+
script = JSON.parse(readFileSync(packagePath, "utf8")).scripts?.test;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return { reason: "package.json could not be read" };
|
|
18
|
+
}
|
|
19
|
+
if (typeof script !== "string")
|
|
20
|
+
return { reason: "TypeScript tests require a declared test script" };
|
|
21
|
+
const runners = [...script.matchAll(/\btsx(?:\s+--conditions\s+[\w,-]+)?\s+--test\b/g)];
|
|
22
|
+
if (runners.length !== 1)
|
|
23
|
+
return { reason: "Cannot identify one TypeScript node:test runner in the test script" };
|
|
24
|
+
return {
|
|
25
|
+
command: proposed.replace(/^node --test/, `npx --no-install ${runners[0][0]}`),
|
|
26
|
+
reason: "TypeScript node:test runner from package.json test script",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
4
29
|
/** Choose the repository's conventional full test command without executing anything. */
|
|
5
30
|
export function inferFullCommand(repoPath) {
|
|
6
31
|
if (existsSync(join(repoPath, "pom.xml"))) {
|
|
@@ -27,8 +27,10 @@ function readSelectionFromObservation(path) {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
function resolveSelection(options) {
|
|
30
|
-
if (options.selectedFromReport)
|
|
31
|
-
|
|
30
|
+
if (options.selectedFromReport) {
|
|
31
|
+
const selection = readSelectionFromObservation(options.selectedFromReport);
|
|
32
|
+
return options.selectedCommandOverride ? { ...selection, command: options.selectedCommandOverride } : selection;
|
|
33
|
+
}
|
|
32
34
|
if (!options.selected)
|
|
33
35
|
throw new Error("--selected <command> or --selected-from-report <path> is required");
|
|
34
36
|
return { command: options.selected, source: "manual" };
|