Skip to content

Commit d01fc64

Browse files
committed
Creating rust dependencies tree view
1 parent 09e0a00 commit d01fc64

File tree

4 files changed

+115
-6
lines changed

4 files changed

+115
-6
lines changed

editors/code/package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,14 @@
285285
"title": "Clear flycheck diagnostics",
286286
"category": "rust-analyzer"
287287
},
288+
{
289+
"command": "rust-analyzer.revealDependency",
290+
"title": "Reveal File"
291+
},
292+
{
293+
"command": "rust-analyzer.openFile",
294+
"title": "Open File"
295+
},
288296
{
289297
"command": "rust-analyzer.revealDependency",
290298
"title": "Reveal File"
@@ -1975,4 +1983,4 @@
19751983
}
19761984
]
19771985
}
1978-
}
1986+
}

editors/code/src/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { applySnippetWorkspaceEdit, applySnippetTextEdits } from "./snippets";
88
import { spawnSync } from "child_process";
99
import { RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
1010
import { AstInspector } from "./ast_inspector";
11-
import { isRustDocument, isCargoTomlDocument, sleep, isRustEditor, RustEditor } from "./util";
11+
import { isRustDocument, isCargoTomlDocument, sleep, isRustEditor, RustEditor } from './util';
1212
import { startDebugSession, makeDebugConfig } from "./debug";
1313
import { LanguageClient } from "vscode-languageclient/node";
1414
import { LINKED_COMMANDS } from "./client";

editors/code/src/ctx.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ import * as lc from "vscode-languageclient/node";
33
import * as ra from "./lsp_ext";
44
import * as path from "path";
55

6-
import {Config, prepareVSCodeConfig} from "./config";
7-
import {createClient} from "./client";
6+
import {Config, prepareVSCodeConfig} from './config';
7+
import {createClient} from './client';
88
import {
99
executeDiscoverProject,
1010
isRustDocument,
1111
isRustEditor,
1212
LazyOutputChannel,
1313
log,
1414
RustEditor,
15-
} from "./util";
16-
import {ServerStatusParams} from "./lsp_ext";
15+
} from './util';
16+
import {ServerStatusParams} from './lsp_ext';
17+
import { Dependency, DependencyFile, RustDependenciesProvider, DependencyId } from './dependencies_provider';
18+
import { execRevealDependency } from './commands';
1719
import {
1820
Dependency,
1921
DependencyFile,

editors/code/src/toolchain.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,43 @@ export class Cargo {
9898
return artifacts[0].fileName;
9999
}
100100

101+
async crates(): Promise<Crate[]> {
102+
const pathToCargo = await cargoPath();
103+
return await new Promise((resolve, reject) => {
104+
const crates: Crate[] = [];
105+
106+
const cargo = cp.spawn(pathToCargo, ['tree', '--prefix', 'none'], {
107+
stdio: ['ignore', 'pipe', 'pipe'],
108+
cwd: this.rootFolder
109+
});
110+
const rl = readline.createInterface({ input: cargo.stdout });
111+
rl.on('line', line => {
112+
const match = line.match(TREE_LINE_PATTERN);
113+
if (match) {
114+
const name = match[1];
115+
const version = match[2];
116+
const extraInfo = match[3];
117+
// ignore duplicates '(*)' and path dependencies
118+
if (this.shouldIgnore(extraInfo)) {
119+
return;
120+
}
121+
crates.push({ name, version });
122+
}
123+
});
124+
cargo.on('exit', (exitCode, _) => {
125+
if (exitCode === 0)
126+
resolve(crates);
127+
else
128+
reject(new Error(`exit code: ${exitCode}.`));
129+
});
130+
131+
});
132+
}
133+
134+
private shouldIgnore(extraInfo: string): boolean {
135+
return extraInfo !== undefined && (extraInfo === '*' || path.isAbsolute(extraInfo));
136+
}
137+
101138
private async runCargo(
102139
cargoArgs: string[],
103140
onStdoutJson: (obj: any) => void,
@@ -129,6 +166,58 @@ export class Cargo {
129166
}
130167
}
131168

169+
export async function activeToolchain(): Promise<string> {
170+
const pathToRustup = await rustupPath();
171+
return await new Promise((resolve, reject) => {
172+
const execution = cp.spawn(pathToRustup, ['show', 'active-toolchain'], {
173+
stdio: ['ignore', 'pipe', 'pipe'],
174+
cwd: os.homedir()
175+
});
176+
const rl = readline.createInterface({ input: execution.stdout });
177+
178+
let currToolchain: string | undefined = undefined;
179+
rl.on('line', line => {
180+
const match = line.match(TOOLCHAIN_PATTERN);
181+
if (match) {
182+
currToolchain = match[1];
183+
}
184+
});
185+
execution.on('exit', (exitCode, _) => {
186+
if (exitCode === 0 && currToolchain)
187+
resolve(currToolchain);
188+
else
189+
reject(new Error(`exit code: ${exitCode}.`));
190+
});
191+
192+
});
193+
}
194+
195+
export async function rustVersion(): Promise<string> {
196+
const pathToRustup = await rustupPath();
197+
return await new Promise((resolve, reject) => {
198+
const execution = cp.spawn(pathToRustup, ['show', 'active-toolchain'], {
199+
stdio: ['ignore', 'pipe', 'pipe'],
200+
cwd: os.homedir()
201+
});
202+
const rl = readline.createInterface({ input: execution.stdout });
203+
204+
let currToolchain: string | undefined = undefined;
205+
rl.on('line', line => {
206+
const match = line.match(TOOLCHAIN_PATTERN);
207+
if (match) {
208+
currToolchain = match[1];
209+
}
210+
});
211+
execution.on('exit', (exitCode, _) => {
212+
if (exitCode === 1 && currToolchain)
213+
resolve(currToolchain);
214+
else
215+
reject(new Error(`exit code: ${exitCode}.`));
216+
});
217+
218+
});
219+
}
220+
132221
/** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/
133222
export async function getSysroot(dir: string): Promise<string> {
134223
const rustcPath = await getPathForExecutable("rustc");
@@ -147,6 +236,16 @@ export async function getRustcId(dir: string): Promise<string> {
147236
return rx.exec(data)![1];
148237
}
149238

239+
export async function getRustcVersion(dir: string): Promise<string> {
240+
const rustcPath = await getPathForExecutable("rustc");
241+
242+
// do not memoize the result because the toolchain may change between runs
243+
const data = await execute(`${rustcPath} -V`, { cwd: dir });
244+
const rx = /(\d\.\d+\.\d+)/;
245+
246+
return rx.exec(data)![1];
247+
}
248+
150249
/** Mirrors `toolchain::cargo()` implementation */
151250
export function cargoPath(): Promise<string> {
152251
return getPathForExecutable("cargo");

0 commit comments

Comments
 (0)