initial
This commit is contained in:
89
ts/mod_cargo/classes.cargoconfig.ts
Normal file
89
ts/mod_cargo/classes.cargoconfig.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as smolToml from 'smol-toml';
|
||||
import { FsHelpers } from '../mod_fs/index.js';
|
||||
|
||||
export interface ICargoWorkspaceInfo {
|
||||
isWorkspace: boolean;
|
||||
rustDir: string;
|
||||
binTargets: string[];
|
||||
}
|
||||
|
||||
export class CargoConfig {
|
||||
private rustDir: string;
|
||||
|
||||
constructor(rustDir: string) {
|
||||
this.rustDir = rustDir;
|
||||
}
|
||||
|
||||
public async parse(): Promise<ICargoWorkspaceInfo> {
|
||||
const cargoTomlPath = path.join(this.rustDir, 'Cargo.toml');
|
||||
const content = await fs.promises.readFile(cargoTomlPath, 'utf-8');
|
||||
const parsed = smolToml.parse(content);
|
||||
|
||||
const isWorkspace = !!(parsed as any).workspace;
|
||||
let binTargets: string[] = [];
|
||||
|
||||
if (isWorkspace) {
|
||||
binTargets = await this.collectWorkspaceBinTargets(parsed);
|
||||
} else {
|
||||
binTargets = this.collectCrateBinTargets(parsed, this.rustDir);
|
||||
}
|
||||
|
||||
return {
|
||||
isWorkspace,
|
||||
rustDir: this.rustDir,
|
||||
binTargets,
|
||||
};
|
||||
}
|
||||
|
||||
private async collectWorkspaceBinTargets(parsed: any): Promise<string[]> {
|
||||
const members: string[] = parsed.workspace?.members || [];
|
||||
const binTargets: string[] = [];
|
||||
|
||||
for (const member of members) {
|
||||
const memberDir = path.join(this.rustDir, member);
|
||||
const memberCargoToml = path.join(memberDir, 'Cargo.toml');
|
||||
|
||||
if (!(await FsHelpers.fileExists(memberCargoToml))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const memberContent = await fs.promises.readFile(memberCargoToml, 'utf-8');
|
||||
const memberParsed = smolToml.parse(memberContent);
|
||||
const memberBins = this.collectCrateBinTargets(memberParsed, memberDir);
|
||||
binTargets.push(...memberBins);
|
||||
}
|
||||
|
||||
return binTargets;
|
||||
}
|
||||
|
||||
private collectCrateBinTargets(parsed: any, crateDir: string): string[] {
|
||||
const binTargets: string[] = [];
|
||||
|
||||
// Check for explicit [[bin]] entries
|
||||
if (Array.isArray(parsed.bin)) {
|
||||
for (const bin of parsed.bin) {
|
||||
if (bin.name) {
|
||||
binTargets.push(bin.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no [[bin]] but package has a name and src/main.rs exists, use package name
|
||||
if (binTargets.length === 0 && parsed.package?.name) {
|
||||
const mainRsPath = path.join(crateDir, 'src', 'main.rs');
|
||||
// Use sync check since this is called during parsing
|
||||
try {
|
||||
const stat = fs.statSync(mainRsPath);
|
||||
if (stat.isFile()) {
|
||||
binTargets.push(parsed.package.name);
|
||||
}
|
||||
} catch {
|
||||
// No main.rs, not a binary crate
|
||||
}
|
||||
}
|
||||
|
||||
return binTargets;
|
||||
}
|
||||
}
|
||||
59
ts/mod_cargo/classes.cargorunner.ts
Normal file
59
ts/mod_cargo/classes.cargorunner.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
export interface ICargoRunResult {
|
||||
success: boolean;
|
||||
exitCode: number;
|
||||
stdout: string;
|
||||
}
|
||||
|
||||
export class CargoRunner {
|
||||
private shell: plugins.smartshell.Smartshell;
|
||||
private rustDir: string;
|
||||
|
||||
constructor(rustDir: string) {
|
||||
this.rustDir = rustDir;
|
||||
this.shell = new plugins.smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
});
|
||||
}
|
||||
|
||||
public async checkCargoInstalled(): Promise<boolean> {
|
||||
const result = await this.shell.execSilent('cargo --version');
|
||||
return result.exitCode === 0;
|
||||
}
|
||||
|
||||
public async getCargoVersion(): Promise<string> {
|
||||
const result = await this.shell.execSilent('cargo --version');
|
||||
return result.stdout.trim();
|
||||
}
|
||||
|
||||
public async build(options: { debug?: boolean; clean?: boolean } = {}): Promise<ICargoRunResult> {
|
||||
if (options.clean) {
|
||||
console.log('Cleaning previous build...');
|
||||
await this.clean();
|
||||
}
|
||||
|
||||
const profile = options.debug ? '' : ' --release';
|
||||
const command = `cd ${this.rustDir} && cargo build${profile}`;
|
||||
|
||||
console.log(`Running: cargo build${profile}`);
|
||||
const result = await this.shell.exec(command);
|
||||
|
||||
return {
|
||||
success: result.exitCode === 0,
|
||||
exitCode: result.exitCode,
|
||||
stdout: result.stdout,
|
||||
};
|
||||
}
|
||||
|
||||
public async clean(): Promise<ICargoRunResult> {
|
||||
const command = `cd ${this.rustDir} && cargo clean`;
|
||||
const result = await this.shell.exec(command);
|
||||
|
||||
return {
|
||||
success: result.exitCode === 0,
|
||||
exitCode: result.exitCode,
|
||||
stdout: result.stdout,
|
||||
};
|
||||
}
|
||||
}
|
||||
2
ts/mod_cargo/index.ts
Normal file
2
ts/mod_cargo/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { CargoConfig } from './classes.cargoconfig.js';
|
||||
export { CargoRunner } from './classes.cargorunner.js';
|
||||
Reference in New Issue
Block a user