mirror of
https://github.com/golang/go.git
synced 2025-12-27 22:25:05 +00:00
Additional tests and bug fixes realized while writing go.dev/doc/gotoolchain (CL 500775). - Handle go get toolchain@go1.22 (resolve to latest patch release, same as go get go@1.22). (See modload/query.go and gover/mod.go.) - Handle go get go@patch toolchain@patch. (See modload/query.go and gover/mod.go.) - Remove prefix-goVERSION-suffix form for toolchain name, standardizing on goVERSION-suffix. I have no good explanation for having two forms, so simplify to one. (See vendor and gover.) - Fail toolchain downloads when GOSUMDB=off. Because toolchain downloads cannot always be predicted (especially during switching rather than selection), they cannot be listed in go.sum. We rely on the checksum database for integrity of the download, especially if proxied. If the checksum database is disabled, this integrity check won't happen, so fail toolchain downloads. (See modfetch/sumdb.go and script/gotoolchain_net.txt) - Use names from documentation in package toolchain (Select, Switch; SwitchTo renamed to Exec to avoid both names; reqs.go renamed to switch.go; toolchain.go renamed to select.go.) - Make "go env GOTOOLCHAIN" and "go env -w GOTOOLCHAIN" work even when GOTOOLCHAIN is misconfigured. (See special case at top of Select in select.go.) - Clarify what goInstallVersion does (report whether this is go install or go run pkg@version) and explain the potential version switch more clearly. Use the Switcher directly instead of reimplementing it. (See select.go.) - Document go@ and toolchain@ forms in go help get, linking to go.dev/doc/toolchain. (See modget/get.go.) - Update URL of documentation in $GOROOT/go.env. For #57001. Change-Id: I895ef3519ff95db8710ed23b36ebaf4f648120cb Reviewed-on: https://go-review.googlesource.com/c/go/+/500797 Reviewed-by: Michael Matloob <matloob@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Bypass: Russ Cox <rsc@golang.org>
128 lines
3.4 KiB
Go
128 lines
3.4 KiB
Go
// 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 gover
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
|
|
"golang.org/x/mod/module"
|
|
"golang.org/x/mod/semver"
|
|
)
|
|
|
|
// IsToolchain reports whether the module path corresponds to the
|
|
// virtual, non-downloadable module tracking go or toolchain directives in the go.mod file.
|
|
//
|
|
// Note that IsToolchain only matches "go" and "toolchain", not the
|
|
// real, downloadable module "golang.org/toolchain" containing toolchain files.
|
|
//
|
|
// IsToolchain("go") = true
|
|
// IsToolchain("toolchain") = true
|
|
// IsToolchain("golang.org/x/tools") = false
|
|
// IsToolchain("golang.org/toolchain") = false
|
|
func IsToolchain(path string) bool {
|
|
return path == "go" || path == "toolchain"
|
|
}
|
|
|
|
// ModCompare returns the result of comparing the versions x and y
|
|
// for the module with the given path.
|
|
// The path is necessary because the "go" and "toolchain" modules
|
|
// use a different version syntax and semantics (gover, this package)
|
|
// than most modules (semver).
|
|
func ModCompare(path string, x, y string) int {
|
|
if path == "go" {
|
|
return Compare(x, y)
|
|
}
|
|
if path == "toolchain" {
|
|
return Compare(maybeToolchainVersion(x), maybeToolchainVersion(y))
|
|
}
|
|
return semver.Compare(x, y)
|
|
}
|
|
|
|
// ModSort is like module.Sort but understands the "go" and "toolchain"
|
|
// modules and their version ordering.
|
|
func ModSort(list []module.Version) {
|
|
sort.Slice(list, func(i, j int) bool {
|
|
mi := list[i]
|
|
mj := list[j]
|
|
if mi.Path != mj.Path {
|
|
return mi.Path < mj.Path
|
|
}
|
|
// To help go.sum formatting, allow version/file.
|
|
// Compare semver prefix by semver rules,
|
|
// file by string order.
|
|
vi := mi.Version
|
|
vj := mj.Version
|
|
var fi, fj string
|
|
if k := strings.Index(vi, "/"); k >= 0 {
|
|
vi, fi = vi[:k], vi[k:]
|
|
}
|
|
if k := strings.Index(vj, "/"); k >= 0 {
|
|
vj, fj = vj[:k], vj[k:]
|
|
}
|
|
if vi != vj {
|
|
return ModCompare(mi.Path, vi, vj) < 0
|
|
}
|
|
return fi < fj
|
|
})
|
|
}
|
|
|
|
// ModIsValid reports whether vers is a valid version syntax for the module with the given path.
|
|
func ModIsValid(path, vers string) bool {
|
|
if IsToolchain(path) {
|
|
if path == "toolchain" {
|
|
return IsValid(FromToolchain(vers))
|
|
}
|
|
return IsValid(vers)
|
|
}
|
|
return semver.IsValid(vers)
|
|
}
|
|
|
|
// ModIsPrefix reports whether v is a valid version syntax prefix for the module with the given path.
|
|
// The caller is assumed to have checked that ModIsValid(path, vers) is true.
|
|
func ModIsPrefix(path, vers string) bool {
|
|
if IsToolchain(path) {
|
|
if path == "toolchain" {
|
|
return IsLang(FromToolchain(vers))
|
|
}
|
|
return IsLang(vers)
|
|
}
|
|
// Semver
|
|
dots := 0
|
|
for i := 0; i < len(vers); i++ {
|
|
switch vers[i] {
|
|
case '-', '+':
|
|
return false
|
|
case '.':
|
|
dots++
|
|
if dots >= 2 {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// ModIsPrerelease reports whether v is a prerelease version for the module with the given path.
|
|
// The caller is assumed to have checked that ModIsValid(path, vers) is true.
|
|
func ModIsPrerelease(path, vers string) bool {
|
|
if IsToolchain(path) {
|
|
return IsPrerelease(vers)
|
|
}
|
|
return semver.Prerelease(vers) != ""
|
|
}
|
|
|
|
// ModMajorMinor returns the "major.minor" truncation of the version v,
|
|
// for use as a prefix in "@patch" queries.
|
|
func ModMajorMinor(path, vers string) string {
|
|
if IsToolchain(path) {
|
|
if path == "toolchain" {
|
|
return "go" + Lang(FromToolchain(vers))
|
|
}
|
|
return Lang(vers)
|
|
}
|
|
return semver.MajorMinor(vers)
|
|
}
|