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 version provides operations on [Go versions] 6 // in [Go toolchain name syntax]: strings like 7 // "go1.20", "go1.21.0", "go1.22rc2", and "go1.23.4-bigcorp". 8 // 9 // [Go versions]: https://go.dev/doc/toolchain#version 10 // [Go toolchain name syntax]: https://go.dev/doc/toolchain#name 11 package version // import "go/version" 12 13 import ( 14 "internal/gover" 15 "strings" 16 ) 17 18 // stripGo converts from a "go1.21-bigcorp" version to a "1.21" version. 19 // If v does not start with "go", stripGo returns the empty string (a known invalid version). 20 func stripGo(v string) string { 21 v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix. 22 if len(v) < 2 || v[:2] != "go" { 23 return "" 24 } 25 return v[2:] 26 } 27 28 // Lang returns the Go language version for version x. 29 // If x is not a valid version, Lang returns the empty string. 30 // For example: 31 // 32 // Lang("go1.21rc2") = "go1.21" 33 // Lang("go1.21.2") = "go1.21" 34 // Lang("go1.21") = "go1.21" 35 // Lang("go1") = "go1" 36 // Lang("bad") = "" 37 // Lang("1.21") = "" 38 func Lang(x string) string { 39 v := gover.Lang(stripGo(x)) 40 if v == "" { 41 return "" 42 } 43 if strings.HasPrefix(x[2:], v) { 44 return x[:2+len(v)] // "go"+v without allocation 45 } else { 46 return "go" + v 47 } 48 } 49 50 // Compare returns -1, 0, or +1 depending on whether 51 // x < y, x == y, or x > y, interpreted as Go versions. 52 // The versions x and y must begin with a "go" prefix: "go1.21" not "1.21". 53 // Invalid versions, including the empty string, compare less than 54 // valid versions and equal to each other. 55 // The language version "go1.21" compares less than the 56 // release candidate and eventual releases "go1.21rc1" and "go1.21.0". 57 func Compare(x, y string) int { 58 return gover.Compare(stripGo(x), stripGo(y)) 59 } 60 61 // IsValid reports whether the version x is valid. 62 func IsValid(x string) bool { 63 return gover.IsValid(stripGo(x)) 64 } 65