diff options
author | Bryan C. Mills <bcmills@google.com> | 2021-03-03 10:27:19 -0500 |
---|---|---|
committer | Bryan C. Mills <bcmills@google.com> | 2021-03-25 03:17:36 +0000 |
commit | 954879d6d19175a5f0066c0ac0df0edda7f731b3 (patch) | |
tree | 891e4d63c5fa5cd41bbb957d6030d4e910105151 /src/cmd/go/internal/modload/modfile.go | |
parent | a95e2ae2804becdda6c265c6d589ae8184a34160 (diff) | |
download | go-954879d6d19175a5f0066c0ac0df0edda7f731b3.tar.gz go-954879d6d19175a5f0066c0ac0df0edda7f731b3.zip |
cmd/go/internal/modload: replace the global buildList with structured requirements
This is intended to be a pure-refactoring change, with very little
observable change in the behavior of the 'go' command. A few error
messages have prefixes changed (by virtue of being attached to
packages or modules instead of the build list overall), and
'go list -m' (without arguments) no longer loads the complete module
graph in order to provide the name of the (local) main module.
The previous modload.buildList variable contained a flattened build
list, from which the go.mod file was reconstructed using various
heuristics and metadata cobbled together from the original go.mod
file, the package loader (which was occasionally constructed without
actually loading packages, for the sole purpose of populating
otherwise-unrelated metadata!), and the updated build list.
This change replaces that variable with a new package-level variable,
named "requirements". The new variable is structured to match the
structure of the go.mod file: it explicitly specifies the roots of the
module graph, from which the complete module graph and complete build
list can be reconstructed (and cached) on demand. Similarly, the
"direct" markings on the go.mod requirements are now stored alongside
the requirements themselves, rather than side-channeled through the
loader.
The requirements are now plumbed explicitly though the modload
package, with accesses to the package-level variable occurring only
within top-level exported functions. The structured requirements are
logically immutable, so a new copy of the requirements is constructed
whenever the requirements are changed, substantially reducing implicit
communication-by-sharing in the package.
For #36460
Updates #40775
Change-Id: I97bb0381708f9d3e42af385b5c88a7038e1f0556
Reviewed-on: https://go-review.googlesource.com/c/go/+/293689
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Diffstat (limited to 'src/cmd/go/internal/modload/modfile.go')
-rw-r--r-- | src/cmd/go/internal/modload/modfile.go | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go index 6cbad46c4d..53a7895c4d 100644 --- a/src/cmd/go/internal/modload/modfile.go +++ b/src/cmd/go/internal/modload/modfile.go @@ -30,6 +30,11 @@ import ( // tests outside of the main module. const narrowAllVersionV = "v1.16" +// go1117LazyTODO is a constant that exists only until lazy loading is +// implemented. Its use indicates a condition that will need to change if the +// main module is lazy. +const go117LazyTODO = false + var modFile *modfile.File // A modFileIndex is an index of data corresponding to a modFile @@ -133,10 +138,7 @@ func CheckRetractions(ctx context.Context, m module.Version) error { // We load the raw file here: the go.mod file may have a different module // path that we expect if the module or its repository was renamed. // We still want to apply retractions to other aliases of the module. - rm := module.Version{Path: path, Version: rev.Version} - if repl := Replacement(rm); repl.Path != "" { - rm = repl - } + rm := resolveReplacement(module.Version{Path: path, Version: rev.Version}) summary, err := rawGoModSummary(rm) if err != nil { return &entry{nil, err} @@ -242,6 +244,15 @@ func Replacement(mod module.Version) module.Version { return module.Version{} } +// resolveReplacement returns the module actually used to load the source code +// for m: either m itself, or the replacement for m (iff m is replaced). +func resolveReplacement(m module.Version) module.Version { + if r := Replacement(m); r.Path != "" { + return r + } + return m +} + // indexModFile rebuilds the index of modFile. // If modFile has been changed since it was first read, // modFile.Cleanup must be called before indexModFile. @@ -441,10 +452,7 @@ func goModSummary(m module.Version) (*modFileSummary, error) { return summary, nil } - actual := Replacement(m) - if actual.Path == "" { - actual = m - } + actual := resolveReplacement(m) if HasModRoot() && cfg.BuildMod == "readonly" && actual.Version != "" { key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"} if !modfetch.HaveSum(key) { |