Skip to content

Commit c34e813

Browse files
authored
fix(cli): reuse warm index for graph queries (#189)
* fix(cli): reuse warm index for graph queries * chore: synchronize npm lockfile * fix(cli): reuse warm index for graph summaries * fix(cli): reuse warm index for duplicates
1 parent 60dd0e1 commit c34e813

6 files changed

Lines changed: 62 additions & 42 deletions

File tree

package-lock.json

Lines changed: 26 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli.ts

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,19 +1043,15 @@ async function runCliWithActiveRuntime(rawArgs: string[]) {
10431043

10441044
if (cmd === "duplicates") {
10451045
const files = await resolveFiles();
1046+
const duplicateIndexOptions = buildAgentOptions();
1047+
duplicateIndexOptions.cache ??= "disk";
10461048
const { handleDuplicatesCommand } = await import("./cli/duplicates.js");
10471049
await handleDuplicatesCommand({
10481050
projectRootFs,
10491051
files,
10501052
getOpt,
10511053
hasFlag,
1052-
indexOptions: {
1053-
onProgress: progressHandler,
1054-
discovery: discoveryOptions,
1055-
...(hasGraphOverrides ? { graph: buildGraphOptions() } : {}),
1056-
...(nativeMode !== "auto" ? { native: nativeMode } : {}),
1057-
...workerOpts,
1058-
},
1054+
indexOptions: duplicateIndexOptions,
10591055
writeJSONLine,
10601056
writeStdoutLine,
10611057
writeStderrLine,
@@ -1190,13 +1186,12 @@ async function runCliWithActiveRuntime(rawArgs: string[]) {
11901186
return;
11911187
}
11921188

1193-
const buildGraphQueryIndexOptions = (graphOptions: GraphBuildOptions | undefined): BuildOptions => ({
1194-
onProgress: progressHandler,
1195-
discovery: discoveryOptions,
1196-
...(graphOptions ? { graph: graphOptions } : {}),
1197-
...(nativeMode !== "auto" ? { native: nativeMode } : {}),
1198-
...workerOpts,
1199-
});
1189+
const buildGraphQueryIndexOptions = (graphOptions: GraphBuildOptions | undefined): BuildOptions => {
1190+
const options = buildAgentOptions();
1191+
options.cache ??= "disk";
1192+
if (graphOptions) options.graph = graphOptions;
1193+
return options;
1194+
};
12001195

12011196
if (cmd === "deps" || cmd === "rdeps") {
12021197
const graphOptions = hasGraphOverrides || nativeMode !== "auto" ? buildGraphOptions() : undefined;
@@ -1222,7 +1217,8 @@ async function runCliWithActiveRuntime(rawArgs: string[]) {
12221217
if (cmd === "path" || cmd === "cycles" || cmd === "unresolved") {
12231218
const graphOptions = hasGraphOverrides || nativeMode !== "auto" ? buildGraphOptions() : undefined;
12241219
const { handleGraphQueryCommand } = await import("./cli/graphQueries.js");
1225-
const collectGraph = cmd === "cycles" ? (await import("./graph-builder.js")).collectGraph : undefined;
1220+
const collectGraph =
1221+
cmd === "cycles" && includeRootsAbs.length ? (await import("./graph-builder.js")).collectGraph : undefined;
12261222
await handleGraphQueryCommand({
12271223
command: cmd,
12281224
positionals: parsed.positionals,
@@ -1299,12 +1295,7 @@ async function runCliWithActiveRuntime(rawArgs: string[]) {
12991295
writeStderrLine,
13001296
exit: exitCli,
13011297
listProjectFilesForScan: async () => await listProjectFilesForScan(projectRootFs),
1302-
indexOptions: {
1303-
onProgress: progressHandler,
1304-
discovery: discoveryOptions,
1305-
...(nativeMode !== "auto" ? { native: nativeMode } : {}),
1306-
...workerOpts,
1307-
},
1298+
indexOptions: buildGraphQueryIndexOptions(undefined),
13081299
});
13091300
return;
13101301
}

src/cli/duplicates.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { buildProjectIndexFromFiles } from "../indexer/build-index.js";
1+
import { buildProjectIndexIncremental } from "../indexer/build-index.js";
22
import {
33
findDuplicates,
44
type DuplicateCleanupLabel,
@@ -441,7 +441,11 @@ export async function handleDuplicatesCommand(context: DuplicatesCommandContext)
441441
options.limit = boundedLimit;
442442
}
443443

444-
const index = await buildProjectIndexFromFiles(context.projectRootFs, context.files, context.indexOptions);
444+
const index = await buildProjectIndexIncremental(context.projectRootFs, {
445+
...context.indexOptions,
446+
files: context.files,
447+
filesAreProjectScope: true,
448+
});
445449
const result = await findDuplicates(index, options);
446450
const sorted = sortedResult(result, sortMode, requestedLimit, profile);
447451
if (!renderPretty) {

src/cli/graphQueries.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { buildProjectIndex as defaultBuildProjectIndex } from "../indexer/build-index.js";
1+
import { buildProjectIndexIncremental as defaultBuildProjectIndex } from "../indexer/build-index.js";
22
import { getApiSurface } from "../indexer/symbols.js";
33
import { type BuildOptions, type ProjectIndex } from "../indexer/types.js";
44
import type { GraphAdjacencyIndex } from "../graphs/adjacency.js";

tests/cli-command-modules.test.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,21 +1503,30 @@ describe("CLI command modules", () => {
15031503

15041504
try {
15051505
const deps = await captureCli(["deps", "main.ts", "--root", tempDir, "--json"]);
1506+
const warmDeps = await captureCli(["deps", "main.ts", "--root", tempDir, "--json", "--progress"]);
15061507
const rdeps = await captureCli(["rdeps", "util.ts", "--root", tempDir]);
15071508
const graphPath = await captureCli(["path", "main.ts", "util.ts", "--root", tempDir]);
1508-
const cycles = await captureCli(["cycles", "--root", tempDir]);
1509+
const cycles = await captureCli(["cycles", "--root", tempDir, "--progress"]);
15091510
const unresolved = await captureCli(["unresolved", "--root", tempDir, "--verbose"]);
1510-
const apiSurface = await captureCli(["apisurface", "--root", tempDir]);
1511+
const apiSurface = await captureCli(["apisurface", "--root", tempDir, "--progress"]);
15111512

15121513
expect(JSON.stringify(JSON.parse(deps.stdout))).toContain("util.ts");
1514+
expect(warmDeps.stderr).toContain("Checking project index");
1515+
expect(warmDeps.stderr).toContain("Checked project index");
1516+
expect(warmDeps.stderr).not.toContain("Building project index");
1517+
expect(warmDeps.stderr).not.toContain("files processed");
15131518
expect(rdeps.stdout).toContain("Reverse dependencies for util.ts:");
15141519
expect(graphPath.stdout).toContain("main.ts");
15151520
expect(graphPath.stdout).toContain("util.ts");
15161521
expect(cycles.stdout).toContain("No dependency cycles found.");
1522+
expect(cycles.stderr).toContain("Checked project index");
1523+
expect(cycles.stderr).not.toContain("Building project index");
15171524
expect(unresolved.stdout).toContain("missing-pkg");
15181525
expect(unresolved.stdout).toContain('as "missing-pkg"');
15191526
expect(apiSurface.stdout).toContain("API Surface");
15201527
expect(apiSurface.stdout).toContain("run");
1528+
expect(apiSurface.stderr).toContain("Checked project index");
1529+
expect(apiSurface.stderr).not.toContain("Building project index");
15211530
} finally {
15221531
await fsp.rm(tempDir, { recursive: true, force: true });
15231532
}

tests/duplicates.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,10 @@ export function formatUsage(value: string) {
13641364
const result = await captureCli(["duplicates", "--root", ".", "src/app/[slug]", "--json", "--include-small"], {
13651365
cwd: root,
13661366
});
1367+
const warmResult = await captureCli(
1368+
["duplicates", "--root", ".", "src/app/[slug]", "--json", "--include-small", "--progress"],
1369+
{ cwd: root },
1370+
);
13671371
const parsed = JSON.parse(result.stdout) as {
13681372
groups?: Array<{ primaryLeft?: { file?: string }; primaryRight?: { file?: string } }>;
13691373
};
@@ -1372,6 +1376,8 @@ export function formatUsage(value: string) {
13721376
expect(parsed.groups?.length).toBeGreaterThan(0);
13731377
expect(parsed.groups?.[0]?.primaryLeft?.file?.startsWith("src/app/[slug]/")).toBeTruthy();
13741378
expect(parsed.groups?.[0]?.primaryRight?.file?.startsWith("src/app/[slug]/")).toBeTruthy();
1379+
expect(warmResult.stderr).toContain("Checked project index");
1380+
expect(warmResult.stderr).not.toContain("Building project index");
13751381
});
13761382

13771383
test("duplicates CLI cleanup profile defaults to reduced-lines and summary output", async () => {

0 commit comments

Comments
 (0)