diff options
author | Bryan C. Mills <bcmills@google.com> | 2021-05-13 09:48:40 -0400 |
---|---|---|
committer | Carlos Amedee <carlos@golang.org> | 2021-06-02 19:00:32 +0000 |
commit | f2222d8284fec442da68c6b09f0dabad97ec17c3 (patch) | |
tree | 60100162287bbc73f5ac0e5c2c034c24ab9de205 | |
parent | c9f27b8d31291cc1051824c108452c2e05c0b79d (diff) | |
download | go-f2222d8284fec442da68c6b09f0dabad97ec17c3.tar.gz go-f2222d8284fec442da68c6b09f0dabad97ec17c3.zip |
[release-branch.go1.16] cmd/go: error out of 'go mod tidy' if the go version is newer than supported
This backports the test from CL 319669, but — because of extensive
changes to the module loader during the Go 1.17 cycle — the
implementation is entirely different. (This implementation is based on
the addGoStmt function present in init.go in the 1.16 branch.)
Fixes #46144
Updates #46142
Change-Id: Ib7a0a159e53cbe476be6aa9a050add10cc750dec
Reviewed-on: https://go-review.googlesource.com/c/go/+/319671
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>
-rw-r--r-- | src/cmd/go/internal/modcmd/tidy.go | 2 | ||||
-rw-r--r-- | src/cmd/go/internal/modload/buildlist.go | 30 | ||||
-rw-r--r-- | src/cmd/go/testdata/script/mod_tidy_too_new.txt | 48 |
3 files changed, 80 insertions, 0 deletions
diff --git a/src/cmd/go/internal/modcmd/tidy.go b/src/cmd/go/internal/modcmd/tidy.go index 8bc9ed50be..67f90b123c 100644 --- a/src/cmd/go/internal/modcmd/tidy.go +++ b/src/cmd/go/internal/modcmd/tidy.go @@ -61,6 +61,8 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) { modload.ForceUseModules = true modload.RootMode = modload.NeedRoot + modload.CheckTidyVersion(ctx, tidyE) + modload.LoadPackages(ctx, modload.PackageOpts{ Tags: imports.AnyTags(), ResolveMissingImports: true, diff --git a/src/cmd/go/internal/modload/buildlist.go b/src/cmd/go/internal/modload/buildlist.go index 45f220a6ee..0ed985384d 100644 --- a/src/cmd/go/internal/modload/buildlist.go +++ b/src/cmd/go/internal/modload/buildlist.go @@ -11,10 +11,13 @@ import ( "cmd/go/internal/mvs" "context" "fmt" + "go/build" "os" "strings" + "golang.org/x/mod/modfile" "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) // buildList is the list of modules to use for building packages. @@ -226,6 +229,33 @@ func ReloadBuildList() []module.Version { return capVersionSlice(buildList) } +// CheckTidyVersion reports an error to stderr if the Go version indicated by +// the go.mod file is not supported by this version of the 'go' command. +// +// If allowError is false, such an error terminates the program. +func CheckTidyVersion(ctx context.Context, allowError bool) { + LoadModFile(ctx) + if index.goVersionV == "" { + return + } + + tags := build.Default.ReleaseTags + maxGo := tags[len(tags)-1] + if !strings.HasPrefix(maxGo, "go") || !modfile.GoVersionRE.MatchString(maxGo[2:]) { + base.Fatalf("go: unrecognized go version %q", maxGo) + } + max := maxGo[2:] + + if semver.Compare(index.goVersionV, "v"+max) > 0 { + have := index.goVersionV[1:] + if allowError { + fmt.Fprintf(os.Stderr, "go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", have, max) + } else { + base.Fatalf("go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", have, max) + } + } +} + // TidyBuildList trims the build list to the minimal requirements needed to // retain the same versions of all packages from the preceding call to // LoadPackages. diff --git a/src/cmd/go/testdata/script/mod_tidy_too_new.txt b/src/cmd/go/testdata/script/mod_tidy_too_new.txt new file mode 100644 index 0000000000..ca3163ec2c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_too_new.txt @@ -0,0 +1,48 @@ +# https://golang.org/issue/46142: 'go mod tidy' should error out if the version +# in the go.mod file is newer than the most recent supported version. + +cp go.mod go.mod.orig + + +# If the go.mod file specifies an unsupported Go version, 'go mod tidy' should +# refuse to edit it: we don't know what a tidy go.mod file for that version +# would look like. + +! go mod tidy +stderr 'go mod tidy: go.mod file indicates go 2000.0, but maximum supported version is '$goversion'$' +cmp go.mod go.mod.orig + + +# The -e flag should push past the error and edit the file anyway, +# but preserve the too-high version. + +cp go.mod.orig go.mod +go mod tidy -e +stderr 'go mod tidy: go.mod file indicates go 2000.0, but maximum supported version is '$goversion'$' +cmp go.mod go.mod.tidy + + +-- go.mod -- +module example.net/from/the/future + +go 2000.0 + +replace example.net/m v0.0.0 => ./m +-- go.mod.tidy -- +module example.net/from/the/future + +go 2000.0 + +replace example.net/m v0.0.0 => ./m + +require example.net/m v0.0.0 +-- x.go -- +package x + +import "example.net/m" +-- m/go.mod -- +module example.net/m + +go 1.17 +-- m/m.go -- +package m |