Skip to content

Commit

Permalink
[release-branch.go1.16] cmd/go: error out of 'go mod tidy' if the go …
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
Bryan C. Mills authored and cagedmantis committed Jun 2, 2021
1 parent c9f27b8 commit f2222d8
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/cmd/go/internal/modcmd/tidy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
30 changes: 30 additions & 0 deletions src/cmd/go/internal/modload/buildlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
48 changes: 48 additions & 0 deletions src/cmd/go/testdata/script/mod_tidy_too_new.txt
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit f2222d8

Please sign in to comment.