src/util.ts,goLanguageServer.ts: set cwd for cp.execFile

There are many more locations where we invoke child process without
explicit cwd setting. But I don't want to go through testing all
the cases right now, so this change fixes only the place we call
`go version`, `gopls version`, and go downloader.

Change-Id: I7d3e1c9bd5d6dca0c036c7533115d097965313b7
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/253602
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/goEnvironmentStatus.ts b/src/goEnvironmentStatus.ts
index ed13d42..554fa0f 100644
--- a/src/goEnvironmentStatus.ts
+++ b/src/goEnvironmentStatus.ts
@@ -242,7 +242,7 @@
 		const goXExecutable = getBinPath(newExecutableName);
 		outputChannel.appendLine(`Running: ${goXExecutable} download`);
 		try {
-			await execFile(goXExecutable, ['download'], { env });
+			await execFile(goXExecutable, ['download'], { env, cwd: toolsTmpDir });
 		} catch (downloadErr) {
 			outputChannel.appendLine(`Error finishing installation: ${downloadErr}`);
 			throw new Error('Could not download Go version.');
diff --git a/src/goLanguageServer.ts b/src/goLanguageServer.ts
index dd90e59..b24890e 100644
--- a/src/goLanguageServer.ts
+++ b/src/goLanguageServer.ts
@@ -48,7 +48,7 @@
 import { getTool, Tool } from './goTools';
 import { GoTypeDefinitionProvider } from './goTypeDefinition';
 import { getFromGlobalState, updateGlobalState } from './stateUtils';
-import { getBinPath, getCurrentGoPath, getGoConfig } from './util';
+import { getBinPath, getCurrentGoPath, getGoConfig, getWorkspaceFolderPath } from './util';
 import { getToolFromToolPath } from './utils/pathUtils';
 
 interface LanguageServerConfig {
@@ -745,7 +745,9 @@
 	const execFile = util.promisify(cp.execFile);
 	let output: any;
 	try {
-		const { stdout } = await execFile(cfg.path, ['version'], { env: toolExecutionEnvironment() });
+		const env = toolExecutionEnvironment();
+		const cwd = getWorkspaceFolderPath();
+		const { stdout } = await execFile(cfg.path, ['version'], { env, cwd });
 		output = stdout;
 	} catch (e) {
 		// The "gopls version" command is not supported, or something else went wrong.
diff --git a/src/util.ts b/src/util.ts
index b7152be..b405ada 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -341,8 +341,10 @@
 	}
 	try {
 		const env = toolExecutionEnvironment();
+		const docUri = vscode.window.activeTextEditor.document.uri;
+		const cwd = getWorkspaceFolderPath(docUri && docUri.fsPath.endsWith('.go') ? docUri : undefined);
 		const execFile = util.promisify(cp.execFile);
-		const { stdout, stderr } = await execFile(goRuntimePath, ['version'], {env});
+		const { stdout, stderr } = await execFile(goRuntimePath, ['version'], {env, cwd});
 		if (stderr) {
 			warn(`failed to run "${goRuntimePath} version": stdout: ${stdout}, stderr: ${stderr}`);
 			return;