mirror of
https://github.com/golang/go
synced 2024-11-16 23:54:44 -07:00
cmd/go/internal/modcmd: factor out a type for flags whose arguments are Go versions
For #46141 Updates #45094 Change-Id: I6553600c69273762a81795ef021c66f4e0872b6b Reviewed-on: https://go-review.googlesource.com/c/go/+/321069 Trust: Bryan C. Mills <bcmills@google.com> Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
This commit is contained in:
parent
cca23a7373
commit
05819bc104
@ -196,7 +196,7 @@ func runEdit(ctx context.Context, cmd *base.Command, args []string) {
|
|||||||
|
|
||||||
if *editGo != "" {
|
if *editGo != "" {
|
||||||
if !modfile.GoVersionRE.MatchString(*editGo) {
|
if !modfile.GoVersionRE.MatchString(*editGo) {
|
||||||
base.Fatalf(`go mod: invalid -go option; expecting something like "-go 1.12"`)
|
base.Fatalf(`go mod: invalid -go option; expecting something like "-go %s"`, modload.LatestGoVersion())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,10 @@ import (
|
|||||||
"cmd/go/internal/imports"
|
"cmd/go/internal/imports"
|
||||||
"cmd/go/internal/modload"
|
"cmd/go/internal/modload"
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"golang.org/x/mod/modfile"
|
"golang.org/x/mod/modfile"
|
||||||
|
"golang.org/x/mod/semver"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdTidy = &base.Command{
|
var cmdTidy = &base.Command{
|
||||||
@ -44,28 +46,48 @@ See https://golang.org/ref/mod#go-mod-tidy for more about 'go mod tidy'.
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tidyE bool // if true, report errors but proceed anyway.
|
tidyE bool // if true, report errors but proceed anyway.
|
||||||
tidyGo string // go version to write to the tidied go.mod file (toggles lazy loading)
|
tidyGo goVersionFlag // go version to write to the tidied go.mod file (toggles lazy loading)
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "")
|
cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "")
|
||||||
cmdTidy.Flag.BoolVar(&tidyE, "e", false, "")
|
cmdTidy.Flag.BoolVar(&tidyE, "e", false, "")
|
||||||
cmdTidy.Flag.StringVar(&tidyGo, "go", "", "")
|
cmdTidy.Flag.Var(&tidyGo, "go", "")
|
||||||
base.AddModCommonFlags(&cmdTidy.Flag)
|
base.AddModCommonFlags(&cmdTidy.Flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A goVersionFlag is a flag.Value representing a supported Go version.
|
||||||
|
//
|
||||||
|
// (Note that the -go argument to 'go mod edit' is *not* a goVersionFlag.
|
||||||
|
// It intentionally allows newer-than-supported versions as arguments.)
|
||||||
|
type goVersionFlag struct {
|
||||||
|
v string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *goVersionFlag) String() string { return f.v }
|
||||||
|
func (f *goVersionFlag) Get() interface{} { return f.v }
|
||||||
|
|
||||||
|
func (f *goVersionFlag) Set(s string) error {
|
||||||
|
if s != "" {
|
||||||
|
latest := modload.LatestGoVersion()
|
||||||
|
if !modfile.GoVersionRE.MatchString(s) {
|
||||||
|
return fmt.Errorf("expecting a Go version like %q", latest)
|
||||||
|
}
|
||||||
|
if semver.Compare("v"+s, "v"+latest) > 0 {
|
||||||
|
return fmt.Errorf("maximum supported Go version is %s", latest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f.v = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func runTidy(ctx context.Context, cmd *base.Command, args []string) {
|
func runTidy(ctx context.Context, cmd *base.Command, args []string) {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
base.Fatalf("go mod tidy: no arguments allowed")
|
base.Fatalf("go mod tidy: no arguments allowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if tidyGo != "" {
|
|
||||||
if !modfile.GoVersionRE.MatchString(tidyGo) {
|
|
||||||
base.Fatalf(`go mod: invalid -go option %q; expecting something like "-go 1.17"`, tidyGo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tidy aims to make 'go test' reproducible for any package in 'all', so we
|
// Tidy aims to make 'go test' reproducible for any package in 'all', so we
|
||||||
// need to include test dependencies. For modules that specify go 1.15 or
|
// need to include test dependencies. For modules that specify go 1.15 or
|
||||||
// earlier this is a no-op (because 'all' saturates transitive test
|
// earlier this is a no-op (because 'all' saturates transitive test
|
||||||
@ -80,7 +102,7 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) {
|
|||||||
modload.RootMode = modload.NeedRoot
|
modload.RootMode = modload.NeedRoot
|
||||||
|
|
||||||
modload.LoadPackages(ctx, modload.PackageOpts{
|
modload.LoadPackages(ctx, modload.PackageOpts{
|
||||||
GoVersion: tidyGo,
|
GoVersion: tidyGo.String(),
|
||||||
Tags: imports.AnyTags(),
|
Tags: imports.AnyTags(),
|
||||||
Tidy: true,
|
Tidy: true,
|
||||||
VendorModulesInGOROOTSrc: true,
|
VendorModulesInGOROOTSrc: true,
|
||||||
|
@ -405,7 +405,7 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) {
|
|||||||
if modRoot == "" {
|
if modRoot == "" {
|
||||||
Target = module.Version{Path: "command-line-arguments"}
|
Target = module.Version{Path: "command-line-arguments"}
|
||||||
targetPrefix = "command-line-arguments"
|
targetPrefix = "command-line-arguments"
|
||||||
goVersion := latestGoVersion()
|
goVersion := LatestGoVersion()
|
||||||
rawGoVersion.Store(Target, goVersion)
|
rawGoVersion.Store(Target, goVersion)
|
||||||
requirements = newRequirements(modDepthFromGoVersion(goVersion), nil, nil)
|
requirements = newRequirements(modDepthFromGoVersion(goVersion), nil, nil)
|
||||||
return requirements, false
|
return requirements, false
|
||||||
@ -448,7 +448,7 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) {
|
|||||||
// TODO(#45551): Do something more principled instead of checking
|
// TODO(#45551): Do something more principled instead of checking
|
||||||
// cfg.CmdName directly here.
|
// cfg.CmdName directly here.
|
||||||
if cfg.BuildMod == "mod" && cfg.CmdName != "mod graph" && cfg.CmdName != "mod why" {
|
if cfg.BuildMod == "mod" && cfg.CmdName != "mod graph" && cfg.CmdName != "mod why" {
|
||||||
addGoStmt(latestGoVersion())
|
addGoStmt(LatestGoVersion())
|
||||||
if go117EnableLazyLoading {
|
if go117EnableLazyLoading {
|
||||||
// We need to add a 'go' version to the go.mod file, but we must assume
|
// We need to add a 'go' version to the go.mod file, but we must assume
|
||||||
// that its existing contents match something between Go 1.11 and 1.16.
|
// that its existing contents match something between Go 1.11 and 1.16.
|
||||||
@ -500,7 +500,7 @@ func CreateModFile(ctx context.Context, modPath string) {
|
|||||||
modFile = new(modfile.File)
|
modFile = new(modfile.File)
|
||||||
modFile.AddModuleStmt(modPath)
|
modFile.AddModuleStmt(modPath)
|
||||||
initTarget(modFile.Module.Mod)
|
initTarget(modFile.Module.Mod)
|
||||||
addGoStmt(latestGoVersion()) // Add the go directive before converted module requirements.
|
addGoStmt(LatestGoVersion()) // Add the go directive before converted module requirements.
|
||||||
|
|
||||||
convertedFrom, err := convertLegacyConfig(modPath)
|
convertedFrom, err := convertLegacyConfig(modPath)
|
||||||
if convertedFrom != "" {
|
if convertedFrom != "" {
|
||||||
@ -793,9 +793,9 @@ func addGoStmt(v string) {
|
|||||||
rawGoVersion.Store(Target, v)
|
rawGoVersion.Store(Target, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// latestGoVersion returns the latest version of the Go language supported by
|
// LatestGoVersion returns the latest version of the Go language supported by
|
||||||
// this toolchain, like "1.17".
|
// this toolchain, like "1.17".
|
||||||
func latestGoVersion() string {
|
func LatestGoVersion() string {
|
||||||
tags := build.Default.ReleaseTags
|
tags := build.Default.ReleaseTags
|
||||||
version := tags[len(tags)-1]
|
version := tags[len(tags)-1]
|
||||||
if !strings.HasPrefix(version, "go") || !modfile.GoVersionRE.MatchString(version[2:]) {
|
if !strings.HasPrefix(version, "go") || !modfile.GoVersionRE.MatchString(version[2:]) {
|
||||||
|
@ -931,8 +931,8 @@ func loadFromRoots(ctx context.Context, params loaderParams) *loader {
|
|||||||
ld.allClosesOverTests = true
|
ld.allClosesOverTests = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld.Tidy && semver.Compare(goVersionV, "v"+latestGoVersion()) > 0 {
|
if ld.Tidy && semver.Compare(goVersionV, "v"+LatestGoVersion()) > 0 {
|
||||||
ld.errorf("go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", params.GoVersion, latestGoVersion())
|
ld.errorf("go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", params.GoVersion, LatestGoVersion())
|
||||||
base.ExitIfErrors()
|
base.ExitIfErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ var modFile *modfile.File
|
|||||||
// in modFile are intepreted, or the latest Go version if modFile is nil.
|
// in modFile are intepreted, or the latest Go version if modFile is nil.
|
||||||
func modFileGoVersion() string {
|
func modFileGoVersion() string {
|
||||||
if modFile == nil {
|
if modFile == nil {
|
||||||
return latestGoVersion()
|
return LatestGoVersion()
|
||||||
}
|
}
|
||||||
if modFile.Go == nil || modFile.Go.Version == "" {
|
if modFile.Go == nil || modFile.Go.Version == "" {
|
||||||
// The main module necessarily has a go.mod file, and that file lacks a
|
// The main module necessarily has a go.mod file, and that file lacks a
|
||||||
|
12
src/cmd/go/testdata/script/mod_tidy_version.txt
vendored
12
src/cmd/go/testdata/script/mod_tidy_version.txt
vendored
@ -32,12 +32,22 @@
|
|||||||
|
|
||||||
cp go.mod go.mod.orig
|
cp go.mod go.mod.orig
|
||||||
|
|
||||||
|
|
||||||
# An invalid argument should be rejected.
|
# An invalid argument should be rejected.
|
||||||
|
|
||||||
! go mod tidy -go=bananas
|
! go mod tidy -go=bananas
|
||||||
stderr '^go mod: invalid -go option "bananas"; expecting something like "-go 1.17"$'
|
stderr '^invalid value "bananas" for flag -go: expecting a Go version like "'$goversion'"$'
|
||||||
cmp go.mod go.mod.orig
|
cmp go.mod go.mod.orig
|
||||||
|
|
||||||
|
! go mod tidy -go=0.9
|
||||||
|
stderr '^invalid value "0.9" for flag -go: expecting a Go version like "'$goversion'"$'
|
||||||
|
|
||||||
|
! go mod tidy -go=2000.0
|
||||||
|
stderr '^invalid value "2000.0" for flag -go: maximum supported Go version is '$goversion'$'
|
||||||
|
|
||||||
|
|
||||||
|
# Supported versions should change the go.mod file to be tidy according to the
|
||||||
|
# indicated version.
|
||||||
|
|
||||||
go mod tidy -go=1.15
|
go mod tidy -go=1.15
|
||||||
cmp go.mod go.mod.115
|
cmp go.mod go.mod.115
|
||||||
|
Loading…
Reference in New Issue
Block a user