From 7e4fb8b3ef9774e58f90359f51e89ac5103d388d Mon Sep 17 00:00:00 2001 From: Jay Conrod Date: Fri, 24 Sep 2021 10:46:09 -0700 Subject: [PATCH] cmd/go: make 'go mod why -m' work in inconsistent, pruned module 'go mod why -m' works by listing modules matching command line arguments, then loading "all" packages and finding which of the listed modules provide packages imported by the main module. If go.mod is inconsistent (that is, a requirement has a lower version than MVS would select when the module graph is loaded) and pruned (that is, the module graph is only loaded when necessary), then modload.ListModules may return modules with different versions than would be selected in modload.LoadPackages. 'go mod why -m' was too strict about this, mapping module paths and versions to packages. With this fix, it maps module paths without versions to packages. Fixes #48613 Change-Id: I836c46289bb647d6c46ec65e7589531da532d5e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/352115 Trust: Jay Conrod Run-TryBot: Jay Conrod TryBot-Result: Go Bot Reviewed-by: Bryan C. Mills --- src/cmd/go/internal/modcmd/why.go | 8 +++----- src/cmd/go/testdata/script/mod_skip_write.txt | 6 +----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/cmd/go/internal/modcmd/why.go b/src/cmd/go/internal/modcmd/why.go index 9647784b67a..d8355cca957 100644 --- a/src/cmd/go/internal/modcmd/why.go +++ b/src/cmd/go/internal/modcmd/why.go @@ -12,8 +12,6 @@ import ( "cmd/go/internal/base" "cmd/go/internal/imports" "cmd/go/internal/modload" - - "golang.org/x/mod/module" ) var cmdWhy = &base.Command{ @@ -90,19 +88,19 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) { base.Fatalf("go: %v", err) } - byModule := make(map[module.Version][]string) + byModule := make(map[string][]string) _, pkgs := modload.LoadPackages(ctx, loadOpts, "all") for _, path := range pkgs { m := modload.PackageModule(path) if m.Path != "" { - byModule[m] = append(byModule[m], path) + byModule[m.Path] = append(byModule[m.Path], path) } } sep := "" for _, m := range mods { best := "" bestDepth := 1000000000 - for _, path := range byModule[module.Version{Path: m.Path, Version: m.Version}] { + for _, path := range byModule[m.Path] { d := modload.WhyDepth(path) if d > 0 && d < bestDepth { best = path diff --git a/src/cmd/go/testdata/script/mod_skip_write.txt b/src/cmd/go/testdata/script/mod_skip_write.txt index c3e5906589f..9fdb6fc1212 100644 --- a/src/cmd/go/testdata/script/mod_skip_write.txt +++ b/src/cmd/go/testdata/script/mod_skip_write.txt @@ -24,9 +24,8 @@ go mod why rsc.io/sampler cmp stdout why.want cmp go.mod go.mod.edit -# TODO(#48613): 'go mod why -m' incorrectly reports sampler is not needed. go mod why -m rsc.io/sampler -cmp stdout why-broken.want +cmp stdout why.want cmp go.mod go.mod.edit cp go.mod.orig go.mod @@ -91,6 +90,3 @@ rsc.io/sampler@v1.3.0 golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c m rsc.io/quote rsc.io/sampler --- why-broken.want -- -# rsc.io/sampler -(main module does not need module rsc.io/sampler)