aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorMichael Matloob <matloob@golang.org>2026-03-09 12:45:20 -0400
committerMichael Matloob <matloob@golang.org>2026-03-18 09:35:22 -0700
commita61fd428974822a8c57a2b2840fc237e6711b24d (patch)
tree49f7b72c7658bfee013e869f302d93350db4e914 /src/cmd
parent72327dd645fe5f1755dbe89c2d9299dfc47d05b9 (diff)
downloadgo-a61fd428974822a8c57a2b2840fc237e6711b24d.tar.xz
cmd/go: make the package loader a part of the module loader
This is a part of the project to remove global state in the module loader. Before this change, the packageLoader was stored in a global field "loaded" which meant that even though the module loader is no longer global, part of the module loader still depended on global state. This change will make progress to the point where we can potentially have multiple module loaders in the same go/command execution. Change-Id: If4963a8a9d0e04960cf5424e496114276a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/753220 Reviewed-by: Ian Alexander <jitsu@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Matloob <matloob@google.com>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/go/internal/modcmd/vendor.go4
-rw-r--r--src/cmd/go/internal/modcmd/why.go8
-rw-r--r--src/cmd/go/internal/modget/get.go4
-rw-r--r--src/cmd/go/internal/modload/build.go4
-rw-r--r--src/cmd/go/internal/modload/init.go14
-rw-r--r--src/cmd/go/internal/modload/load.go38
-rw-r--r--src/cmd/go/internal/workcmd/sync.go2
7 files changed, 37 insertions, 37 deletions
diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go
index 5f9d40a4dc..8f2269d4b8 100644
--- a/src/cmd/go/internal/modcmd/vendor.go
+++ b/src/cmd/go/internal/modcmd/vendor.go
@@ -106,7 +106,7 @@ func RunVendor(loaderstate *modload.State, ctx context.Context, vendorE bool, ve
modpkgs := make(map[module.Version][]string)
for _, pkg := range pkgs {
- m := modload.PackageModule(pkg)
+ m := loaderstate.PackageModule(pkg)
if m.Path == "" || loaderstate.MainModules.Contains(m.Path) {
continue
}
@@ -294,7 +294,7 @@ func vendorPkg(s *modload.State, vdir, pkg string) {
return matchPotentialSourceFile(dir, info, goVersion)
}
copyDir(dst, src, matcher, copiedFiles)
- if m := modload.PackageModule(realPath); m.Path != "" {
+ if m := s.PackageModule(realPath); m.Path != "" {
copyMetadata(m.Path, realPath, dst, src, copiedFiles)
}
diff --git a/src/cmd/go/internal/modcmd/why.go b/src/cmd/go/internal/modcmd/why.go
index bebcf16e80..93a2d607ce 100644
--- a/src/cmd/go/internal/modcmd/why.go
+++ b/src/cmd/go/internal/modcmd/why.go
@@ -92,7 +92,7 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) {
byModule := make(map[string][]string)
_, pkgs := modload.LoadPackages(moduleLoaderState, ctx, loadOpts, "all")
for _, path := range pkgs {
- m := modload.PackageModule(path)
+ m := moduleLoaderState.PackageModule(path)
if m.Path != "" {
byModule[m.Path] = append(byModule[m.Path], path)
}
@@ -102,13 +102,13 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) {
best := ""
bestDepth := 1000000000
for _, path := range byModule[m.Path] {
- d := modload.WhyDepth(path)
+ d := moduleLoaderState.WhyDepth(path)
if d > 0 && d < bestDepth {
best = path
bestDepth = d
}
}
- why := modload.Why(best)
+ why := moduleLoaderState.Why(best)
if why == "" {
vendoring := ""
if *whyVendor {
@@ -128,7 +128,7 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) {
sep := ""
for _, m := range matches {
for _, path := range m.Pkgs {
- why := modload.Why(path)
+ why := moduleLoaderState.Why(path)
if why == "" {
vendoring := ""
if *whyVendor {
diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go
index 3531ee9fd7..f29365b5b6 100644
--- a/src/cmd/go/internal/modget/get.go
+++ b/src/cmd/go/internal/modget/get.go
@@ -1700,13 +1700,13 @@ func (r *resolver) checkPackageProblems(loaderstate *modload.State, ctx context.
}
}
}
- if m := modload.PackageModule(pkg); m.Path != "" {
+ if m := loaderstate.PackageModule(pkg); m.Path != "" {
relevantMods[m] |= hasPkg
}
}
for _, match := range matches {
for _, pkg := range match.Pkgs {
- m := modload.PackageModule(pkg)
+ m := loaderstate.PackageModule(pkg)
relevantMods[m] |= named
}
}
diff --git a/src/cmd/go/internal/modload/build.go b/src/cmd/go/internal/modload/build.go
index 057288a200..2f1dca6f7b 100644
--- a/src/cmd/go/internal/modload/build.go
+++ b/src/cmd/go/internal/modload/build.go
@@ -54,7 +54,7 @@ func PackageModuleInfo(loaderstate *State, ctx context.Context, pkgpath string)
if isStandardImportPath(pkgpath) || !loaderstate.Enabled() {
return nil
}
- m, ok := findModule(loaded, pkgpath)
+ m, ok := findModule(loaderstate.pkgLoader, pkgpath)
if !ok {
return nil
}
@@ -71,7 +71,7 @@ func PackageModRoot(loaderstate *State, ctx context.Context, pkgpath string) str
if isStandardImportPath(pkgpath) || !loaderstate.Enabled() || cfg.BuildMod == "vendor" {
return ""
}
- m, ok := findModule(loaded, pkgpath)
+ m, ok := findModule(loaderstate.pkgLoader, pkgpath)
if !ok {
return ""
}
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index ccdb8a03aa..288d63db66 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -435,6 +435,14 @@ type State struct {
modulesEnabled bool
MainModules *MainModuleSet
+ // pkgLoader is the most recently-used package loader.
+ // It holds details about individual packages.
+ //
+ // This variable should only be accessed directly in top-level exported
+ // functions. All other functions that require or produce a *packageLoader should pass
+ // or return it as an explicit parameter.
+ pkgLoader *packageLoader
+
// requirements is the requirement graph for the main module.
//
// It is always non-nil if the main module's go.mod file has been
@@ -1976,7 +1984,7 @@ func commitRequirements(loaderstate *State, ctx context.Context, opts WriteOpts)
if loaderstate.inWorkspaceMode() {
// go.mod files aren't updated in workspace mode, but we still want to
// update the go.work.sum file.
- return loaderstate.Fetcher().WriteGoSum(ctx, keepSums(loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate))
+ return loaderstate.Fetcher().WriteGoSum(ctx, keepSums(loaderstate, ctx, loaderstate.pkgLoader, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate))
}
_, updatedGoMod, modFile, err := UpdateGoModFromReqs(loaderstate, ctx, opts)
if err != nil {
@@ -2000,7 +2008,7 @@ func commitRequirements(loaderstate *State, ctx context.Context, opts WriteOpts)
// Don't write go.mod, but write go.sum in case we added or trimmed sums.
// 'go mod init' shouldn't write go.sum, since it will be incomplete.
if cfg.CmdName != "mod init" {
- if err := loaderstate.Fetcher().WriteGoSum(ctx, keepSums(loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate)); err != nil {
+ if err := loaderstate.Fetcher().WriteGoSum(ctx, keepSums(loaderstate, ctx, loaderstate.pkgLoader, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate)); err != nil {
return err
}
}
@@ -2023,7 +2031,7 @@ func commitRequirements(loaderstate *State, ctx context.Context, opts WriteOpts)
// 'go mod init' shouldn't write go.sum, since it will be incomplete.
if cfg.CmdName != "mod init" {
if err == nil {
- err = loaderstate.Fetcher().WriteGoSum(ctx, keepSums(loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate))
+ err = loaderstate.Fetcher().WriteGoSum(ctx, keepSums(loaderstate, ctx, loaderstate.pkgLoader, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate))
}
}
}()
diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go
index a4f2e2fc95..f5266149d6 100644
--- a/src/cmd/go/internal/modload/load.go
+++ b/src/cmd/go/internal/modload/load.go
@@ -128,14 +128,6 @@ import (
"golang.org/x/mod/module"
)
-// loaded is the most recently-used package loader.
-// It holds details about individual packages.
-//
-// This variable should only be accessed directly in top-level exported
-// functions. All other functions that require or produce a *packageLoader should pass
-// or return it as an explicit parameter.
-var loaded *packageLoader
-
// PackageOpts control the behavior of the LoadPackages function.
type PackageOpts struct {
// TidyGoVersion is the Go version to which the go.mod file should be updated
@@ -454,8 +446,8 @@ func LoadPackages(loaderstate *State, ctx context.Context, opts PackageOpts, pat
if opts.TidyDiff {
cfg.BuildMod = "readonly"
- loaded = ld
- loaderstate.requirements = loaded.requirements
+ loaderstate.pkgLoader = ld
+ loaderstate.requirements = loaderstate.pkgLoader.requirements
currentGoMod, updatedGoMod, _, err := UpdateGoModFromReqs(loaderstate, ctx, WriteOpts{})
if err != nil {
base.Fatal(err)
@@ -466,7 +458,7 @@ func LoadPackages(loaderstate *State, ctx context.Context, opts PackageOpts, pat
// Dropping compatibility for 1.16 may result in a strictly smaller go.sum.
// Update the keep map with only the loaded.requirements.
if gover.Compare(compatVersion, "1.16") > 0 {
- keep = keepSums(loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums)
+ keep = keepSums(loaderstate, ctx, loaderstate.pkgLoader, loaderstate.requirements, addBuildListZipSums)
}
currentGoSum, tidyGoSum := loaderstate.fetcher.TidyGoSum(keep)
goSumDiff := diff.Diff("current/go.sum", currentGoSum, "tidy/go.sum", tidyGoSum)
@@ -504,8 +496,8 @@ func LoadPackages(loaderstate *State, ctx context.Context, opts PackageOpts, pat
// We'll skip updating if ExplicitWriteGoMod is true (the caller has opted
// to call WriteGoMod itself) or if ResolveMissingImports is false (the
// command wants to examine the package graph as-is).
- loaded = ld
- loaderstate.requirements = loaded.requirements
+ loaderstate.pkgLoader = ld
+ loaderstate.requirements = loaderstate.pkgLoader.requirements
for _, pkg := range ld.pkgs {
if !pkg.isTest() {
@@ -775,7 +767,7 @@ func ImportFromFiles(loaderstate *State, ctx context.Context, gofiles []string)
base.Fatal(err)
}
- loaded = loadFromRoots(loaderstate, ctx, loaderParams{
+ loaderstate.pkgLoader = loadFromRoots(loaderstate, ctx, loaderParams{
PackageOpts: PackageOpts{
Tags: tags,
ResolveMissingImports: true,
@@ -788,7 +780,7 @@ func ImportFromFiles(loaderstate *State, ctx context.Context, gofiles []string)
return roots
},
})
- loaderstate.requirements = loaded.requirements
+ loaderstate.requirements = loaderstate.pkgLoader.requirements
if !ExplicitWriteGoMod {
if err := commitRequirements(loaderstate, ctx, WriteOpts{}); err != nil {
@@ -841,8 +833,8 @@ func (mms *MainModuleSet) DirImportPath(loaderstate *State, ctx context.Context,
}
// PackageModule returns the module providing the package named by the import path.
-func PackageModule(path string) module.Version {
- pkg, ok := loaded.pkgCache.Get(path)
+func (loaderstate *State) PackageModule(path string) module.Version {
+ pkg, ok := loaderstate.pkgLoader.pkgCache.Get(path)
if !ok {
return module.Version{}
}
@@ -859,9 +851,9 @@ func Lookup(loaderstate *State, parentPath string, parentIsStd bool, path string
}
if parentIsStd {
- path = loaded.stdVendor(loaderstate, parentPath, path)
+ path = loaderstate.pkgLoader.stdVendor(loaderstate, parentPath, path)
}
- pkg, ok := loaded.pkgCache.Get(path)
+ pkg, ok := loaderstate.pkgLoader.pkgCache.Get(path)
if !ok {
// The loader should have found all the relevant paths.
// There are a few exceptions, though:
@@ -2391,8 +2383,8 @@ func (pkg *loadPkg) why() string {
// The package graph must have been loaded already, usually by LoadPackages.
// If there is no reason for the package to be in the current build,
// Why returns an empty string.
-func Why(path string) string {
- pkg, ok := loaded.pkgCache.Get(path)
+func (loaderstate *State) Why(path string) string {
+ pkg, ok := loaderstate.pkgLoader.pkgCache.Get(path)
if !ok {
return ""
}
@@ -2402,9 +2394,9 @@ func Why(path string) string {
// WhyDepth returns the number of steps in the Why listing.
// If there is no reason for the package to be in the current build,
// WhyDepth returns 0.
-func WhyDepth(path string) int {
+func (loaderstate *State) WhyDepth(path string) int {
n := 0
- pkg, _ := loaded.pkgCache.Get(path)
+ pkg, _ := loaderstate.pkgLoader.pkgCache.Get(path)
for p := pkg; p != nil; p = p.stack {
n++
}
diff --git a/src/cmd/go/internal/workcmd/sync.go b/src/cmd/go/internal/workcmd/sync.go
index 13ce1e5f42..8c90c75bdb 100644
--- a/src/cmd/go/internal/workcmd/sync.go
+++ b/src/cmd/go/internal/workcmd/sync.go
@@ -82,7 +82,7 @@ func runSync(ctx context.Context, cmd *base.Command, args []string) {
inMustSelect = map[module.Version]bool{}
)
for _, pkg := range pkgs {
- if r := modload.PackageModule(pkg); r.Version != "" && !inMustSelect[r] {
+ if r := moduleLoaderState.PackageModule(pkg); r.Version != "" && !inMustSelect[r] {
// r has a known version, so force that version.
mustSelect = append(mustSelect, r)
inMustSelect[r] = true