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 <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/gopls/README.md b/gopls/README.md
index 56d1592..396f86c 100644
--- a/gopls/README.md
+++ b/gopls/README.md
@@ -93,6 +93,7 @@
| ----------- | --------------------------------------------------- |
| 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 04fe713..7486f24 100644
--- a/gopls/internal/lsp/general.go
+++ b/gopls/internal/lsp/general.go
@@ -8,6 +8,7 @@
"context"
"encoding/json"
"fmt"
+ "go/build"
"log"
"os"
"path"
@@ -239,14 +240,16 @@
// 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 @@
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 @@
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 @@
//
// 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 @@
}
}
+// 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 a0312ba..6bc0dc1 100644
--- a/gopls/internal/lsp/general_test.go
+++ b/gopls/internal/lsp/general_test.go
@@ -14,18 +14,22 @@
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)