From b9d5a25442ff4df9080250dd4b0d62c565466cec Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Thu, 14 Jul 2022 14:44:21 -0400 Subject: [PATCH] cmd/go: save zip sums for downloaded modules in 'go mod download' in a workspace Within a single module we expect all needed checksums to have already been recorded by a previous call to 'go get' or 'go mod tidy' in that module. However, when we combine multiple modules in a workspace, they may upgrade each other's dependencies, so a given module might be upgraded above the highest version recorded in the individual go.sum files for the workspace modules. Since the checksums might not be present in individual go.sum files, record them in go.work.sum. Fixes #51946. Change-Id: Icb4ea874b9e5c5b1950d42650974a24b5d6543d4 Reviewed-on: https://go-review.googlesource.com/c/go/+/417654 Auto-Submit: Bryan Mills Reviewed-by: Hyang-Ah Hana Kim TryBot-Result: Gopher Robot Run-TryBot: Bryan Mills --- src/cmd/go/internal/modcmd/download.go | 26 ++++++++++++++----- .../script/work_why_download_graph.txt | 10 +++++-- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/cmd/go/internal/modcmd/download.go b/src/cmd/go/internal/modcmd/download.go index a5fc63ed26..0b50afb668 100644 --- a/src/cmd/go/internal/modcmd/download.go +++ b/src/cmd/go/internal/modcmd/download.go @@ -206,12 +206,13 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) { type token struct{} sem := make(chan token, runtime.GOMAXPROCS(0)) infos, infosErr := modload.ListModules(ctx, args, 0, *downloadReuse) - if !haveExplicitArgs { + if !haveExplicitArgs && modload.WorkFilePath() == "" { // 'go mod download' is sometimes run without arguments to pre-populate the - // module cache. It may fetch modules that aren't needed to build packages - // in the main module. This is usually not intended, so don't save sums for - // downloaded modules (golang.org/issue/45332). We do still fix - // inconsistencies in go.mod though. + // module cache. In modules that aren't at go 1.17 or higher, it may fetch + // modules that aren't needed to build packages in the main module. This is + // usually not intended, so don't save sums for downloaded modules + // (golang.org/issue/45332). We do still fix inconsistencies in go.mod + // though. // // TODO(#45551): In the future, report an error if go.mod or go.sum need to // be updated after loading the build list. This may require setting @@ -282,8 +283,19 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) { // 'go get mod@version', which may have other side effects. We print this in // some error message hints. // - // Don't save sums for 'go mod download' without arguments; see comment above. - if haveExplicitArgs { + // If we're in workspace mode, update go.work.sum with checksums for all of + // the modules we downloaded that aren't already recorded. Since a requirement + // in one module may upgrade a dependency of another, we can't be sure that + // the import graph matches the import graph of any given module in isolation, + // so we may end up needing to load packages from modules that wouldn't + // otherwise be relevant. + // + // TODO(#44435): If we adjust the set of modules downloaded in workspace mode, + // we may also need to adjust the logic for saving checksums here. + // + // Don't save sums for 'go mod download' without arguments unless we're in + // workspace mode; see comment above. + if haveExplicitArgs || modload.WorkFilePath() != "" { if err := modload.WriteGoMod(ctx); err != nil { base.Errorf("go: %v", err) } diff --git a/src/cmd/go/testdata/script/work_why_download_graph.txt b/src/cmd/go/testdata/script/work_why_download_graph.txt index 7964c914a2..8f1aeddf47 100644 --- a/src/cmd/go/testdata/script/work_why_download_graph.txt +++ b/src/cmd/go/testdata/script/work_why_download_graph.txt @@ -7,13 +7,19 @@ exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +grep '^rsc\.io/quote v1\.5\.2/go\.mod h1:' go.work.sum +grep '^rsc\.io/quote v1\.5\.2 h1:' go.work.sum +go clean -modcache +rm go.work.sum go mod download exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +grep '^rsc\.io/quote v1\.5\.2/go\.mod h1:' go.work.sum +grep '^rsc\.io/quote v1\.5\.2 h1:' go.work.sum go mod why rsc.io/quote stdout '# rsc.io/quote\nexample.com/a\nrsc.io/quote' @@ -25,8 +31,8 @@ stdout 'example.com/a rsc.io/quote@v1.5.2\nexample.com/b example.com/c@v1.0.0\nr go 1.18 use ( - ./a - ./b + ./a + ./b ) -- a/go.mod -- go 1.18 -- 2.48.1