Skip to content

Commit dec5a1a

Browse files
committed
[release] src/goInstallTools: use GOBIN correctly installing dlv-dap/gocode-gomod
We incorrectly added `bin` to the final binary path when the destination was determined by GOBIN env var. Changed install.test.ts to set the temporary GOPATH instead of stubbing getToolsGopath. When populating tools installation environment, the extension ignores GOBIN if users configured go.toolsGopath currently, so depending on toolsGopath to point to the temporary GOPATH prevents from testing GOBIN-related behavior. Fixes #1430 Change-Id: Id6450e9422a791f6d5e7810f6bbbec1bc695e924 Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/310769 Trust: Hyang-Ah Hana Kim <[email protected]> Run-TryBot: Hyang-Ah Hana Kim <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]> (cherry picked from commit 015d002) Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/311450 Reviewed-by: Suzy Mueller <[email protected]>
1 parent d767aa0 commit dec5a1a

File tree

2 files changed

+45
-17
lines changed

2 files changed

+45
-17
lines changed

src/goInstallTools.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
getBinPath,
3535
getBinPathWithExplanation,
3636
getCheckForToolsUpdatesConfig,
37+
getCurrentGoPath,
3738
getGoVersion,
3839
getTempFilePath,
3940
getWorkspaceFolderPath,
@@ -281,12 +282,16 @@ export async function installTool(
281282
logVerbose(`install: ${goBinary} ${args.join(' ')}\n${stdout}${stderr}`);
282283
if (hasModSuffix(tool) || tool.name === 'dlv-dap') {
283284
// Actual installation of the -gomod tool and dlv-dap is done by running go build.
284-
const gopath = env['GOBIN'] || env['GOPATH'];
285-
if (!gopath) {
285+
let destDir = env['GOBIN'];
286+
if (!destDir) {
287+
const gopath0 = env['GOPATH']?.split(path.delimiter)[0];
288+
destDir = gopath0 ? path.join(gopath0, 'bin') : undefined;
289+
}
290+
if (!destDir) {
286291
throw new Error('GOBIN/GOPATH not configured in environment');
287292
}
288-
const destDir = gopath.split(path.delimiter)[0];
289-
const outputFile = path.join(destDir, 'bin', process.platform === 'win32' ? `${tool.name}.exe` : tool.name);
293+
const outputFile = path.join(destDir, correctBinname(tool.name));
294+
290295
// go build does not take @version suffix yet.
291296
const importPath = getImportPath(tool, goVersion);
292297
await execFile(goBinary, ['build', '-o', outputFile, importPath], opts);

test/integration/install.test.ts

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import AdmZip = require('adm-zip');
88
import * as assert from 'assert';
99
import * as config from '../../src/config';
10-
import { toolInstallationEnvironment } from '../../src/goEnv';
1110
import { inspectGoToolVersion, installTools } from '../../src/goInstallTools';
1211
import { allToolsInformation, getConfiguredTools, getTool, getToolAtVersion } from '../../src/goTools';
1312
import { getBinPath, getGoVersion, GoVersion, rmdirRecursive } from '../../src/util';
@@ -39,7 +38,7 @@ suite('Installation Tests', function () {
3938
let tmpToolsGopath: string;
4039
let tmpToolsGopath2: string;
4140
let sandbox: sinon.SinonSandbox;
42-
let toolsGopathStub: sinon.SinonStub;
41+
let toolsGopath: string;
4342

4443
setup(() => {
4544
// Create a temporary directory in which to install tools.
@@ -48,11 +47,9 @@ suite('Installation Tests', function () {
4847
// a temporary directory to be used as the second GOPATH element.
4948
tmpToolsGopath2 = fs.mkdtempSync(path.join(os.tmpdir(), 'install-test2'));
5049

51-
const toolsGopath = tmpToolsGopath + path.delimiter + tmpToolsGopath2;
50+
toolsGopath = tmpToolsGopath + path.delimiter + tmpToolsGopath2;
5251

5352
sandbox = sinon.createSandbox();
54-
const utils = require('../../src/util');
55-
toolsGopathStub = sandbox.stub(utils, 'getToolsGopath').returns(toolsGopath);
5653
});
5754

5855
teardown(async () => {
@@ -74,7 +71,10 @@ suite('Installation Tests', function () {
7471

7572
// runTest actually executes the logic of the test.
7673
// If withLocalProxy is true, the test does not require internet.
77-
async function runTest(testCases: installationTestCase[], withLocalProxy?: boolean) {
74+
// If withGOBIN is true, the test will set GOBIN env var.
75+
async function runTest(testCases: installationTestCase[], withLocalProxy?: boolean, withGOBIN?: boolean) {
76+
const gobin = withLocalProxy && withGOBIN ? path.join(tmpToolsGopath, 'gobin') : undefined;
77+
7878
let proxyDir: string;
7979
let configStub: sinon.SinonStub;
8080
if (withLocalProxy) {
@@ -83,14 +83,21 @@ suite('Installation Tests', function () {
8383
toolsEnvVars: {
8484
value: {
8585
GOPROXY: url.pathToFileURL(proxyDir),
86-
GOSUMDB: 'off'
86+
GOSUMDB: 'off',
87+
GOBIN: gobin
8788
}
88-
}
89+
},
90+
gopath: { value: toolsGopath }
8991
});
9092
configStub = sandbox.stub(config, 'getGoConfig').returns(goConfig);
9193
} else {
92-
const env = toolInstallationEnvironment();
93-
console.log(`Installing tools using GOPROXY=${env['GOPROXY']}`);
94+
const goConfig = Object.create(vscode.workspace.getConfiguration('go'), {
95+
toolsEnvVars: {
96+
value: { GOBIN: gobin }
97+
},
98+
gopath: { value: toolsGopath }
99+
});
100+
configStub = sandbox.stub(config, 'getGoConfig').returns(goConfig);
94101
}
95102

96103
const missingTools = testCases.map((tc) => getToolAtVersion(tc.name));
@@ -104,7 +111,9 @@ suite('Installation Tests', function () {
104111
checks.push(
105112
new Promise<void>(async (resolve) => {
106113
// Check that the expect tool has been installed to $GOPATH/bin.
107-
const bin = path.join(tmpToolsGopath, 'bin', correctBinname(tc.name));
114+
const bin = gobin
115+
? path.join(gobin, correctBinname(tc.name))
116+
: path.join(tmpToolsGopath, 'bin', correctBinname(tc.name));
108117
const ok = await exists(bin);
109118
if (!ok) {
110119
assert.fail(`expected ${bin}, not found`);
@@ -124,8 +133,6 @@ suite('Installation Tests', function () {
124133
}
125134
await Promise.all(checks);
126135

127-
sandbox.assert.calledWith(toolsGopathStub);
128-
129136
if (withLocalProxy) {
130137
sandbox.assert.calledWith(configStub);
131138
rmdirRecursive(proxyDir);
@@ -160,6 +167,22 @@ suite('Installation Tests', function () {
160167
);
161168
});
162169

170+
test('Install multiple tools with a local proxy & GOBIN', async () => {
171+
await runTest(
172+
[
173+
{ name: 'gopls', versions: ['v0.1.0', 'v1.0.0-pre.1', 'v1.0.0'], wantVersion: 'v1.0.0' },
174+
{ name: 'guru', versions: ['v1.0.0'], wantVersion: 'v1.0.0' },
175+
{
176+
name: 'dlv-dap',
177+
versions: ['v1.0.0', 'master'],
178+
wantVersion: 'v' + getTool('dlv-dap').latestVersion!.toString()
179+
}
180+
],
181+
true, // LOCAL PROXY
182+
true // GOBIN
183+
);
184+
});
185+
163186
test('Install all tools via GOPROXY', async () => {
164187
// Only run this test if we are in CI before a Nightly release.
165188
if (!shouldRunSlowTests()) {

0 commit comments

Comments
 (0)