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