src/goVulncheck: add "Current Module" option

When users need to scan vulnerabilities of a module located not in the
workspace root, they can use this option - which infer the module
root directory by running `go env GOMOD`.

Change-Id: I70126de30fc4cc08a7207ab4a74a12f6290ccba1
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/429476
Reviewed-by: Suzy Mueller <suzmue@golang.org>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/goVulncheck.ts b/src/goVulncheck.ts
index b41441f..037e03a 100644
--- a/src/goVulncheck.ts
+++ b/src/goVulncheck.ts
@@ -223,7 +223,7 @@
 	}
 
 	private async runInternal(goCtx: GoExtensionContext) {
-		const pick = await vscode.window.showQuickPick(['Current Package', 'Workspace']);
+		const pick = await vscode.window.showQuickPick(['Current Package', 'Current Module', 'Workspace']);
 		let dir, pattern: string;
 		const document = vscode.window.activeTextEditor?.document;
 		switch (pick) {
@@ -241,6 +241,14 @@
 				dir = path.dirname(document.fileName);
 				pattern = '.';
 				break;
+			case 'Current Module':
+				dir = await moduleDir(document);
+				if (!dir) {
+					vscode.window.showErrorMessage('vulncheck error: no current module');
+					return;
+				}
+				pattern = './...';
+				break;
 			case 'Workspace':
 				dir = await this.activeDir();
 				pattern = './...';
@@ -308,6 +316,18 @@
 	}
 }
 
+async function moduleDir(document: vscode.TextDocument | undefined) {
+	const docDir = document && document.fileName && path.dirname(document.fileName);
+	if (!docDir) {
+		return;
+	}
+	const modFile = await getGoModFile(vscode.Uri.file(docDir));
+	if (!modFile) {
+		return;
+	}
+	return path.dirname(modFile);
+}
+
 // run `gopls vulncheck`.
 export async function vulncheck(
 	goCtx: GoExtensionContext,