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 gover implements support for Go toolchain versions like 1.21.0 and 1.21rc1.
6// (For historical reasons, Go does not use semver for its toolchains.)
7// This package provides the same basic analysis that golang.org/x/mod/semver does for semver.
8// It also provides some helpers for extracting versions from go.mod files
9// and for dealing with module.Versions that may use Go versions or semver
10// depending on the module path.
11package gover
12
13import (
14	"internal/gover"
15)
16
17// Compare returns -1, 0, or +1 depending on whether
18// x < y, x == y, or x > y, interpreted as toolchain versions.
19// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21".
20// Malformed versions compare less than well-formed versions and equal to each other.
21// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0".
22func Compare(x, y string) int {
23	return gover.Compare(x, y)
24}
25
26// Max returns the maximum of x and y interpreted as toolchain versions,
27// compared using Compare.
28// If x and y compare equal, Max returns x.
29func Max(x, y string) string {
30	return gover.Max(x, y)
31}
32
33// IsLang reports whether v denotes the overall Go language version
34// and not a specific release. Starting with the Go 1.21 release, "1.x" denotes
35// the overall language version; the first release is "1.x.0".
36// The distinction is important because the relative ordering is
37//
38//	1.21 < 1.21rc1 < 1.21.0
39//
40// meaning that Go 1.21rc1 and Go 1.21.0 will both handle go.mod files that
41// say "go 1.21", but Go 1.21rc1 will not handle files that say "go 1.21.0".
42func IsLang(x string) bool {
43	return gover.IsLang(x)
44}
45
46// Lang returns the Go language version. For example, Lang("1.2.3") == "1.2".
47func Lang(x string) string {
48	return gover.Lang(x)
49}
50
51// IsPrerelease reports whether v denotes a Go prerelease version.
52func IsPrerelease(x string) bool {
53	return gover.Parse(x).Kind != ""
54}
55
56// Prev returns the Go major release immediately preceding v,
57// or v itself if v is the first Go major release (1.0) or not a supported
58// Go version.
59//
60// Examples:
61//
62//	Prev("1.2") = "1.1"
63//	Prev("1.3rc4") = "1.2"
64func Prev(x string) string {
65	v := gover.Parse(x)
66	if gover.CmpInt(v.Minor, "1") <= 0 {
67		return v.Major
68	}
69	return v.Major + "." + gover.DecInt(v.Minor)
70}
71
72// IsValid reports whether the version x is valid.
73func IsValid(x string) bool {
74	return gover.IsValid(x)
75}
76