From 5ff5cbb00a33ae987651ad350e36f1648b06882b Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Mon, 22 May 2023 13:24:35 -0400 Subject: [PATCH] gopls: deprecate support for Go 1.16 and 1.17, update warnings Update our version table to reflect the existence of gopls@v0.12.0, and deprecate support for Go 1.16 and 1.17. Fixes golang/go#60341 Change-Id: Id061aafacb4099f57d464b5a7453bc1f98fda80a Reviewed-on: https://go-review.googlesource.com/c/tools/+/496881 Run-TryBot: Robert Findley TryBot-Result: Gopher Robot Reviewed-by: Alan Donovan --- gopls/README.md | 1 + gopls/internal/lsp/general.go | 42 +++++++++++++++++++++++------- gopls/internal/lsp/general_test.go | 16 +++++++----- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/gopls/README.md b/gopls/README.md index 56d15921a70..396f86c0242 100644 --- a/gopls/README.md +++ b/gopls/README.md @@ -93,6 +93,7 @@ version of gopls. | ----------- | --------------------------------------------------- | | Go 1.12 | [gopls@v0.7.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.7.5) | | Go 1.15 | [gopls@v0.9.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.9.5) | +| Go 1.17 | [gopls@v0.11.0](https://github.com/golang/tools/releases/tag/gopls%2Fv0.11.0) | Our extended support is enforced via [continuous integration with older Go versions](doc/contributing.md#ci). This legacy Go CI may not block releases: diff --git a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go index 04fe7136562..7486f24904a 100644 --- a/gopls/internal/lsp/general.go +++ b/gopls/internal/lsp/general.go @@ -8,6 +8,7 @@ import ( "context" "encoding/json" "fmt" + "go/build" "log" "os" "path" @@ -239,14 +240,16 @@ func (s *Server) initialized(ctx context.Context, params *protocol.InitializedPa // GoVersionTable maps Go versions to the gopls version in which support will // be deprecated, and the final gopls version supporting them without warnings. -// Keep this in sync with gopls/README.md +// Keep this in sync with gopls/README.md. // // Must be sorted in ascending order of Go version. // // Mutable for testing. var GoVersionTable = []GoVersionSupport{ {12, "", "v0.7.5"}, - {15, "v0.11.0", "v0.9.5"}, + {15, "", "v0.9.5"}, + {16, "v0.13.0", "v0.11.0"}, + {17, "v0.13.0", "v0.11.0"}, } // GoVersionSupport holds information about end-of-life Go version support. @@ -262,11 +265,13 @@ func OldestSupportedGoVersion() int { return GoVersionTable[len(GoVersionTable)-1].GoVersion + 1 } -// versionMessage returns the warning/error message to display if the user is -// on the given Go version, if any. The goVersion variable is the X in Go 1.X. +// versionMessage returns the warning/error message to display if the user has +// the given Go version, if any. The goVersion variable is the X in Go 1.X. If +// fromBuild is set, the Go version is the version used to build gopls. +// Otherwise, it is the go command version. // // If goVersion is invalid (< 0), it returns "", 0. -func versionMessage(goVersion int) (string, protocol.MessageType) { +func versionMessage(goVersion int, fromBuild bool) (string, protocol.MessageType) { if goVersion < 0 { return "", 0 } @@ -276,7 +281,11 @@ func versionMessage(goVersion int) (string, protocol.MessageType) { var msgBuilder strings.Builder mType := protocol.Error - fmt.Fprintf(&msgBuilder, "Found Go version 1.%d", goVersion) + if fromBuild { + fmt.Fprintf(&msgBuilder, "Gopls was built with Go version 1.%d", goVersion) + } else { + fmt.Fprintf(&msgBuilder, "Found Go version 1.%d", goVersion) + } if v.DeprecatedVersion != "" { // not deprecated yet, just a warning fmt.Fprintf(&msgBuilder, ", which will be unsupported by gopls %s. ", v.DeprecatedVersion) @@ -299,15 +308,15 @@ func versionMessage(goVersion int) (string, protocol.MessageType) { // // It should be called after views change. func (s *Server) checkViewGoVersions() { - oldestVersion := -1 + oldestVersion, fromBuild := go1Point(), true for _, view := range s.session.Views() { viewVersion := view.GoVersion() if oldestVersion == -1 || viewVersion < oldestVersion { - oldestVersion = viewVersion + oldestVersion, fromBuild = viewVersion, false } } - if msg, mType := versionMessage(oldestVersion); msg != "" { + if msg, mType := versionMessage(oldestVersion, fromBuild); msg != "" { s.eventuallyShowMessage(context.Background(), &protocol.ShowMessageParams{ Type: mType, Message: msg, @@ -315,6 +324,21 @@ func (s *Server) checkViewGoVersions() { } } +// go1Point returns the x in Go 1.x. If an error occurs extracting the go +// version, it returns -1. +// +// Copied from the testenv package. +func go1Point() int { + for i := len(build.Default.ReleaseTags) - 1; i >= 0; i-- { + var version int + if _, err := fmt.Sscanf(build.Default.ReleaseTags[i], "go1.%d", &version); err != nil { + continue + } + return version + } + return -1 +} + func (s *Server) addFolders(ctx context.Context, folders []protocol.WorkspaceFolder) error { originalViews := len(s.session.Views()) viewErrors := make(map[span.URI]error) diff --git a/gopls/internal/lsp/general_test.go b/gopls/internal/lsp/general_test.go index a0312ba1b43..6bc0dc1cb2b 100644 --- a/gopls/internal/lsp/general_test.go +++ b/gopls/internal/lsp/general_test.go @@ -14,18 +14,22 @@ import ( func TestVersionMessage(t *testing.T) { tests := []struct { goVersion int + fromBuild bool wantContains []string // string fragments that we expect to see wantType protocol.MessageType }{ - {-1, nil, 0}, - {12, []string{"1.12", "not supported", "upgrade to Go 1.16", "install gopls v0.7.5"}, protocol.Error}, - {13, []string{"1.13", "will be unsupported by gopls v0.11.0", "upgrade to Go 1.16", "install gopls v0.9.5"}, protocol.Warning}, - {15, []string{"1.15", "will be unsupported by gopls v0.11.0", "upgrade to Go 1.16", "install gopls v0.9.5"}, protocol.Warning}, - {16, nil, 0}, + {-1, false, nil, 0}, + {12, false, []string{"1.12", "not supported", "upgrade to Go 1.18", "install gopls v0.7.5"}, protocol.Error}, + {13, false, []string{"1.13", "not supported", "upgrade to Go 1.18", "install gopls v0.9.5"}, protocol.Error}, + {15, false, []string{"1.15", "not supported", "upgrade to Go 1.18", "install gopls v0.9.5"}, protocol.Error}, + {15, true, []string{"Gopls was built with Go version 1.15", "not supported", "upgrade to Go 1.18", "install gopls v0.9.5"}, protocol.Error}, + {16, false, []string{"1.16", "will be unsupported by gopls v0.13.0", "upgrade to Go 1.18", "install gopls v0.11.0"}, protocol.Warning}, + {17, false, []string{"1.17", "will be unsupported by gopls v0.13.0", "upgrade to Go 1.18", "install gopls v0.11.0"}, protocol.Warning}, + {17, true, []string{"Gopls was built with Go version 1.17", "will be unsupported by gopls v0.13.0", "upgrade to Go 1.18", "install gopls v0.11.0"}, protocol.Warning}, } for _, test := range tests { - gotMsg, gotType := versionMessage(test.goVersion) + gotMsg, gotType := versionMessage(test.goVersion, test.fromBuild) if len(test.wantContains) == 0 && gotMsg != "" { t.Errorf("versionMessage(%d) = %q, want \"\"", test.goVersion, gotMsg)