src: refactor tools env variables to handle installation and execution
I modified this change to focus only on addressing the differences between environment variables when installing tools vs. when running them. https://golang.org/cl/233325 now handles the issue reports on restart.
Change-Id: I9d03e2c8f9244bade19606e9d9c6892da9fa0c66
GitHub-Last-Rev: e6f4db38c2ae407481b8bc05f689c743a7517efb
GitHub-Pull-Request: golang/vscode-go#28
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/232863
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/src/goBuild.ts b/src/goBuild.ts
index 9b8129d..0aaee96 100644
--- a/src/goBuild.ts
+++ b/src/goBuild.ts
@@ -5,6 +5,7 @@
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { buildDiagnosticCollection } from './goMain';
import { isModSupported } from './goModules';
import { getNonVendorPackages } from './goPackages';
@@ -16,7 +17,6 @@
getGoConfig,
getModuleCache,
getTempFilePath,
- getToolsEnvVars,
getWorkspaceFolderPath,
handleDiagnosticErrors,
ICheckResult,
@@ -100,14 +100,14 @@
return [];
}
- const buildEnv = Object.assign({}, getToolsEnvVars());
+ const buildEnv = toolExecutionEnvironment();
const tmpPath = getTempFilePath('go-code-check');
const isTestFile = fileUri && fileUri.fsPath.endsWith('_test.go');
const buildFlags: string[] = isTestFile
? getTestFlags(goConfig)
: Array.isArray(goConfig['buildFlags'])
- ? [...goConfig['buildFlags']]
- : [];
+ ? [...goConfig['buildFlags']]
+ : [];
const buildArgs: string[] = isTestFile ? ['test', '-c'] : ['build'];
if (goConfig['installDependenciesWhenBuilding'] === true && !isMod) {
diff --git a/src/goDebugConfiguration.ts b/src/goDebugConfiguration.ts
index d09f2b1..a69087a 100644
--- a/src/goDebugConfiguration.ts
+++ b/src/goDebugConfiguration.ts
@@ -7,10 +7,11 @@
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { packagePathToGoModPathMap } from './goModules';
import { getFromGlobalState, updateGlobalState } from './stateUtils';
-import { getBinPath, getCurrentGoPath, getGoConfig, getToolsEnvVars } from './util';
+import { getBinPath, getCurrentGoPath, getGoConfig } from './util';
export class GoDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
public provideDebugConfigurations(
@@ -61,7 +62,7 @@
}
const goConfig = getGoConfig(folder && folder.uri);
- const goToolsEnvVars = getToolsEnvVars();
+ const goToolsEnvVars = toolExecutionEnvironment();
Object.keys(goToolsEnvVars).forEach((key) => {
if (!debugConfiguration['env'].hasOwnProperty(key)) {
debugConfiguration['env'][key] = goToolsEnvVars[key];
diff --git a/src/goDeclaration.ts b/src/goDeclaration.ts
index 798b014..7eb03ee 100644
--- a/src/goDeclaration.ts
+++ b/src/goDeclaration.ts
@@ -8,6 +8,7 @@
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
import { getModFolderPath, promptToUpdateToolForModules } from './goModules';
import {
@@ -16,7 +17,6 @@
getFileArchive,
getGoConfig,
getModuleCache,
- getToolsEnvVars,
getWorkspaceFolderPath,
goKeywords,
isPositionInString,
@@ -132,7 +132,7 @@
return Promise.reject(missingToolMsg + godefTool);
}
const offset = byteOffsetAt(input.document, input.position);
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
let p: cp.ChildProcess;
if (token) {
token.onCancellationRequested(() => killTree(p.pid));
@@ -223,7 +223,7 @@
return Promise.reject(missingToolMsg + 'gogetdoc');
}
const offset = byteOffsetAt(input.document, input.position);
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
let p: cp.ChildProcess;
if (token) {
token.onCancellationRequested(() => killTree(p.pid));
@@ -297,7 +297,7 @@
return Promise.reject(missingToolMsg + 'guru');
}
const offset = byteOffsetAt(input.document, input.position);
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
let p: cp.ChildProcess;
if (token) {
token.onCancellationRequested(() => killTree(p.pid));
diff --git a/src/goDoctor.ts b/src/goDoctor.ts
index 9833596..b8a396b 100644
--- a/src/goDoctor.ts
+++ b/src/goDoctor.ts
@@ -8,8 +8,9 @@
import cp = require('child_process');
import { dirname, isAbsolute } from 'path';
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
-import { getBinPath, getToolsEnvVars } from './util';
+import { getBinPath } from './util';
/**
* Extracts function out of current selection and replaces the current selection with a call to the extracted function.
@@ -78,7 +79,7 @@
'-w',
'-pos',
`${selection.start.line + 1},${selection.start.character + 1}:${selection.end.line + 1},${
- selection.end.character
+ selection.end.character
}`,
'-file',
fileName,
@@ -86,7 +87,7 @@
newName
],
{
- env: getToolsEnvVars(),
+ env: toolExecutionEnvironment(),
cwd: dirname(fileName)
},
(err, stdout, stderr) => {
diff --git a/src/goEnv.ts b/src/goEnv.ts
new file mode 100644
index 0000000..aa02546
--- /dev/null
+++ b/src/goEnv.ts
@@ -0,0 +1,69 @@
+/*---------------------------------------------------------
+ * Copyright (C) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+'use strict';
+
+import path = require('path');
+import vscode = require('vscode');
+import { getCurrentGoPath, getGoConfig, getToolsGopath, resolvePath } from './util';
+
+// toolInstallationEnvironment returns the environment in which tools should
+// be installed. It always returns a new object.
+export function toolInstallationEnvironment(): NodeJS.Dict<string> {
+ const env = newEnvironment();
+
+ // If the go.toolsGopath is set, use its value as the GOPATH for `go` processes.
+ // Else use the Current Gopath
+ let toolsGopath = getToolsGopath();
+ if (toolsGopath) {
+ // User has explicitly chosen to use toolsGopath, so ignore GOBIN.
+ env['GOBIN'] = '';
+ } else {
+ toolsGopath = getCurrentGoPath();
+ }
+ if (!toolsGopath) {
+ const msg = 'Cannot install Go tools. Set either go.gopath or go.toolsGopath in settings.';
+ vscode.window.showInformationMessage(msg, 'Open User Settings', 'Open Workspace Settings').then((selected) => {
+ switch (selected) {
+ case 'Open User Settings':
+ vscode.commands.executeCommand('workbench.action.openGlobalSettings');
+ break;
+ case 'Open Workspace Settings':
+ vscode.commands.executeCommand('workbench.action.openWorkspaceSettings');
+ break;
+ }
+ });
+ return;
+ }
+ env['GOPATH'] = toolsGopath;
+
+ return env;
+}
+
+// toolExecutionEnvironment returns the environment in which tools should
+// be executed. It always returns a new object.
+export function toolExecutionEnvironment(): NodeJS.Dict<string> {
+ const env = newEnvironment();
+ const gopath = getCurrentGoPath();
+ if (gopath) {
+ env['GOPATH'] = gopath;
+ }
+ return env;
+}
+
+function newEnvironment(): NodeJS.Dict<string> {
+ const toolsEnvVars = getGoConfig()['toolsEnvVars'];
+ const env = Object.assign({}, process.env, toolsEnvVars);
+
+ // The http.proxy setting takes precedence over environment variables.
+ const httpProxy = vscode.workspace.getConfiguration('http', null).get('proxy');
+ if (httpProxy && typeof httpProxy === 'string') {
+ env['http_proxy'] = httpProxy;
+ env['HTTP_PROXY'] = httpProxy;
+ env['https_proxy'] = httpProxy;
+ env['HTTPS_PROXY'] = httpProxy;
+ }
+ return env;
+}
diff --git a/src/goFillStruct.ts b/src/goFillStruct.ts
index beb12aa..4e9fba6 100644
--- a/src/goFillStruct.ts
+++ b/src/goFillStruct.ts
@@ -7,8 +7,9 @@
import cp = require('child_process');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
-import { byteOffsetAt, getBinPath, getFileArchive, getToolsEnvVars, makeMemoizedByteOffsetConverter } from './util';
+import { byteOffsetAt, getBinPath, getFileArchive, makeMemoizedByteOffsetConverter } from './util';
// Interface for the output from fillstruct
interface GoFillStructOutput {
@@ -59,7 +60,7 @@
const tabsCount = getTabsCount(editor);
return new Promise<void>((resolve, reject) => {
- const p = cp.execFile(fillstruct, args, { env: getToolsEnvVars() }, (err, stdout, stderr) => {
+ const p = cp.execFile(fillstruct, args, { env: toolExecutionEnvironment() }, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('fillstruct');
diff --git a/src/goFormat.ts b/src/goFormat.ts
index 78a52a3..6321e66 100644
--- a/src/goFormat.ts
+++ b/src/goFormat.ts
@@ -8,8 +8,9 @@
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
-import { getBinPath, getGoConfig, getToolsEnvVars, killTree } from './util';
+import { getBinPath, getGoConfig, killTree } from './util';
export class GoDocumentFormattingEditProvider implements vscode.DocumentFormattingEditProvider {
public provideDocumentFormattingEdits(
@@ -70,7 +71,7 @@
return reject();
}
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
const cwd = path.dirname(document.fileName);
let stdout = '';
let stderr = '';
diff --git a/src/goGenerateTests.ts b/src/goGenerateTests.ts
index 9521e7e..a9e71c9 100644
--- a/src/goGenerateTests.ts
+++ b/src/goGenerateTests.ts
@@ -9,10 +9,11 @@
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { GoDocumentSymbolProvider } from './goOutline';
import { outputChannel } from './goStatus';
-import { getBinPath, getGoConfig, getToolsEnvVars } from './util';
+import { getBinPath, getGoConfig } from './util';
const generatedWord = 'Generated ';
@@ -172,7 +173,7 @@
args = args.concat(['-all', conf.dir]);
}
- cp.execFile(cmd, args, { env: getToolsEnvVars() }, (err, stdout, stderr) => {
+ cp.execFile(cmd, args, { env: toolExecutionEnvironment() }, (err, stdout, stderr) => {
outputChannel.appendLine('Generating Tests: ' + cmd + ' ' + args.join(' '));
try {
diff --git a/src/goImpl.ts b/src/goImpl.ts
index dcaf4f0..3672315 100644
--- a/src/goImpl.ts
+++ b/src/goImpl.ts
@@ -8,8 +8,9 @@
import cp = require('child_process');
import { dirname } from 'path';
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
-import { getBinPath, getToolsEnvVars } from './util';
+import { getBinPath } from './util';
// Supports only passing interface, see TODO in implCursor to finish
const inputRegex = /^(\w+\ \*?\w+\ )?([\w./]+)$/;
@@ -49,7 +50,7 @@
const p = cp.execFile(
goimpl,
args,
- { env: getToolsEnvVars(), cwd: dirname(editor.document.fileName) },
+ { env: toolExecutionEnvironment(), cwd: dirname(editor.document.fileName) },
(err, stdout, stderr) => {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('impl');
diff --git a/src/goImplementations.ts b/src/goImplementations.ts
index 2bc45d5..4ee9e29 100644
--- a/src/goImplementations.ts
+++ b/src/goImplementations.ts
@@ -8,6 +8,7 @@
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { envPath } from './goPath';
import {
@@ -15,7 +16,6 @@
canonicalizeGOPATHPrefix,
getBinPath,
getGoConfig,
- getToolsEnvVars,
getWorkspaceFolderPath,
killTree
} from './util';
@@ -66,7 +66,7 @@
if (token.isCancellationRequested) {
return resolve(null);
}
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
const listProcess = cp.execFile(
goRuntimePath,
['list', '-e', '-json'],
diff --git a/src/goImport.ts b/src/goImport.ts
index c8445c7..fade834 100644
--- a/src/goImport.ts
+++ b/src/goImport.ts
@@ -7,11 +7,12 @@
import cp = require('child_process');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { documentSymbols, GoOutlineImportsOptions } from './goOutline';
import { getImportablePackages } from './goPackages';
import { envPath } from './goPath';
-import { getBinPath, getImportPath, getToolsEnvVars, parseFilePrelude } from './util';
+import { getBinPath, getImportPath, parseFilePrelude } from './util';
const missingToolMsg = 'Missing tool: ';
@@ -183,7 +184,7 @@
);
return;
}
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
cp.execFile(goRuntimePath, ['list', '-f', '{{.Dir}}', importPath], { env }, (err, stdout, stderr) => {
const dirs = (stdout || '').split('\n');
diff --git a/src/goInstall.ts b/src/goInstall.ts
index 32aaa9c..4f351aa 100644
--- a/src/goInstall.ts
+++ b/src/goInstall.ts
@@ -6,10 +6,11 @@
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { isModSupported } from './goModules';
import { envPath, getCurrentGoWorkspaceFromGOPATH } from './goPath';
import { outputChannel } from './goStatus';
-import { getBinPath, getCurrentGoPath, getGoConfig, getModuleCache, getToolsEnvVars } from './util';
+import { getBinPath, getCurrentGoPath, getGoConfig, getModuleCache } from './util';
export async function installCurrentPackage(): Promise<void> {
const editor = vscode.window.activeTextEditor;
@@ -32,7 +33,7 @@
return;
}
- const env = Object.assign({}, getToolsEnvVars());
+ const env = toolExecutionEnvironment();
const cwd = path.dirname(editor.document.uri.fsPath);
const isMod = await isModSupported(editor.document.uri);
diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts
index 121d056..1d2bc4e 100644
--- a/src/goInstallTools.ts
+++ b/src/goInstallTools.ts
@@ -11,6 +11,7 @@
import { SemVer } from 'semver';
import util = require('util');
import vscode = require('vscode');
+import { toolInstallationEnvironment } from './goEnv';
import { getLanguageServerToolPath } from './goLanguageServer';
import { restartLanguageServer } from './goMain';
import { envPath, getToolFromToolPath } from './goPath';
@@ -28,12 +29,9 @@
} from './goTools';
import {
getBinPath,
- getCurrentGoPath,
getGoConfig,
getGoVersion,
getTempFilePath,
- getToolsEnvVars,
- getToolsGopath,
GoVersion,
resolvePath,
rmdirRecursive
@@ -106,54 +104,22 @@
return;
}
- // http.proxy setting takes precedence over environment variables
- const httpProxy = vscode.workspace.getConfiguration('http', null).get('proxy');
- const envForTools = Object.assign({}, process.env, getToolsEnvVars());
- if (httpProxy) {
- envForTools['http_proxy'] = httpProxy;
- envForTools['HTTP_PROXY'] = httpProxy;
- envForTools['https_proxy'] = httpProxy;
- envForTools['HTTPS_PROXY'] = httpProxy;
- }
-
outputChannel.show();
outputChannel.clear();
- // If the go.toolsGopath is set, use its value as the GOPATH for the "go get" child process.
- // Else use the Current Gopath
- let toolsGopath = getToolsGopath();
- if (toolsGopath) {
- // User has explicitly chosen to use toolsGopath, so ignore GOBIN
- envForTools['GOBIN'] = '';
- outputChannel.appendLine(`Using the value ${toolsGopath} from the go.toolsGopath setting.`);
- } else {
- toolsGopath = getCurrentGoPath();
- outputChannel.appendLine(`go.toolsGopath setting is not set. Using GOPATH ${toolsGopath}`);
+ const envForTools = toolInstallationEnvironment();
+ const toolsGopath = envForTools['GOPATH'];
+ let envMsg = `Tools environment: GOPATH=${toolsGopath}`;
+ if (envForTools['GOBIN']) {
+ envMsg += `, GOBIN=${envForTools['GOBIN']}`;
}
- if (toolsGopath) {
- const paths = toolsGopath.split(path.delimiter);
- toolsGopath = paths[0];
- envForTools['GOPATH'] = toolsGopath;
- } else {
- const msg = 'Cannot install Go tools. Set either go.gopath or go.toolsGopath in settings.';
- vscode.window.showInformationMessage(msg, 'Open User Settings', 'Open Workspace Settings').then((selected) => {
- switch (selected) {
- case 'Open User Settings':
- vscode.commands.executeCommand('workbench.action.openGlobalSettings');
- break;
- case 'Open Workspace Settings':
- vscode.commands.executeCommand('workbench.action.openWorkspaceSettings');
- break;
- }
- });
- return;
- }
+ outputChannel.appendLine(envMsg);
let installingMsg = `Installing ${missing.length} ${missing.length > 1 ? 'tools' : 'tool'} at `;
if (envForTools['GOBIN']) {
installingMsg += `the configured GOBIN: ${envForTools['GOBIN']}`;
} else {
- installingMsg += toolsGopath + path.sep + 'bin';
+ installingMsg += `${toolsGopath}${path.sep}bin`;
}
// If the user is on Go >= 1.11, tools should be installed with modules enabled.
@@ -258,6 +224,7 @@
args.push(importPath);
let output: string;
+ let result: string = '';
try {
const opts = {
env,
@@ -281,13 +248,13 @@
outputChannel.appendLine(`Installing ${importPath} SUCCEEDED`);
} catch (e) {
outputChannel.appendLine(`Installing ${importPath} FAILED`);
- return `failed to install ${tool}: ${e} ${output} `;
+ result = `failed to install ${tool}: ${e} ${output} `;
}
// Delete the temporary installation directory.
rmdirRecursive(toolsTmpDir);
- return '';
+ return result;
}
export async function promptForMissingTool(toolName: string) {
diff --git a/src/goLanguageServer.ts b/src/goLanguageServer.ts
index 257ffdb..9de10a2 100644
--- a/src/goLanguageServer.ts
+++ b/src/goLanguageServer.ts
@@ -20,6 +20,7 @@
} from 'vscode-languageclient';
import WebRequest = require('web-request');
import { GoDefinitionProvider } from './goDeclaration';
+import { toolExecutionEnvironment } from './goEnv';
import { GoHoverProvider } from './goExtraInfo';
import { GoDocumentFormattingEditProvider } from './goFormat';
import { GoImplementationProvider } from './goImplementations';
@@ -37,7 +38,7 @@
import { getTool, Tool } from './goTools';
import { GoTypeDefinitionProvider } from './goTypeDefinition';
import { getFromGlobalState, updateGlobalState } from './stateUtils';
-import { getBinPath, getCurrentGoPath, getGoConfig, getToolsEnvVars } from './util';
+import { getBinPath, getCurrentGoPath, getGoConfig } from './util';
interface LanguageServerConfig {
serverName: string;
@@ -346,7 +347,6 @@
export function buildLanguageServerConfig(): LanguageServerConfig {
const goConfig = getGoConfig();
- const toolsEnv = getToolsEnvVars();
const cfg: LanguageServerConfig = {
serverName: '',
path: '',
@@ -359,8 +359,8 @@
diagnostics: goConfig['languageServerExperimentalFeatures']['diagnostics'],
documentLink: goConfig['languageServerExperimentalFeatures']['documentLink']
},
- env: toolsEnv,
- checkForUpdates: goConfig['useGoProxyToCheckForToolUpdates'],
+ env: toolExecutionEnvironment(),
+ checkForUpdates: goConfig['useGoProxyToCheckForToolUpdates']
};
// Don't look for the path if the server is not enabled.
if (!cfg.enabled) {
@@ -582,11 +582,10 @@
// installed on the user's machine. This is determined by running the
// `gopls version` command.
export async function getLocalGoplsVersion(goplsPath: string): Promise<string> {
- const env = getToolsEnvVars();
const execFile = util.promisify(cp.execFile);
let output: any;
try {
- const { stdout } = await execFile(goplsPath, ['version'], { env });
+ const { stdout } = await execFile(goplsPath, ['version'], { env: toolExecutionEnvironment() });
output = stdout;
} catch (e) {
// The "gopls version" command is not supported, or something else went wrong.
@@ -827,7 +826,7 @@
// Wait for the command to finish before restarting the
// server, but don't bother handling errors.
const execFile = util.promisify(cp.execFile);
- await execFile(latestConfig.path, ['bug'], { env: getToolsEnvVars() });
+ await execFile(latestConfig.path, ['bug'], { env: toolExecutionEnvironment() });
break;
case 'Next time':
break;
diff --git a/src/goLint.ts b/src/goLint.ts
index eca0101..2eb80ea 100644
--- a/src/goLint.ts
+++ b/src/goLint.ts
@@ -5,11 +5,11 @@
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { lintDiagnosticCollection } from './goMain';
import { diagnosticsStatusBarItem, outputChannel } from './goStatus';
import {
getGoConfig,
- getToolsEnvVars,
getToolsGopath,
getWorkspaceFolderPath,
handleDiagnosticErrors,
@@ -83,7 +83,7 @@
const lintTool = goConfig['lintTool'] || 'golint';
const lintFlags: string[] = goConfig['lintFlags'] || [];
- const lintEnv = Object.assign({}, getToolsEnvVars());
+ const lintEnv = toolExecutionEnvironment();
const args: string[] = [];
lintFlags.forEach((flag) => {
diff --git a/src/goLiveErrors.ts b/src/goLiveErrors.ts
index 8c18dd4..e6b6cb8 100644
--- a/src/goLiveErrors.ts
+++ b/src/goLiveErrors.ts
@@ -8,10 +8,11 @@
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { buildDiagnosticCollection } from './goMain';
import { isModSupported } from './goModules';
-import { getBinPath, getGoConfig, getToolsEnvVars } from './util';
+import { getBinPath, getGoConfig } from './util';
// Interface for settings configuration for adding and removing tags
interface GoLiveErrorsConfig {
@@ -77,7 +78,7 @@
const fileContents = e.document.getText();
const fileName = e.document.fileName;
const args = ['-e', '-a', '-lf=' + fileName, path.dirname(fileName)];
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
const p = cp.execFile(gotypeLive, args, { env }, (err, stdout, stderr) => {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('gotype-live');
diff --git a/src/goMain.ts b/src/goMain.ts
index dc16200..3451bd5 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -17,6 +17,7 @@
} from './goCover';
import { GoDebugConfigurationProvider } from './goDebugConfiguration';
import { extractFunction, extractVariable } from './goDoctor';
+import { toolExecutionEnvironment } from './goEnv';
import { runFillStruct } from './goFillStruct';
import * as goGenerateTests from './goGenerateTests';
import { goGetPackage } from './goGetPackage';
@@ -47,7 +48,7 @@
import { cancelRunningTests, showTestOutput } from './testUtils';
import {
cleanupTempDir, getBinPath, getCurrentGoPath, getExtensionCommands, getGoConfig,
- getGoVersion, getToolsEnvVars, getToolsGopath, getWorkspaceFolderPath, handleDiagnosticErrors, isGoPathSet
+ getGoVersion, getToolsGopath, getWorkspaceFolderPath, handleDiagnosticErrors, isGoPathSet
} from './util';
export let buildDiagnosticCollection: vscode.DiagnosticCollection;
@@ -409,7 +410,7 @@
updateCodeCoverageDecorators(updatedGoConfig['coverageDecorator']);
}
if (e.affectsConfiguration('go.toolsEnvVars')) {
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
if (GO111MODULE !== env['GO111MODULE']) {
const reloadMsg =
'Reload VS Code window so that the Go tools can respect the change to GO111MODULE';
diff --git a/src/goModifytags.ts b/src/goModifytags.ts
index ac25e88..bfaa5b2 100644
--- a/src/goModifytags.ts
+++ b/src/goModifytags.ts
@@ -7,8 +7,9 @@
import cp = require('child_process');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
-import { byteOffsetAt, getBinPath, getFileArchive, getGoConfig, getToolsEnvVars } from './util';
+import { byteOffsetAt, getBinPath, getFileArchive, getGoConfig } from './util';
// Interface for the output from gomodifytags
interface GomodifytagsOutput {
@@ -144,7 +145,7 @@
const gomodifytags = getBinPath('gomodifytags');
const editor = vscode.window.activeTextEditor;
const input = getFileArchive(editor.document);
- const p = cp.execFile(gomodifytags, args, { env: getToolsEnvVars() }, (err, stdout, stderr) => {
+ const p = cp.execFile(gomodifytags, args, { env: toolExecutionEnvironment() }, (err, stdout, stderr) => {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('gomodifytags');
return;
diff --git a/src/goModules.ts b/src/goModules.ts
index 65d8b78..a9b644e 100644
--- a/src/goModules.ts
+++ b/src/goModules.ts
@@ -6,12 +6,12 @@
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { installTools } from './goInstallTools';
-import { restartLanguageServer } from './goMain';
import { envPath, fixDriveCasingInWindows } from './goPath';
import { getTool } from './goTools';
import { getFromGlobalState, updateGlobalState } from './stateUtils';
-import { getBinPath, getGoConfig, getGoVersion, getModuleCache, getToolsEnvVars } from './util';
+import { getBinPath, getGoConfig, getGoVersion, getModuleCache } from './util';
export let GO111MODULE: string;
@@ -23,10 +23,10 @@
);
return;
}
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
GO111MODULE = env['GO111MODULE'];
return new Promise((resolve) => {
- cp.execFile(goExecutable, ['env', 'GOMOD'], { cwd: folderPath, env: getToolsEnvVars() }, (err, stdout) => {
+ cp.execFile(goExecutable, ['env', 'GOMOD'], { cwd: folderPath, env }, (err, stdout) => {
if (err) {
console.warn(`Error when running go env GOMOD: ${err}`);
return resolve();
@@ -169,7 +169,7 @@
return;
}
return new Promise<string>((resolve) => {
- const childProcess = cp.spawn(goRuntimePath, ['list'], { cwd, env: getToolsEnvVars() });
+ const childProcess = cp.spawn(goRuntimePath, ['list'], { cwd, env: toolExecutionEnvironment() });
const chunks: any[] = [];
childProcess.stdout.on('data', (stdout) => {
chunks.push(stdout);
diff --git a/src/goOutline.ts b/src/goOutline.ts
index 15ad345..97af953 100644
--- a/src/goOutline.ts
+++ b/src/goOutline.ts
@@ -7,12 +7,12 @@
import cp = require('child_process');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
import {
getBinPath,
getFileArchive,
getGoConfig,
- getToolsEnvVars,
killProcess,
makeMemoizedByteOffsetConverter
} from './util';
@@ -92,7 +92,7 @@
}
// Spawn `go-outline` process
- p = cp.execFile(gooutline, gooutlineFlags, { env: getToolsEnvVars() }, (err, stdout, stderr) => {
+ p = cp.execFile(gooutline, gooutlineFlags, { env: toolExecutionEnvironment() }, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('go-outline');
@@ -193,7 +193,7 @@
}
export class GoDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
- constructor(private includeImports?: boolean) {}
+ constructor(private includeImports?: boolean) { }
public provideDocumentSymbols(
document: vscode.TextDocument,
diff --git a/src/goPackages.ts b/src/goPackages.ts
index 208d2d2..8965435 100644
--- a/src/goPackages.ts
+++ b/src/goPackages.ts
@@ -6,9 +6,10 @@
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
import { envPath, fixDriveCasingInWindows, getCurrentGoWorkspaceFromGOPATH } from './goPath';
-import { getBinPath, getCurrentGoPath, getGoVersion, getToolsEnvVars, isVendorSupported } from './util';
+import { getBinPath, getCurrentGoPath, getGoVersion, isVendorSupported } from './util';
type GopkgsDone = (res: Map<string, PackageInfo>) => void;
interface Cache {
@@ -45,7 +46,7 @@
args.push('-workDir', workDir);
}
- const cmd = cp.spawn(gopkgsBinPath, args, { env: getToolsEnvVars() });
+ const cmd = cp.spawn(gopkgsBinPath, args, { env: toolExecutionEnvironment() });
const chunks: any[] = [];
const errchunks: any[] = [];
let err: any;
@@ -269,7 +270,7 @@
const childProcess = cp.spawn(
goRuntimePath,
['list', '-f', 'ImportPath: {{.ImportPath}} FolderPath: {{.Dir}}', './...'],
- { cwd: currentFolderPath, env: getToolsEnvVars() }
+ { cwd: currentFolderPath, env: toolExecutionEnvironment() }
);
const chunks: any[] = [];
childProcess.stdout.on('data', (stdout) => {
diff --git a/src/goReferences.ts b/src/goReferences.ts
index bb7acfb..44a86fc 100644
--- a/src/goReferences.ts
+++ b/src/goReferences.ts
@@ -8,6 +8,7 @@
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import {
byteOffsetAt,
@@ -15,7 +16,6 @@
getBinPath,
getFileArchive,
getGoConfig,
- getToolsEnvVars,
killTree
} from './util';
@@ -51,7 +51,7 @@
const filename = canonicalizeGOPATHPrefix(document.fileName);
const cwd = path.dirname(filename);
const offset = byteOffsetAt(document, wordRange.start);
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
const buildTags = getGoConfig(document.uri)['buildTags'];
const args = buildTags ? ['-tags', buildTags] : [];
args.push('-modified', 'referrers', `${filename}:#${offset.toString()}`);
diff --git a/src/goRename.ts b/src/goRename.ts
index bab3e25..55a97f7 100644
--- a/src/goRename.ts
+++ b/src/goRename.ts
@@ -8,9 +8,10 @@
import cp = require('child_process');
import vscode = require('vscode');
import { Edit, FilePatch, getEditsFromUnifiedDiffStr, isDiffToolAvailable } from './diffUtils';
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { outputChannel } from './goStatus';
-import { byteOffsetAt, canonicalizeGOPATHPrefix, getBinPath, getGoConfig, getToolsEnvVars, killTree } from './util';
+import { byteOffsetAt, canonicalizeGOPATHPrefix, getBinPath, getGoConfig, killTree } from './util';
export class GoRenameProvider implements vscode.RenameProvider {
public provideRenameEdits(
@@ -35,7 +36,7 @@
const range = document.getWordRangeAtPosition(position);
const pos = range ? range.start : position;
const offset = byteOffsetAt(document, pos);
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
const gorename = getBinPath('gorename');
const buildTags = getGoConfig(document.uri)['buildTags'];
const gorenameArgs = ['-offset', filename + ':#' + offset, '-to', newName];
diff --git a/src/goSuggest.ts b/src/goSuggest.ts
index 139fbc1..73c1263 100644
--- a/src/goSuggest.ts
+++ b/src/goSuggest.ts
@@ -8,6 +8,7 @@
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { getTextEditForAddImport } from './goImport';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
import { isModSupported } from './goModules';
@@ -19,7 +20,6 @@
getCurrentGoPath,
getGoConfig,
getParametersAndReturnType,
- getToolsEnvVars,
goBuiltinTypes,
goKeywords,
guessPackageNameFromFile,
@@ -269,7 +269,7 @@
const gocodeName = this.isGoMod ? 'gocode-gomod' : 'gocode';
const gocode = getBinPath(gocodeName);
if (path.isAbsolute(gocode)) {
- cp.spawn(gocode, ['close'], { env: getToolsEnvVars() });
+ cp.spawn(gocode, ['close'], { env: toolExecutionEnvironment() });
}
}
@@ -293,7 +293,7 @@
return reject();
}
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
let stdout = '';
let stderr = '';
@@ -380,8 +380,8 @@
config['useCodeSnippetsOnFunctionSuggestWithoutType']) &&
((suggest.class === 'func' && lineText.substr(position.character, 2) !== '()') || // Avoids met() -> method()()
(suggest.class === 'var' &&
- suggest.type.startsWith('func(') &&
- lineText.substr(position.character, 1) !== ')' && // Avoids snippets when typing params in a func call
+ suggest.type.startsWith('func(') &&
+ lineText.substr(position.character, 1) !== ')' && // Avoids snippets when typing params in a func call
lineText.substr(position.character, 1) !== ',')) // Avoids snippets when typing params in a func call
) {
const { params, returnType } = getParametersAndReturnType(suggest.type.substring(4));
@@ -421,22 +421,22 @@
const arg = param.substr(0, param.indexOf(' '));
paramSnippets.push(
'${' +
- (i + 1) +
- ':' +
- arg +
- '}' +
- param.substr(param.indexOf(' '), param.length)
+ (i + 1) +
+ ':' +
+ arg +
+ '}' +
+ param.substr(param.indexOf(' '), param.length)
);
}
}
item.insertText = new vscode.SnippetString(
suggest.name +
- '(func(' +
- paramSnippets.join(', ') +
- ') {\n $' +
- (params.length + 1) +
- '\n})' +
- returnType
+ '(func(' +
+ paramSnippets.join(', ') +
+ ') {\n $' +
+ (params.length + 1) +
+ '\n})' +
+ returnType
);
}
@@ -504,7 +504,7 @@
const setGocodeProps = new Promise<void>((resolve, reject) => {
const gocode = getBinPath('gocode');
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
cp.execFile(gocode, ['set'], { env }, (err, stdout, stderr) => {
if (err && stdout.startsWith('gocode: unknown subcommand:')) {
diff --git a/src/goSymbol.ts b/src/goSymbol.ts
index 2c03f6d..ae8cf8c 100644
--- a/src/goSymbol.ts
+++ b/src/goSymbol.ts
@@ -7,8 +7,9 @@
import cp = require('child_process');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
-import { getBinPath, getGoConfig, getToolsEnvVars, getWorkspaceFolderPath, killTree } from './util';
+import { getBinPath, getGoConfig, getWorkspaceFolderPath, killTree } from './util';
// Keep in sync with github.com/acroca/go-symbols'
interface GoSymbolDeclaration {
@@ -112,7 +113,7 @@
function callGoSymbols(args: string[], token: vscode.CancellationToken): Promise<GoSymbolDeclaration[]> {
const gosyms = getBinPath('go-symbols');
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
let p: cp.ChildProcess;
if (token) {
diff --git a/src/goTypeDefinition.ts b/src/goTypeDefinition.ts
index d414559..100deb1 100644
--- a/src/goTypeDefinition.ts
+++ b/src/goTypeDefinition.ts
@@ -9,6 +9,7 @@
import path = require('path');
import vscode = require('vscode');
import { adjustWordPosition, definitionLocation, parseMissingError } from './goDeclaration';
+import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import {
byteOffsetAt,
@@ -16,7 +17,6 @@
getBinPath,
getFileArchive,
getGoConfig,
- getToolsEnvVars,
goBuiltinTypes,
killTree
} from './util';
@@ -61,7 +61,7 @@
const filename = canonicalizeGOPATHPrefix(document.fileName);
const offset = byteOffsetAt(document, position);
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
const buildTags = getGoConfig(document.uri)['buildTags'];
const args = buildTags ? ['-tags', buildTags] : [];
args.push('-json', '-modified', 'describe', `${filename}:#${offset.toString()}`);
diff --git a/src/goVet.ts b/src/goVet.ts
index 1de766b..210213a 100644
--- a/src/goVet.ts
+++ b/src/goVet.ts
@@ -5,12 +5,12 @@
import path = require('path');
import vscode = require('vscode');
+import { toolExecutionEnvironment } from './goEnv';
import { vetDiagnosticCollection } from './goMain';
import { diagnosticsStatusBarItem, outputChannel } from './goStatus';
import {
getGoConfig,
getGoVersion,
- getToolsEnvVars,
getWorkspaceFolderPath,
handleDiagnosticErrors,
ICheckResult,
@@ -81,7 +81,7 @@
}
const vetFlags: string[] = goConfig['vetFlags'] || [];
- const vetEnv = Object.assign({}, getToolsEnvVars());
+ const vetEnv = toolExecutionEnvironment();
const args: string[] = [];
vetFlags.forEach((flag) => {
diff --git a/src/testUtils.ts b/src/testUtils.ts
index 4bba6f2..c318b0f 100644
--- a/src/testUtils.ts
+++ b/src/testUtils.ts
@@ -8,6 +8,7 @@
import vscode = require('vscode');
import { applyCodeCoverageToAllEditors } from './goCover';
+import { toolExecutionEnvironment } from './goEnv';
import { getCurrentPackage } from './goModules';
import { GoDocumentSymbolProvider } from './goOutline';
import { getNonVendorPackages } from './goPackages';
@@ -17,7 +18,6 @@
getCurrentGoPath,
getGoVersion,
getTempFilePath,
- getToolsEnvVars,
killTree,
LineBuffer,
resolvePath
@@ -80,7 +80,7 @@
}
export function getTestEnvVars(config: vscode.WorkspaceConfiguration): any {
- const envVars = getToolsEnvVars();
+ const envVars = toolExecutionEnvironment();
const testEnvConfig = config['testEnvVars'] || {};
let fileEnv: { [key: string]: any } = {};
diff --git a/src/util.ts b/src/util.ts
index 4a1ef83..13a2f53 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -11,6 +11,7 @@
import kill = require('tree-kill');
import vscode = require('vscode');
import { NearestNeighborDict, Node } from './avlTree';
+import { toolExecutionEnvironment } from './goEnv';
import { buildDiagnosticCollection, lintDiagnosticCollection, vetDiagnosticCollection } from './goMain';
import { getCurrentPackage } from './goModules';
import {
@@ -426,24 +427,6 @@
return document.fileName + '\n' + Buffer.byteLength(fileContents, 'utf8') + '\n' + fileContents;
}
-export function getToolsEnvVars(): any {
- const config = getGoConfig();
- const toolsEnvVars = config['toolsEnvVars'];
-
- const gopath = getCurrentGoPath();
- const envVars = Object.assign({}, process.env, gopath ? { GOPATH: gopath } : {});
-
- if (toolsEnvVars && typeof toolsEnvVars === 'object') {
- Object.keys(toolsEnvVars).forEach(
- (key) =>
- (envVars[key] =
- typeof toolsEnvVars[key] === 'string' ? resolvePath(toolsEnvVars[key]) : toolsEnvVars[key])
- );
- }
-
- return envVars;
-}
-
export function substituteEnv(input: string): string {
return input.replace(/\${env:([^}]+)}/g, (match, capture) => {
return process.env[capture.trim()] || '';
@@ -975,7 +958,7 @@
symbol = receiver + '.' + symbol;
}
- const env = getToolsEnvVars();
+ const env = toolExecutionEnvironment();
const args = ['doc', '-c', '-cmd', '-u', packageImportPath, symbol];
const p = cp.execFile(goRuntimePath, args, { env, cwd }, (err, stdout, stderr) => {
if (err) {