mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-26 11:55:04 +00:00
Merge #9908
9908: fix check of the toolchain's path r=lnicola a=gfreezy fixed #9907 Co-authored-by: Alex.F <gfreezy@gmail.com>
This commit is contained in:
commit
19348bc478
3 changed files with 27 additions and 20 deletions
|
@ -107,7 +107,8 @@ export async function buildCargoTask(
|
||||||
// Check whether we must use a user-defined substitute for cargo.
|
// Check whether we must use a user-defined substitute for cargo.
|
||||||
// Split on spaces to allow overrides like "wrapper cargo".
|
// Split on spaces to allow overrides like "wrapper cargo".
|
||||||
const overrideCargo = definition.overrideCargo ?? definition.overrideCargo;
|
const overrideCargo = definition.overrideCargo ?? definition.overrideCargo;
|
||||||
const cargoCommand = overrideCargo?.split(" ") ?? [toolchain.cargoPath()];
|
const cargoPath = await toolchain.cargoPath();
|
||||||
|
const cargoCommand = overrideCargo?.split(" ") ?? [cargoPath];
|
||||||
|
|
||||||
const fullCommand = [...cargoCommand, ...args];
|
const fullCommand = [...cargoCommand, ...args];
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as readline from 'readline';
|
import * as readline from 'readline';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { execute, log, memoize } from './util';
|
import { execute, log, memoizeAsync } from './util';
|
||||||
|
|
||||||
interface CompilationArtifact {
|
interface CompilationArtifact {
|
||||||
fileName: string;
|
fileName: string;
|
||||||
|
@ -89,13 +89,14 @@ export class Cargo {
|
||||||
return artifacts[0].fileName;
|
return artifacts[0].fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private runCargo(
|
private async runCargo(
|
||||||
cargoArgs: string[],
|
cargoArgs: string[],
|
||||||
onStdoutJson: (obj: any) => void,
|
onStdoutJson: (obj: any) => void,
|
||||||
onStderrString: (data: string) => void
|
onStderrString: (data: string) => void
|
||||||
): Promise<number> {
|
): Promise<number> {
|
||||||
return new Promise((resolve, reject) => {
|
const path = await cargoPath();
|
||||||
const cargo = cp.spawn(cargoPath(), cargoArgs, {
|
return await new Promise((resolve, reject) => {
|
||||||
|
const cargo = cp.spawn(path, cargoArgs, {
|
||||||
stdio: ['ignore', 'pipe', 'pipe'],
|
stdio: ['ignore', 'pipe', 'pipe'],
|
||||||
cwd: this.rootFolder
|
cwd: this.rootFolder
|
||||||
});
|
});
|
||||||
|
@ -121,15 +122,15 @@ export class Cargo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/
|
/** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/
|
||||||
export function getSysroot(dir: string): Promise<string> {
|
export async function getSysroot(dir: string): Promise<string> {
|
||||||
const rustcPath = getPathForExecutable("rustc");
|
const rustcPath = await getPathForExecutable("rustc");
|
||||||
|
|
||||||
// do not memoize the result because the toolchain may change between runs
|
// do not memoize the result because the toolchain may change between runs
|
||||||
return execute(`${rustcPath} --print sysroot`, { cwd: dir });
|
return await execute(`${rustcPath} --print sysroot`, { cwd: dir });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getRustcId(dir: string): Promise<string> {
|
export async function getRustcId(dir: string): Promise<string> {
|
||||||
const rustcPath = getPathForExecutable("rustc");
|
const rustcPath = await getPathForExecutable("rustc");
|
||||||
|
|
||||||
// do not memoize the result because the toolchain may change between runs
|
// do not memoize the result because the toolchain may change between runs
|
||||||
const data = await execute(`${rustcPath} -V -v`, { cwd: dir });
|
const data = await execute(`${rustcPath} -V -v`, { cwd: dir });
|
||||||
|
@ -139,27 +140,27 @@ export async function getRustcId(dir: string): Promise<string> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mirrors `toolchain::cargo()` implementation */
|
/** Mirrors `toolchain::cargo()` implementation */
|
||||||
export function cargoPath(): string {
|
export function cargoPath(): Promise<string> {
|
||||||
return getPathForExecutable("cargo");
|
return getPathForExecutable("cargo");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mirrors `toolchain::get_path_for_executable()` implementation */
|
/** Mirrors `toolchain::get_path_for_executable()` implementation */
|
||||||
export const getPathForExecutable = memoize(
|
export const getPathForExecutable = memoizeAsync(
|
||||||
// We apply caching to decrease file-system interactions
|
// We apply caching to decrease file-system interactions
|
||||||
(executableName: "cargo" | "rustc" | "rustup"): string => {
|
async (executableName: "cargo" | "rustc" | "rustup"): Promise<string> => {
|
||||||
{
|
{
|
||||||
const envVar = process.env[executableName.toUpperCase()];
|
const envVar = process.env[executableName.toUpperCase()];
|
||||||
if (envVar) return envVar;
|
if (envVar) return envVar;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lookupInPath(executableName)) return executableName;
|
if (await lookupInPath(executableName)) return executableName;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// hmm, `os.homedir()` seems to be infallible
|
// hmm, `os.homedir()` seems to be infallible
|
||||||
// it is not mentioned in docs and cannot be infered by the type signature...
|
// it is not mentioned in docs and cannot be infered by the type signature...
|
||||||
const standardPath = vscode.Uri.joinPath(vscode.Uri.file(os.homedir()), ".cargo", "bin", executableName);
|
const standardPath = vscode.Uri.joinPath(vscode.Uri.file(os.homedir()), ".cargo", "bin", executableName);
|
||||||
|
|
||||||
if (isFileAtUri(standardPath)) return standardPath.fsPath;
|
if (await isFileAtUri(standardPath)) return standardPath.fsPath;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error("Failed to read the fs info", err);
|
log.error("Failed to read the fs info", err);
|
||||||
}
|
}
|
||||||
|
@ -167,7 +168,7 @@ export const getPathForExecutable = memoize(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
function lookupInPath(exec: string): boolean {
|
async function lookupInPath(exec: string): Promise<boolean> {
|
||||||
const paths = process.env.PATH ?? "";;
|
const paths = process.env.PATH ?? "";;
|
||||||
|
|
||||||
const candidates = paths.split(path.delimiter).flatMap(dirInPath => {
|
const candidates = paths.split(path.delimiter).flatMap(dirInPath => {
|
||||||
|
@ -177,7 +178,12 @@ function lookupInPath(exec: string): boolean {
|
||||||
: [candidate];
|
: [candidate];
|
||||||
});
|
});
|
||||||
|
|
||||||
return candidates.some(isFileAtPath);
|
for await (const isFile of candidates.map(isFileAtPath)) {
|
||||||
|
if (isFile) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function isFileAtPath(path: string): Promise<boolean> {
|
async function isFileAtPath(path: string): Promise<boolean> {
|
||||||
|
|
|
@ -126,16 +126,16 @@ export function setContextValue(key: string, value: any): Thenable<void> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a higher-order function that caches the results of invoking the
|
* Returns a higher-order function that caches the results of invoking the
|
||||||
* underlying function.
|
* underlying async function.
|
||||||
*/
|
*/
|
||||||
export function memoize<Ret, TThis, Param extends string>(func: (this: TThis, arg: Param) => Ret) {
|
export function memoizeAsync<Ret, TThis, Param extends string>(func: (this: TThis, arg: Param) => Promise<Ret>) {
|
||||||
const cache = new Map<string, Ret>();
|
const cache = new Map<string, Ret>();
|
||||||
|
|
||||||
return function(this: TThis, arg: Param) {
|
return async function(this: TThis, arg: Param) {
|
||||||
const cached = cache.get(arg);
|
const cached = cache.get(arg);
|
||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
|
|
||||||
const result = func.call(this, arg);
|
const result = await func.call(this, arg);
|
||||||
cache.set(arg, result);
|
cache.set(arg, result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Reference in a new issue