Skip to content

Commit d9187fe

Browse files
committed
[release] src/goInstallTools.ts: add GOROOT/bin to PATH when it wasn't found from PATH
The fix for #679 changed to prepend GOROOT/bin to PATH or Path only if users explicitly configured to use go different from what's found from PATH. I forgot the case where go was not found from PATH and the extension picked up a common default go installation directory. (C:\Go\bin or /usr/local/go/bin). This change rewrote the fix - rewrote getBinPath to return why it chose the path as well. Then, we mutate the PATH env var if getBinPath picked go with a reason other than it's in PATH (why === 'path'). Since getBinPath and getBinPathWithPreferredGopathGoroot are used in many places, this CL introduces getBinPathWithExplanation and getBinPath wraps it. Updates #679 Fixes #713 Change-Id: Ie00612fcef2cf4c2a187a263da04b342182c030b Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/258316 Trust: Hyang-Ah Hana Kim <[email protected]> Run-TryBot: Hyang-Ah Hana Kim <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Suzy Mueller <[email protected]> (cherry picked from commit 9bf9d64) Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/258519
1 parent a42b5de commit d9187fe

File tree

3 files changed

+40
-51
lines changed

3 files changed

+40
-51
lines changed

src/goInstallTools.ts

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ import {
3030
import { getFromWorkspaceState } from './stateUtils';
3131
import {
3232
getBinPath,
33+
getBinPathWithExplanation,
3334
getGoConfig,
3435
getGoVersion,
3536
getTempFilePath,
3637
getWorkspaceFolderPath,
3738
GoVersion,
3839
rmdirRecursive,
3940
} from './util';
40-
import { correctBinname, envPath, getCurrentGoRoot, getToolFromToolPath, setCurrentGoRoot } from './utils/pathUtils';
41+
import { envPath, getCurrentGoRoot, getToolFromToolPath, setCurrentGoRoot } from './utils/pathUtils';
4142

4243
// declinedUpdates tracks the tools that the user has declined to update.
4344
const declinedUpdates: Tool[] = [];
@@ -343,7 +344,8 @@ export async function promptForUpdatingTool(toolName: string, newVersion?: SemVe
343344
}
344345

345346
export function updateGoVarsFromConfig(): Promise<void> {
346-
const goRuntimePath = getBinPath('go', false);
347+
const {binPath, why} = getBinPathWithExplanation('go', false);
348+
const goRuntimePath = binPath;
347349

348350
if (!goRuntimePath || !path.isAbsolute(goRuntimePath)) {
349351
// getBinPath returns the absolute path to the tool if it exists.
@@ -384,8 +386,8 @@ export function updateGoVarsFromConfig(): Promise<void> {
384386
// cgo, gopls, and other underlying tools will inherit the environment and attempt
385387
// to locate 'go' from the PATH env var.
386388
// Update the PATH only if users configured to use a different
387-
// version of go than the system default.
388-
if (!!goPickedByExtension()) {
389+
// version of go than the system default found from PATH (or Path).
390+
if (why !== 'path') {
389391
addGoRuntimeBaseToPATH(path.join(getCurrentGoRoot(), 'bin'));
390392
}
391393
initGoStatusBar();
@@ -396,41 +398,6 @@ export function updateGoVarsFromConfig(): Promise<void> {
396398
});
397399
}
398400

399-
// The go command is picked up by searching directories in PATH by default.
400-
// But users can override it and force the extension to pick a different
401-
// one by configuring
402-
//
403-
// 1) with the go.environment.choose command, which stores the selection
404-
// in the workspace memento with the key 'selectedGo',
405-
// 2) with 'go.alternateTools': { 'go': ... } setting, or
406-
// 3) with 'go.goroot' setting
407-
//
408-
// goPickedByExtension returns the chosen path if the default path should
409-
// be overridden by above methods.
410-
// TODO: This logic is duplicated in getBinPath. Centralize this logic.
411-
function goPickedByExtension(): string | undefined {
412-
// getFromWorkspaceState('selectedGo')
413-
const selectedGoPath: string = getFromWorkspaceState('selectedGo')?.binpath;
414-
if (selectedGoPath) {
415-
return selectedGoPath;
416-
}
417-
418-
const cfg = getGoConfig();
419-
420-
// 'go.alternateTools.go'
421-
const alternateTools: { [key: string]: string } = cfg.get('alternateTools');
422-
const alternateToolPath: string = alternateTools['go'];
423-
if (alternateToolPath) {
424-
return alternateToolPath;
425-
}
426-
// 'go.goroot'
427-
const goRoot: string = cfg.get('goroot');
428-
if (goRoot) {
429-
return path.join(goRoot, 'bin', correctBinname('go'));
430-
}
431-
return undefined;
432-
}
433-
434401
let alreadyOfferedToInstallTools = false;
435402

436403
export async function offerToInstallTools() {

src/util.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { getFromWorkspaceState } from './stateUtils';
2020
import {
2121
envPath,
2222
fixDriveCasingInWindows,
23-
getBinPathWithPreferredGopathGoroot,
23+
getBinPathWithPreferredGopathGorootWithExplanation,
2424
getCurrentGoRoot,
2525
getInferredGopath,
2626
resolveHomeDir,
@@ -477,7 +477,15 @@ function resolveToolsGopath(): string {
477477
}
478478
}
479479

480+
// getBinPath returns the path to the tool.
480481
export function getBinPath(tool: string, useCache = true): string {
482+
const r = getBinPathWithExplanation(tool, useCache);
483+
return r.binPath;
484+
}
485+
486+
// getBinPathWithExplanation returns the path to the tool, and the explanation on why
487+
// the path was chosen. See getBinPathWithPreferredGopathGorootWithExplanation for details.
488+
export function getBinPathWithExplanation(tool: string, useCache = true): {binPath: string, why?: string} {
481489
const cfg = getGoConfig();
482490
const alternateTools: { [key: string]: string } = cfg.get('alternateTools');
483491
const alternateToolPath: string = alternateTools[tool];
@@ -487,7 +495,7 @@ export function getBinPath(tool: string, useCache = true): string {
487495
selectedGoPath = getFromWorkspaceState('selectedGo')?.binpath;
488496
}
489497

490-
return getBinPathWithPreferredGopathGoroot(
498+
return getBinPathWithPreferredGopathGorootWithExplanation(
491499
tool,
492500
tool === 'go' ? [] : [getToolsGopath(), getCurrentGoPath()],
493501
tool === 'go' && cfg.get('goroot') ? resolvePath(cfg.get('goroot')) : undefined,

src/utils/pathUtils.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,37 @@ export function getBinPathWithPreferredGopathGoroot(
3737
preferredGopaths: string[],
3838
preferredGoroot?: string,
3939
alternateTool?: string,
40-
useCache = true,
40+
useCache = true
4141
): string {
42+
const r = getBinPathWithPreferredGopathGorootWithExplanation(
43+
toolName, preferredGopaths, preferredGoroot, alternateTool, useCache);
44+
return r.binPath;
45+
}
46+
47+
// Is same as getBinPAthWithPreferredGopathGoroot, but returns why the
48+
// returned path was chosen.
49+
export function getBinPathWithPreferredGopathGorootWithExplanation(
50+
toolName: string,
51+
preferredGopaths: string[],
52+
preferredGoroot?: string,
53+
alternateTool?: string,
54+
useCache = true,
55+
): {binPath: string, why?: string} {
4256
if (alternateTool && path.isAbsolute(alternateTool) && executableFileExists(alternateTool)) {
4357
binPathCache[toolName] = alternateTool;
44-
return alternateTool;
58+
return {binPath: alternateTool, why: 'alternateTool'};
4559
}
4660

4761
// FIXIT: this cache needs to be invalidated when go.goroot or go.alternateTool is changed.
4862
if (useCache && binPathCache[toolName]) {
49-
return binPathCache[toolName];
63+
return {binPath: binPathCache[toolName], why: 'cached'};
5064
}
5165

5266
const binname = alternateTool && !path.isAbsolute(alternateTool) ? alternateTool : toolName;
5367
const pathFromGoBin = getBinPathFromEnvVar(binname, process.env['GOBIN'], false);
5468
if (pathFromGoBin) {
5569
binPathCache[toolName] = pathFromGoBin;
56-
return pathFromGoBin;
70+
return {binPath: pathFromGoBin, why: 'gobin'};
5771
}
5872

5973
for (const preferred of preferredGopaths) {
@@ -62,7 +76,7 @@ export function getBinPathWithPreferredGopathGoroot(
6276
const pathFrompreferredGoPath = getBinPathFromEnvVar(binname, preferred, true);
6377
if (pathFrompreferredGoPath) {
6478
binPathCache[toolName] = pathFrompreferredGoPath;
65-
return pathFrompreferredGoPath;
79+
return {binPath: pathFrompreferredGoPath, why: 'gopath'};
6680
}
6781
}
6882
}
@@ -71,28 +85,28 @@ export function getBinPathWithPreferredGopathGoroot(
7185
const pathFromGoRoot = getBinPathFromEnvVar(binname, preferredGoroot || getCurrentGoRoot(), true);
7286
if (pathFromGoRoot) {
7387
binPathCache[toolName] = pathFromGoRoot;
74-
return pathFromGoRoot;
88+
return {binPath: pathFromGoRoot, why: 'goroot'};
7589
}
7690

7791
// Finally search PATH parts
7892
const pathFromPath = getBinPathFromEnvVar(binname, envPath, false);
7993
if (pathFromPath) {
8094
binPathCache[toolName] = pathFromPath;
81-
return pathFromPath;
95+
return {binPath: pathFromPath, why: 'path'};
8296
}
8397

8498
// Check default path for go
8599
if (toolName === 'go') {
86100
const defaultPathForGo = process.platform === 'win32' ? 'C:\\Go\\bin\\go.exe' : '/usr/local/go/bin/go';
87101
if (executableFileExists(defaultPathForGo)) {
88102
binPathCache[toolName] = defaultPathForGo;
89-
return defaultPathForGo;
103+
return {binPath: defaultPathForGo, why: 'default'};
90104
}
91-
return;
105+
return {binPath: ''};
92106
}
93107

94108
// Else return the binary name directly (this will likely always fail downstream)
95-
return toolName;
109+
return {binPath: toolName};
96110
}
97111

98112
/**

0 commit comments

Comments
 (0)