src/goInstallTools.ts: add GOROOT/bin to PATH when it wasn't found from PATH
The fix for golang/vscode-go#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 golang/vscode-go#679
Fixes golang/vscode-go#713
Change-Id: Ie00612fcef2cf4c2a187a263da04b342182c030b
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/258316
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Suzy Mueller <suzmue@golang.org>
diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts
index 4065f89..bc4f5a4 100644
--- a/src/goInstallTools.ts
+++ b/src/goInstallTools.ts
@@ -31,6 +31,7 @@
import { getFromWorkspaceState } from './stateUtils';
import {
getBinPath,
+ getBinPathWithExplanation,
getGoConfig,
getGoVersion,
getTempFilePath,
@@ -38,7 +39,7 @@
GoVersion,
rmdirRecursive,
} from './util';
-import { correctBinname, envPath, getCurrentGoRoot, getToolFromToolPath, setCurrentGoRoot } from './utils/pathUtils';
+import { envPath, getCurrentGoRoot, getToolFromToolPath, setCurrentGoRoot } from './utils/pathUtils';
// declinedUpdates tracks the tools that the user has declined to update.
const declinedUpdates: Tool[] = [];
@@ -344,7 +345,9 @@
}
export function updateGoVarsFromConfig(): Promise<void> {
- const goRuntimePath = getBinPath('go', false);
+ const {binPath, why} = getBinPathWithExplanation('go', false);
+ const goRuntimePath = binPath;
+
logVerbose(`updateGoVarsFromConfig: found 'go' in ${goRuntimePath}`);
if (!goRuntimePath || !path.isAbsolute(goRuntimePath)) {
// getBinPath returns the absolute path to the tool if it exists.
@@ -386,8 +389,8 @@
// cgo, gopls, and other underlying tools will inherit the environment and attempt
// to locate 'go' from the PATH env var.
// Update the PATH only if users configured to use a different
- // version of go than the system default.
- if (!!goPickedByExtension()) {
+ // version of go than the system default found from PATH (or Path).
+ if (why !== 'path') {
addGoRuntimeBaseToPATH(path.join(getCurrentGoRoot(), 'bin'));
}
initGoStatusBar();
@@ -398,41 +401,6 @@
});
}
-// The go command is picked up by searching directories in PATH by default.
-// But users can override it and force the extension to pick a different
-// one by configuring
-//
-// 1) with the go.environment.choose command, which stores the selection
-// in the workspace memento with the key 'selectedGo',
-// 2) with 'go.alternateTools': { 'go': ... } setting, or
-// 3) with 'go.goroot' setting
-//
-// goPickedByExtension returns the chosen path if the default path should
-// be overridden by above methods.
-// TODO: This logic is duplicated in getBinPath. Centralize this logic.
-function goPickedByExtension(): string | undefined {
- // getFromWorkspaceState('selectedGo')
- const selectedGoPath: string = getFromWorkspaceState('selectedGo')?.binpath;
- if (selectedGoPath) {
- return selectedGoPath;
- }
-
- const cfg = getGoConfig();
-
- // 'go.alternateTools.go'
- const alternateTools: { [key: string]: string } = cfg.get('alternateTools');
- const alternateToolPath: string = alternateTools['go'];
- if (alternateToolPath) {
- return alternateToolPath;
- }
- // 'go.goroot'
- const goRoot: string = cfg.get('goroot');
- if (goRoot) {
- return path.join(goRoot, 'bin', correctBinname('go'));
- }
- return undefined;
-}
-
let alreadyOfferedToInstallTools = false;
export async function offerToInstallTools() {
diff --git a/src/util.ts b/src/util.ts
index fa94f7b..ee361b4 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -20,7 +20,7 @@
import {
envPath,
fixDriveCasingInWindows,
- getBinPathWithPreferredGopathGoroot,
+ getBinPathWithPreferredGopathGorootWithExplanation,
getCurrentGoRoot,
getInferredGopath,
resolveHomeDir,
@@ -477,7 +477,15 @@
}
}
+// getBinPath returns the path to the tool.
export function getBinPath(tool: string, useCache = true): string {
+ const r = getBinPathWithExplanation(tool, useCache);
+ return r.binPath;
+}
+
+// getBinPathWithExplanation returns the path to the tool, and the explanation on why
+// the path was chosen. See getBinPathWithPreferredGopathGorootWithExplanation for details.
+export function getBinPathWithExplanation(tool: string, useCache = true): {binPath: string, why?: string} {
const cfg = getGoConfig();
const alternateTools: { [key: string]: string } = cfg.get('alternateTools');
const alternateToolPath: string = alternateTools[tool];
@@ -487,7 +495,7 @@
selectedGoPath = getFromWorkspaceState('selectedGo')?.binpath;
}
- return getBinPathWithPreferredGopathGoroot(
+ return getBinPathWithPreferredGopathGorootWithExplanation(
tool,
tool === 'go' ? [] : [getToolsGopath(), getCurrentGoPath()],
tool === 'go' && cfg.get('goroot') ? resolvePath(cfg.get('goroot')) : undefined,
diff --git a/src/utils/pathUtils.ts b/src/utils/pathUtils.ts
index 74fe93c..e0c2118 100644
--- a/src/utils/pathUtils.ts
+++ b/src/utils/pathUtils.ts
@@ -38,23 +38,37 @@
preferredGopaths: string[],
preferredGoroot?: string,
alternateTool?: string,
- useCache = true,
+ useCache = true
): string {
+ const r = getBinPathWithPreferredGopathGorootWithExplanation(
+ toolName, preferredGopaths, preferredGoroot, alternateTool, useCache);
+ return r.binPath;
+}
+
+// Is same as getBinPAthWithPreferredGopathGoroot, but returns why the
+// returned path was chosen.
+export function getBinPathWithPreferredGopathGorootWithExplanation(
+ toolName: string,
+ preferredGopaths: string[],
+ preferredGoroot?: string,
+ alternateTool?: string,
+ useCache = true,
+): {binPath: string, why?: string} {
if (alternateTool && path.isAbsolute(alternateTool) && executableFileExists(alternateTool)) {
binPathCache[toolName] = alternateTool;
- return alternateTool;
+ return {binPath: alternateTool, why: 'alternateTool'};
}
// FIXIT: this cache needs to be invalidated when go.goroot or go.alternateTool is changed.
if (useCache && binPathCache[toolName]) {
- return binPathCache[toolName];
+ return {binPath: binPathCache[toolName], why: 'cached'};
}
const binname = alternateTool && !path.isAbsolute(alternateTool) ? alternateTool : toolName;
const pathFromGoBin = getBinPathFromEnvVar(binname, process.env['GOBIN'], false);
if (pathFromGoBin) {
binPathCache[toolName] = pathFromGoBin;
- return pathFromGoBin;
+ return {binPath: pathFromGoBin, why: 'gobin'};
}
for (const preferred of preferredGopaths) {
@@ -63,7 +77,7 @@
const pathFrompreferredGoPath = getBinPathFromEnvVar(binname, preferred, true);
if (pathFrompreferredGoPath) {
binPathCache[toolName] = pathFrompreferredGoPath;
- return pathFrompreferredGoPath;
+ return {binPath: pathFrompreferredGoPath, why: 'gopath'};
}
}
}
@@ -72,14 +86,14 @@
const pathFromGoRoot = getBinPathFromEnvVar(binname, preferredGoroot || getCurrentGoRoot(), true);
if (pathFromGoRoot) {
binPathCache[toolName] = pathFromGoRoot;
- return pathFromGoRoot;
+ return {binPath: pathFromGoRoot, why: 'goroot'};
}
// Finally search PATH parts
const pathFromPath = getBinPathFromEnvVar(binname, envPath, false);
if (pathFromPath) {
binPathCache[toolName] = pathFromPath;
- return pathFromPath;
+ return {binPath: pathFromPath, why: 'path'};
}
// Check default path for go
@@ -87,13 +101,13 @@
const defaultPathForGo = process.platform === 'win32' ? 'C:\\Go\\bin\\go.exe' : '/usr/local/go/bin/go';
if (executableFileExists(defaultPathForGo)) {
binPathCache[toolName] = defaultPathForGo;
- return defaultPathForGo;
+ return {binPath: defaultPathForGo, why: 'default'};
}
- return;
+ return {binPath: ''};
}
// Else return the binary name directly (this will likely always fail downstream)
- return toolName;
+ return {binPath: toolName};
}
/**