greenbump 0.8.0 → 0.9.0
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 +58 -15
- package/README.zh-CN.md +37 -4
- package/dist/action/github.test.js +37 -0
- package/dist/action/github.test.js.map +1 -0
- package/dist/action/main.js +19 -4
- package/dist/action/main.js.map +1 -1
- package/dist/agent/fixer.js +201 -25
- package/dist/agent/fixer.js.map +1 -1
- package/dist/agent/fixer.test.js +221 -0
- package/dist/agent/fixer.test.js.map +1 -1
- package/dist/benchmarks/run.js +0 -0
- package/dist/benchmarks/run.js.map +1 -0
- package/dist/cli/interactive.js +46 -11
- package/dist/cli/interactive.js.map +1 -1
- package/dist/cli.js +35 -7
- package/dist/cli.js.map +1 -1
- package/dist/engine/analyzers/changelog-parser.js +19 -0
- package/dist/engine/analyzers/changelog-parser.js.map +1 -1
- package/dist/engine/batch.js +54 -10
- package/dist/engine/batch.js.map +1 -1
- package/dist/engine/cache/manager.js +19 -1
- package/dist/engine/cache/manager.js.map +1 -1
- package/dist/engine/cache/manager.test.js +17 -0
- package/dist/engine/cache/manager.test.js.map +1 -1
- package/dist/engine/change-detector.js +52 -23
- package/dist/engine/change-detector.js.map +1 -1
- package/dist/engine/change-detector.test.js +72 -0
- package/dist/engine/change-detector.test.js.map +1 -0
- package/dist/engine/changelog.js +22 -2
- package/dist/engine/changelog.js.map +1 -1
- package/dist/engine/changelog.test.js +31 -0
- package/dist/engine/changelog.test.js.map +1 -0
- package/dist/engine/checks.js +10 -4
- package/dist/engine/checks.js.map +1 -1
- package/dist/engine/context/optimizer.js +14 -44
- package/dist/engine/context/optimizer.js.map +1 -1
- package/dist/engine/context/optimizer.test.js +23 -1
- package/dist/engine/context/optimizer.test.js.map +1 -1
- package/dist/engine/ecosystems/cargo.js +2 -1
- package/dist/engine/ecosystems/cargo.js.map +1 -1
- package/dist/engine/ecosystems/conan.js +2 -1
- package/dist/engine/ecosystems/conan.js.map +1 -1
- package/dist/engine/ecosystems/elm.js +2 -1
- package/dist/engine/ecosystems/elm.js.map +1 -1
- package/dist/engine/ecosystems/gradle.js +2 -1
- package/dist/engine/ecosystems/gradle.js.map +1 -1
- package/dist/engine/ecosystems/http.js +18 -0
- package/dist/engine/ecosystems/http.js.map +1 -0
- package/dist/engine/ecosystems/maven.js +2 -1
- package/dist/engine/ecosystems/maven.js.map +1 -1
- package/dist/engine/ecosystems/swiftpm.js +2 -1
- package/dist/engine/ecosystems/swiftpm.js.map +1 -1
- package/dist/engine/exec.js +37 -7
- package/dist/engine/exec.js.map +1 -1
- package/dist/engine/exec.test.js +36 -0
- package/dist/engine/exec.test.js.map +1 -0
- package/dist/engine/fixer/patterns.js +55 -18
- package/dist/engine/fixer/patterns.js.map +1 -1
- package/dist/engine/fixer/patterns.test.js +95 -1
- package/dist/engine/fixer/patterns.test.js.map +1 -1
- package/dist/engine/git.js +38 -16
- package/dist/engine/git.js.map +1 -1
- package/dist/engine/git.test.js +51 -1
- package/dist/engine/git.test.js.map +1 -1
- package/dist/engine/perf/metrics.js +44 -57
- package/dist/engine/perf/metrics.js.map +1 -1
- package/dist/engine/run.js +120 -12
- package/dist/engine/run.js.map +1 -1
- package/dist/engine/run.test.js +65 -1
- package/dist/engine/run.test.js.map +1 -1
- package/dist/engine/sandbox/docker-manager.js +52 -26
- package/dist/engine/sandbox/docker-manager.js.map +1 -1
- package/dist/engine/sandbox/template-generator.js +0 -4
- package/dist/engine/sandbox/template-generator.js.map +1 -1
- package/dist/engine/sandbox/template-generator.test.js +16 -0
- package/dist/engine/sandbox/template-generator.test.js.map +1 -0
- package/dist/engine/scan/benchmark-crosscheck.test.js +116 -0
- package/dist/engine/scan/benchmark-crosscheck.test.js.map +1 -0
- package/dist/engine/scan/detect.js +96 -0
- package/dist/engine/scan/detect.js.map +1 -0
- package/dist/engine/scan/impact.js +128 -0
- package/dist/engine/scan/impact.js.map +1 -0
- package/dist/engine/scan/impact.test.js +217 -0
- package/dist/engine/scan/impact.test.js.map +1 -0
- package/dist/engine/scan/indexer.js +129 -0
- package/dist/engine/scan/indexer.js.map +1 -0
- package/dist/engine/scan/indexer.test.js +149 -0
- package/dist/engine/scan/indexer.test.js.map +1 -0
- package/dist/engine/scan/probes.js +92 -0
- package/dist/engine/scan/probes.js.map +1 -0
- package/dist/engine/scan/probes.test.js +100 -0
- package/dist/engine/scan/probes.test.js.map +1 -0
- package/dist/engine/verify.js +41 -58
- package/dist/engine/verify.js.map +1 -1
- package/dist/engine/verify.test.js +49 -0
- package/dist/engine/verify.test.js.map +1 -0
- package/dist/format.js +81 -0
- package/dist/format.js.map +1 -1
- package/dist/format.test.js +8 -0
- package/dist/format.test.js.map +1 -1
- package/dist/pr.test.js +48 -0
- package/dist/pr.test.js.map +1 -0
- package/package.json +4 -4
- package/dist/engine/dep-graph.js +0 -101
- package/dist/engine/dep-graph.js.map +0 -1
- package/dist/engine/staged-fix.js +0 -108
- package/dist/engine/staged-fix.js.map +0 -1
- package/dist/engine/stages.js +0 -125
- package/dist/engine/stages.js.map +0 -1
|
@@ -1,7 +1,26 @@
|
|
|
1
|
-
import { exec } from "../
|
|
1
|
+
import { exec } from "../exec.js";
|
|
2
2
|
import { existsSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { rm } from "fs/promises";
|
|
5
|
+
/**
|
|
6
|
+
* Compose command detection: v1 standalone binary or v2 `docker compose`
|
|
7
|
+
* plugin. Cached for the process lifetime.
|
|
8
|
+
*/
|
|
9
|
+
let composeCommandCache;
|
|
10
|
+
async function composeCommand() {
|
|
11
|
+
if (composeCommandCache !== undefined)
|
|
12
|
+
return composeCommandCache;
|
|
13
|
+
if ((await exec("docker-compose", ["--version"], { cwd: process.cwd() })).code === 0) {
|
|
14
|
+
composeCommandCache = ["docker-compose"];
|
|
15
|
+
}
|
|
16
|
+
else if ((await exec("docker", ["compose", "version"], { cwd: process.cwd() })).code === 0) {
|
|
17
|
+
composeCommandCache = ["docker", "compose"];
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
composeCommandCache = null;
|
|
21
|
+
}
|
|
22
|
+
return composeCommandCache;
|
|
23
|
+
}
|
|
5
24
|
/**
|
|
6
25
|
* Check if Docker is available and running
|
|
7
26
|
*/
|
|
@@ -12,18 +31,15 @@ export async function checkDockerAvailable() {
|
|
|
12
31
|
};
|
|
13
32
|
try {
|
|
14
33
|
const versionResult = await exec("docker", ["--version"], { cwd: process.cwd() });
|
|
34
|
+
if (versionResult.code !== 0)
|
|
35
|
+
return info;
|
|
15
36
|
info.version = versionResult.stdout.trim();
|
|
16
37
|
// Check if Docker daemon is running
|
|
17
|
-
await exec("docker", ["ps"], { cwd: process.cwd() });
|
|
38
|
+
const psResult = await exec("docker", ["ps"], { cwd: process.cwd() });
|
|
39
|
+
if (psResult.code !== 0)
|
|
40
|
+
return info;
|
|
18
41
|
info.available = true;
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
await exec("docker-compose", ["--version"], { cwd: process.cwd() });
|
|
22
|
-
info.composeAvailable = true;
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
// docker-compose not available, but that's okay
|
|
26
|
-
}
|
|
42
|
+
info.composeAvailable = (await composeCommand()) !== null;
|
|
27
43
|
}
|
|
28
44
|
catch {
|
|
29
45
|
// Docker not available
|
|
@@ -70,21 +86,18 @@ export async function runVerificationInContainer(cwd, options) {
|
|
|
70
86
|
let stderr = "";
|
|
71
87
|
let buildSuccess = false;
|
|
72
88
|
let testsPassed = false;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
89
|
+
const result = await exec("docker", args, {
|
|
90
|
+
cwd,
|
|
91
|
+
timeout: options.timeout || 600000, // 10 minutes default (milliseconds)
|
|
92
|
+
});
|
|
93
|
+
stdout = result.stdout;
|
|
94
|
+
stderr = result.stderr;
|
|
95
|
+
exitCode = result.code;
|
|
96
|
+
if (result.code === 0) {
|
|
81
97
|
buildSuccess = true;
|
|
82
98
|
testsPassed = true;
|
|
83
99
|
}
|
|
84
|
-
|
|
85
|
-
exitCode = error.exitCode || 1;
|
|
86
|
-
stdout = error.stdout || "";
|
|
87
|
-
stderr = error.stderr || "";
|
|
100
|
+
else {
|
|
88
101
|
// Determine what failed
|
|
89
102
|
buildSuccess = !stderr.includes("npm run build") && !stdout.includes("build failed");
|
|
90
103
|
testsPassed = false;
|
|
@@ -102,8 +115,12 @@ export async function runVerificationInContainer(cwd, options) {
|
|
|
102
115
|
*/
|
|
103
116
|
export async function startComposeServices(cwd, composeFile) {
|
|
104
117
|
console.log("🚀 Starting docker-compose services...");
|
|
118
|
+
const cmd = await composeCommand();
|
|
119
|
+
if (!cmd)
|
|
120
|
+
throw new Error("docker-compose is not available");
|
|
105
121
|
const projectName = `greenbump-${Date.now()}`;
|
|
106
|
-
await exec(
|
|
122
|
+
await exec(cmd[0], [
|
|
123
|
+
...cmd.slice(1),
|
|
107
124
|
"-f", composeFile,
|
|
108
125
|
"-p", projectName,
|
|
109
126
|
"up", "-d",
|
|
@@ -115,7 +132,10 @@ export async function startComposeServices(cwd, composeFile) {
|
|
|
115
132
|
*/
|
|
116
133
|
export async function checkServiceHealth(projectName, serviceName) {
|
|
117
134
|
try {
|
|
118
|
-
const
|
|
135
|
+
const cmd = await composeCommand();
|
|
136
|
+
if (!cmd)
|
|
137
|
+
return false;
|
|
138
|
+
const result = await exec(cmd[0], [...cmd.slice(1), "-p", projectName, "ps", "--filter", `name=${serviceName}`, "--format", "json"], { cwd: process.cwd() });
|
|
119
139
|
const output = result.stdout.trim();
|
|
120
140
|
if (!output)
|
|
121
141
|
return false;
|
|
@@ -129,7 +149,9 @@ export async function checkServiceHealth(projectName, serviceName) {
|
|
|
129
149
|
/**
|
|
130
150
|
* Wait for services to become healthy
|
|
131
151
|
*/
|
|
132
|
-
export async function waitForServices(projectName, services,
|
|
152
|
+
export async function waitForServices(projectName, services,
|
|
153
|
+
/** seconds */
|
|
154
|
+
timeout = 60) {
|
|
133
155
|
console.log("⏳ Waiting for services to become healthy...");
|
|
134
156
|
const deadline = Date.now() + timeout * 1000;
|
|
135
157
|
const healthyServices = new Set();
|
|
@@ -157,8 +179,12 @@ export async function waitForServices(projectName, services, timeout = 60) {
|
|
|
157
179
|
*/
|
|
158
180
|
export async function stopComposeServices(cwd, composeFile, projectName) {
|
|
159
181
|
console.log("🛑 Stopping docker-compose services...");
|
|
182
|
+
const cmd = await composeCommand();
|
|
183
|
+
if (!cmd)
|
|
184
|
+
return;
|
|
160
185
|
try {
|
|
161
|
-
await exec(
|
|
186
|
+
await exec(cmd[0], [
|
|
187
|
+
...cmd.slice(1),
|
|
162
188
|
"-f", composeFile,
|
|
163
189
|
"-p", projectName,
|
|
164
190
|
"down", "-v",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker-manager.js","sourceRoot":"","sources":["../../../src/engine/sandbox/docker-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"docker-manager.js","sourceRoot":"","sources":["../../../src/engine/sandbox/docker-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-generator.js","sourceRoot":"","sources":["../../../src/engine/sandbox/template-generator.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"template-generator.js","sourceRoot":"","sources":["../../../src/engine/sandbox/template-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { generateComposeFile } from "./template-generator.js";
|
|
4
|
+
test("generateComposeFile: no fixed network name, so compose's per-project default network applies", async () => {
|
|
5
|
+
// orchestrator.ts joins the verify container to `${projectName}_default`.
|
|
6
|
+
// An explicit `name:` on the network would suppress the project prefix and
|
|
7
|
+
// break that join (and collide across concurrent runs).
|
|
8
|
+
const yaml = await generateComposeFile(["postgres"]);
|
|
9
|
+
assert.ok(yaml.includes("postgres"));
|
|
10
|
+
assert.doesNotMatch(yaml, /networks:/);
|
|
11
|
+
assert.doesNotMatch(yaml, /greenbump_network/);
|
|
12
|
+
});
|
|
13
|
+
test("generateComposeFile: unknown services produce an empty file", async () => {
|
|
14
|
+
assert.equal(await generateComposeFile(["nonsense-service"]), "");
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=template-generator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-generator.test.js","sourceRoot":"","sources":["../../../src/engine/sandbox/template-generator.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,IAAI,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;IAC9G,0EAA0E;IAC1E,2EAA2E;IAC3E,wDAAwD;IACxD,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IACrD,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACrC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACvC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;IAC7E,MAAM,CAAC,KAAK,CAAC,MAAM,mBAAmB,CAAC,CAAC,kBAAkB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACpE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFile, readdir, access, mkdtemp, rm } from "node:fs/promises";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { buildScanReport } from "./impact.js";
|
|
8
|
+
import { WORKSPACE_ROOT } from "../workspace.js";
|
|
9
|
+
import { resetCacheForTests } from "../cache/manager.js";
|
|
10
|
+
/**
|
|
11
|
+
* Cross-check: `--scan` must predict exactly the breakages the fix loop
|
|
12
|
+
* already knows how to fix.
|
|
13
|
+
*
|
|
14
|
+
* Each benchmark case under benchmarks/cases/ ships a real fixture repo plus
|
|
15
|
+
* an `expect.json` whose `forbiddenPatterns` describe the breakage present
|
|
16
|
+
* BEFORE the fix (and required absent after). If scan's deterministic
|
|
17
|
+
* prediction can't find those same patterns in the fixture, then either the
|
|
18
|
+
* codemod registry or the scan probe logic has drifted — the user would be
|
|
19
|
+
* told "no impact" for an upgrade greenbump would actually have to fix.
|
|
20
|
+
*/
|
|
21
|
+
const CASES_DIR = fileURLToPath(new URL("../../../benchmarks/cases", import.meta.url));
|
|
22
|
+
async function exists(p) {
|
|
23
|
+
try {
|
|
24
|
+
await access(p);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Every fixture that ships a case.json + expect.json with forbidden patterns. */
|
|
32
|
+
async function loadCases() {
|
|
33
|
+
const entries = await readdir(CASES_DIR, { withFileTypes: true });
|
|
34
|
+
const cases = [];
|
|
35
|
+
for (const e of entries) {
|
|
36
|
+
if (!e.isDirectory())
|
|
37
|
+
continue;
|
|
38
|
+
const dir = join(CASES_DIR, e.name, "repo");
|
|
39
|
+
if (!(await exists(dir)))
|
|
40
|
+
continue;
|
|
41
|
+
const meta = JSON.parse(await readFile(join(CASES_DIR, e.name, "case.json"), "utf8"));
|
|
42
|
+
const exp = JSON.parse(await readFile(join(CASES_DIR, e.name, "expect.json"), "utf8"));
|
|
43
|
+
if (!exp.forbiddenPatterns || exp.forbiddenPatterns.length === 0)
|
|
44
|
+
continue;
|
|
45
|
+
cases.push({ dir, meta, expect: exp });
|
|
46
|
+
}
|
|
47
|
+
return cases;
|
|
48
|
+
}
|
|
49
|
+
function asOutdated(meta) {
|
|
50
|
+
return {
|
|
51
|
+
name: meta.dep,
|
|
52
|
+
current: meta.from,
|
|
53
|
+
wanted: meta.from,
|
|
54
|
+
latest: meta.to,
|
|
55
|
+
workspacePath: WORKSPACE_ROOT,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Run `fn` with an empty, isolated cache dir so the codemod registry is the
|
|
60
|
+
* only possible source of scan results. Uses a real temp dir — pointing at a
|
|
61
|
+
* path under the repo would have the cache manager create it.
|
|
62
|
+
*/
|
|
63
|
+
async function withEmptyCache(fn) {
|
|
64
|
+
const cacheDir = await mkdtemp(join(tmpdir(), "greenbump-crosscheck-cache-"));
|
|
65
|
+
const prevCache = process.env.GREENBUMP_CACHE_DIR;
|
|
66
|
+
process.env.GREENBUMP_CACHE_DIR = cacheDir;
|
|
67
|
+
resetCacheForTests();
|
|
68
|
+
try {
|
|
69
|
+
await fn();
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
if (prevCache === undefined)
|
|
73
|
+
delete process.env.GREENBUMP_CACHE_DIR;
|
|
74
|
+
else
|
|
75
|
+
process.env.GREENBUMP_CACHE_DIR = prevCache;
|
|
76
|
+
resetCacheForTests();
|
|
77
|
+
await rm(cacheDir, { recursive: true, force: true });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
test("scan cross-check: finds the benchmark fixtures", async () => {
|
|
81
|
+
const cases = await loadCases();
|
|
82
|
+
assert.ok(cases.length >= 5, `expected at least 5 fixtures, found ${cases.length}`);
|
|
83
|
+
});
|
|
84
|
+
test("scan cross-check: every tier-1 fixture's breakage is predicted from codemods alone", async () => {
|
|
85
|
+
const cases = await loadCases();
|
|
86
|
+
const tier1 = cases.filter((c) => c.meta.expectedTier === 1);
|
|
87
|
+
assert.ok(tier1.length > 0, "expected at least one tier-1 fixture");
|
|
88
|
+
await withEmptyCache(async () => {
|
|
89
|
+
for (const { dir, meta, expect } of tier1) {
|
|
90
|
+
const report = await buildScanReport(dir, [asOutdated(meta)]);
|
|
91
|
+
const det = report.detections[0];
|
|
92
|
+
assert.equal(det.status, "ok", `${meta.name}: scan did not recognise this upgrade`);
|
|
93
|
+
assert.ok(det.locationsMatched >= 1, `${meta.name}: scan found no impact, but this fixture is a known tier-1 breakage`);
|
|
94
|
+
// At least one predicted location must actually carry the breakage the
|
|
95
|
+
// benchmark says is present in the fixture.
|
|
96
|
+
const excerpts = det.changes.flatMap((c) => c.fileGroups.flatMap((g) => g.locations.map((l) => l.excerpt)));
|
|
97
|
+
const hit = expect.forbiddenPatterns.some((re) => excerpts.some((line) => new RegExp(re).test(line)));
|
|
98
|
+
assert.ok(hit, `${meta.name}: none of the ${expect.forbiddenPatterns.join(", ")} patterns appeared in scan output:\n` +
|
|
99
|
+
excerpts.map((e) => ` ${e}`).join("\n"));
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
test("scan cross-check: without a cache, an uncovered upgrade is reported unknown rather than guessed", async () => {
|
|
104
|
+
// A dependency with no built-in codemod and no cached digest must not
|
|
105
|
+
// invent an impact result — it reports "unknown" and nothing else.
|
|
106
|
+
await withEmptyCache(async () => {
|
|
107
|
+
const dir = join(CASES_DIR, "zod-3-to-4-issues", "repo");
|
|
108
|
+
const report = await buildScanReport(dir, [
|
|
109
|
+
{ name: "some-unmapped-package", current: "1.0.0", wanted: "1.0.0", latest: "2.0.0", workspacePath: WORKSPACE_ROOT },
|
|
110
|
+
]);
|
|
111
|
+
assert.equal(report.detections[0].status, "unknown");
|
|
112
|
+
assert.deepEqual(report.detections[0].changes, []);
|
|
113
|
+
assert.equal(report.summary.depsWithKnownBreaking, 0);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
//# sourceMappingURL=benchmark-crosscheck.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmark-crosscheck.test.js","sourceRoot":"","sources":["../../../src/engine/scan/benchmark-crosscheck.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { readDigestFromCache } from "../analyzers/changelog-parser.js";
|
|
2
|
+
import { codemodsForUpgrade, probesFromCodemod, probesFromChange } from "./probes.js";
|
|
3
|
+
/**
|
|
4
|
+
* Generate detection metadata for a single outdated dependency.
|
|
5
|
+
*
|
|
6
|
+
* Collects probes from two sources:
|
|
7
|
+
* - Tier A: built-in codemods (zero IO, always available)
|
|
8
|
+
* - Tier B: changelog digest cache (read-only, no LLM calls)
|
|
9
|
+
*/
|
|
10
|
+
export async function detectForOutdated(cwd, o, noCache) {
|
|
11
|
+
const codemods = codemodsForUpgrade(o.name, o.current, o.latest);
|
|
12
|
+
const digest = noCache ? null : await readDigestFromCache(o.name, o.current, o.latest);
|
|
13
|
+
const probes = [];
|
|
14
|
+
const changesMetadata = [];
|
|
15
|
+
const fileCreations = [];
|
|
16
|
+
let changeIndex = 0;
|
|
17
|
+
// Tier A: codemods
|
|
18
|
+
for (const codemod of codemods) {
|
|
19
|
+
if (codemod.transform) {
|
|
20
|
+
const codemodProbes = probesFromCodemod(codemod, o.name, changeIndex);
|
|
21
|
+
probes.push(...codemodProbes);
|
|
22
|
+
changesMetadata.push({
|
|
23
|
+
description: codemod.description,
|
|
24
|
+
oldApi: codemod.transform.find,
|
|
25
|
+
newApi: codemod.transform.replace,
|
|
26
|
+
severity: "high", // codemods are known breakages
|
|
27
|
+
source: "builtin-codemod",
|
|
28
|
+
rewrite: codemod.transform.replace,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (codemod.creates) {
|
|
32
|
+
for (const create of codemod.creates) {
|
|
33
|
+
fileCreations.push({
|
|
34
|
+
path: create.path,
|
|
35
|
+
note: `will be created by codemod: ${codemod.description}`,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (!codemod.transform && !codemod.creates) {
|
|
40
|
+
// Guidance-only codemod
|
|
41
|
+
changesMetadata.push({
|
|
42
|
+
description: codemod.description,
|
|
43
|
+
oldApi: "",
|
|
44
|
+
severity: "medium",
|
|
45
|
+
source: "builtin-codemod",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
changeIndex++;
|
|
49
|
+
}
|
|
50
|
+
// Tier B: changelog digest
|
|
51
|
+
if (digest && digest.length > 0) {
|
|
52
|
+
for (const change of digest) {
|
|
53
|
+
const changeProbes = probesFromChange(change, o.name, changeIndex);
|
|
54
|
+
probes.push(...changeProbes);
|
|
55
|
+
changesMetadata.push({
|
|
56
|
+
description: change.description,
|
|
57
|
+
oldApi: change.oldApi,
|
|
58
|
+
newApi: change.newApi,
|
|
59
|
+
severity: change.severity,
|
|
60
|
+
source: "changelog-cache",
|
|
61
|
+
});
|
|
62
|
+
changeIndex++;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Determine status
|
|
66
|
+
let status;
|
|
67
|
+
let kind;
|
|
68
|
+
if (codemods.length > 0 && digest && digest.length > 0) {
|
|
69
|
+
kind = "both";
|
|
70
|
+
status = "ok";
|
|
71
|
+
}
|
|
72
|
+
else if (codemods.length > 0) {
|
|
73
|
+
kind = "codemod";
|
|
74
|
+
status = codemods.some((c) => c.transform || c.creates) ? "ok" : "info-only";
|
|
75
|
+
}
|
|
76
|
+
else if (digest && digest.length > 0) {
|
|
77
|
+
kind = "digest";
|
|
78
|
+
status = "ok";
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
kind = "codemod";
|
|
82
|
+
status = "unknown";
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
name: o.name,
|
|
86
|
+
current: o.current,
|
|
87
|
+
latest: o.latest,
|
|
88
|
+
workspacePath: o.workspacePath,
|
|
89
|
+
kind,
|
|
90
|
+
status,
|
|
91
|
+
probes,
|
|
92
|
+
changesMetadata,
|
|
93
|
+
fileCreations,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../src/engine/scan/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { detectForOutdated } from "./detect.js";
|
|
2
|
+
import { scanOnce } from "./indexer.js";
|
|
3
|
+
export async function buildScanReport(cwd, outdated, opts = {}) {
|
|
4
|
+
const maxPerChange = opts.maxPerChange ?? 200;
|
|
5
|
+
// Phase 1: collect detections (probes) for all outdated deps
|
|
6
|
+
const pendingDetections = await Promise.all(outdated.map((o) => detectForOutdated(cwd, o, opts.noCache ?? false)));
|
|
7
|
+
// Phase 2: collect all probes
|
|
8
|
+
const allProbes = [];
|
|
9
|
+
for (const detection of pendingDetections) {
|
|
10
|
+
allProbes.push(...detection.probes);
|
|
11
|
+
}
|
|
12
|
+
// Phase 3: single-pass scan
|
|
13
|
+
const { hits, truncatedProbes } = await scanOnce(cwd, allProbes, { perProbeCap: maxPerChange });
|
|
14
|
+
// Phase 4: assemble report
|
|
15
|
+
const detections = pendingDetections.map((pending) => {
|
|
16
|
+
// Group hits by change index
|
|
17
|
+
const changeHits = new Map();
|
|
18
|
+
for (const hit of hits) {
|
|
19
|
+
const probe = pending.probes.find((p) => p.key === hit.probeKey);
|
|
20
|
+
if (!probe)
|
|
21
|
+
continue;
|
|
22
|
+
const changeIndex = probe.refs[0]?.changeIndex;
|
|
23
|
+
if (changeIndex === undefined)
|
|
24
|
+
continue;
|
|
25
|
+
if (!changeHits.has(changeIndex)) {
|
|
26
|
+
changeHits.set(changeIndex, []);
|
|
27
|
+
}
|
|
28
|
+
changeHits.get(changeIndex).push(hit);
|
|
29
|
+
}
|
|
30
|
+
// Build BreakingChangeImpact for each change
|
|
31
|
+
const changes = pending.changesMetadata.map((meta, idx) => {
|
|
32
|
+
const changeHitsList = changeHits.get(idx) ?? [];
|
|
33
|
+
const truncated = pending.probes
|
|
34
|
+
.filter((p) => p.refs[0]?.changeIndex === idx)
|
|
35
|
+
.some((p) => truncatedProbes.has(p.key));
|
|
36
|
+
// Group by file
|
|
37
|
+
const fileMap = new Map();
|
|
38
|
+
for (const hit of changeHitsList) {
|
|
39
|
+
if (!fileMap.has(hit.file)) {
|
|
40
|
+
fileMap.set(hit.file, []);
|
|
41
|
+
}
|
|
42
|
+
fileMap.get(hit.file).push(hit);
|
|
43
|
+
}
|
|
44
|
+
const fileGroups = Array.from(fileMap.entries()).map(([file, locations]) => ({
|
|
45
|
+
file,
|
|
46
|
+
locations: locations.map((l) => ({ file: l.file, line: l.line, excerpt: l.excerpt })),
|
|
47
|
+
shown: Math.min(locations.length, 20),
|
|
48
|
+
totalInFile: locations.length,
|
|
49
|
+
}));
|
|
50
|
+
const approx = pending.probes
|
|
51
|
+
.filter((p) => p.refs[0]?.changeIndex === idx)
|
|
52
|
+
.some((p) => p.approx);
|
|
53
|
+
return {
|
|
54
|
+
description: meta.description,
|
|
55
|
+
oldApi: meta.oldApi,
|
|
56
|
+
newApi: meta.newApi,
|
|
57
|
+
severity: meta.severity,
|
|
58
|
+
source: meta.source,
|
|
59
|
+
rewrite: meta.rewrite,
|
|
60
|
+
fileGroups,
|
|
61
|
+
truncated,
|
|
62
|
+
matches: changeHitsList.length,
|
|
63
|
+
...(approx ? { approx: true } : {}),
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
// Calculate detection-level stats
|
|
67
|
+
const allFiles = new Set();
|
|
68
|
+
let totalLocations = 0;
|
|
69
|
+
for (const change of changes) {
|
|
70
|
+
for (const fg of change.fileGroups) {
|
|
71
|
+
allFiles.add(fg.file);
|
|
72
|
+
totalLocations += fg.totalInFile;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const hasApprox = changes.some((c) => c.approx);
|
|
76
|
+
const status = pending.status === "unknown" || pending.status === "info-only"
|
|
77
|
+
? pending.status
|
|
78
|
+
: hasApprox
|
|
79
|
+
? "approx"
|
|
80
|
+
: "ok";
|
|
81
|
+
return {
|
|
82
|
+
name: pending.name,
|
|
83
|
+
current: pending.current,
|
|
84
|
+
latest: pending.latest,
|
|
85
|
+
workspacePath: pending.workspacePath,
|
|
86
|
+
kind: pending.kind,
|
|
87
|
+
status,
|
|
88
|
+
changes,
|
|
89
|
+
...(pending.fileCreations.length > 0 ? { fileCreations: pending.fileCreations } : {}),
|
|
90
|
+
filesMatched: allFiles.size,
|
|
91
|
+
locationsMatched: totalLocations,
|
|
92
|
+
displayedImpact: changes.length > 0 && totalLocations > 0,
|
|
93
|
+
truncated: pending.probes.some((p) => truncatedProbes.has(p.key)),
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
// Summary stats
|
|
97
|
+
const allAffectedFiles = new Set();
|
|
98
|
+
let totalLocationsAffected = 0;
|
|
99
|
+
let depsWithKnownBreaking = 0;
|
|
100
|
+
let anyTruncated = false;
|
|
101
|
+
for (const d of detections) {
|
|
102
|
+
if (d.status === "ok" || d.status === "approx") {
|
|
103
|
+
depsWithKnownBreaking++;
|
|
104
|
+
for (const change of d.changes) {
|
|
105
|
+
for (const fg of change.fileGroups) {
|
|
106
|
+
allAffectedFiles.add(fg.file);
|
|
107
|
+
totalLocationsAffected += fg.totalInFile;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (d.truncated)
|
|
112
|
+
anyTruncated = true;
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
schemaVersion: 1,
|
|
116
|
+
cwd,
|
|
117
|
+
packageManager: "", // filled by caller
|
|
118
|
+
summary: {
|
|
119
|
+
depsScanned: outdated.length,
|
|
120
|
+
depsWithKnownBreaking,
|
|
121
|
+
filesAffected: allAffectedFiles.size,
|
|
122
|
+
locationsAffected: totalLocationsAffected,
|
|
123
|
+
truncated: anyTruncated,
|
|
124
|
+
},
|
|
125
|
+
detections,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=impact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact.js","sourceRoot":"","sources":["../../../src/engine/scan/impact.ts"],"names":[],"mappings":"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"}
|