src: convert installTools to be async

Broke out a piece of https://go-review.googlesource.com/c/vscode-go/+/233538 into this PR, which converts all of the call sites of `installTools` to use async/await.

Change-Id: I16d53d57790f4a01c9f116d4aed0de0b5b5c8161
GitHub-Last-Rev: 5463347f27ec2f3220a2b334b094a2676f9c55c7
GitHub-Pull-Request: golang/vscode-go#46
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/234021
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts
index 2475f32..3d8508f 100644
--- a/src/goInstallTools.ts
+++ b/src/goInstallTools.ts
@@ -57,7 +57,7 @@
 
 	// Update existing tools by finding all tools the user has already installed.
 	if (updateExistingToolsOnly) {
-		installTools(
+		await installTools(
 			allTools.filter((tool) => {
 				const toolPath = getBinPath(tool.name);
 				return toolPath && path.isAbsolute(toolPath);
@@ -68,29 +68,23 @@
 	}
 
 	// Otherwise, allow the user to select which tools to install or update.
-	vscode.window
-		.showQuickPick(
-			allTools.map((x) => {
-				const item: vscode.QuickPickItem = {
-					label: x.name,
-					description: x.description
-				};
-				return item;
-			}),
-			{
-				canPickMany: true,
-				placeHolder: 'Select the tools to install/update.'
-			}
-		)
-		.then((selectedTools) => {
-			if (!selectedTools) {
-				return;
-			}
-			installTools(
-				selectedTools.map((x) => getTool(x.label)),
-				goVersion
-			);
-		});
+	const selected = await vscode.window.showQuickPick(
+		allTools.map((x) => {
+			const item: vscode.QuickPickItem = {
+				label: x.name,
+				description: x.description
+			};
+			return item;
+		}),
+		{
+			canPickMany: true,
+			placeHolder: 'Select the tools to install/update.'
+		}
+	);
+	if (!selected) {
+		return;
+	}
+	await installTools(selected.map((x) => getTool(x.label)), goVersion);
 }
 
 /**
@@ -100,7 +94,7 @@
  *                If a tool's version is not specified, it will install the latest.
  * @param goVersion version of Go that affects how to install the tool. (e.g. modules vs legacy GOPATH mode)
  */
-export function installTools(missing: ToolAtVersion[], goVersion: GoVersion): Promise<void> {
+export async function installTools(missing: ToolAtVersion[], goVersion: GoVersion): Promise<void> {
 	const goRuntimePath = getBinPath('go');
 	if (!goRuntimePath) {
 		vscode.window.showErrorMessage(
@@ -326,25 +320,22 @@
 		// Offer the option to install all tools.
 		installOptions.push('Install All');
 	}
-	const msg = `The "${tool.name}" command is not available. Run "go get -v ${getImportPath(
-		tool,
-		goVersion
-	)}" to install.`;
-	vscode.window.showInformationMessage(msg, ...installOptions).then((selected) => {
-		switch (selected) {
-			case 'Install':
-				installTools([tool], goVersion);
-				break;
-			case 'Install All':
-				installTools(missing, goVersion);
-				hideGoStatus();
-				break;
-			default:
-				// The user has declined to install this tool.
-				declinedInstalls.push(tool);
-				break;
-		}
-	});
+	const msg = `The "${tool.name}" command is not available.
+Run "go get -v ${getImportPath(tool, goVersion)}" to install.`;
+	const selected = await vscode.window.showInformationMessage(msg, ...installOptions);
+	switch (selected) {
+		case 'Install':
+			await installTools([tool], goVersion);
+			break;
+		case 'Install All':
+			await installTools(missing, goVersion);
+			hideGoStatus();
+			break;
+		default:
+			// The user has declined to install this tool.
+			declinedInstalls.push(tool);
+			break;
+	}
 }
 
 export async function promptForUpdatingTool(toolName: string, newVersion?: SemVer) {
@@ -364,22 +355,21 @@
 	if (newVersion) {
 		updateMsg = `A new version of ${tool.name} (v${newVersion}) is available. Please update for an improved experience.`;
 	}
-	vscode.window.showInformationMessage(updateMsg, ...choices).then((selected) => {
-		switch (selected) {
-			case 'Update':
-				installTools([toolVersion], goVersion);
-				break;
-			case 'Release Notes':
-				vscode.commands.executeCommand(
-					'vscode.open',
-					vscode.Uri.parse('https://github.com/golang/go/issues/33030#issuecomment-510151934')
-				);
-				break;
-			default:
-				declinedUpdates.push(tool);
-				break;
-		}
-	});
+	const selected = await vscode.window.showInformationMessage(updateMsg, ...choices);
+	switch (selected) {
+		case 'Update':
+			await installTools([toolVersion], goVersion);
+			break;
+		case 'Release Notes':
+			vscode.commands.executeCommand(
+				'vscode.open',
+				vscode.Uri.parse('https://github.com/golang/go/issues/33030#issuecomment-510151934')
+			);
+			break;
+		default:
+			declinedUpdates.push(tool);
+			break;
+	}
 }
 
 export function updateGoPathGoRootFromConfig(): Promise<void> {
@@ -455,9 +445,9 @@
 		vscode.commands.registerCommand('go.promptforinstall', () => {
 			const installItem = {
 				title: 'Install',
-				command() {
+				async command() {
 					hideGoStatus();
-					installTools(missing, goVersion);
+					await installTools(missing, goVersion);
 				}
 			};
 			const showItem = {
@@ -490,22 +480,18 @@
 			'The language server from Sourcegraph is no longer under active development and it does not support Go modules as well. Please install and use the language server from Google or disable the use of language servers altogether.';
 		const disableLabel = 'Disable language server';
 		const installLabel = 'Install';
-		vscode.window.showInformationMessage(promptMsg, installLabel, disableLabel).then((selected) => {
-			if (selected === installLabel) {
-				installTools([getTool('gopls')], goVersion).then(() => {
-					// Restart the language server since the binary has changed.
-					restartLanguageServer();
-				});
-			} else if (selected === disableLabel) {
-				const goConfig = getGoConfig();
-				const inspectLanguageServerSetting = goConfig.inspect('useLanguageServer');
-				if (inspectLanguageServerSetting.globalValue === true) {
-					goConfig.update('useLanguageServer', false, vscode.ConfigurationTarget.Global);
-				} else if (inspectLanguageServerSetting.workspaceFolderValue === true) {
-					goConfig.update('useLanguageServer', false, vscode.ConfigurationTarget.WorkspaceFolder);
-				}
+		const selected = await vscode.window.showInformationMessage(promptMsg, installLabel, disableLabel);
+		if (selected === installLabel) {
+			await installTools([getTool('gopls')], goVersion);
+		} else if (selected === disableLabel) {
+			const goConfig = getGoConfig();
+			const inspectLanguageServerSetting = goConfig.inspect('useLanguageServer');
+			if (inspectLanguageServerSetting.globalValue === true) {
+				goConfig.update('useLanguageServer', false, vscode.ConfigurationTarget.Global);
+			} else if (inspectLanguageServerSetting.workspaceFolderValue === true) {
+				goConfig.update('useLanguageServer', false, vscode.ConfigurationTarget.WorkspaceFolder);
 			}
-		});
+		}
 	}
 }
 
diff --git a/src/goMain.ts b/src/goMain.ts
index 2d71c75..5fae062 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -366,7 +366,7 @@
 		vscode.commands.registerCommand('go.tools.install', async (args) => {
 			if (Array.isArray(args) && args.length) {
 				const goVersion = await getGoVersion();
-				installTools(args, goVersion);
+				await installTools(args, goVersion);
 				return;
 			}
 			installAllTools();
diff --git a/src/goModules.ts b/src/goModules.ts
index 6ec5017..eb07317 100644
--- a/src/goModules.ts
+++ b/src/goModules.ts
@@ -128,17 +128,7 @@
 			if (tool === 'switchFormatToolToGoimports') {
 				goConfig.update('formatTool', 'goimports', vscode.ConfigurationTarget.Global);
 			} else {
-				installTools([getTool(tool)], goVersion).then(() => {
-					if (tool === 'gopls') {
-						if (goConfig.get('useLanguageServer') === false) {
-							goConfig.update('useLanguageServer', true, vscode.ConfigurationTarget.Global);
-						}
-						if (goConfig.inspect('useLanguageServer').workspaceFolderValue === false) {
-							goConfig.update('useLanguageServer', true, vscode.ConfigurationTarget.WorkspaceFolder);
-						}
-						restartLanguageServer();
-					}
-				});
+				await installTools([getTool(tool)], goVersion);
 			}
 			promptedToolsForModules[tool] = true;
 			updateGlobalState('promptedToolsForModules', promptedToolsForModules);