[vscode-go] src/language/goLanguageServer: improve suggestGoplsIssueReport

38 views
Skip to first unread message

Hyang-Ah Hana Kim (Gerrit)

unread,
Nov 2, 2023, 2:44:39 PM11/2/23
to goph...@pubsubhelper.golang.org, Hyang-Ah Hana Kim, golang-co...@googlegroups.com

Hyang-Ah Hana Kim has uploaded this change for review.

View Change

src/language/goLanguageServer: improve suggestGoplsIssueReport

The extension runs suggestGoplsIssueReport when it observes
the language server client crashes. It prompts the user and
collects useful information from settings, configuration,
and the LSP server output channel ("gopls (server)")
where stderr and LSP log messages are logged, populates a
github issue template when the user agrees.

This change improves the log collection and sanitization.

* Incorrect version info and timestamp - previously they were
computed after the user chooses "Yes" on the prompt. Usually,
there is a delay between the problem occurs and the user
notices the popup. Often, vscode hides the prompt window!
It's possible that a new gopls or extension version was installed
and restarted in between. This CL makes the suggestGoplsIssueReport
accepts the configuration used when starting the crashed gopls
session, and computes the issue timestamp before prompting.

Moreover, we also compute the gopls version when the configuration
object is built. Previously, it was lazily evaluated to avoid
excessive file stats and `gopls version` process runs. In this
CL, we remove unnecessary buildLanguageServerConfig calls -
the latest config is cached in `goCtx.latestCfg`.

One side-effect of this change is `buildLanguageServerConfig`
is now async to run `gopls version`.

* Gopls's crash info is in `gopls (server)` output channel.
collectGoplsLog attempted to collect the data in a hacky way
by iterating all open documents and picking the first one that
looks like our log. Unfortunately, this doesn't work when there
are multiple extensions with output channels. Fix this bug
- recent versions of vscode now use file names that include the
channel name, so we can pin point the right output channel doc.

* The extension may trigger multiple gopls restarts back to back
because there are currently multiple vantage points for checking
for gopls update asynchronously. Such successive restarts may
be unclean and the lsp client lib classifies them as crashes.
The new session may be already up and running. This CL makes
suggestGoplsIssueReport check gopls versions (what's used in the
currently crashed session and what's the latest config the extension
saw) and prompt only if they are same. It would be nice if we
can centralize gopls install/upgrade decision making and reduce
the chance of successive, unnecessary gopls restarts. But that
is a major change and can be a separate project.

We also learned a couple of new crash log patterns. Integrate
the followings in the log scrubbing logic.

* log.Fatal - "filename.go:line ...."
* LSP 3.17 client library changed the initialization error log text.
That explains the increased in the number of empty reports after
we updated our dependency.

This change also embeds `gopls stats -anon` output. That may
reveal issues caught by gopls bug reports.

While we are here, we also simplify the periodic gopls update check
(scheduleGoplsSuggestions). That will remove another
buildLanguageServerConfig call.

Fixes golang/vscode-go#984
Fixes golang/vscode-go#2690

Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
---
M src/commands/startLanguageServer.ts
M src/goCheck.ts
M src/goStatus.ts
M src/language/goLanguageServer.ts
M src/utils/pathUtils.ts
M test/gopls/goplsTestEnv.utils.ts
M test/gopls/report.test.ts
M test/integration/extension.test.ts
8 files changed, 116 insertions(+), 95 deletions(-)

diff --git a/src/commands/startLanguageServer.ts b/src/commands/startLanguageServer.ts
index 6c672fb..d2a28bf 100644
--- a/src/commands/startLanguageServer.ts
+++ b/src/commands/startLanguageServer.ts
@@ -17,7 +17,7 @@
RestartReason,
scheduleGoplsSuggestions,
stopLanguageClient,
- suggestGoplsIssueReport,
+suggestGoplsIssueReport,
toServerInfo,
updateRestartHistory
} from '../language/goLanguageServer';
@@ -30,7 +30,7 @@
export const startLanguageServer: CommandFactory = (ctx, goCtx) => {
return async (reason: RestartReason = RestartReason.MANUAL) => {
const goConfig = getGoConfig();
- const cfg = buildLanguageServerConfig(goConfig);
+ const cfg = await buildLanguageServerConfig(goConfig);

if (typeof reason === 'string') {
updateRestartHistory(goCtx, reason, cfg.enabled);
@@ -39,16 +39,17 @@
const unlock = await languageServerStartMutex.lock();
goCtx.latestConfig = cfg;
try {
- if (reason === RestartReason.MANUAL) {
+if (reason === RestartReason.MANUAL) {
await suggestGoplsIssueReport(
goCtx,
+ cfg,
"Looks like you're about to manually restart the language server.",
errorKind.manualRestart
);
}
// If the client has already been started, make sure to clear existing
// diagnostics and stop it.
- if (goCtx.languageClient) {
+ if (goCtx.languageClient && goCtx.languageClient) {
await stopLanguageClient(goCtx);
}
updateStatus(goCtx, goConfig, false);
@@ -111,7 +112,7 @@
case 'vsls':
outputChannel.appendLine(
'Language service on the guest side is disabled. ' +
- 'The server-side language service will provide the language features.'
+ 'The server-side language service will provide the language features.'
);
return;
case 'ssh':
diff --git a/src/goCheck.ts b/src/goCheck.ts
index ff81136..19f3674 100644
--- a/src/goCheck.ts
+++ b/src/goCheck.ts
@@ -68,9 +68,8 @@

// If a user has enabled diagnostics via a language server,
// then we disable running build or vet to avoid duplicate errors and warnings.
- const lspConfig = buildLanguageServerConfig(goConfig);
- const disableBuildAndVet = lspConfig.enabled;
-
+ const disableBuildAndVet = goConfig.get('useLanguageServer');
+
let testPromise: Thenable<boolean>;
const testConfig: TestConfig = {
goConfig,
diff --git a/src/goStatus.ts b/src/goStatus.ts
index 01b1224..3105b47 100644
--- a/src/goStatus.ts
+++ b/src/goStatus.ts
@@ -61,14 +61,15 @@
{ label: 'Choose Go Environment' }
];

- // Get the gopls configuration
+ const cfg = goCtx.latestConfig;
+ // Get the gopls configuration.
const goConfig = getGoConfig();
- const cfg = buildLanguageServerConfig(goConfig);
- if (languageServerIsRunning && cfg.serverName === 'gopls') {
- const goplsVersion = await getLocalGoplsVersion(cfg);
+ const goplsIsRunning = languageServerIsRunning && cfg && cfg.serverName === 'gopls';
+ if (goplsIsRunning) {
+ const goplsVersion = cfg.version;
options.push({ label: `${languageServerIcon}Open 'gopls' trace`, description: `${goplsVersion?.version}` });
}
- if (!languageServerIsRunning && !cfg.serverName && goConfig['useLanguageServer'] === true) {
+ if (!goplsIsRunning && goConfig.get('useLanguageServer') === true && cfg?.serverName === '') {
options.push({
label: 'Install Go Language Server',
description: `${languageServerErrorIcon}'gopls' is required but missing`
diff --git a/src/language/goLanguageServer.ts b/src/language/goLanguageServer.ts
index 75972ae..936fb24 100644
--- a/src/language/goLanguageServer.ts
+++ b/src/language/goLanguageServer.ts
@@ -158,9 +158,6 @@
return;
}
// Some helper functions.
- const usingGopls = (cfg: LanguageServerConfig): boolean => {
- return cfg.enabled && cfg.serverName === 'gopls';
- };
const usingGo = (): boolean => {
return vscode.workspace.textDocuments.some((doc) => doc.languageId === 'go');
};
@@ -187,20 +184,11 @@
};
const update = async () => {
setTimeout(update, timeDay);
-
- let cfg = buildLanguageServerConfig(getGoConfig());
- if (!usingGopls(cfg)) {
- // This shouldn't happen, but if the user has a non-gopls language
- // server enabled, we shouldn't prompt them to change.
- if (cfg.serverName !== '' && cfg.serverName !== 'gopls') {
- return;
- }
- // Check if the language server has now been enabled, and if so,
- // it will be installed below.
- cfg = buildLanguageServerConfig(getGoConfig());
- if (!cfg.enabled) {
- return;
- }
+ let cfg = goCtx.latestConfig;
+ // trigger periodic update check only if the user is already using gopls.
+ // Otherwise, let's check again tomorrow.
+ if (!cfg || !cfg.enabled || cfg.serverName !== 'gopls') {
+ return;
}
await installGopls(cfg);
};
@@ -300,14 +288,6 @@
updateGlobalState(goplsOptOutConfigKey, JSON.stringify(cfg));
};

-const race = function (promise: Promise<unknown>, timeoutInMilliseconds: number) {
- let token: NodeJS.Timeout;
- const timeout = new Promise((resolve, reject) => {
- token = setTimeout(() => reject('timeout'), timeoutInMilliseconds);
- });
- return Promise.race([promise, timeout]).then(() => clearTimeout(token));
-};
-
// exported for testing.
export async function stopLanguageClient(goCtx: GoExtensionContext) {
const c = goCtx.languageClient;
@@ -322,10 +302,8 @@
// LanguageClient.stop may hang if the language server
// crashes during shutdown before responding to the
// shutdown request. Enforce client-side timeout.
- // TODO(hyangah): replace with the new LSP client API that supports timeout
- // and remove this.
try {
- await race(c.stop(), 2000);
+ c.stop(2000);
} catch (e) {
c.outputChannel?.appendLine(`Failed to stop client: ${e}`);
}
@@ -418,6 +396,7 @@
goCtx: GoExtensionContext,
cfg: BuildLanguageClientOption
): Promise<GoLanguageClient> {
+ await getLocalGoplsVersion(cfg); // populate and cache cfg.version
const goplsWorkspaceConfig = await adjustGoplsWorkspaceConfiguration(cfg, getGoplsConfig(), 'gopls', undefined);

const documentSelector = [
@@ -437,7 +416,7 @@
const govulncheckOutputChannel = goCtx.govulncheckOutputChannel;
const pendingVulncheckProgressToken = new Map<ProgressToken, any>();
const onDidChangeVulncheckResultEmitter = new vscode.EventEmitter<VulncheckEvent>();
-
+ // cfg is captured by closures for later use during error report.
const c = new GoLanguageClient(
'go', // id
cfg.serverName, // name e.g. gopls
@@ -472,6 +451,7 @@
};
}
return {
+ message: '', // suppresses error popups
action: ErrorAction.Shutdown
};
},
@@ -479,6 +459,7 @@
if (initializationError !== undefined) {
suggestGoplsIssueReport(
goCtx,
+ cfg,
'The gopls server failed to initialize.',
errorKind.initializationFailure,
initializationError
@@ -486,7 +467,7 @@
initializationError = undefined;
// In case of initialization failure, do not try to restart.
return {
- message: 'The gopls server failed to initialize.',
+ message: '', // suppresses error popups - there will be other popups. :-(
action: CloseAction.DoNotRestart
};
}
@@ -502,11 +483,13 @@
}
suggestGoplsIssueReport(
goCtx,
+ cfg,
'The connection to gopls has been closed. The gopls server may have crashed.',
errorKind.crash
);
updateLanguageServerIconGoStatusBar(false, true);
return {
+ message: '', // suppresses error popups - there will be other popups.
action: CloseAction.DoNotRestart
};
}
@@ -953,16 +936,14 @@
}
}

-export function buildLanguageServerConfig(goConfig: vscode.WorkspaceConfiguration): LanguageServerConfig {
+export async function buildLanguageServerConfig(goConfig: vscode.WorkspaceConfiguration): Promise<LanguageServerConfig> {
let formatter: GoDocumentFormattingEditProvider | undefined;
if (usingCustomFormatTool(goConfig)) {
formatter = new GoDocumentFormattingEditProvider();
}
const cfg: LanguageServerConfig = {
- serverName: '',
+ serverName: '', // remain empty if gopls binary can't be found.
path: '',
- version: undefined, // compute version lazily
- modtime: undefined,
enabled: goConfig['useLanguageServer'] === true,
flags: goConfig['languageServerFlags'] || [],
features: {
@@ -1000,7 +981,7 @@
return cfg;
}
cfg.modtime = stats.mtime;
-
+ cfg.version = await getLocalGoplsVersion(cfg);
return cfg;
}

@@ -1193,13 +1174,13 @@
// If this command has already been executed, it returns the saved result.
export const getLocalGoplsVersion = async (cfg?: LanguageServerConfig) => {
if (!cfg) {
- return null;
+ return;
}
if (cfg.version) {
return cfg.version;
}
if (cfg.path === '') {
- return null;
+ return;
}
const env = toolExecutionEnvironment();
const cwd = getWorkspaceFolderPath();
@@ -1225,7 +1206,7 @@
} catch (e) {
// The "gopls version" command is not supported, or something else went wrong.
// TODO: Should we propagate this error?
- return null;
+ return;
}

const lines = output.trim().split('\n');
@@ -1233,17 +1214,17 @@
case 0:
// No results, should update.
// Worth doing anything here?
- return null;
+ return;
case 1:
// Built in $GOPATH mode. Should update.
// TODO: Should we check the Go version here?
// Do we even allow users to enable gopls if their Go version is too low?
- return null;
+ return;
case 2:
// We might actually have a parseable version.
break;
default:
- return null;
+ return;
}

// The second line should be the sum line.
@@ -1262,7 +1243,7 @@
//
const split = moduleVersion.trim().split('@');
if (split.length < 2) {
- return null;
+ return;
}
// The version comes after the @ symbol:
//
@@ -1311,15 +1292,26 @@
// suggestGoplsIssueReport prompts users to file an issue with gopls.
export async function suggestGoplsIssueReport(
goCtx: GoExtensionContext,
+ cfg: LanguageServerConfig, // config used when starting this gopls.
msg: string,
reason: errorKind,
initializationError?: WebRequest.ResponseError<InitializeError>
) {
+ const issueTime = new Date();
+
// Don't prompt users who manually restart to file issues until gopls/v1.0.
if (reason === errorKind.manualRestart) {
return;
}

+ // cfg is the config used when starting this crashed gopls instance, while
+ // goCtx.latestConfig is the config used by the latest gopls instance.
+ // They may be different if gopls upgrade occurred in between.
+ // Let's not report issue yet if they don't match.
+ if (JSON.stringify(goCtx.latestConfig?.version) !== JSON.stringify(cfg.version)) {
+ return;
+ }
+
// The user may have an outdated version of gopls, in which case we should
// just prompt them to update, not file an issue.
const tool = getTool('gopls');
@@ -1363,15 +1355,16 @@
if (failureReason === GoplsFailureModes.INCORRECT_COMMAND_USAGE) {
const languageServerFlags = getGoConfig()['languageServerFlags'] as string[];
if (languageServerFlags && languageServerFlags.length > 0) {
- selected = await vscode.window.showInformationMessage(
+ selected = await vscode.window.showErrorMessage(
`The extension was unable to start the language server.
You may have an invalid value in your "go.languageServerFlags" setting.
-It is currently set to [${languageServerFlags}]. Please correct the setting by navigating to Preferences -> Settings.`,
- 'Open settings',
+It is currently set to [${languageServerFlags}].
+Please correct the setting.`,
+ 'Open Settings',
'I need more help.'
);
switch (selected) {
- case 'Open settings':
+ case 'Open Settings':
await vscode.commands.executeCommand('workbench.action.openSettings', 'go.languageServerFlags');
return;
case 'I need more help':
@@ -1380,7 +1373,8 @@
}
}
}
- selected = await vscode.window.showInformationMessage(
+ const showMessage = sanitizedLog ? vscode.window.showWarningMessage : vscode.window.showInformationMessage;
+ selected = await showMessage(
`${msg} Would you like to report a gopls issue on GitHub?
You will be asked to provide additional information and logs, so PLEASE READ THE CONTENT IN YOUR BROWSER.`,
'Yes',
@@ -1400,11 +1394,9 @@
errKind = 'initialization';
break;
}
- // Get the user's version in case the update prompt above failed.
- const usersGoplsVersion = await getLocalGoplsVersion(goCtx.latestConfig);
- const goVersion = await getGoVersion();
const settings = goCtx.latestConfig.flags.join(' ');
const title = `gopls: automated issue report (${errKind})`;
+ const goplsStats = await getGoplsStats(goCtx.latestConfig?.path);
const goplsLog = sanitizedLog
? `<pre>${sanitizedLog}</pre>`
: `Please attach the stack trace from the crash.
@@ -1415,17 +1407,15 @@

Failed to auto-collect gopls trace: ${failureReason}.
`;
- const now = new Date();

const body = `
-gopls version: ${usersGoplsVersion?.version} (${usersGoplsVersion?.goVersion})
+gopls version: ${cfg.version?.version}/${cfg.version?.goVersion}
gopls flags: ${settings}
-update flags: ${goCtx.latestConfig.checkForUpdates}
+update flags: ${cfg.checkForUpdates}
extension version: ${extensionInfo.version}
-go version: ${goVersion?.format(true)}
environment: ${extensionInfo.appName} ${process.platform}
initialization error: ${initializationError}
-issue timestamp: ${now.toUTCString()}
+issue timestamp: ${issueTime.toUTCString()}
restart history:
${formatRestartHistory(goCtx)}

@@ -1437,6 +1427,10 @@

${goplsLog}

+<details><summary>gopls stats -anon</summary>
+${goplsStats}
+</details>
+
OPTIONAL: If you would like to share more information, you can attach your complete gopls logs.

NOTE: THESE MAY CONTAIN SENSITIVE INFORMATION ABOUT YOUR CODEBASE.
@@ -1444,7 +1438,7 @@

<OPTIONAL: ATTACH LOGS HERE>
`;
- const url = `https://github.com/golang/vscode-go/issues/new?title=${title}&labels=upstream-tools&body=${body}`;
+ const url = `https://github.com/golang/vscode-go/issues/new?title=${title}&labels=automatedReport&body=${body}`;
await vscode.env.openExternal(vscode.Uri.parse(url));
}
break;
@@ -1510,12 +1504,10 @@
if (doc.isDirty || doc.isClosed) {
continue;
}
- // The document's name should look like 'extension-output-#X'.
- if (doc.fileName.indexOf('extension-output-') === -1) {
- continue;
+ if (doc.fileName.indexOf('gopls (server)') > -1) {
+ logs = doc.getText();
+ break;
}
- logs = doc.getText();
- break;
}
if (logs) {
break;
@@ -1523,7 +1515,6 @@
// sleep a bit before the next try. The choice of the sleep time is arbitrary.
await sleep((i + 1) * 100);
}
-
return sanitizeGoplsTrace(logs);
}

@@ -1573,7 +1564,7 @@
}
return { failureReason: GoplsFailureModes.INCOMPLETE_PANIC_TRACE };
}
- const initFailMsgBegin = logs.lastIndexOf('Starting client failed');
+ const initFailMsgBegin = logs.lastIndexOf('gopls client:');
if (initFailMsgBegin > -1) {
// client start failed. Capture up to the 'Code:' line.
const initFailMsgEnd = logs.indexOf('Code: ', initFailMsgBegin);
@@ -1587,9 +1578,16 @@
};
}
}
- if (logs.lastIndexOf('Usage: gopls') > -1) {
+ if (logs.lastIndexOf('Usage:') > -1) {
return { failureReason: GoplsFailureModes.INCORRECT_COMMAND_USAGE };
}
+ // Capture Fatal
+ // foo.go:1: the last message (caveat - we capture only the first log line)
+ const m = logs.match(/(^\S+\.go:\d+:.*$)/gm);
+ if (m && m.length > 0) {
+ return { sanitizedLog: m[0].toString() };
+ }
+
return { failureReason: GoplsFailureModes.UNRECOGNIZED_CRASH_PATTERN };
}

@@ -1619,3 +1617,19 @@
};
callback();
}
+
+async function getGoplsStats(binpath?: string) {
+ if (!binpath) {
+ return 'gopls path unknown';
+ }
+ const env = toolExecutionEnvironment();
+ const cwd = getWorkspaceFolderPath();
+
+ const execFile = util.promisify(cp.execFile);
+ try {
+ const { stdout } = await execFile(binpath, ['stats', '-anon'], { env, cwd });
+ return stdout
+ } catch (e) {
+ return `gopls stats -anon failed: %{e}`;
+ }
+}
\ No newline at end of file
diff --git a/src/utils/pathUtils.ts b/src/utils/pathUtils.ts
index ead04ac..ad4509d 100644
--- a/src/utils/pathUtils.ts
+++ b/src/utils/pathUtils.ts
@@ -247,7 +247,7 @@
}

/**
- * Returns the tool name from the given path to the tool
+ * Returns the tool name (executable's basename) from the given path to the tool
* @param toolPath
*/
export function getToolFromToolPath(toolPath: string): string | undefined {
diff --git a/test/gopls/goplsTestEnv.utils.ts b/test/gopls/goplsTestEnv.utils.ts
index 9fe8803..f03aa10 100644
--- a/test/gopls/goplsTestEnv.utils.ts
+++ b/test/gopls/goplsTestEnv.utils.ts
@@ -104,7 +104,7 @@
if (!goConfig) {
goConfig = getGoConfig();
}
- const cfg: BuildLanguageClientOption = buildLanguageServerConfig(
+ const cfg: BuildLanguageClientOption = await buildLanguageServerConfig(
Object.create(goConfig, {
useLanguageServer: { value: true },
languageServerFlags: { value: ['-rpc.trace'] } // enable rpc tracing to monitor progress reports
diff --git a/test/gopls/report.test.ts b/test/gopls/report.test.ts
index dd121e7..10348f9 100644
--- a/test/gopls/report.test.ts
+++ b/test/gopls/report.test.ts
@@ -22,8 +22,8 @@
},
{
name: 'initialization error message',
- in: traceFromIssueVSCodeGo572,
- want: sanitizedTraceFromIssuVSCodeGo572
+ in: traceFromIssueVSCodeGo572LSP317,
+ want: sanitizedTraceFromIssueVSCodeGo572LSP317
},
{
name: 'incomplete panic trace',
@@ -40,8 +40,8 @@
testCases.map((tc: TestCase) => {
const { sanitizedLog, failureReason } = sanitizeGoplsTrace(tc.in);
assert.strictEqual(
- sanitizedLog,
- tc.want,
+ JSON.stringify(sanitizedLog),
+ JSON.stringify(tc.want),
`sanitizeGoplsTrace(${tc.name}) returned unexpected sanitizedLog result`
);
assert.strictEqual(
@@ -317,15 +317,21 @@
handler.go:100 +0x171
[Info - 12:50:26 PM] `;

-const traceFromIssueVSCodeGo572 = `
-
-[Error - 下午9:23:45] Starting client failed
-Message: unsupported URI scheme: (gopls only supports file URIs)
-Code: 0
-[Info - 下午9:23:45] 2020/08/25 21:23:45 server shutdown without initialization
-
+const traceFromIssueVSCodeGo572LSP317 = `
+[Error - 12:20:35 PM] Stopping server failed
+Error: Client is not running and can't be stopped. It's current state is: startFailed
+ at GoLanguageClient.shutdown (/Users/hakim/projects/vscode-go/dist/goMain.js:21702:17)
+ at GoLanguageClient.stop (/Users/hakim/projects/vscode-go/dist/goMain.js:21679:21)
+ at GoLanguageClient.stop (/Users/hakim/projects/vscode-go/dist/goMain.js:23486:22)
+ at GoLanguageClient.handleConnectionError (/Users/hakim/projects/vscode-go/dist/goMain.js:21920:16)
+ at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+[Error - 12:20:35 PM]
+[Error - 12:20:35 PM] gopls client: couldn't create connection to server.
+ Message: Socket closed before the connection was established
+ Code: -32099
+Error starting language server: Error: Socket closed before the connection was established <-- this will be included in the initialization error field.
`;

-const sanitizedTraceFromIssuVSCodeGo572 = `Starting client failed
-Message: unsupported URI scheme: (gopls only supports file URIs)
-Code: 0`;
+const sanitizedTraceFromIssueVSCodeGo572LSP317 = `gopls client: couldn't create connection to server.
+ Message: Socket closed before the connection was established
+ Code: -32099 `;
\ No newline at end of file
diff --git a/test/integration/extension.test.ts b/test/integration/extension.test.ts
index 17d13a1..3e2e7e3 100644
--- a/test/integration/extension.test.ts
+++ b/test/integration/extension.test.ts
@@ -212,7 +212,7 @@
];
// If a user has enabled diagnostics via a language server,
// then we disable running build or vet to avoid duplicate errors and warnings.
- const lspConfig = buildLanguageServerConfig(getGoConfig());
+ const lspConfig = await buildLanguageServerConfig(getGoConfig());
const expectedBuildVetErrors = lspConfig.enabled
? []
: [{ line: 11, severity: 'error', msg: 'undefined: prin' }];
@@ -506,7 +506,7 @@
});

test('Build Tags checking', async () => {
- const goplsConfig = buildLanguageServerConfig(getGoConfig());
+ const goplsConfig = await buildLanguageServerConfig(getGoConfig());
if (goplsConfig.enabled) {
// Skip this test if gopls is enabled. Build/Vet checks this test depend on are
// disabled when the language server is enabled, and gopls is not handling tags yet.

To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: vscode-go
Gerrit-Branch: master
Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
Gerrit-Change-Number: 539415
Gerrit-PatchSet: 1
Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>

kokoro (Gerrit)

unread,
Nov 2, 2023, 2:59:32 PM11/2/23
to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Attention is currently required from: Hyang-Ah Hana Kim.

Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/cb90e263-e5a8-4c72-9803-9cec662b2447

Patch set 1:TryBot-Result -1

View Change

    To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-MessageType: comment
    Gerrit-Project: vscode-go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
    Gerrit-Change-Number: 539415
    Gerrit-PatchSet: 1
    Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
    Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
    Gerrit-Reviewer: kokoro <noreply...@google.com>
    Gerrit-CC: kokoro <noreply...@google.com>
    Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
    Gerrit-Comment-Date: Thu, 02 Nov 2023 18:59:28 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes

    Hyang-Ah Hana Kim (Gerrit)

    unread,
    Nov 2, 2023, 3:28:55 PM11/2/23
    to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Hyang-Ah Hana Kim.

    Hyang-Ah Hana Kim uploaded patch set #2 to this change.

    View Change

    The following approvals got outdated and were removed: Commit-Queue+1 by Hyang-Ah Hana Kim, TryBot-Result-1 by kokoro

    8 files changed, 115 insertions(+), 93 deletions(-)

    To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-MessageType: newpatchset
    Gerrit-Project: vscode-go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
    Gerrit-Change-Number: 539415
    Gerrit-PatchSet: 2

    kokoro (Gerrit)

    unread,
    Nov 2, 2023, 3:41:04 PM11/2/23
    to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Hyang-Ah Hana Kim.

    Kokoro presubmit build finished with status: SUCCESS
    Logs at: https://source.cloud.google.com/results/invocations/dfcc7837-c89a-43ec-a715-fba3877fd730

    Patch set 2:TryBot-Result +1

    View Change

      To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: comment
      Gerrit-Project: vscode-go
      Gerrit-Branch: master
      Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
      Gerrit-Change-Number: 539415
      Gerrit-PatchSet: 2
      Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Reviewer: kokoro <noreply...@google.com>
      Gerrit-CC: kokoro <noreply...@google.com>
      Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Comment-Date: Thu, 02 Nov 2023 19:41:00 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: Yes

      Robert Findley (Gerrit)

      unread,
      Nov 17, 2023, 11:58:32 AM11/17/23
      to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, Suzy Mueller, kokoro, golang-co...@googlegroups.com

      Attention is currently required from: Hyang-Ah Hana Kim, Suzy Mueller.

      Patch set 2:Code-Review +1

      View Change

      4 comments:

      • Patchset:

        • Patch Set #2:

          Thanks so much for this. I reviewed the semantics of the change, but not the code as I am unfamiliar.

          I had one significant comment: I don't think we should run `gopls stats`.

      • Commit Message:

        • Moreover, we also compute the gopls version when the configuration
          object is built.

        • This change also embeds `gopls stats -anon` output. That may
          reveal issues caught by gopls bug reports.

        • This could take a long time to run, and could itself crash. Are we sure we want to do this?

          -anon does not include bug reports, because they may reference symbols in the user code.

      To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: comment
      Gerrit-Project: vscode-go
      Gerrit-Branch: master
      Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
      Gerrit-Change-Number: 539415
      Gerrit-PatchSet: 2
      Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Reviewer: Suzy Mueller <suz...@golang.org>
      Gerrit-Reviewer: kokoro <noreply...@google.com>
      Gerrit-CC: kokoro <noreply...@google.com>
      Gerrit-Attention: Suzy Mueller <suz...@golang.org>
      Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Comment-Date: Fri, 17 Nov 2023 16:58:28 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes

      Hyang-Ah Hana Kim (Gerrit)

      unread,
      Nov 27, 2023, 5:39:58 PM11/27/23
      to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

      Attention is currently required from: Hyang-Ah Hana Kim, Suzy Mueller.

      Hyang-Ah Hana Kim uploaded patch set #3 to this change.

      View Change

      The following approvals got outdated and were removed: Commit-Queue+1 by Hyang-Ah Hana Kim, TryBot-Result+1 by kokoro

      src/language/goLanguageServer: improve suggestGoplsIssueReport

      The extension runs suggestGoplsIssueReport when it observes
      the language server client crashes. It prompts the user and
      collects useful information from settings, configuration,
      and the LSP server output channel ("gopls (server)")
      where stderr and LSP log messages are logged, populates a
      github issue template when the user agrees.

      This change improves the log collection and sanitization.

      * Incorrect version info and timestamp - previously they were
      computed after the user chooses "Yes" on the prompt. Usually,
      there is a delay between the problem occurs and the user
      notices the popup. Often, vscode hides the prompt window!
      It's possible that a new gopls or extension version was installed
      and restarted in between. This CL makes the suggestGoplsIssueReport
      accepts the configuration used when starting the crashed gopls
      session, and computes the issue timestamp before prompting.

      Moreover, we also compute the gopls version when the configuration
      This change also embeds `gopls stats -anon` output. That may
      reveal issues caught by gopls bug reports.

      While we are here, we also simplify the periodic gopls update check
      (scheduleGoplsSuggestions). That will remove another
      buildLanguageServerConfig call.

      Fixes golang/vscode-go#984
      Fixes golang/vscode-go#2690

      Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
      ---
      M src/commands/startLanguageServer.ts
      M src/goCheck.ts
      M src/goStatus.ts
      M src/language/goLanguageServer.ts
      M src/utils/pathUtils.ts
      M test/gopls/goplsTestEnv.utils.ts
      M test/gopls/report.test.ts
      M test/integration/extension.test.ts
      8 files changed, 118 insertions(+), 93 deletions(-)

      To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: newpatchset
      Gerrit-Project: vscode-go
      Gerrit-Branch: master
      Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
      Gerrit-Change-Number: 539415
      Gerrit-PatchSet: 3

      Hyang-Ah Hana Kim (Gerrit)

      unread,
      Nov 27, 2023, 5:42:56 PM11/27/23
      to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

      Attention is currently required from: Hyang-Ah Hana Kim, Suzy Mueller.

      Hyang-Ah Hana Kim uploaded patch set #4 to this change.

      View Change

      src/language/goLanguageServer: improve suggestGoplsIssueReport
      reveal issues in the workspace setup. For a large project, gopls stats
      may take a while. Limit the execution to 60sec.


      While we are here, we also simplify the periodic gopls update check
      (scheduleGoplsSuggestions). That will remove another
      buildLanguageServerConfig call.

      Fixes golang/vscode-go#984
      Fixes golang/vscode-go#2690

      Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
      ---
      M src/commands/startLanguageServer.ts
      M src/goCheck.ts
      M src/goStatus.ts
      M src/language/goLanguageServer.ts
      M src/utils/pathUtils.ts
      M test/gopls/goplsTestEnv.utils.ts
      M test/gopls/report.test.ts
      M test/integration/extension.test.ts
      8 files changed, 118 insertions(+), 93 deletions(-)

      To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: newpatchset
      Gerrit-Project: vscode-go
      Gerrit-Branch: master
      Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
      Gerrit-Change-Number: 539415
      Gerrit-PatchSet: 4

      Hyang-Ah Hana Kim (Gerrit)

      unread,
      Nov 27, 2023, 5:43:34 PM11/27/23
      to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, Robert Findley, Suzy Mueller, kokoro, golang-co...@googlegroups.com

      Attention is currently required from: Robert Findley, Suzy Mueller.

      Patch set 3:Run-TryBot +1Commit-Queue +1

      View Change

      2 comments:

        • This change also embeds `gopls stats -anon` output. That may


        • reveal issues caught by gopls bug reports.

        • This could take a long time to run, and could itself crash. Are we sure we want to do this? […]

          Added a timeout (1minute) as discussed before and corrected the commit message.

      To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: comment
      Gerrit-Project: vscode-go
      Gerrit-Branch: master
      Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
      Gerrit-Change-Number: 539415
      Gerrit-PatchSet: 3
      Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Reviewer: Suzy Mueller <suz...@golang.org>
      Gerrit-Reviewer: kokoro <noreply...@google.com>
      Gerrit-CC: kokoro <noreply...@google.com>
      Gerrit-Attention: Robert Findley <rfin...@google.com>
      Gerrit-Attention: Suzy Mueller <suz...@golang.org>
      Gerrit-Comment-Date: Mon, 27 Nov 2023 22:43:31 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      Comment-In-Reply-To: Robert Findley <rfin...@google.com>

      kokoro (Gerrit)

      unread,
      Nov 27, 2023, 5:53:06 PM11/27/23
      to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, Robert Findley, Suzy Mueller, golang-co...@googlegroups.com

      Attention is currently required from: Robert Findley, Suzy Mueller.

      Kokoro presubmit build finished with status: SUCCESS
      Logs at: https://source.cloud.google.com/results/invocations/d10eccd1-2f7c-4cd4-bbe6-12b1b61490a3

      Patch set 4:TryBot-Result +1

      View Change

        To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-MessageType: comment
        Gerrit-Project: vscode-go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
        Gerrit-Change-Number: 539415
        Gerrit-PatchSet: 4
        Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: Robert Findley <rfin...@google.com>
        Gerrit-Reviewer: Suzy Mueller <suz...@golang.org>
        Gerrit-Reviewer: kokoro <noreply...@google.com>
        Gerrit-CC: kokoro <noreply...@google.com>
        Gerrit-Attention: Robert Findley <rfin...@google.com>
        Gerrit-Attention: Suzy Mueller <suz...@golang.org>
        Gerrit-Comment-Date: Mon, 27 Nov 2023 22:53:00 +0000
        Gerrit-HasComments: No
        Gerrit-Has-Labels: Yes

        Robert Findley (Gerrit)

        unread,
        Nov 27, 2023, 6:18:57 PM11/27/23
        to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, kokoro, Suzy Mueller, golang-co...@googlegroups.com

        Attention is currently required from: Hyang-Ah Hana Kim, Suzy Mueller.

        Patch set 4:Code-Review +1

        View Change

        1 comment:

        To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-MessageType: comment
        Gerrit-Project: vscode-go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
        Gerrit-Change-Number: 539415
        Gerrit-PatchSet: 4
        Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: Robert Findley <rfin...@google.com>
        Gerrit-Reviewer: Suzy Mueller <suz...@golang.org>
        Gerrit-Reviewer: kokoro <noreply...@google.com>
        Gerrit-CC: kokoro <noreply...@google.com>
        Gerrit-Attention: Suzy Mueller <suz...@golang.org>
        Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Comment-Date: Mon, 27 Nov 2023 23:18:53 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: Yes

        Suzy Mueller (Gerrit)

        unread,
        Nov 28, 2023, 8:08:07 PM11/28/23
        to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, kokoro, Robert Findley, golang-co...@googlegroups.com

        Attention is currently required from: Hyang-Ah Hana Kim.

        Patch set 4:Code-Review +2

        View Change

        1 comment:

        • File src/commands/startLanguageServer.ts:

        To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-MessageType: comment
        Gerrit-Project: vscode-go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
        Gerrit-Change-Number: 539415
        Gerrit-PatchSet: 4
        Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: Robert Findley <rfin...@google.com>
        Gerrit-Reviewer: Suzy Mueller <suz...@golang.org>
        Gerrit-Reviewer: kokoro <noreply...@google.com>
        Gerrit-CC: kokoro <noreply...@google.com>
        Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Comment-Date: Wed, 29 Nov 2023 01:08:02 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: Yes

        Hyang-Ah Hana Kim (Gerrit)

        unread,
        Nov 29, 2023, 1:40:36 PM11/29/23
        to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

        Attention is currently required from: Hyang-Ah Hana Kim.

        Hyang-Ah Hana Kim uploaded patch set #5 to this change.

        View Change

        The following approvals got outdated and were removed: Commit-Queue+1 by Hyang-Ah Hana Kim, Run-TryBot+1 by Hyang-Ah Hana Kim, TryBot-Result+1 by kokoro

        This change also embeds `gopls stats -anon` output. That may
        reveal issues in the workspace setup. For a large project, gopls stats
        may take a while. Limit the execution to 60sec.

        While we are here, we also simplify the periodic gopls update check
        (scheduleGoplsSuggestions). That will remove another
        buildLanguageServerConfig call.

        Fixes golang/vscode-go#984
        Fixes golang/vscode-go#2690

        Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
        ---
        M src/commands/startLanguageServer.ts
        M src/goCheck.ts
        M src/goStatus.ts
        M src/language/goLanguageServer.ts
        M src/utils/pathUtils.ts
        M test/gopls/goplsTestEnv.utils.ts
        M test/gopls/report.test.ts
        M test/integration/extension.test.ts
        8 files changed, 117 insertions(+), 92 deletions(-)

        To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-MessageType: newpatchset
        Gerrit-Project: vscode-go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
        Gerrit-Change-Number: 539415
        Gerrit-PatchSet: 5

        Hyang-Ah Hana Kim (Gerrit)

        unread,
        Nov 29, 2023, 1:41:48 PM11/29/23
        to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, Suzy Mueller, kokoro, Robert Findley, golang-co...@googlegroups.com

        Patch set 5:Run-TryBot +1Auto-Submit +1

        View Change

        1 comment:

        • File src/commands/startLanguageServer.ts:

          • ooops. deleted.

        To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-MessageType: comment
        Gerrit-Project: vscode-go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
        Gerrit-Change-Number: 539415
        Gerrit-PatchSet: 5
        Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
        Gerrit-Reviewer: Robert Findley <rfin...@google.com>
        Gerrit-Reviewer: Suzy Mueller <suz...@golang.org>
        Gerrit-Reviewer: kokoro <noreply...@google.com>
        Gerrit-CC: kokoro <noreply...@google.com>
        Gerrit-Comment-Date: Wed, 29 Nov 2023 18:41:45 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: Yes
        Comment-In-Reply-To: Suzy Mueller <suz...@golang.org>

        kokoro (Gerrit)

        unread,
        Nov 29, 2023, 1:52:45 PM11/29/23
        to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, Suzy Mueller, Robert Findley, golang-co...@googlegroups.com

        Attention is currently required from: Hyang-Ah Hana Kim.

        Kokoro presubmit build finished with status: SUCCESS
        Logs at: https://source.cloud.google.com/results/invocations/df040210-8a94-4531-a071-b4954bd30af4

        Patch set 5:TryBot-Result +1

        View Change

          To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-MessageType: comment
          Gerrit-Project: vscode-go
          Gerrit-Branch: master
          Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
          Gerrit-Change-Number: 539415
          Gerrit-PatchSet: 5
          Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
          Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
          Gerrit-Reviewer: Robert Findley <rfin...@google.com>
          Gerrit-Reviewer: Suzy Mueller <suz...@golang.org>
          Gerrit-Reviewer: kokoro <noreply...@google.com>
          Gerrit-CC: kokoro <noreply...@google.com>
          Gerrit-Attention: Hyang-Ah Hana Kim <hya...@gmail.com>
          Gerrit-Comment-Date: Wed, 29 Nov 2023 18:52:41 +0000
          Gerrit-HasComments: No
          Gerrit-Has-Labels: Yes

          Gopher Robot (Gerrit)

          unread,
          Nov 29, 2023, 1:53:07 PM11/29/23
          to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, kokoro, Suzy Mueller, Robert Findley, golang-co...@googlegroups.com

          Gopher Robot submitted this change.

          View Change



          4 is the latest approved patch-set.
          The change was submitted with unreviewed changes in the following files:

          ```
          The name of the file: src/commands/startLanguageServer.ts
          Insertions: 1, Deletions: 1.

          @@ -49,7 +49,7 @@

          }
          // If the client has already been started, make sure to clear existing
          // diagnostics and stop it.
          -			if (goCtx.languageClient && goCtx.languageClient) {
          + if (goCtx.languageClient) {

          await stopLanguageClient(goCtx);
          }
          updateStatus(goCtx, goConfig, false);
          ```

          Approvals: Hyang-Ah Hana Kim: Run legacy TryBots; Automatically submit change; Run LUCI TryBots Robert Findley: Looks good to me, but someone else must approve Suzy Mueller: Looks good to me, approved kokoro: TryBots succeeded
          Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/539415
          Auto-Submit: Hyang-Ah Hana Kim <hya...@gmail.com>
          Commit-Queue: Hyang-Ah Hana Kim <hya...@gmail.com>
          TryBot-Result: kokoro <noreply...@google.com>
          Reviewed-by: Robert Findley <rfin...@google.com>
          Reviewed-by: Suzy Mueller <suz...@golang.org>
          Run-TryBot: Hyang-Ah Hana Kim <hya...@gmail.com>

          ---
          M src/commands/startLanguageServer.ts
          M src/goCheck.ts
          M src/goStatus.ts
          M src/language/goLanguageServer.ts
          M src/utils/pathUtils.ts
          M test/gopls/goplsTestEnv.utils.ts
          M test/gopls/report.test.ts
          M test/integration/extension.test.ts
          8 files changed, 117 insertions(+), 92 deletions(-)

          
          
          diff --git a/src/commands/startLanguageServer.ts b/src/commands/startLanguageServer.ts
          index 6c672fb..f01d1f9 100644
          --- a/src/commands/startLanguageServer.ts
          +++ b/src/commands/startLanguageServer.ts

          @@ -30,7 +30,7 @@
          export const startLanguageServer: CommandFactory = (ctx, goCtx) => {
          return async (reason: RestartReason = RestartReason.MANUAL) => {
          const goConfig = getGoConfig();
          - const cfg = buildLanguageServerConfig(goConfig);
          + const cfg = await buildLanguageServerConfig(goConfig);

          if (typeof reason === 'string') {
          updateRestartHistory(goCtx, reason, cfg.enabled);
          @@ -42,6 +42,7 @@

          if (reason === RestartReason.MANUAL) {
          await suggestGoplsIssueReport(
          goCtx,
          + cfg,
          "Looks like you're about to manually restart the language server.",
          errorKind.manualRestart
          );
          diff --git a/src/goCheck.ts b/src/goCheck.ts
          index ff81136..c71574b 100644
          --- a/src/goCheck.ts
          +++ b/src/goCheck.ts
          @@ -11,7 +11,6 @@
          import vscode = require('vscode');
          import { getGoplsConfig } from './config';
          import { goBuild } from './goBuild';
          -import { buildLanguageServerConfig } from './language/goLanguageServer';
          import { goLint } from './goLint';
          import { isModSupported } from './goModules';
          import { diagnosticsStatusBarItem, outputChannel } from './goStatus';
          @@ -68,8 +67,7 @@


          // If a user has enabled diagnostics via a language server,
          // then we disable running build or vet to avoid duplicate errors and warnings.
          - const lspConfig = buildLanguageServerConfig(goConfig);
          - const disableBuildAndVet = lspConfig.enabled;
          +	const disableBuildAndVet = goConfig.get('useLanguageServer');

           	let testPromise: Thenable<boolean>;
          const testConfig: TestConfig = {
          diff --git a/src/goStatus.ts b/src/goStatus.ts
          index 01b1224..6ce338b 100644
          --- a/src/goStatus.ts
          +++ b/src/goStatus.ts
          @@ -11,7 +11,6 @@
          import vscodeUri = require('vscode-uri');
          import { getGoConfig } from './config';
          import { formatGoVersion, GoEnvironmentOption, terminalCreationListener } from './goEnvironmentStatus';
          -import { buildLanguageServerConfig, getLocalGoplsVersion } from './language/goLanguageServer';
          import { isGoFile } from './goMode';
          import { isModSupported, runGoEnv } from './goModules';
          import { allToolsInformation } from './goToolsInformation';
          @@ -61,14 +60,16 @@

          { label: 'Choose Go Environment' }
          ];

          - // Get the gopls configuration
          + const cfg = goCtx.latestConfig;
          + // Get the gopls configuration.
          const goConfig = getGoConfig();
          - const cfg = buildLanguageServerConfig(goConfig);
          - if (languageServerIsRunning && cfg.serverName === 'gopls') {
          - const goplsVersion = await getLocalGoplsVersion(cfg);
          + const goplsIsRunning = languageServerIsRunning && cfg && cfg.serverName === 'gopls';
          + if (goplsIsRunning) {
          + const goplsVersion = cfg.version;
          options.push({ label: `${languageServerIcon}Open 'gopls' trace`, description: `${goplsVersion?.version}` });
          }
          - if (!languageServerIsRunning && !cfg.serverName && goConfig['useLanguageServer'] === true) {
          +	// In case gopls still need to be installed, cfg.serverName will be empty.

          + if (!goplsIsRunning && goConfig.get('useLanguageServer') === true && cfg?.serverName === '') {
          options.push({
          label: 'Install Go Language Server',
          description: `${languageServerErrorIcon}'gopls' is required but missing`
          diff --git a/src/language/goLanguageServer.ts b/src/language/goLanguageServer.ts
          index 60ee6ed..ea2c3c2 100644
          +		const cfg = goCtx.latestConfig;
          @@ -416,6 +394,7 @@

          goCtx: GoExtensionContext,
          cfg: BuildLanguageClientOption
          ): Promise<GoLanguageClient> {
          + await getLocalGoplsVersion(cfg); // populate and cache cfg.version
          const goplsWorkspaceConfig = await adjustGoplsWorkspaceConfiguration(cfg, getGoplsConfig(), 'gopls', undefined);

          const documentSelector = [
          @@ -435,7 +414,7 @@


          const pendingVulncheckProgressToken = new Map<ProgressToken, any>();
          const onDidChangeVulncheckResultEmitter = new vscode.EventEmitter<VulncheckEvent>();
          -
          + // cfg is captured by closures for later use during error report.
          const c = new GoLanguageClient(
          'go', // id
          cfg.serverName, // name e.g. gopls
          @@ -470,6 +449,7 @@

          };
          }
          return {
          + message: '', // suppresses error popups
          action: ErrorAction.Shutdown
          };
          },
          @@ -477,6 +457,7 @@

          if (initializationError !== undefined) {
          suggestGoplsIssueReport(
          goCtx,
          + cfg,
          'The gopls server failed to initialize.',
          errorKind.initializationFailure,
          initializationError
          @@ -484,7 +465,7 @@

          initializationError = undefined;
          // In case of initialization failure, do not try to restart.
          return {
          - message: 'The gopls server failed to initialize.',
          + message: '', // suppresses error popups - there will be other popups. :-(
          action: CloseAction.DoNotRestart
          };
          }
          @@ -500,11 +481,13 @@

          }
          suggestGoplsIssueReport(
          goCtx,
          + cfg,
          'The connection to gopls has been closed. The gopls server may have crashed.',
          errorKind.crash
          );
          updateLanguageServerIconGoStatusBar(false, true);
          return {
          + message: '', // suppresses error popups - there will be other popups.
          action: CloseAction.DoNotRestart
          };
          }
          @@ -968,16 +951,16 @@

          }
          }

          -export function buildLanguageServerConfig(goConfig: vscode.WorkspaceConfiguration): LanguageServerConfig {
          +export async function buildLanguageServerConfig(
          +	goConfig: vscode.WorkspaceConfiguration
          +): Promise<LanguageServerConfig> {

          let formatter: GoDocumentFormattingEditProvider | undefined;
          if (usingCustomFormatTool(goConfig)) {
          formatter = new GoDocumentFormattingEditProvider();
          }
          const cfg: LanguageServerConfig = {
          - serverName: '',
          + serverName: '', // remain empty if gopls binary can't be found.
          path: '',
          - version: undefined, // compute version lazily
          - modtime: undefined,
          enabled: goConfig['useLanguageServer'] === true,
          flags: goConfig['languageServerFlags'] || [],
          features: {
          @@ -1015,7 +998,7 @@

          return cfg;
          }
          cfg.modtime = stats.mtime;
          -
          + cfg.version = await getLocalGoplsVersion(cfg);
          return cfg;
          }

          @@ -1208,13 +1191,13 @@

          // If this command has already been executed, it returns the saved result.
          export const getLocalGoplsVersion = async (cfg?: LanguageServerConfig) => {
          if (!cfg) {
          - return null;
          + return;
          }
          if (cfg.version) {
          return cfg.version;
          }
          if (cfg.path === '') {
          - return null;
          + return;
          }
          const env = toolExecutionEnvironment();
          const cwd = getWorkspaceFolderPath();
          @@ -1240,7 +1223,7 @@

          } catch (e) {
          // The "gopls version" command is not supported, or something else went wrong.
          // TODO: Should we propagate this error?
          - return null;
          + return;
          }

          const lines = output.trim().split('\n');
          @@ -1248,17 +1231,17 @@

          case 0:
          // No results, should update.
          // Worth doing anything here?
          - return null;
          + return;
          case 1:
          // Built in $GOPATH mode. Should update.
          // TODO: Should we check the Go version here?
          // Do we even allow users to enable gopls if their Go version is too low?
          - return null;
          + return;
          case 2:
          // We might actually have a parseable version.
          break;
          default:
          - return null;
          + return;
          }

          // The second line should be the sum line.
          @@ -1277,7 +1260,7 @@

          //
          const split = moduleVersion.trim().split('@');
          if (split.length < 2) {
          - return null;
          + return;
          }
          // The version comes after the @ symbol:
          //
          @@ -1326,15 +1309,26 @@

          // suggestGoplsIssueReport prompts users to file an issue with gopls.
          export async function suggestGoplsIssueReport(
          goCtx: GoExtensionContext,
          + cfg: LanguageServerConfig, // config used when starting this gopls.
          msg: string,
          reason: errorKind,
          initializationError?: WebRequest.ResponseError<InitializeError>
          ) {
          + const issueTime = new Date();
          +
          // Don't prompt users who manually restart to file issues until gopls/v1.0.
          if (reason === errorKind.manualRestart) {
          return;
          }

          + // cfg is the config used when starting this crashed gopls instance, while
          + // goCtx.latestConfig is the config used by the latest gopls instance.
          + // They may be different if gopls upgrade occurred in between.
          + // Let's not report issue yet if they don't match.
          + if (JSON.stringify(goCtx.latestConfig?.version) !== JSON.stringify(cfg.version)) {
          + return;
          + }
          +
          // The user may have an outdated version of gopls, in which case we should
          // just prompt them to update, not file an issue.
          const tool = getTool('gopls');
          @@ -1378,15 +1372,16 @@

          if (failureReason === GoplsFailureModes.INCORRECT_COMMAND_USAGE) {
          const languageServerFlags = getGoConfig()['languageServerFlags'] as string[];
          if (languageServerFlags && languageServerFlags.length > 0) {
          - selected = await vscode.window.showInformationMessage(
          + selected = await vscode.window.showErrorMessage(
          `The extension was unable to start the language server.
          You may have an invalid value in your "go.languageServerFlags" setting.
          -It is currently set to [${languageServerFlags}]. Please correct the setting by navigating to Preferences -> Settings.`,
          - 'Open settings',
          +It is currently set to [${languageServerFlags}].
          +Please correct the setting.`,
          + 'Open Settings',
          'I need more help.'
          );
          switch (selected) {
          - case 'Open settings':
          + case 'Open Settings':
          await vscode.commands.executeCommand('workbench.action.openSettings', 'go.languageServerFlags');
          return;
          case 'I need more help':
          @@ -1395,7 +1390,8 @@

          }
          }
          }
          - selected = await vscode.window.showInformationMessage(
          + const showMessage = sanitizedLog ? vscode.window.showWarningMessage : vscode.window.showInformationMessage;
          + selected = await showMessage(
          `${msg} Would you like to report a gopls issue on GitHub?
          You will be asked to provide additional information and logs, so PLEASE READ THE CONTENT IN YOUR BROWSER.`,
          'Yes',
          @@ -1415,11 +1411,9 @@

          errKind = 'initialization';
          break;
          }
          - // Get the user's version in case the update prompt above failed.
          - const usersGoplsVersion = await getLocalGoplsVersion(goCtx.latestConfig);
          - const goVersion = await getGoVersion();
          const settings = goCtx.latestConfig.flags.join(' ');
          const title = `gopls: automated issue report (${errKind})`;
          + const goplsStats = await getGoplsStats(goCtx.latestConfig?.path);
          const goplsLog = sanitizedLog
          ? `<pre>${sanitizedLog}</pre>`
          : `Please attach the stack trace from the crash.
          @@ -1430,17 +1424,15 @@


          Failed to auto-collect gopls trace: ${failureReason}.
          `;
          - const now = new Date();

          const body = `
          -gopls version: ${usersGoplsVersion?.version} (${usersGoplsVersion?.goVersion})
          +gopls version: ${cfg.version?.version}/${cfg.version?.goVersion}
          gopls flags: ${settings}
          -update flags: ${goCtx.latestConfig.checkForUpdates}
          +update flags: ${cfg.checkForUpdates}
          extension version: ${extensionInfo.version}
          -go version: ${goVersion?.format(true)}
          environment: ${extensionInfo.appName} ${process.platform}
          initialization error: ${initializationError}
          -issue timestamp: ${now.toUTCString()}
          +issue timestamp: ${issueTime.toUTCString()}
          restart history:
          ${formatRestartHistory(goCtx)}

          @@ -1452,6 +1444,10 @@


          ${goplsLog}

          +<details><summary>gopls stats -anon</summary>
          +${goplsStats}
          +</details>
          +
          OPTIONAL: If you would like to share more information, you can attach your complete gopls logs.

          NOTE: THESE MAY CONTAIN SENSITIVE INFORMATION ABOUT YOUR CODEBASE.
          @@ -1459,7 +1455,7 @@
          @@ -1525,12 +1521,10 @@

          if (doc.isDirty || doc.isClosed) {
          continue;
          }
          - // The document's name should look like 'extension-output-#X'.
          - if (doc.fileName.indexOf('extension-output-') === -1) {
          - continue;
          + if (doc.fileName.indexOf('gopls (server)') > -1) {
          + logs = doc.getText();
          + break;
          }
          - logs = doc.getText();
          - break;
          }
          if (logs) {
          break;
          @@ -1538,7 +1532,6 @@

          // sleep a bit before the next try. The choice of the sleep time is arbitrary.
          await sleep((i + 1) * 100);
          }
          -
          return sanitizeGoplsTrace(logs);
          }

          @@ -1588,7 +1581,7 @@

          }
          return { failureReason: GoplsFailureModes.INCOMPLETE_PANIC_TRACE };
          }
          - const initFailMsgBegin = logs.lastIndexOf('Starting client failed');
          + const initFailMsgBegin = logs.lastIndexOf('gopls client:');
          if (initFailMsgBegin > -1) {
          // client start failed. Capture up to the 'Code:' line.
          const initFailMsgEnd = logs.indexOf('Code: ', initFailMsgBegin);
          @@ -1602,9 +1595,16 @@

          };
          }
          }
          - if (logs.lastIndexOf('Usage: gopls') > -1) {
          + if (logs.lastIndexOf('Usage:') > -1) {
          return { failureReason: GoplsFailureModes.INCORRECT_COMMAND_USAGE };
          }
          + // Capture Fatal
          + // foo.go:1: the last message (caveat - we capture only the first log line)
          + const m = logs.match(/(^\S+\.go:\d+:.*$)/gm);
          + if (m && m.length > 0) {
          + return { sanitizedLog: m[0].toString() };
          + }
          +
          return { failureReason: GoplsFailureModes.UNRECOGNIZED_CRASH_PATTERN };
          }

          @@ -1656,3 +1656,22 @@

          };
          callback();
          }
          +
          +async function getGoplsStats(binpath?: string) {
          + if (!binpath) {
          + return 'gopls path unknown';
          + }
          + const env = toolExecutionEnvironment();
          + const cwd = getWorkspaceFolderPath();
          +	const start = new Date();

          + const execFile = util.promisify(cp.execFile);
          + try {
          +		const timeout = 60 * 1000; // 60sec;
          + const { stdout } = await execFile(binpath, ['stats', '-anon'], { env, cwd, timeout });

          + return stdout;
          + } catch (e) {
          +		const duration = new Date().getTime() - start.getTime();
          + console.log(`gopls stats -anon failed: ${JSON.stringify(e)}`);
          + return `gopls stats -anon failed after running for ${duration}ms`; // e may contain user information. don't include in the report.
          + }
          +}

          diff --git a/src/utils/pathUtils.ts b/src/utils/pathUtils.ts
          index ead04ac..ad4509d 100644
          --- a/src/utils/pathUtils.ts
          +++ b/src/utils/pathUtils.ts
          @@ -247,7 +247,7 @@
          }

          /**
          - * Returns the tool name from the given path to the tool
          + * Returns the tool name (executable's basename) from the given path to the tool
          * @param toolPath
          */
          export function getToolFromToolPath(toolPath: string): string | undefined {
          diff --git a/test/gopls/goplsTestEnv.utils.ts b/test/gopls/goplsTestEnv.utils.ts
          index a6bc999..95d2d4e 100644
          --- a/test/gopls/goplsTestEnv.utils.ts
          +++ b/test/gopls/goplsTestEnv.utils.ts
          @@ -108,7 +108,7 @@

          if (!goConfig) {
          goConfig = getGoConfig();
          }
          - const cfg: BuildLanguageClientOption = buildLanguageServerConfig(
          + const cfg: BuildLanguageClientOption = await buildLanguageServerConfig(
          Object.create(goConfig, {
          useLanguageServer: { value: true },
          languageServerFlags: { value: ['-rpc.trace'] } // enable rpc tracing to monitor progress reports
          diff --git a/test/gopls/report.test.ts b/test/gopls/report.test.ts
          index dd121e7..4cabab9 100644
          diff --git a/test/integration/extension.test.ts b/test/integration/extension.test.ts
          index b6aa5f7..ca76d4d 100644
          --- a/test/integration/extension.test.ts
          +++ b/test/integration/extension.test.ts
          @@ -210,7 +210,7 @@

          ];
          // If a user has enabled diagnostics via a language server,
          // then we disable running build or vet to avoid duplicate errors and warnings.
          - const lspConfig = buildLanguageServerConfig(getGoConfig());
          + const lspConfig = await buildLanguageServerConfig(getGoConfig());
          const expectedBuildVetErrors = lspConfig.enabled
          ? []
          : [{ line: 11, severity: 'error', msg: 'undefined: prin' }];
          @@ -489,7 +489,7 @@

          });

          test('Build Tags checking', async () => {
          - const goplsConfig = buildLanguageServerConfig(getGoConfig());
          + const goplsConfig = await buildLanguageServerConfig(getGoConfig());
          if (goplsConfig.enabled) {
          // Skip this test if gopls is enabled. Build/Vet checks this test depend on are
          // disabled when the language server is enabled, and gopls is not handling tags yet.

          To view, visit change 539415. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-MessageType: merged
          Gerrit-Project: vscode-go
          Gerrit-Branch: master
          Gerrit-Change-Id: Ib8aa2abbd5f0c812605ced13c9c93b8aa3bb94fd
          Gerrit-Change-Number: 539415
          Gerrit-PatchSet: 6
          Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
          Gerrit-Reviewer: Gopher Robot <go...@golang.org>
          Reply all
          Reply to author
          Forward
          0 new messages