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