version.mx raw

   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  	"bytes"
  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 []byte) []byte {
  21  	v, _, _ = bytes.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 []byte) []byte {
  39  	v := gover.Lang(stripGo(x))
  40  	if v == "" {
  41  		return ""
  42  	}
  43  	if bytes.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 []byte) int {
  58  	return gover.Compare(stripGo(x), stripGo(y))
  59  }
  60  
  61  // IsValid reports whether the version x is valid.
  62  func IsValid(x []byte) bool {
  63  	return gover.IsValid(stripGo(x))
  64  }
  65