initial
This commit is contained in:
146
ts/mod_cli/classes.tsrustcli.ts
Normal file
146
ts/mod_cli/classes.tsrustcli.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import * as path from 'path';
|
||||
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';
|
||||
|
||||
export class TsRustCli {
|
||||
private cli: plugins.smartcli.Smartcli;
|
||||
private cwd: string;
|
||||
|
||||
constructor(cwd: string = process.cwd()) {
|
||||
this.cwd = cwd;
|
||||
this.cli = new plugins.smartcli.Smartcli();
|
||||
this.registerCommands();
|
||||
}
|
||||
|
||||
private registerCommands(): void {
|
||||
this.registerStandardCommand();
|
||||
this.registerCleanCommand();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
const cargoVersion = await runner.getCargoVersion();
|
||||
console.log(`Using ${cargoVersion}`);
|
||||
|
||||
// Detect rust directory
|
||||
const rustDir = await this.detectRustDir();
|
||||
if (!rustDir) {
|
||||
console.error('Error: No rust/ or ts_rust/ directory found with a Cargo.toml.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Found Rust project at: ${path.relative(this.cwd, rustDir) || '.'}`);
|
||||
|
||||
// Parse Cargo.toml
|
||||
const cargoConfig = new CargoConfig(rustDir);
|
||||
const workspaceInfo = await cargoConfig.parse();
|
||||
|
||||
if (workspaceInfo.isWorkspace) {
|
||||
console.log('Detected Cargo workspace');
|
||||
}
|
||||
|
||||
if (workspaceInfo.binTargets.length === 0) {
|
||||
console.error('Error: No binary targets found in Cargo.toml.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Binary targets: ${workspaceInfo.binTargets.join(', ')}`);
|
||||
|
||||
// Build
|
||||
const isDebug = !!(argvArg as any).debug;
|
||||
const shouldClean = !!(argvArg as any).clean;
|
||||
const cargoRunner = new CargoRunner(rustDir);
|
||||
const buildResult = await cargoRunner.build({ debug: isDebug, clean: shouldClean });
|
||||
|
||||
if (!buildResult.success) {
|
||||
console.error(`Build failed with exit code ${buildResult.exitCode}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Copy binaries to dist_rust/
|
||||
const profile = isDebug ? 'debug' : 'release';
|
||||
const targetDir = path.join(rustDir, 'target', profile);
|
||||
const distDir = path.join(this.cwd, 'dist_rust');
|
||||
|
||||
await FsHelpers.ensureEmptyDir(distDir);
|
||||
|
||||
for (const binName of workspaceInfo.binTargets) {
|
||||
const srcBinary = path.join(targetDir, binName);
|
||||
const destBinary = path.join(distDir, binName);
|
||||
|
||||
if (!(await FsHelpers.fileExists(srcBinary))) {
|
||||
console.warn(`Warning: Expected binary not found: ${srcBinary}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
await FsHelpers.copyFile(srcBinary, destBinary);
|
||||
await FsHelpers.makeExecutable(destBinary);
|
||||
|
||||
const size = await FsHelpers.getFileSize(destBinary);
|
||||
console.log(`Copied ${binName} (${FsHelpers.formatFileSize(size)}) -> dist_rust/${binName}`);
|
||||
}
|
||||
|
||||
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
||||
console.log(`Done in ${elapsed}s`);
|
||||
});
|
||||
}
|
||||
|
||||
private registerCleanCommand(): void {
|
||||
this.cli.addCommand('clean').subscribe(async (_argvArg) => {
|
||||
// Clean cargo build
|
||||
const rustDir = await this.detectRustDir();
|
||||
if (rustDir) {
|
||||
console.log('Running cargo clean...');
|
||||
const runner = new CargoRunner(rustDir);
|
||||
await runner.clean();
|
||||
console.log('Cargo clean complete.');
|
||||
}
|
||||
|
||||
// Remove dist_rust/
|
||||
const distDir = path.join(this.cwd, 'dist_rust');
|
||||
if (await FsHelpers.directoryExists(distDir)) {
|
||||
await FsHelpers.removeDirectory(distDir);
|
||||
console.log('Removed dist_rust/');
|
||||
}
|
||||
|
||||
console.log('Clean complete.');
|
||||
});
|
||||
}
|
||||
|
||||
private async detectRustDir(): Promise<string | null> {
|
||||
// Check rust/ first
|
||||
const rustDir = path.join(this.cwd, 'rust');
|
||||
if (await FsHelpers.fileExists(path.join(rustDir, 'Cargo.toml'))) {
|
||||
return rustDir;
|
||||
}
|
||||
|
||||
// Fallback to ts_rust/
|
||||
const tsRustDir = path.join(this.cwd, 'ts_rust');
|
||||
if (await FsHelpers.fileExists(path.join(tsRustDir, 'Cargo.toml'))) {
|
||||
return tsRustDir;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public run(): void {
|
||||
this.cli.startParse();
|
||||
}
|
||||
}
|
||||
|
||||
export const runCli = async (): Promise<void> => {
|
||||
const cli = new TsRustCli();
|
||||
cli.run();
|
||||
};
|
||||
Reference in New Issue
Block a user