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.