in src/goLanguageServer.ts [1062:1128]
export async function shouldUpdateLanguageServer(
tool: Tool,
cfg: LanguageServerConfig,
mustCheck?: boolean
): Promise<semver.SemVer> {
// Only support updating gopls for now.
if (tool.name !== 'gopls' || (!mustCheck && (cfg.checkForUpdates === 'off' || IsInCloudIDE))) {
return null;
}
if (!cfg.enabled) {
return null;
}
// If the Go version is too old, don't update.
const goVersion = await getGoVersion();
if (!goVersion || (tool.minimumGoVersion && goVersion.lt(tool.minimumGoVersion.format()))) {
return null;
}
// First, run the "gopls version" command and parse its results.
// TODO(rstambler): Confirm that the gopls binary's modtime matches the
// modtime in the config. Update it if needed.
const usersVersion = await getLocalGoplsVersion(cfg);
// We might have a developer version. Don't make the user update.
if (usersVersion === '(devel)') {
return null;
}
// Get the latest gopls version. If it is for nightly, using the prereleased version is ok.
let latestVersion =
cfg.checkForUpdates === 'local' ? tool.latestVersion : await latestToolVersion(tool, isInPreviewMode());
// If we failed to get the gopls version, pick the one we know to be latest at the time of this extension's last update
if (!latestVersion) {
latestVersion = tool.latestVersion;
}
// If "gopls" is so old that it doesn't have the "gopls version" command,
// or its version doesn't match our expectations, usersVersion will be empty or invalid.
// Suggest the latestVersion.
if (!usersVersion || !semver.valid(usersVersion)) {
return latestVersion;
}
// The user may have downloaded golang.org/x/tools/gopls@master,
// which means that they have a pseudoversion.
const usersTime = parseTimestampFromPseudoversion(usersVersion);
// If the user has a pseudoversion, get the timestamp for the latest gopls version and compare.
if (usersTime) {
let latestTime = cfg.checkForUpdates
? await getTimestampForVersion(tool, latestVersion)
: tool.latestVersionTimestamp;
if (!latestTime) {
latestTime = tool.latestVersionTimestamp;
}
return usersTime.isBefore(latestTime) ? latestVersion : null;
}
// If the user's version does not contain a timestamp,
// default to a semver comparison of the two versions.
const usersVersionSemver = semver.parse(usersVersion, {
includePrerelease: true,
loose: true
});
return semver.lt(usersVersionSemver, latestVersion) ? latestVersion : null;
}