src/goInstallTools: install -gomod tools in the right directory
Tools with the `-gomod` prefix are installed using `go build -o`
in order to avoid the conflicts with GOPATH-mode tools that have
the same name. The extension used `$GOPATH/bin/gocode-gomod`
as the -o flag value even ehen GOPATH contains multiple directories.
The go command uses whatever passed with `-o` and creates the
output directory if necessary. As a result, if the OS accepts
the output, the go command will succeed.
When GOPATH includes multiple elements, we should install
them in the first element's bin directory.
Fixes golang/vscode-go#368
Change-Id: Ief53545042056063a3bdcf57df4bf63a5a133fe2
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/243417
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts
index 96beb02..218095e 100644
--- a/src/goInstallTools.ts
+++ b/src/goInstallTools.ts
@@ -236,7 +236,8 @@
if (!gopath) {
return `GOPATH not configured in environment`;
}
- const outputFile = path.join(gopath, 'bin', process.platform === 'win32' ? `${tool.name}.exe` : tool.name);
+ const destDir = gopath.split(path.delimiter)[0];
+ const outputFile = path.join(destDir, 'bin', process.platform === 'win32' ? `${tool.name}.exe` : tool.name);
await execFile(goVersion.binaryPath, ['build', '-o', outputFile, importPath], opts);
}
const toolImportPath = tool.version ? importPath + '@' + tool.version : importPath;
diff --git a/test/integration/install.test.ts b/test/integration/install.test.ts
index 2c663f5..395ae46 100644
--- a/test/integration/install.test.ts
+++ b/test/integration/install.test.ts
@@ -26,18 +26,22 @@
this.timeout(timeout);
let tmpToolsGopath: string;
+ let tmpToolsGopath2: string;
let sandbox: sinon.SinonSandbox;
let toolsGopathStub: sinon.SinonStub;
setup(() => {
// Create a temporary directory in which to install tools.
tmpToolsGopath = fs.mkdtempSync(path.join(os.tmpdir(), 'install-test'));
- fs.mkdirSync(path.join(tmpToolsGopath, 'bin'));
- fs.mkdirSync(path.join(tmpToolsGopath, 'src'));
+
+ // a temporary directory to be used as the second GOPATH element.
+ tmpToolsGopath2 = fs.mkdtempSync(path.join(os.tmpdir(), 'install-test2'));
+
+ const toolsGopath = tmpToolsGopath + path.delimiter + tmpToolsGopath2;
sandbox = sinon.createSandbox();
const utils = require('../../src/util');
- toolsGopathStub = sandbox.stub(utils, 'getToolsGopath').returns(tmpToolsGopath);
+ toolsGopathStub = sandbox.stub(utils, 'getToolsGopath').returns(toolsGopath);
});
teardown(async () => {
@@ -46,12 +50,15 @@
// Clean up the temporary GOPATH. To delete the module cache, run `go clean -modcache`.
const goRuntimePath = getBinPath('go');
const envForTest = Object.assign({}, process.env);
- envForTest['GOPATH'] = tmpToolsGopath;
- const execFile = util.promisify(cp.execFile);
- await execFile(goRuntimePath, ['clean', '-modcache'], {
- env: envForTest,
- });
- rmdirRecursive(tmpToolsGopath);
+
+ for (const p of [tmpToolsGopath, tmpToolsGopath2]) {
+ envForTest['GOPATH'] = p;
+ const execFile = util.promisify(cp.execFile);
+ await execFile(goRuntimePath, ['clean', '-modcache'], {
+ env: envForTest,
+ });
+ rmdirRecursive(p);
+ }
});
// runTest actually executes the logic of the test.