diff options
author | Jay Conrod <jayconrod@google.com> | 2019-05-16 12:38:41 -0400 |
---|---|---|
committer | Jay Conrod <jayconrod@google.com> | 2019-05-16 22:39:38 +0000 |
commit | 97ecc4321ec3069d405c04cb2dc3132b39ef732e (patch) | |
tree | ebb1fb639ff4425c317c031b999cb6f30e654ca8 /src/cmd/go/internal/mvs/mvs.go | |
parent | 4e7bef84c1a84f60791f4b3c23bdd3f3d9392e70 (diff) | |
download | go-97ecc4321ec3069d405c04cb2dc3132b39ef732e.tar.gz go-97ecc4321ec3069d405c04cb2dc3132b39ef732e.zip |
cmd/go: don't panic when explaining lost upgrades due to downgrades
If a user runs 'go get mod@vers' where the module transitively
requires itself at a newer version, 'go get' attempts to perform a
downgrade, which necessarily excludes the requested version of the
module.
Previously, we called mvs.BuildList with the requested module
version as the target. This panicked because BuildList doesn't allow
the target module (typically the main module) to require a newer
version of itself.
With this change, when we lose an upgrade due to a downgrade, we call
mvs.BuildList through a wrapper that treats the lost module version as
requirement of a synthetic root module, rather than the target
module. This avoids the panic.
This change also starts reporting errors when an upgraded module is
lost entirely (downgrades caused the module to be completely removed
from the build list).
Fixes #31491
Change-Id: I70ca261c20af7553cad2d3b840a1eaf3d18a4191
Reviewed-on: https://go-review.googlesource.com/c/go/+/177602
Run-TryBot: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/cmd/go/internal/mvs/mvs.go')
-rw-r--r-- | src/cmd/go/internal/mvs/mvs.go | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/src/cmd/go/internal/mvs/mvs.go b/src/cmd/go/internal/mvs/mvs.go index d1c3d8c08a..90f8f269b5 100644 --- a/src/cmd/go/internal/mvs/mvs.go +++ b/src/cmd/go/internal/mvs/mvs.go @@ -121,9 +121,6 @@ func BuildList(target module.Version, reqs Reqs) ([]module.Version, error) { func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) module.Version) ([]module.Version, error) { // Explore work graph in parallel in case reqs.Required // does high-latency network operations. - var work par.Work - work.Add(target) - type modGraphNode struct { m module.Version required []module.Version @@ -137,6 +134,7 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) mo haveErr int32 ) + var work par.Work work.Add(target) work.Do(10, func(item interface{}) { m := item.(module.Version) @@ -217,6 +215,11 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) mo // Construct the list by traversing the graph again, replacing older // modules with required minimum versions. if v := min[target.Path]; v != target.Version { + // TODO(jayconrod): there is a special case in modload.mvsReqs.Max + // that prevents us from selecting a newer version of a module + // when the module has no version. This may only be the case for target. + // Should we always panic when target has a version? + // See golang.org/issue/31491, golang.org/issue/29773. panic(fmt.Sprintf("mistake: chose version %q instead of target %+v", v, target)) // TODO: Don't panic. } |