versions.go 2.0 KB

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