diff options
author | Bryan C. Mills <bcmills@google.com> | 2021-03-18 21:01:37 -0400 |
---|---|---|
committer | Bryan C. Mills <bcmills@google.com> | 2021-03-19 19:59:56 +0000 |
commit | 3b0d28808df261747d7561badf91498bbb5d3e3e (patch) | |
tree | 42fb7b0044cf8ca9e733556f1fb9ec1e17d818b9 /src/cmd/go/internal/modload/init.go | |
parent | 1c590661e7d3b477662f76ead56f39567ea8345a (diff) | |
download | go-3b0d28808df261747d7561badf91498bbb5d3e3e.tar.gz go-3b0d28808df261747d7561badf91498bbb5d3e3e.zip |
cmd/go: assume Go 1.16 instead of Go 1.11 for dependencies that lack explicit 'go' directives
Fixes #45109
Updates #44976
Updates #36876
Change-Id: Icb00f8b6e0d4e076d82da1697e7058b9e7603916
Reviewed-on: https://go-review.googlesource.com/c/go/+/303229
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>
Diffstat (limited to 'src/cmd/go/internal/modload/init.go')
-rw-r--r-- | src/cmd/go/internal/modload/init.go | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go index 2466a3bdfd..dd97a6bfb9 100644 --- a/src/cmd/go/internal/modload/init.go +++ b/src/cmd/go/internal/modload/init.go @@ -405,9 +405,38 @@ func LoadModFile(ctx context.Context) { readVendorList() checkVendorConsistency() } - if index.goVersionV == "" && cfg.BuildMod == "mod" { - addGoStmt() - WriteGoMod() + if index.goVersionV == "" { + // The main module necessarily has a go.mod file, and that file lacks a + // 'go' directive. The 'go' command has been adding that directive + // automatically since Go 1.12, so this module either dates to Go 1.11 or + // has been erroneously hand-edited. + // + // If we are able to modify the go.mod file, we will add a 'go' directive + // to at least make the situation explicit going forward. + if cfg.BuildMod == "mod" { + // TODO(#44976): If we implicitly upgrade to the latest Go version once + // lazy loading is implemented, we could accidentally prune out + // dependencies from what was formerly a Go 1.11 module, resulting in + // downgrades (if only lower requirements on that module remain) and/or + // upgrades (if no requirement remains and we end up re-resolving to + // latest). + // + // We should probably instead load the dependencies using Go 1.11 + // semantics to ensure that we capture everything that is relevant, or + // perhaps error out and let the user tell us which version they intend. + // + // If we are running 'go mod tidy' in particular, we will have enough + // information to upgrade the 'go' version after loading is complete. + addGoStmt(latestGoVersion()) + WriteGoMod() + } else { + // Reproducibility requires that if we change the semantics of a module, + // we write some explicit change to its go.mod file. We cannot write to + // the go.mod file (because we are in readonly or vendor mode), so we must + // not change its semantics either. The go.mod file looks as if it were + // created by Go 1.11, so assume Go 1.11 semantics. + rawGoVersion.Store(Target, "1.11") + } } } @@ -442,7 +471,7 @@ func CreateModFile(ctx context.Context, modPath string) { modFile = new(modfile.File) modFile.AddModuleStmt(modPath) initTarget(modFile.Module.Mod) - addGoStmt() // Add the go directive before converted module requirements. + addGoStmt(latestGoVersion()) // Add the go directive before converted module requirements. convertedFrom, err := convertLegacyConfig(modPath) if convertedFrom != "" { @@ -680,11 +709,10 @@ func convertLegacyConfig(modPath string) (from string, err error) { // addGoStmt adds a go directive to the go.mod file if it does not already // include one. The 'go' version added, if any, is the latest version supported // by this toolchain. -func addGoStmt() { +func addGoStmt(v string) { if modFile.Go != nil && modFile.Go.Version != "" { return } - v := latestGoVersion() if err := modFile.AddGoStmt(v); err != nil { base.Fatalf("go: internal error: %v", err) } @@ -692,7 +720,7 @@ func addGoStmt() { } // latestGoVersion returns the latest version of the Go language supported by -// this toolchain. +// this toolchain, like "1.17". func latestGoVersion() string { tags := build.Default.ReleaseTags version := tags[len(tags)-1] |