golang.org/x/tools/gopls@v0.15.3/internal/util/goversion/goversion.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package goversions defines gopls's policy for which versions of Go it supports.
     6  package goversion
     7  
     8  import (
     9  	"fmt"
    10  	"strings"
    11  )
    12  
    13  // Support holds information about end-of-life Go version support.
    14  //
    15  // Exposed for testing.
    16  type Support struct {
    17  	// GoVersion is the Go version to which these settings relate.
    18  	GoVersion int
    19  
    20  	// DeprecatedVersion is the first version of gopls that no longer supports
    21  	// this Go version.
    22  	//
    23  	// If unset, the version is already deprecated.
    24  	DeprecatedVersion string
    25  
    26  	// InstallGoplsVersion is the latest gopls version that supports this Go
    27  	// version without warnings.
    28  	InstallGoplsVersion string
    29  }
    30  
    31  // Supported maps Go versions to the gopls version in which support will
    32  // be deprecated, and the final gopls version supporting them without warnings.
    33  // Keep this in sync with gopls/README.md.
    34  //
    35  // Must be sorted in ascending order of Go version.
    36  //
    37  // Exposed (and mutable) for testing.
    38  var Supported = []Support{
    39  	{12, "", "v0.7.5"},
    40  	{15, "", "v0.9.5"},
    41  	{16, "", "v0.11.0"},
    42  	{17, "", "v0.11.0"},
    43  	{18, "v0.16.0", "v0.14.2"},
    44  }
    45  
    46  // OldestSupported is the last X in Go 1.X that this version of gopls
    47  // supports without warnings.
    48  //
    49  // Exported for testing.
    50  func OldestSupported() int {
    51  	return Supported[len(Supported)-1].GoVersion + 1
    52  }
    53  
    54  // Message returns the message to display if the user has the given Go
    55  // version, if any. The goVersion variable is the X in Go 1.X. If
    56  // fromBuild is set, the Go version is the version used to build
    57  // gopls. Otherwise, it is the go command version.
    58  //
    59  // The second component of the result indicates whether the message is
    60  // an error, not a mere warning.
    61  //
    62  // If goVersion is invalid (< 0), it returns "", false.
    63  func Message(goVersion int, fromBuild bool) (string, bool) {
    64  	if goVersion < 0 {
    65  		return "", false
    66  	}
    67  
    68  	for _, v := range Supported {
    69  		if goVersion <= v.GoVersion {
    70  			var msgBuilder strings.Builder
    71  
    72  			isError := true
    73  			if fromBuild {
    74  				fmt.Fprintf(&msgBuilder, "Gopls was built with Go version 1.%d", goVersion)
    75  			} else {
    76  				fmt.Fprintf(&msgBuilder, "Found Go version 1.%d", goVersion)
    77  			}
    78  			if v.DeprecatedVersion != "" {
    79  				// not deprecated yet, just a warning
    80  				fmt.Fprintf(&msgBuilder, ", which will be unsupported by gopls %s. ", v.DeprecatedVersion)
    81  				isError = false // warning
    82  			} else {
    83  				fmt.Fprint(&msgBuilder, ", which is not supported by this version of gopls. ")
    84  			}
    85  			fmt.Fprintf(&msgBuilder, "Please upgrade to Go 1.%d or later and reinstall gopls. ", OldestSupported())
    86  			fmt.Fprintf(&msgBuilder, "If you can't upgrade and want this message to go away, please install gopls %s. ", v.InstallGoplsVersion)
    87  			fmt.Fprint(&msgBuilder, "See https://go.dev/s/gopls-support-policy for more details.")
    88  
    89  			return msgBuilder.String(), isError
    90  		}
    91  	}
    92  	return "", false
    93  }