aboutsummaryrefslogtreecommitdiff
path: root/editors/code
diff options
context:
space:
mode:
authorveetaha <[email protected]>2020-05-05 23:42:04 +0100
committerCraig Disselkoen <[email protected]>2020-05-06 00:12:56 +0100
commitc9b395be2bfcd67e045c1031143b7e8c27a6d3fb (patch)
tree57ae8c2de16be47befcd115766fd15ceeb395a86 /editors/code
parenta78dd06951dffcc6ff69aec21a2d8224c12f5026 (diff)
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 613aa82da..2a2c2e0e1 100644
--- a/editors/code/src/cargo.ts
+++ b/editors/code/src/cargo.ts
@@ -1,6 +1,9 @@
1import * as cp from 'child_process'; 1import * as cp from 'child_process';
2import * as os from 'os';
3import * as path from 'path';
2import * as readline from 'readline'; 4import * as readline from 'readline';
3import { OutputChannel } from 'vscode'; 5import { OutputChannel } from 'vscode';
6import { isValidExecutable } from './util';
4 7
5interface CompilationArtifact { 8interface CompilationArtifact {
6 fileName: string; 9 fileName: string;
@@ -63,7 +66,14 @@ export class Cargo {
63 onStderrString: (data: string) => void 66 onStderrString: (data: string) => void
64 ): Promise<number> { 67 ): Promise<number> {
65 return new Promise((resolve, reject) => { 68 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, {
67 stdio: ['ignore', 'pipe', 'pipe'], 77 stdio: ['ignore', 'pipe', 'pipe'],
68 cwd: this.rootFolder 78 cwd: this.rootFolder
69 }); 79 });
@@ -87,3 +97,27 @@ export class Cargo {
87 }); 97 });
88 } 98 }
89} 99}
100
101// Mirrors `ra_env::get_path_for_executable` implementation
102function 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}
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index efd56a84b..9b020d001 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -8,10 +8,9 @@ import { activateInlayHints } from './inlay_hints';
8import { activateStatusDisplay } from './status_display'; 8import { activateStatusDisplay } from './status_display';
9import { Ctx } from './ctx'; 9import { Ctx } from './ctx';
10import { Config, NIGHTLY_TAG } from './config'; 10import { Config, NIGHTLY_TAG } from './config';
11import { log, assert } from './util'; 11import { log, assert, isValidExecutable } from './util';
12import { PersistentState } from './persistent_state'; 12import { PersistentState } from './persistent_state';
13import { fetchRelease, download } from './net'; 13import { fetchRelease, download } from './net';
14import { spawnSync } from 'child_process';
15import { activateTaskProvider } from './tasks'; 14import { activateTaskProvider } from './tasks';
16 15
17let ctx: Ctx | undefined; 16let ctx: Ctx | undefined;
@@ -179,10 +178,7 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise<
179 178
180 log.debug("Using server binary at", path); 179 log.debug("Using server binary at", path);
181 180
182 const res = spawnSync(path, ["--version"], { encoding: 'utf8' }); 181 if (!isValidExecutable(path)) {
183 log.debug("Checked binary availability via --version", res);
184 log.debug(res, "--version output:", res.output);
185 if (res.status !== 0) {
186 throw new Error(`Failed to execute ${path} --version`); 182 throw new Error(`Failed to execute ${path} --version`);
187 } 183 }
188 184
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index 6f91f81d6..127a9e911 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -1,6 +1,7 @@
1import * as lc from "vscode-languageclient"; 1import * as lc from "vscode-languageclient";
2import * as vscode from "vscode"; 2import * as vscode from "vscode";
3import { strict as nativeAssert } from "assert"; 3import { strict as nativeAssert } from "assert";
4import { spawnSync } from "child_process";
4 5
5export function assert(condition: boolean, explanation: string): asserts condition { 6export function assert(condition: boolean, explanation: string): asserts condition {
6 try { 7 try {
@@ -82,3 +83,13 @@ export function isRustDocument(document: vscode.TextDocument): document is RustD
82export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor { 83export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor {
83 return isRustDocument(editor.document); 84 return isRustDocument(editor.document);
84} 85}
86
87export 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}