golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/internal/versions/versions.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 versions
     6  
     7  import (
     8  	"strings"
     9  )
    10  
    11  // Note: If we use build tags to use go/versions when go >=1.22,
    12  // we run into go.dev/issue/53737. Under some operations users would see an
    13  // import of "go/versions" even if they would not compile the file.
    14  // For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include
    15  // For this reason, this library just a clone of go/versions for the moment.
    16  
    17  // Lang returns the Go language version for version x.
    18  // If x is not a valid version, Lang returns the empty string.
    19  // For example:
    20  //
    21  //	Lang("go1.21rc2") = "go1.21"
    22  //	Lang("go1.21.2") = "go1.21"
    23  //	Lang("go1.21") = "go1.21"
    24  //	Lang("go1") = "go1"
    25  //	Lang("bad") = ""
    26  //	Lang("1.21") = ""
    27  func Lang(x string) string {
    28  	v := lang(stripGo(x))
    29  	if v == "" {
    30  		return ""
    31  	}
    32  	return x[:2+len(v)] // "go"+v without allocation
    33  }
    34  
    35  // Compare returns -1, 0, or +1 depending on whether
    36  // x < y, x == y, or x > y, interpreted as Go versions.
    37  // The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
    38  // Invalid versions, including the empty string, compare less than
    39  // valid versions and equal to each other.
    40  // The language version "go1.21" compares less than the
    41  // release candidate and eventual releases "go1.21rc1" and "go1.21.0".
    42  // Custom toolchain suffixes are ignored during comparison:
    43  // "go1.21.0" and "go1.21.0-bigcorp" are equal.
    44  func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) }
    45  
    46  // IsValid reports whether the version x is valid.
    47  func IsValid(x string) bool { return isValid(stripGo(x)) }
    48  
    49  // stripGo converts from a "go1.21" version to a "1.21" version.
    50  // If v does not start with "go", stripGo returns the empty string (a known invalid version).
    51  func stripGo(v string) string {
    52  	v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix.
    53  	if len(v) < 2 || v[:2] != "go" {
    54  		return ""
    55  	}
    56  	return v[2:]
    57  }