Unnamed repository; edit this file 'description' to name the repository.
Creating rust dependencies tree view
bruno-ortiz 2023-05-02
parent 09e0a00 · commit d01fc64
-rw-r--r--editors/code/package.json10
-rw-r--r--editors/code/src/commands.ts2
-rw-r--r--editors/code/src/ctx.ts10
-rw-r--r--editors/code/src/toolchain.ts99
4 files changed, 115 insertions, 6 deletions
diff --git a/editors/code/package.json b/editors/code/package.json
index 0efc191d74..b009e381ec 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -288,6 +288,14 @@
{
"command": "rust-analyzer.revealDependency",
"title": "Reveal File"
+ },
+ {
+ "command": "rust-analyzer.openFile",
+ "title": "Open File"
+ },
+ {
+ "command": "rust-analyzer.revealDependency",
+ "title": "Reveal File"
}
],
"keybindings": [
@@ -1975,4 +1983,4 @@
}
]
}
-}
+} \ No newline at end of file
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 7fe32754c9..fb6778b687 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -8,7 +8,7 @@ import { applySnippetWorkspaceEdit, applySnippetTextEdits } from "./snippets";
import { spawnSync } from "child_process";
import { RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
import { AstInspector } from "./ast_inspector";
-import { isRustDocument, isCargoTomlDocument, sleep, isRustEditor, RustEditor } from "./util";
+import { isRustDocument, isCargoTomlDocument, sleep, isRustEditor, RustEditor } from './util';
import { startDebugSession, makeDebugConfig } from "./debug";
import { LanguageClient } from "vscode-languageclient/node";
import { LINKED_COMMANDS } from "./client";
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index d62716c26d..ce70dfd2f6 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -3,8 +3,8 @@ import * as lc from "vscode-languageclient/node";
import * as ra from "./lsp_ext";
import * as path from "path";
-import {Config, prepareVSCodeConfig} from "./config";
-import {createClient} from "./client";
+import {Config, prepareVSCodeConfig} from './config';
+import {createClient} from './client';
import {
executeDiscoverProject,
isRustDocument,
@@ -12,8 +12,10 @@ import {
LazyOutputChannel,
log,
RustEditor,
-} from "./util";
-import {ServerStatusParams} from "./lsp_ext";
+} from './util';
+import {ServerStatusParams} from './lsp_ext';
+import { Dependency, DependencyFile, RustDependenciesProvider, DependencyId } from './dependencies_provider';
+import { execRevealDependency } from './commands';
import {
Dependency,
DependencyFile,
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");