]> Cypherpunks repositories - gostls13.git/commit
cmd/go: prune more dependencies in 'go get'
authorBryan C. Mills <bcmills@google.com>
Fri, 18 Nov 2022 22:35:45 +0000 (17:35 -0500)
committerGopher Robot <gobot@golang.org>
Wed, 17 May 2023 13:05:03 +0000 (13:05 +0000)
commita094a82452ea4f1242ec9f3b1c0f9f230c2b2a6d
tree9086599fd36bcdbd38321da0013ad55d4e17501f
parent9fd876924a0bc5f94c18ae8b9dce22ad48da9a8f
cmd/go: prune more dependencies in 'go get'

Prior to this change, 'go get' pulled in every version of each module
whose path is explicitly listed in the go.mod file. When graph pruning
is enabled (that is, when the main module is at 'go 1.17' or higher),
that pulled in transitive dependencies of older-than-selected versions
of dependencies, which are normally pruned out by other 'go' commands
(including 'go mod tidy' and 'go mod graph').

To make matters worse, different parts of `go get` were making
different assumptions about which kinds of conflicts would be
reported: the modget package assumed that any conflict is necessarily
due to some explicit constraint, but 'go get' was imposing an
additional constraint that modules could not be incidentally upgraded
in the course of a downgrade. When that additional constraint failed,
the modload package reported the failure as though it were a real
(caller-supplied) constraint, confusing the caller (which couldn't
identify any specific package or argument that caused the failure).

This change fixes both of those problems by replacing the
modload.EditRequirements algorithm with a different one.

The new algorithm is, roughly, as follows.

1. Propose a list of “root requirements” to be written to the updated
   go.mod file.

2. Load the module graph from those requirements mostly as usual, but
   if any root is upgraded due to transitive dependencies, retain the
   original roots and the paths leading from those roots to the
   upgrades. (This forms an “extended graph”, in which we can trace a
   path from to each version that appears in the graph starting at one
   or more of the original roots.)

3. Identify which roots caused any module path to be upgraded above
   its passed-in version constraint. For each such root, either report
   an unresolvable conflict (if the root itself is constrained to a
   specific version) or identify an updated version to propose: either
   a downgrade to the next-highest version, or an upgrade to the
   actually-selected version of the root (if that version is allowed).
   To avoid looping forever or devolving into an NP-complete search,
   we never propose a version that was already rejected previously,
   regardless of what other roots were present alongside it at the
   time.

4. If the version of any root was changed, repeat from (1).

This algorithm is guaranteed to terminate, because there are finitely
many root versions and we permanently reject at least one each time we
downgrade its path to a lower version.

In addition, this change implements support for the '-v' flag to log
more information about version changes at each iteration.

Fixes #56494.
Fixes #55955.

Change-Id: Iebc17dd7586594d5732e228043c3c4c6da230f44
Reviewed-on: https://go-review.googlesource.com/c/go/+/471595
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
13 files changed:
src/cmd/go/internal/modget/get.go
src/cmd/go/internal/modload/buildlist.go
src/cmd/go/internal/modload/edit.go
src/cmd/go/internal/modload/modfile.go
src/cmd/go/internal/modload/mvs.go
src/cmd/go/testdata/script/mod_get_boost.txt [new file with mode: 0644]
src/cmd/go/testdata/script/mod_get_downup_indirect.txt
src/cmd/go/testdata/script/mod_get_downup_indirect_pruned.txt [new file with mode: 0644]
src/cmd/go/testdata/script/mod_get_issue56494.txt
src/cmd/go/testdata/script/mod_get_newcycle.txt
src/cmd/go/testdata/script/mod_get_patchcycle.txt
src/cmd/go/testdata/script/mod_install_pkg_version.txt
src/cmd/go/testdata/script/mod_load_badchain.txt