This commit is contained in:
2026-02-09 09:32:20 +00:00
commit f23ced9c47
22 changed files with 9064 additions and 0 deletions

View 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;
}
}