feat(toolchain): add automatic bundled Rust toolchain fallback and integrate with CLI/CargoRunner

This commit is contained in:
2026-02-09 20:57:52 +00:00
parent 18dc4c3a79
commit 85273e2933
10 changed files with 218 additions and 43 deletions

View File

@@ -3,6 +3,7 @@ import * as plugins from '../plugins.js';
import { CargoConfig } from '../mod_cargo/index.js';
import { CargoRunner } from '../mod_cargo/index.js';
import { FsHelpers } from '../mod_fs/index.js';
import { ToolchainManager } from '../mod_toolchain/index.js';
/** Maps friendly target names to Rust target triples */
const targetAliasMap: Record<string, string> = {
@@ -62,18 +63,33 @@ export class TsRustCli {
this.registerCleanCommand();
}
/**
* Resolves the Rust toolchain to use. Tries system cargo first,
* then falls back to a bundled toolchain at /tmp/tsrust_toolchain/.
* Returns the envPrefix string to prepend to shell commands.
*/
private async resolveToolchain(): Promise<string> {
// 1. Try system cargo
const systemRunner = new CargoRunner(this.cwd);
if (await systemRunner.checkCargoInstalled()) {
return ''; // system toolchain, no prefix needed
}
// 2. Fall back to bundled toolchain
console.log('System cargo not found. Checking for bundled toolchain...');
const toolchain = new ToolchainManager();
await toolchain.ensureInstalled();
return toolchain.getEnvPrefix();
}
private registerStandardCommand(): void {
this.cli.standardCommand().subscribe(async (argvArg) => {
const startTime = Date.now();
// Check cargo is installed
const runner = new CargoRunner(this.cwd); // temporary, just for version check
if (!(await runner.checkCargoInstalled())) {
console.error('Error: cargo is not installed or not in PATH.');
console.error('Install Rust via https://rustup.rs/');
process.exit(1);
}
// Resolve toolchain (system or bundled fallback)
const envPrefix = await this.resolveToolchain();
const runner = new CargoRunner(this.cwd, envPrefix);
const cargoVersion = await runner.getCargoVersion();
console.log(`Using ${cargoVersion}`);
@@ -125,7 +141,7 @@ export class TsRustCli {
for (const { triple, friendly } of resolvedTargets) {
console.log(`\n--- Building for ${friendly} (${triple}) ---`);
const cargoRunner = new CargoRunner(rustDir);
const cargoRunner = new CargoRunner(rustDir, envPrefix);
const buildResult = await cargoRunner.build({ debug: isDebug, clean: shouldClean, target: triple });
if (!buildResult.success) {
@@ -159,8 +175,8 @@ export class TsRustCli {
}
}
} else {
// Native build (unchanged behavior)
const cargoRunner = new CargoRunner(rustDir);
// Native build
const cargoRunner = new CargoRunner(rustDir, envPrefix);
const buildResult = await cargoRunner.build({ debug: isDebug, clean: shouldClean });
if (!buildResult.success) {
@@ -199,8 +215,9 @@ export class TsRustCli {
// Clean cargo build
const rustDir = await this.detectRustDir();
if (rustDir) {
const envPrefix = await this.resolveToolchain();
console.log('Running cargo clean...');
const runner = new CargoRunner(rustDir);
const runner = new CargoRunner(rustDir, envPrefix);
await runner.clean();
console.log('Cargo clean complete.');
}