src/goMain.ts: include go env results in go.locate.tools

There can be multiple workspace folders, so we print them
all. This may be too verbose if there are many folders.
Let's improve that if we find that too verbose.

Fixes golang/vscode-go#195

Change-Id: I97d928be31c2d4be3964ea7ef8ba14de55a6d829
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/244023
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/src/goMain.ts b/src/goMain.ts
index 241078a..249984e 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -53,6 +53,7 @@
 	getCurrentGoPath,
 	getExtensionCommands,
 	getGoConfig,
+	getGoEnv,
 	getGoVersion,
 	getToolsGopath,
 	getWorkspaceFolderPath,
@@ -686,4 +687,25 @@
 		}
 		outputChannel.appendLine(`   ${tool.name}: ${toolPath} ${msg}`);
 	});
+
+	let folders = vscode.workspace.workspaceFolders?.map((folder) => {
+		return { name: folder.name, path: folder.uri.path };
+	});
+	if (!folders) {
+		folders = [{ name: 'no folder', path: undefined }];
+	}
+
+	outputChannel.appendLine('');
+	outputChannel.appendLine('go env');
+	for (const folder of folders) {
+		outputChannel.appendLine(`Workspace Folder (${folder.name}): ${folder.path}`);
+		try {
+			const out = await getGoEnv(folder.path);
+			// Append '\t' to the beginning of every line (^) of 'out'.
+			// 'g' = 'global matching', and 'm' = 'multi-line matching'
+			outputChannel.appendLine(out.replace(/^/gm, '\t'));
+		} catch (e) {
+			outputChannel.appendLine(`failed to run 'go env': ${e}`);
+		}
+	}
 }
diff --git a/src/util.ts b/src/util.ts
index 54737f1..e8a77f2 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -336,6 +336,21 @@
 }
 
 /**
+ * Returns the output of `go env` from the specified directory.
+ * Throws an error if the command fails.
+ */
+export async function getGoEnv(cwd?: string): Promise<string> {
+	const goRuntime = getBinPath('go');
+	const execFile = util.promisify(cp.execFile);
+	const opts = {cwd, env: toolExecutionEnvironment()};
+	const { stdout, stderr } = await execFile(goRuntime, ['env'], opts);
+	if (stderr) {
+		throw new Error(`failed to run 'go env': ${stderr}`);
+	}
+	return stdout;
+}
+
+/**
  * Returns boolean denoting if current version of Go supports vendoring
  */
 export async function isVendorSupported(): Promise<boolean> {
@@ -370,6 +385,7 @@
  */
 export function isGoPathSet(): boolean {
 	if (!getCurrentGoPath()) {
+		// TODO(hyangah): is it still possible after go1.8? (https://golang.org/doc/go1.8#gopath)
 		vscode.window
 			.showInformationMessage(
 				'Set GOPATH environment variable and restart VS Code or set GOPATH in Workspace settings',