Skip to content

Commit c9b395b

Browse files
Veetahacdisselkoen
authored andcommitted
Fix cargo not found on macos bug at vscode extension side
1 parent a78dd06 commit c9b395b

File tree

3 files changed

+48
-7
lines changed

3 files changed

+48
-7
lines changed

editors/code/src/cargo.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import * as cp from 'child_process';
2+
import * as os from 'os';
3+
import * as path from 'path';
24
import * as readline from 'readline';
35
import { OutputChannel } from 'vscode';
6+
import { isValidExecutable } from './util';
47

58
interface CompilationArtifact {
69
fileName: string;
@@ -63,7 +66,14 @@ export class Cargo {
6366
onStderrString: (data: string) => void
6467
): Promise<number> {
6568
return new Promise((resolve, reject) => {
66-
const cargo = cp.spawn('cargo', cargoArgs, {
69+
let cargoPath;
70+
try {
71+
cargoPath = getCargoPathOrFail();
72+
} catch (err) {
73+
return reject(err);
74+
}
75+
76+
const cargo = cp.spawn(cargoPath, cargoArgs, {
6777
stdio: ['ignore', 'pipe', 'pipe'],
6878
cwd: this.rootFolder
6979
});
@@ -87,3 +97,27 @@ export class Cargo {
8797
});
8898
}
8999
}
100+
101+
// Mirrors `ra_env::get_path_for_executable` implementation
102+
function getCargoPathOrFail(): string {
103+
const envVar = process.env.CARGO;
104+
const executableName = "cargo";
105+
106+
if (envVar) {
107+
if (isValidExecutable(envVar)) return envVar;
108+
109+
throw new Error(`\`${envVar}\` environment variable points to something that's not a valid executable`);
110+
}
111+
112+
if (isValidExecutable(executableName)) return executableName;
113+
114+
const standardLocation = path.join(os.homedir(), '.cargo', 'bin', executableName);
115+
116+
if (isValidExecutable(standardLocation)) return standardLocation;
117+
118+
throw new Error(
119+
`Failed to find \`${executableName}\` executable. ` +
120+
`Make sure \`${executableName}\` is in \`$PATH\`, ` +
121+
`or set \`${envVar}\` to point to a valid executable.`
122+
);
123+
}

editors/code/src/main.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ import { activateInlayHints } from './inlay_hints';
88
import { activateStatusDisplay } from './status_display';
99
import { Ctx } from './ctx';
1010
import { Config, NIGHTLY_TAG } from './config';
11-
import { log, assert } from './util';
11+
import { log, assert, isValidExecutable } from './util';
1212
import { PersistentState } from './persistent_state';
1313
import { fetchRelease, download } from './net';
14-
import { spawnSync } from 'child_process';
1514
import { activateTaskProvider } from './tasks';
1615

1716
let ctx: Ctx | undefined;
@@ -179,10 +178,7 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise<
179178

180179
log.debug("Using server binary at", path);
181180

182-
const res = spawnSync(path, ["--version"], { encoding: 'utf8' });
183-
log.debug("Checked binary availability via --version", res);
184-
log.debug(res, "--version output:", res.output);
185-
if (res.status !== 0) {
181+
if (!isValidExecutable(path)) {
186182
throw new Error(`Failed to execute ${path} --version`);
187183
}
188184

editors/code/src/util.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as lc from "vscode-languageclient";
22
import * as vscode from "vscode";
33
import { strict as nativeAssert } from "assert";
4+
import { spawnSync } from "child_process";
45

56
export function assert(condition: boolean, explanation: string): asserts condition {
67
try {
@@ -82,3 +83,13 @@ export function isRustDocument(document: vscode.TextDocument): document is RustD
8283
export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor {
8384
return isRustDocument(editor.document);
8485
}
86+
87+
export function isValidExecutable(path: string): boolean {
88+
log.debug("Checking availability of a binary at", path);
89+
90+
const res = spawnSync(path, ["--version"], { encoding: 'utf8' });
91+
92+
log.debug(res, "--version output:", res.output);
93+
94+
return res.status === 0;
95+
}

0 commit comments

Comments
 (0)