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 } 58