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.ts | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts index 784ee260d0..6ae365c71c 100644 --- a/editors/code/src/toolchain.ts +++ b/editors/code/src/toolchain.ts @@ -3,7 +3,7 @@ import * as os from "os"; import * as path from "path"; import * as readline from "readline"; import * as vscode from "vscode"; -import { Env, log, memoizeAsync, unwrapUndefinable } from "./util"; +import { Env, isWindows, log, memoizeAsync, unwrapUndefinable } from "./util"; import type { CargoRunnableArgs } from "./lsp_ext"; interface CompilationArtifact { @@ -178,20 +178,22 @@ async function getPathForExecutableWithEnv( executableName: "cargo" | "rustc" | "rustup", env: Env, ): Promise<string> { - const envVar = env[executableName.toUpperCase()]; + const envVar = getEnvVar(env, executableName.toUpperCase()); if (envVar) { return envVar; } - if (await lookupInPath(executableName, env["PATH"] ?? "")) { + if (await lookupInPath(executableName, getEnvVar(env, "PATH") ?? "")) { return executableName; } - const cargoHome = getCargoHomeFromPath(env["CARGO_HOME"]); + const cargoHome = getCargoHomeFromPath(getEnvVar(env, "CARGO_HOME")); if (cargoHome) { - const standardPath = vscode.Uri.joinPath(cargoHome, "bin", executableName); - if (await isFileAtUri(standardPath)) { - return standardPath.fsPath; + for (const candidate of executableCandidates(executableName)) { + const standardPath = vscode.Uri.joinPath(cargoHome, "bin", candidate); + if (await isFileAtUri(standardPath)) { + return standardPath.fsPath; + } } } @@ -211,8 +213,10 @@ const getPathForExecutable = memoizeAsync( const cargoHome = getCargoHome(); if (cargoHome) { - const standardPath = vscode.Uri.joinPath(cargoHome, "bin", executableName); - if (await isFileAtUri(standardPath)) return standardPath.fsPath; + for (const candidate of executableCandidates(executableName)) { + const standardPath = vscode.Uri.joinPath(cargoHome, "bin", candidate); + if (await isFileAtUri(standardPath)) return standardPath.fsPath; + } } return executableName; }, @@ -220,8 +224,7 @@ const getPathForExecutable = memoizeAsync( async function lookupInPath(exec: string, paths: string): Promise<boolean> { const candidates = paths.split(path.delimiter).flatMap((dirInPath) => { - const candidate = path.join(dirInPath, exec); - return os.type() === "Windows_NT" ? [candidate, `${candidate}.exe`] : [candidate]; + return executableCandidates(exec).map((candidate) => path.join(dirInPath, candidate)); }); for await (const isFile of candidates.map(isFileAtPath)) { @@ -232,6 +235,22 @@ async function lookupInPath(exec: string, paths: string): Promise<boolean> { return false; } +function executableCandidates(executableName: string): string[] { + // Keep the extension-side probe aligned with `crates/toolchain::probe_for_binary()`, which + // checks both the bare executable name and the platform suffix such as `.exe` on Windows. + // That matters for both PATH lookups and `$CARGO_HOME/bin/<tool>` fallbacks. + return isWindows ? [executableName, `${executableName}.exe`] : [executableName]; +} + +function getEnvVar(env: Env, name: string): string | undefined { + if (!isWindows) { + return env[name]; + } + + const foldedName = name.toLowerCase(); + return Object.entries(env).find(([key]) => key.toLowerCase() === foldedName)?.[1]; +} + function getCargoHome(): vscode.Uri | null { const envVar = process.env["CARGO_HOME"]; return getCargoHomeFromPath(envVar); |