Skip to content

Commit f1c5335

Browse files
h9jianggopherbot
authored andcommitted
extension/src: rename latestToolVersion to latestModuleVersion
Refactor logic to determine the latest version to make it more clear. Replace type assersion using <> with as. https://google.github.io/styleguide/tsguide.html#type-and-non-nullability-assertions For #2891 Change-Id: I2977fcf6e8f77b7a2b7f2aa409f2206685cf59bf Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/693676 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Hongxiang Jiang <[email protected]> Commit-Queue: Hongxiang Jiang <[email protected]>
1 parent fa1bd8a commit f1c5335

File tree

3 files changed

+47
-35
lines changed

3 files changed

+47
-35
lines changed

extension/src/goInstallTools.ts

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ async function installToolWithGo(
343343

344344
let version: semver.SemVer | string | undefined | null = tool.version;
345345
if (!version && tool.usePrereleaseInPreviewMode && extensionInfo.isPreview) {
346-
version = await latestToolVersion(tool, true);
346+
version = await latestModuleVersion(tool.modulePath, true);
347347
}
348348
// TODO(hyangah): should we allow to choose a different version of the tool
349349
// depending on the project's go version (i.e. getGoVersion())? For example,
@@ -733,17 +733,28 @@ async function suggestDownloadGo() {
733733
}
734734

735735
/**
736-
* The output of `go list -m -versions -json`.
736+
* Interface for the expected JSON output from `go list -m -versions -json`.
737+
* See https://go.dev/ref/mod#go-list-m for details.
737738
*/
738739
interface ListVersionsOutput {
739-
Version: string; // module version
740-
Versions?: string[]; // available module versions (with -versions)
740+
/**
741+
* The latest tagged release version (e.g., v1.2.3). Excludes pre-releases.
742+
*/
743+
Version: string;
744+
/**
745+
* All known versions of the module, sorted semantically from earliest to
746+
* latest. Includes pre-release versions.
747+
*/
748+
Versions?: string[];
741749
}
742750

743751
/**
744-
* Returns the latest version of the tool.
752+
* Returns the latest published versions of a Go module.
745753
*/
746-
export async function latestToolVersion(tool: Tool, includePrerelease?: boolean): Promise<semver.SemVer | null> {
754+
export async function latestModuleVersion(
755+
modulePath: string,
756+
includePrerelease?: boolean
757+
): Promise<semver.SemVer | null> {
747758
const goCmd = getBinPath('go');
748759
const tmpDir = await tmpDirForToolInstallation();
749760
const execFile = util.promisify(cp.execFile);
@@ -753,27 +764,28 @@ export async function latestToolVersion(tool: Tool, includePrerelease?: boolean)
753764
try {
754765
const env = toolInstallationEnvironment();
755766
env['GO111MODULE'] = 'on';
756-
// Run go list in a temp directory to avoid altering go.mod
757-
// when using older versions of go (<1.16).
758-
const version = 'latest'; // TODO(hyangah): use 'master' for delve-dap.
759-
const { stdout } = await execFile(
760-
goCmd,
761-
['list', '-m', '--versions', '-json', `${tool.modulePath}@${version}`],
762-
{
763-
env,
764-
cwd: tmpDir
765-
}
766-
);
767-
const m = <ListVersionsOutput>JSON.parse(stdout);
768-
// Versions field is a list of all known versions of the module,
769-
// ordered according to semantic versioning, earliest to latest.
770-
const latest = includePrerelease && m.Versions && m.Versions.length > 0 ? m.Versions.pop() : m.Version;
767+
// Run go list in a temp directory to avoid altering go.mod when using
768+
// older versions of go (<1.16).
769+
const { stdout } = await execFile(goCmd, ['list', '-m', '--versions', '-json', `${modulePath}@latest`], {
770+
env,
771+
cwd: tmpDir
772+
});
773+
const moduleInfo = JSON.parse(stdout) as ListVersionsOutput;
774+
775+
let latest: string;
776+
if (includePrerelease && moduleInfo.Versions && moduleInfo.Versions.length > 0) {
777+
latest = moduleInfo.Versions[moduleInfo.Versions.length - 1];
778+
} else {
779+
latest = moduleInfo.Version;
780+
}
781+
771782
ret = semver.parse(latest);
772783
} catch (e) {
773-
console.log(`failed to retrieve the latest tool ${tool.name} version: ${e}`);
784+
console.log(`failed to retrieve the latest version of module ${modulePath}: ${e}`);
774785
} finally {
775786
rmdirRecursive(tmpDir);
776787
}
788+
777789
return ret;
778790
}
779791

extension/src/language/goLanguageServer.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { Executable, LanguageClient, ServerOptions } from 'vscode-languageclient
4040
import { getGoConfig, getGoplsConfig, extensionInfo } from '../config';
4141
import { toolExecutionEnvironment } from '../goEnv';
4242
import { GoDocumentFormattingEditProvider, usingCustomFormatTool } from './legacy/goFormat';
43-
import { installTools, latestToolVersion, promptForMissingTool, promptForUpdatingTool } from '../goInstallTools';
43+
import { installTools, latestModuleVersion, promptForMissingTool, promptForUpdatingTool } from '../goInstallTools';
4444
import { getTool, Tool } from '../goTools';
4545
import { getFromGlobalState, updateGlobalState, updateWorkspaceState } from '../stateUtils';
4646
import {
@@ -1139,20 +1139,20 @@ export async function shouldUpdateLanguageServer(
11391139
return null;
11401140
}
11411141

1142-
// Get the latest gopls version. If it is for nightly, using the prereleased version is ok.
1143-
let latestVersion =
1144-
cfg.checkForUpdates === 'local' ? tool.latestVersion : await latestToolVersion(tool, extensionInfo.isPreview);
1145-
1146-
// 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
1147-
if (!latestVersion) {
1148-
latestVersion = tool.latestVersion;
1142+
let version = tool.latestVersion;
1143+
if (cfg.checkForUpdates === 'proxy') {
1144+
// Allow installation of gopls pre-releases on insider versions of the extension.
1145+
const latest = await latestModuleVersion(tool.modulePath, extensionInfo.isPreview);
1146+
if (latest) {
1147+
version = latest;
1148+
}
11491149
}
11501150

11511151
// If "gopls" is so old that it doesn't have the "gopls version" command,
11521152
// or its version doesn't match our expectations, usersVersion will be empty or invalid.
11531153
// Suggest the latestVersion.
11541154
if (!usersVersion || !semver.valid(usersVersion.version)) {
1155-
return latestVersion;
1155+
return version;
11561156
}
11571157

11581158
// The user may have downloaded golang.org/x/tools/gopls@master,
@@ -1161,12 +1161,12 @@ export async function shouldUpdateLanguageServer(
11611161
// If the user has a pseudoversion, get the timestamp for the latest gopls version and compare.
11621162
if (usersTime) {
11631163
let latestTime = cfg.checkForUpdates
1164-
? await getTimestampForVersion(tool, latestVersion!)
1164+
? await getTimestampForVersion(tool, version!)
11651165
: tool.latestVersionTimestamp;
11661166
if (!latestTime) {
11671167
latestTime = tool.latestVersionTimestamp;
11681168
}
1169-
return usersTime.isBefore(latestTime) ? latestVersion : null;
1169+
return usersTime.isBefore(latestTime) ? version : null;
11701170
}
11711171

11721172
// If the user's version does not contain a timestamp,
@@ -1175,7 +1175,7 @@ export async function shouldUpdateLanguageServer(
11751175
includePrerelease: true,
11761176
loose: true
11771177
});
1178-
return semver.lt(usersVersionSemver!, latestVersion!) ? latestVersion : null;
1178+
return semver.lt(usersVersionSemver!, version!) ? version : null;
11791179
}
11801180

11811181
// Copied from src/cmd/go/internal/modfetch.go.

extension/test/gopls/update.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ suite('gopls update tests', () => {
9898
sinon.replace(lsp, 'getLocalGoplsVersion', async () => {
9999
return { version: usersVersion };
100100
});
101-
sinon.replace(goInstallTools, 'latestToolVersion', async () => {
101+
sinon.replace(goInstallTools, 'latestModuleVersion', async () => {
102102
if (acceptPrerelease) {
103103
return latestPrereleaseVersion;
104104
}

0 commit comments

Comments
 (0)