about summary refs log tree commit diff
path: root/editors/code
diff options
context:
space:
mode:
authorveetaha <veetaha2@gmail.com>2020-05-06 01:42:04 +0300
committerCraig Disselkoen <craigdissel@gmail.com>2020-05-05 16:12:56 -0700
commitc9b395be2bfcd67e045c1031143b7e8c27a6d3fb (patch)
tree57ae8c2de16be47befcd115766fd15ceeb395a86 /editors/code
parenta78dd06951dffcc6ff69aec21a2d8224c12f5026 (diff)
downloadrust-c9b395be2bfcd67e045c1031143b7e8c27a6d3fb.tar.gz
rust-c9b395be2bfcd67e045c1031143b7e8c27a6d3fb.zip
Fix cargo not found on macos bug at vscode extension side
Diffstat (limited to 'editors/code')
-rw-r--r--editors/code/src/cargo.ts36
-rw-r--r--editors/code/src/main.ts8
-rw-r--r--editors/code/src/util.ts11
3 files changed, 48 insertions, 7 deletions
diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts
index 613aa82da9a..2a2c2e0e1bb 100644
--- a/editors/code/src/cargo.ts
+++ b/editors/code/src/cargo.ts
@@ -1,6 +1,9 @@
 import * as cp from 'child_process';
+import * as os from 'os';
+import * as path from 'path';
 import * as readline from 'readline';
 import { OutputChannel } from 'vscode';
+import { isValidExecutable } from './util';
 
 interface CompilationArtifact {
     fileName: string;
@@ -63,7 +66,14 @@ export class Cargo {
         onStderrString: (data: string) => void
     ): Promise<number> {
         return new Promise((resolve, reject) => {
-            const cargo = cp.spawn('cargo', cargoArgs, {
+            let cargoPath;
+            try {
+                cargoPath = getCargoPathOrFail();
+            } catch (err) {
+                return reject(err);
+            }
+
+            const cargo = cp.spawn(cargoPath, cargoArgs, {
                 stdio: ['ignore', 'pipe', 'pipe'],
                 cwd: this.rootFolder
             });
@@ -87,3 +97,27 @@ export class Cargo {
         });
     }
 }
+
+// Mirrors `ra_env::get_path_for_executable` implementation
+function getCargoPathOrFail(): string {
+    const envVar = process.env.CARGO;
+    const executableName = "cargo";
+
+    if (envVar) {
+        if (isValidExecutable(envVar)) return envVar;
+
+        throw new Error(`\`${envVar}\` environment variable points to something that's not a valid executable`);
+    }
+
+    if (isValidExecutable(executableName)) return executableName;
+
+    const standardLocation = path.join(os.homedir(), '.cargo', 'bin', executableName);
+
+    if (isValidExecutable(standardLocation)) return standardLocation;
+
+    throw new Error(
+        `Failed to find \`${executableName}\` executable. ` +
+        `Make sure \`${executableName}\` is in \`$PATH\`, ` +
+        `or set \`${envVar}\` to point to a valid executable.`
+    );
+}
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index efd56a84b52..9b020d0019a 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -8,10 +8,9 @@ import { activateInlayHints } from './inlay_hints';
 import { activateStatusDisplay } from './status_display';
 import { Ctx } from './ctx';
 import { Config, NIGHTLY_TAG } from './config';
-import { log, assert } from './util';
+import { log, assert, isValidExecutable } from './util';
 import { PersistentState } from './persistent_state';
 import { fetchRelease, download } from './net';
-import { spawnSync } from 'child_process';
 import { activateTaskProvider } from './tasks';
 
 let ctx: Ctx | undefined;
@@ -179,10 +178,7 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise<
 
     log.debug("Using server binary at", path);
 
-    const res = spawnSync(path, ["--version"], { encoding: 'utf8' });
-    log.debug("Checked binary availability via --version", res);
-    log.debug(res, "--version output:", res.output);
-    if (res.status !== 0) {
+    if (!isValidExecutable(path)) {
         throw new Error(`Failed to execute ${path} --version`);
     }
 
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index 6f91f81d63e..127a9e91124 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -1,6 +1,7 @@
 import * as lc from "vscode-languageclient";
 import * as vscode from "vscode";
 import { strict as nativeAssert } from "assert";
+import { spawnSync } from "child_process";
 
 export function assert(condition: boolean, explanation: string): asserts condition {
     try {
@@ -82,3 +83,13 @@ export function isRustDocument(document: vscode.TextDocument): document is RustD
 export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor {
     return isRustDocument(editor.document);
 }
+
+export function isValidExecutable(path: string): boolean {
+    log.debug("Checking availability of a binary at", path);
+
+    const res = spawnSync(path, ["--version"], { encoding: 'utf8' });
+
+    log.debug(res, "--version output:", res.output);
+
+    return res.status === 0;
+}