Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'editors/code/src/toolchain.ts')
-rw-r--r--editors/code/src/toolchain.ts99
1 files changed, 99 insertions, 0 deletions
diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts
index 771f6bcba4..6b40cb678c 100644
--- a/editors/code/src/toolchain.ts
+++ b/editors/code/src/toolchain.ts
@@ -98,6 +98,43 @@ export class Cargo {
return artifacts[0].fileName;
}
+ async crates(): Promise<Crate[]> {
+ const pathToCargo = await cargoPath();
+ return await new Promise((resolve, reject) => {
+ const crates: Crate[] = [];
+
+ const cargo = cp.spawn(pathToCargo, ['tree', '--prefix', 'none'], {
+ stdio: ['ignore', 'pipe', 'pipe'],
+ cwd: this.rootFolder
+ });
+ const rl = readline.createInterface({ input: cargo.stdout });
+ rl.on('line', line => {
+ const match = line.match(TREE_LINE_PATTERN);
+ if (match) {
+ const name = match[1];
+ const version = match[2];
+ const extraInfo = match[3];
+ // ignore duplicates '(*)' and path dependencies
+ if (this.shouldIgnore(extraInfo)) {
+ return;
+ }
+ crates.push({ name, version });
+ }
+ });
+ cargo.on('exit', (exitCode, _) => {
+ if (exitCode === 0)
+ resolve(crates);
+ else
+ reject(new Error(`exit code: ${exitCode}.`));
+ });
+
+ });
+ }
+
+ private shouldIgnore(extraInfo: string): boolean {
+ return extraInfo !== undefined && (extraInfo === '*' || path.isAbsolute(extraInfo));
+ }
+
private async runCargo(
cargoArgs: string[],
onStdoutJson: (obj: any) => void,
@@ -129,6 +166,58 @@ export class Cargo {
}
}
+export async function activeToolchain(): Promise<string> {
+ const pathToRustup = await rustupPath();
+ return await new Promise((resolve, reject) => {
+ const execution = cp.spawn(pathToRustup, ['show', 'active-toolchain'], {
+ stdio: ['ignore', 'pipe', 'pipe'],
+ cwd: os.homedir()
+ });
+ const rl = readline.createInterface({ input: execution.stdout });
+
+ let currToolchain: string | undefined = undefined;
+ rl.on('line', line => {
+ const match = line.match(TOOLCHAIN_PATTERN);
+ if (match) {
+ currToolchain = match[1];
+ }
+ });
+ execution.on('exit', (exitCode, _) => {
+ if (exitCode === 0 && currToolchain)
+ resolve(currToolchain);
+ else
+ reject(new Error(`exit code: ${exitCode}.`));
+ });
+
+ });
+}
+
+export async function rustVersion(): Promise<string> {
+ const pathToRustup = await rustupPath();
+ return await new Promise((resolve, reject) => {
+ const execution = cp.spawn(pathToRustup, ['show', 'active-toolchain'], {
+ stdio: ['ignore', 'pipe', 'pipe'],
+ cwd: os.homedir()
+ });
+ const rl = readline.createInterface({ input: execution.stdout });
+
+ let currToolchain: string | undefined = undefined;
+ rl.on('line', line => {
+ const match = line.match(TOOLCHAIN_PATTERN);
+ if (match) {
+ currToolchain = match[1];
+ }
+ });
+ execution.on('exit', (exitCode, _) => {
+ if (exitCode === 1 && currToolchain)
+ resolve(currToolchain);
+ else
+ reject(new Error(`exit code: ${exitCode}.`));
+ });
+
+ });
+}
+
/** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/
export async function getSysroot(dir: string): Promise<string> {
const rustcPath = await getPathForExecutable("rustc");
@@ -147,6 +236,16 @@ export async function getRustcId(dir: string): Promise<string> {
return rx.exec(data)![1];
}
+export async function getRustcVersion(dir: string): Promise<string> {
+ const rustcPath = await getPathForExecutable("rustc");
+
+ // do not memoize the result because the toolchain may change between runs
+ const data = await execute(`${rustcPath} -V`, { cwd: dir });
+ const rx = /(\d\.\d+\.\d+)/;
+
+ return rx.exec(data)![1];
+}
+
/** Mirrors `toolchain::cargo()` implementation */
export function cargoPath(): Promise<string> {
return getPathForExecutable("cargo");