mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 05:15:04 +00:00
Creating rust dependencies tree view
This commit is contained in:
parent
09e0a00d36
commit
d01fc6405b
4 changed files with 115 additions and 6 deletions
|
@ -285,6 +285,14 @@
|
||||||
"title": "Clear flycheck diagnostics",
|
"title": "Clear flycheck diagnostics",
|
||||||
"category": "rust-analyzer"
|
"category": "rust-analyzer"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"command": "rust-analyzer.revealDependency",
|
||||||
|
"title": "Reveal File"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "rust-analyzer.openFile",
|
||||||
|
"title": "Open File"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "rust-analyzer.revealDependency",
|
"command": "rust-analyzer.revealDependency",
|
||||||
"title": "Reveal File"
|
"title": "Reveal File"
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { applySnippetWorkspaceEdit, applySnippetTextEdits } from "./snippets";
|
||||||
import { spawnSync } from "child_process";
|
import { spawnSync } from "child_process";
|
||||||
import { RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
|
import { RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
|
||||||
import { AstInspector } from "./ast_inspector";
|
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 { startDebugSession, makeDebugConfig } from "./debug";
|
||||||
import { LanguageClient } from "vscode-languageclient/node";
|
import { LanguageClient } from "vscode-languageclient/node";
|
||||||
import { LINKED_COMMANDS } from "./client";
|
import { LINKED_COMMANDS } from "./client";
|
||||||
|
|
|
@ -3,8 +3,8 @@ import * as lc from "vscode-languageclient/node";
|
||||||
import * as ra from "./lsp_ext";
|
import * as ra from "./lsp_ext";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
import {Config, prepareVSCodeConfig} from "./config";
|
import {Config, prepareVSCodeConfig} from './config';
|
||||||
import {createClient} from "./client";
|
import {createClient} from './client';
|
||||||
import {
|
import {
|
||||||
executeDiscoverProject,
|
executeDiscoverProject,
|
||||||
isRustDocument,
|
isRustDocument,
|
||||||
|
@ -12,8 +12,10 @@ import {
|
||||||
LazyOutputChannel,
|
LazyOutputChannel,
|
||||||
log,
|
log,
|
||||||
RustEditor,
|
RustEditor,
|
||||||
} from "./util";
|
} from './util';
|
||||||
import {ServerStatusParams} from "./lsp_ext";
|
import {ServerStatusParams} from './lsp_ext';
|
||||||
|
import { Dependency, DependencyFile, RustDependenciesProvider, DependencyId } from './dependencies_provider';
|
||||||
|
import { execRevealDependency } from './commands';
|
||||||
import {
|
import {
|
||||||
Dependency,
|
Dependency,
|
||||||
DependencyFile,
|
DependencyFile,
|
||||||
|
|
|
@ -98,6 +98,43 @@ export class Cargo {
|
||||||
return artifacts[0].fileName;
|
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(
|
private async runCargo(
|
||||||
cargoArgs: string[],
|
cargoArgs: string[],
|
||||||
onStdoutJson: (obj: any) => void,
|
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*/
|
/** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/
|
||||||
export async function getSysroot(dir: string): Promise<string> {
|
export async function getSysroot(dir: string): Promise<string> {
|
||||||
const rustcPath = await getPathForExecutable("rustc");
|
const rustcPath = await getPathForExecutable("rustc");
|
||||||
|
@ -147,6 +236,16 @@ export async function getRustcId(dir: string): Promise<string> {
|
||||||
return rx.exec(data)![1];
|
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 */
|
/** Mirrors `toolchain::cargo()` implementation */
|
||||||
export function cargoPath(): Promise<string> {
|
export function cargoPath(): Promise<string> {
|
||||||
return getPathForExecutable("cargo");
|
return getPathForExecutable("cargo");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue