Skip to content

Commit 1337b02

Browse files
committed
test(project): inject a no-op tool check so tests don't depend on host PATH
CI runners don't have uv installed; FsProjectManager's requireTool calls ran against the real PATH even with the fake command runner. checkTool is now injectable alongside runner, defaulting to the real requireTool.
1 parent 58dd1fc commit 1337b02

3 files changed

Lines changed: 9 additions & 3 deletions

File tree

src/core/project/manager.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ function manager(): { manager: FsProjectManager; commands: { command: string[];
3535
runner: async (command, { cwd }) => {
3636
commands.push({ command, cwd });
3737
},
38+
checkTool: () => {}, // CI hosts don't have uv installed
3839
}),
3940
commands,
4041
};
@@ -149,6 +150,7 @@ describe("FsProjectManager.create", () => {
149150
runner: async () => {
150151
throw new Error("npm exploded");
151152
},
153+
checkTool: () => {},
152154
});
153155

154156
await expect(

src/core/project/manager.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type ProjectManagerConfig = {
1717
logger: Logger;
1818
source?: AssetSource; // Bun executable or dist/assets depending on runtime
1919
runner?: CommandRunner; // injectable so tests never spawn real processes
20+
checkTool?: typeof requireTool; // injectable so tests don't depend on the host's PATH
2021
};
2122

2223
/**
@@ -26,11 +27,13 @@ export class FsProjectManager implements ProjectManager {
2627
private readonly logger: Logger;
2728
private readonly source: AssetSource;
2829
private readonly runner: CommandRunner;
30+
private readonly checkTool: typeof requireTool;
2931

3032
constructor(config: ProjectManagerConfig) {
3133
this.logger = config.logger;
3234
this.source = config.source ?? defaultSource();
3335
this.runner = config.runner ?? runCommand;
36+
this.checkTool = config.checkTool ?? requireTool;
3437
}
3538

3639
public resolve(_input: ResolveProjectInput): Promise<Project> {
@@ -49,20 +52,20 @@ export class FsProjectManager implements ProjectManager {
4952
// A failed step leaves the scaffolded files in place; the error tells the
5053
// user how to rerun the step by hand.
5154
if (!input.skipInstall) {
52-
requireTool("npm", "Install Node.js: https://nodejs.org/");
55+
this.checkTool("npm", "Install Node.js: https://nodejs.org/");
5356
input.onProgress?.("Installing CDK dependencies (npm install)...");
5457
await this.run(["npm", "install"], join(destination, "agentcore", "cdk"));
5558

5659
const appDir = join(destination, "app", TEMPLATES[input.template].appDir);
5760
if (existsSync(join(appDir, "pyproject.toml"))) {
58-
requireTool("uv", "Install uv: https://docs.astral.sh/uv/getting-started/installation/");
61+
this.checkTool("uv", "Install uv: https://docs.astral.sh/uv/getting-started/installation/");
5962
input.onProgress?.("Syncing Python dependencies (uv sync)...");
6063
await this.run(["uv", "sync"], appDir);
6164
}
6265
}
6366

6467
if (!input.skipGit) {
65-
requireTool("git", "Install git: https://git-scm.com/downloads");
68+
this.checkTool("git", "Install git: https://git-scm.com/downloads");
6669
input.onProgress?.("Initializing git repository...");
6770
await this.run(["git", "init"], destination);
6871
}

src/testing/TestCoreClient.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,7 @@ export class TestCoreClient implements Core {
808808
runner: async (command, { cwd }) => {
809809
this.projectCommands.push({ command, cwd });
810810
},
811+
checkTool: () => {}, // CI hosts don't have uv installed
811812
});
812813
}
813814
}

0 commit comments

Comments
 (0)