// Copyright 2023 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package versions import ( "strings" ) // Note: If we use build tags to use go/versions when go >=1.22, // we run into go.dev/issue/53737. Under some operations users would see an // import of "go/versions" even if they would not compile the file. // For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include // For this reason, this library just a clone of go/versions for the moment. // Lang returns the Go language version for version x. // If x is not a valid version, Lang returns the empty string. // For example: // // Lang("go1.21rc2") = "go1.21" // Lang("go1.21.2") = "go1.21" // Lang("go1.21") = "go1.21" // Lang("go1") = "go1" // Lang("bad") = "" // Lang("1.21") = "" func Lang(x string) string { v := lang(stripGo(x)) if v == "" { return "" } return x[:2+len(v)] // "go"+v without allocation } // Compare returns -1, 0, or +1 depending on whether // x < y, x == y, or x > y, interpreted as Go versions. // The versions x and y must begin with a "go" prefix: "go1.21" not "1.21". // Invalid versions, including the empty string, compare less than // valid versions and equal to each other. // The language version "go1.21" compares less than the // release candidate and eventual releases "go1.21rc1" and "go1.21.0". // Custom toolchain suffixes are ignored during comparison: // "go1.21.0" and "go1.21.0-bigcorp" are equal. func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) } // IsValid reports whether the version x is valid. func IsValid(x string) bool { return isValid(stripGo(x)) } // stripGo converts from a "go1.21" version to a "1.21" version. // If v does not start with "go", stripGo returns the empty string (a known invalid version). func stripGo(v string) string { v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix. if len(v) < 2 || v[:2] != "go" { return "" } return v[2:] }