cmd/go: refactor usage of MainModules

This commit refactors usage of the global variable `MainModules` to
the global LoaderState variable of the same name.

This commit is part of the overall effort to eliminate global
modloader state.

[git-generate]
cd src/cmd/go/internal/modload
rf 'mv State.mainModules State.MainModules'
rf 'ex { MainModules -> LoaderState.MainModules }'
for dir in load modcmd modget test tool workcmd ; do
  cd ../${dir}
  rf 'ex {
    import "cmd/go/internal/modload"
    modload.MainModules -> modload.LoaderState.MainModules
  }'
done
cd ../modload
rf 'rm MainModules'

Change-Id: I15644c84190717d62ae953747a288ec6495ef168
Reviewed-on: https://go-review.googlesource.com/c/go/+/698060
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Michael Matloob <matloob@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Ian Alexander 2025-08-20 19:56:29 -04:00
parent f7a68d3804
commit f2d0d05d28
23 changed files with 182 additions and 184 deletions

View file

@ -49,7 +49,7 @@ func defaultGODEBUG(p *Package, directives, testDirectives, xtestDirectives []bu
if p.Name != "main" { if p.Name != "main" {
return "" return ""
} }
goVersion := modload.MainModules.GoVersion() goVersion := modload.LoaderState.MainModules.GoVersion()
if modload.LoaderState.RootMode == modload.NoRoot && p.Module != nil { if modload.LoaderState.RootMode == modload.NoRoot && p.Module != nil {
// This is go install pkg@version or go run pkg@version. // This is go install pkg@version or go run pkg@version.
// Use the Go version from the package. // Use the Go version from the package.
@ -73,7 +73,7 @@ func defaultGODEBUG(p *Package, directives, testDirectives, xtestDirectives []bu
} }
// Add directives from main module go.mod. // Add directives from main module go.mod.
for _, g := range modload.MainModules.Godebugs() { for _, g := range modload.LoaderState.MainModules.Godebugs() {
if m == nil { if m == nil {
m = make(map[string]string) m = make(map[string]string)
} }

View file

@ -1552,7 +1552,7 @@ func disallowInternal(ctx context.Context, srcDir string, importer *Package, imp
// directory containing them. // directory containing them.
// If the directory is outside the main modules, this will resolve to ".", // If the directory is outside the main modules, this will resolve to ".",
// which is not a prefix of any valid module. // which is not a prefix of any valid module.
importerPath, _ = modload.MainModules.DirImportPath(ctx, importer.Dir) importerPath, _ = modload.LoaderState.MainModules.DirImportPath(ctx, importer.Dir)
} }
parentOfInternal := p.ImportPath[:i] parentOfInternal := p.ImportPath[:i]
if str.HasPathPrefix(importerPath, parentOfInternal) { if str.HasPathPrefix(importerPath, parentOfInternal) {

View file

@ -56,11 +56,11 @@ func MatchPackage(pattern, cwd string) func(*Package) bool {
return func(p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") } return func(p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
case pattern == "tool" && modload.Enabled(): case pattern == "tool" && modload.Enabled():
return func(p *Package) bool { return func(p *Package) bool {
return modload.MainModules.Tools()[p.ImportPath] return modload.LoaderState.MainModules.Tools()[p.ImportPath]
} }
case pattern == "work" && modload.Enabled(): case pattern == "work" && modload.Enabled():
return func(p *Package) bool { return func(p *Package) bool {
return p.Module != nil && modload.MainModules.Contains(p.Module.Path) return p.Module != nil && modload.LoaderState.MainModules.Contains(p.Module.Path)
} }
default: default:

View file

@ -120,7 +120,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
modload.LoadModFile(ctx) // to fill MainModules modload.LoadModFile(ctx) // to fill MainModules
if haveExplicitArgs { if haveExplicitArgs {
for _, mainModule := range modload.MainModules.Versions() { for _, mainModule := range modload.LoaderState.MainModules.Versions() {
targetAtUpgrade := mainModule.Path + "@upgrade" targetAtUpgrade := mainModule.Path + "@upgrade"
targetAtPatch := mainModule.Path + "@patch" targetAtPatch := mainModule.Path + "@patch"
for _, arg := range args { for _, arg := range args {
@ -136,8 +136,8 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
// https://go-review.googlesource.com/c/go/+/359794/comments/ce946a80_6cf53992. // https://go-review.googlesource.com/c/go/+/359794/comments/ce946a80_6cf53992.
args = []string{"all"} args = []string{"all"}
} else { } else {
mainModule := modload.MainModules.Versions()[0] mainModule := modload.LoaderState.MainModules.Versions()[0]
modFile := modload.MainModules.ModFile(mainModule) modFile := modload.LoaderState.MainModules.ModFile(mainModule)
if modFile.Go == nil || gover.Compare(modFile.Go.Version, gover.ExplicitIndirectVersion) < 0 { if modFile.Go == nil || gover.Compare(modFile.Go.Version, gover.ExplicitIndirectVersion) < 0 {
if len(modFile.Require) > 0 { if len(modFile.Require) > 0 {
args = []string{"all"} args = []string{"all"}

View file

@ -106,7 +106,7 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
modpkgs := make(map[module.Version][]string) modpkgs := make(map[module.Version][]string)
for _, pkg := range pkgs { for _, pkg := range pkgs {
m := modload.PackageModule(pkg) m := modload.PackageModule(pkg)
if m.Path == "" || modload.MainModules.Contains(m.Path) { if m.Path == "" || modload.LoaderState.MainModules.Contains(m.Path) {
continue continue
} }
modpkgs[m] = append(modpkgs[m], pkg) modpkgs[m] = append(modpkgs[m], pkg)
@ -116,13 +116,13 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
includeAllReplacements := false includeAllReplacements := false
includeGoVersions := false includeGoVersions := false
isExplicit := map[module.Version]bool{} isExplicit := map[module.Version]bool{}
gv := modload.MainModules.GoVersion() gv := modload.LoaderState.MainModules.GoVersion()
if gover.Compare(gv, "1.14") >= 0 && (modload.FindGoWork(base.Cwd()) != "" || modload.ModFile().Go != nil) { if gover.Compare(gv, "1.14") >= 0 && (modload.FindGoWork(base.Cwd()) != "" || modload.ModFile().Go != nil) {
// If the Go version is at least 1.14, annotate all explicit 'require' and // If the Go version is at least 1.14, annotate all explicit 'require' and
// 'replace' targets found in the go.mod file so that we can perform a // 'replace' targets found in the go.mod file so that we can perform a
// stronger consistency check when -mod=vendor is set. // stronger consistency check when -mod=vendor is set.
for _, m := range modload.MainModules.Versions() { for _, m := range modload.LoaderState.MainModules.Versions() {
if modFile := modload.MainModules.ModFile(m); modFile != nil { if modFile := modload.LoaderState.MainModules.ModFile(m); modFile != nil {
for _, r := range modFile.Require { for _, r := range modFile.Require {
isExplicit[r.Mod] = true isExplicit[r.Mod] = true
} }
@ -156,7 +156,7 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
w = io.MultiWriter(&buf, os.Stderr) w = io.MultiWriter(&buf, os.Stderr)
} }
if modload.MainModules.WorkFile() != nil { if modload.LoaderState.MainModules.WorkFile() != nil {
fmt.Fprintf(w, "## workspace\n") fmt.Fprintf(w, "## workspace\n")
} }
@ -192,8 +192,8 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
// Record unused and wildcard replacements at the end of the modules.txt file: // Record unused and wildcard replacements at the end of the modules.txt file:
// without access to the complete build list, the consumer of the vendor // without access to the complete build list, the consumer of the vendor
// directory can't otherwise determine that those replacements had no effect. // directory can't otherwise determine that those replacements had no effect.
for _, m := range modload.MainModules.Versions() { for _, m := range modload.LoaderState.MainModules.Versions() {
if workFile := modload.MainModules.WorkFile(); workFile != nil { if workFile := modload.LoaderState.MainModules.WorkFile(); workFile != nil {
for _, r := range workFile.Replace { for _, r := range workFile.Replace {
if replacementWritten[r.Old] { if replacementWritten[r.Old] {
// We already recorded this replacement. // We already recorded this replacement.
@ -208,7 +208,7 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
} }
} }
} }
if modFile := modload.MainModules.ModFile(m); modFile != nil { if modFile := modload.LoaderState.MainModules.ModFile(m); modFile != nil {
for _, r := range modFile.Replace { for _, r := range modFile.Replace {
if replacementWritten[r.Old] { if replacementWritten[r.Old] {
// We already recorded this replacement. // We already recorded this replacement.
@ -315,7 +315,7 @@ func vendorPkg(vdir, pkg string) {
} }
} }
var embedPatterns []string var embedPatterns []string
if gover.Compare(modload.MainModules.GoVersion(), "1.22") >= 0 { if gover.Compare(modload.LoaderState.MainModules.GoVersion(), "1.22") >= 0 {
embedPatterns = bp.EmbedPatterns embedPatterns = bp.EmbedPatterns
} else { } else {
// Maintain the behavior of https://github.com/golang/go/issues/63473 // Maintain the behavior of https://github.com/golang/go/issues/63473
@ -431,7 +431,7 @@ func matchPotentialSourceFile(dir string, info fs.DirEntry) bool {
return false return false
} }
if info.Name() == "go.mod" || info.Name() == "go.sum" { if info.Name() == "go.mod" || info.Name() == "go.sum" {
if gv := modload.MainModules.GoVersion(); gover.Compare(gv, "1.17") >= 0 { if gv := modload.LoaderState.MainModules.GoVersion(); gover.Compare(gv, "1.17") >= 0 {
// As of Go 1.17, we strip go.mod and go.sum files from dependency modules. // As of Go 1.17, we strip go.mod and go.sum files from dependency modules.
// Otherwise, 'go' commands invoked within the vendor subtree may misidentify // Otherwise, 'go' commands invoked within the vendor subtree may misidentify
// an arbitrary directory within the vendor tree as a module root. // an arbitrary directory within the vendor tree as a module root.

View file

@ -94,7 +94,7 @@ func verifyMod(ctx context.Context, mod module.Version) []error {
// "go" and "toolchain" have no disk footprint; nothing to verify. // "go" and "toolchain" have no disk footprint; nothing to verify.
return nil return nil
} }
if modload.MainModules.Contains(mod.Path) { if modload.LoaderState.MainModules.Contains(mod.Path) {
return nil return nil
} }
var errs []error var errs []error

View file

@ -426,7 +426,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
if gowork := modload.FindGoWork(base.Cwd()); gowork != "" { if gowork := modload.FindGoWork(base.Cwd()); gowork != "" {
wf, err := modload.ReadWorkFile(gowork) wf, err := modload.ReadWorkFile(gowork)
if err == nil && modload.UpdateWorkGoVersion(wf, modload.MainModules.GoVersion()) { if err == nil && modload.UpdateWorkGoVersion(wf, modload.LoaderState.MainModules.GoVersion()) {
modload.WriteWorkFile(gowork, wf) modload.WriteWorkFile(gowork, wf)
} }
} }
@ -722,7 +722,7 @@ func (r *resolver) queryNone(ctx context.Context, q *query) {
if !q.isWildcard() { if !q.isWildcard() {
q.pathOnce(q.pattern, func() pathSet { q.pathOnce(q.pattern, func() pathSet {
hasModRoot := modload.HasModRoot() hasModRoot := modload.HasModRoot()
if hasModRoot && modload.MainModules.Contains(q.pattern) { if hasModRoot && modload.LoaderState.MainModules.Contains(q.pattern) {
v := module.Version{Path: q.pattern} v := module.Version{Path: q.pattern}
// The user has explicitly requested to downgrade their own module to // The user has explicitly requested to downgrade their own module to
// version "none". This is not an entirely unreasonable request: it // version "none". This is not an entirely unreasonable request: it
@ -746,7 +746,7 @@ func (r *resolver) queryNone(ctx context.Context, q *query) {
continue continue
} }
q.pathOnce(curM.Path, func() pathSet { q.pathOnce(curM.Path, func() pathSet {
if modload.HasModRoot() && curM.Version == "" && modload.MainModules.Contains(curM.Path) { if modload.HasModRoot() && curM.Version == "" && modload.LoaderState.MainModules.Contains(curM.Path) {
return errSet(&modload.QueryMatchesMainModulesError{MainModules: []module.Version{curM}, Pattern: q.pattern, Query: q.version}) return errSet(&modload.QueryMatchesMainModulesError{MainModules: []module.Version{curM}, Pattern: q.pattern, Query: q.version})
} }
return pathSet{mod: module.Version{Path: curM.Path, Version: "none"}} return pathSet{mod: module.Version{Path: curM.Path, Version: "none"}}
@ -766,13 +766,13 @@ func (r *resolver) performLocalQueries(ctx context.Context) {
// Absolute paths like C:\foo and relative paths like ../foo... are // Absolute paths like C:\foo and relative paths like ../foo... are
// restricted to matching packages in the main module. // restricted to matching packages in the main module.
pkgPattern, mainModule := modload.MainModules.DirImportPath(ctx, q.pattern) pkgPattern, mainModule := modload.LoaderState.MainModules.DirImportPath(ctx, q.pattern)
if pkgPattern == "." { if pkgPattern == "." {
modload.MustHaveModRoot() modload.MustHaveModRoot()
versions := modload.MainModules.Versions() versions := modload.LoaderState.MainModules.Versions()
modRoots := make([]string, 0, len(versions)) modRoots := make([]string, 0, len(versions))
for _, m := range versions { for _, m := range versions {
modRoots = append(modRoots, modload.MainModules.ModRoot(m)) modRoots = append(modRoots, modload.LoaderState.MainModules.ModRoot(m))
} }
var plural string var plural string
if len(modRoots) != 1 { if len(modRoots) != 1 {
@ -792,7 +792,7 @@ func (r *resolver) performLocalQueries(ctx context.Context) {
} }
if !q.isWildcard() { if !q.isWildcard() {
modload.MustHaveModRoot() modload.MustHaveModRoot()
return errSet(fmt.Errorf("%s%s is not a package in module rooted at %s", q.pattern, absDetail, modload.MainModules.ModRoot(mainModule))) return errSet(fmt.Errorf("%s%s is not a package in module rooted at %s", q.pattern, absDetail, modload.LoaderState.MainModules.ModRoot(mainModule)))
} }
search.WarnUnmatched([]*search.Match{match}) search.WarnUnmatched([]*search.Match{match})
return pathSet{} return pathSet{}
@ -848,7 +848,7 @@ func (r *resolver) queryWildcard(ctx context.Context, q *query) {
return pathSet{} return pathSet{}
} }
if modload.MainModules.Contains(curM.Path) && !versionOkForMainModule(q.version) { if modload.LoaderState.MainModules.Contains(curM.Path) && !versionOkForMainModule(q.version) {
if q.matchesPath(curM.Path) { if q.matchesPath(curM.Path) {
return errSet(&modload.QueryMatchesMainModulesError{ return errSet(&modload.QueryMatchesMainModulesError{
MainModules: []module.Version{curM}, MainModules: []module.Version{curM},
@ -1065,7 +1065,7 @@ func (r *resolver) queryPath(ctx context.Context, q *query) {
// pattern is "tool". // pattern is "tool".
func (r *resolver) performToolQueries(ctx context.Context) { func (r *resolver) performToolQueries(ctx context.Context) {
for _, q := range r.toolQueries { for _, q := range r.toolQueries {
for tool := range modload.MainModules.Tools() { for tool := range modload.LoaderState.MainModules.Tools() {
q.pathOnce(tool, func() pathSet { q.pathOnce(tool, func() pathSet {
pkgMods, err := r.queryPackages(ctx, tool, q.version, r.initialSelected) pkgMods, err := r.queryPackages(ctx, tool, q.version, r.initialSelected)
return pathSet{pkgMods: pkgMods, err: err} return pathSet{pkgMods: pkgMods, err: err}
@ -1082,10 +1082,10 @@ func (r *resolver) performWorkQueries(ctx context.Context) {
// TODO(matloob): Maybe export MainModules.mustGetSingleMainModule and call that. // TODO(matloob): Maybe export MainModules.mustGetSingleMainModule and call that.
// There are a few other places outside the modload package where we expect // There are a few other places outside the modload package where we expect
// a single main module. // a single main module.
if len(modload.MainModules.Versions()) != 1 { if len(modload.LoaderState.MainModules.Versions()) != 1 {
panic("internal error: number of main modules is not exactly one in resolution phase of go get") panic("internal error: number of main modules is not exactly one in resolution phase of go get")
} }
mainModule := modload.MainModules.Versions()[0] mainModule := modload.LoaderState.MainModules.Versions()[0]
// We know what the result is going to be, assuming the main module is not // We know what the result is going to be, assuming the main module is not
// empty, (it's the main module itself) but first check to see that there // empty, (it's the main module itself) but first check to see that there
@ -1496,7 +1496,7 @@ func (r *resolver) disambiguate(cs pathSet) (filtered pathSet, isPackage bool, m
continue continue
} }
if modload.MainModules.Contains(m.Path) { if modload.LoaderState.MainModules.Contains(m.Path) {
if m.Version == "" { if m.Version == "" {
return pathSet{}, true, m, true return pathSet{}, true, m, true
} }
@ -1612,7 +1612,7 @@ func (r *resolver) checkPackageProblems(ctx context.Context, pkgPatterns []strin
// info, but switch back to single module mode when fetching sums so that we update // info, but switch back to single module mode when fetching sums so that we update
// the single module's go.sum file. // the single module's go.sum file.
var exitWorkspace func() var exitWorkspace func()
if r.workspace != nil && r.workspace.hasModule(modload.MainModules.Versions()[0].Path) { if r.workspace != nil && r.workspace.hasModule(modload.LoaderState.MainModules.Versions()[0].Path) {
var err error var err error
exitWorkspace, err = modload.EnterWorkspace(ctx) exitWorkspace, err = modload.EnterWorkspace(ctx)
if err != nil { if err != nil {
@ -1951,7 +1951,7 @@ func (r *resolver) resolve(q *query, m module.Version) {
panic("internal error: resolving a module.Version with an empty path") panic("internal error: resolving a module.Version with an empty path")
} }
if modload.MainModules.Contains(m.Path) && m.Version != "" { if modload.LoaderState.MainModules.Contains(m.Path) && m.Version != "" {
reportError(q, &modload.QueryMatchesMainModulesError{ reportError(q, &modload.QueryMatchesMainModulesError{
MainModules: []module.Version{{Path: m.Path}}, MainModules: []module.Version{{Path: m.Path}},
Pattern: q.pattern, Pattern: q.pattern,
@ -1983,7 +1983,7 @@ func (r *resolver) updateBuildList(ctx context.Context, additions []module.Versi
resolved := make([]module.Version, 0, len(r.resolvedVersion)) resolved := make([]module.Version, 0, len(r.resolvedVersion))
for mPath, rv := range r.resolvedVersion { for mPath, rv := range r.resolvedVersion {
if !modload.MainModules.Contains(mPath) { if !modload.LoaderState.MainModules.Contains(mPath) {
resolved = append(resolved, module.Version{Path: mPath, Version: rv.version}) resolved = append(resolved, module.Version{Path: mPath, Version: rv.version})
} }
} }

View file

@ -192,7 +192,7 @@ func (q *query) validate() error {
// request that we remove all module requirements, leaving only the main // request that we remove all module requirements, leaving only the main
// module and standard library. Perhaps we should implement that someday. // module and standard library. Perhaps we should implement that someday.
return &modload.QueryUpgradesAllError{ return &modload.QueryUpgradesAllError{
MainModules: modload.MainModules.Versions(), MainModules: modload.LoaderState.MainModules.Versions(),
Query: q.version, Query: q.version,
} }
} }

View file

@ -290,7 +290,7 @@ func addDeprecation(ctx context.Context, m *modinfo.ModulePublic) {
// in rs (which may be nil to indicate that m was not loaded from a requirement // in rs (which may be nil to indicate that m was not loaded from a requirement
// graph). // graph).
func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, mode ListMode, reuse map[module.Version]*modinfo.ModulePublic) *modinfo.ModulePublic { func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, mode ListMode, reuse map[module.Version]*modinfo.ModulePublic) *modinfo.ModulePublic {
if m.Version == "" && MainModules.Contains(m.Path) { if m.Version == "" && LoaderState.MainModules.Contains(m.Path) {
info := &modinfo.ModulePublic{ info := &modinfo.ModulePublic{
Path: m.Path, Path: m.Path,
Version: m.Version, Version: m.Version,
@ -301,7 +301,7 @@ func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, mode Li
} else { } else {
panic("internal error: GoVersion not set for main module") panic("internal error: GoVersion not set for main module")
} }
if modRoot := MainModules.ModRoot(m); modRoot != "" { if modRoot := LoaderState.MainModules.ModRoot(m); modRoot != "" {
info.Dir = modRoot info.Dir = modRoot
info.GoMod = modFilePath(modRoot) info.GoMod = modFilePath(modRoot)
} }

View file

@ -128,7 +128,7 @@ func newRequirements(pruning modPruning, rootModules []module.Version, direct ma
panic("in workspace mode, but pruning is not workspace in newRequirements") panic("in workspace mode, but pruning is not workspace in newRequirements")
} }
for i, m := range rootModules { for i, m := range rootModules {
if m.Version == "" && MainModules.Contains(m.Path) { if m.Version == "" && LoaderState.MainModules.Contains(m.Path) {
panic(fmt.Sprintf("newRequirements called with untrimmed build list: rootModules[%v] is a main module", i)) panic(fmt.Sprintf("newRequirements called with untrimmed build list: rootModules[%v] is a main module", i))
} }
if m.Path == "" || m.Version == "" { if m.Path == "" || m.Version == "" {
@ -174,7 +174,7 @@ func (rs *Requirements) String() string {
// requirements. // requirements.
func (rs *Requirements) initVendor(vendorList []module.Version) { func (rs *Requirements) initVendor(vendorList []module.Version) {
rs.graphOnce.Do(func() { rs.graphOnce.Do(func() {
roots := MainModules.Versions() roots := LoaderState.MainModules.Versions()
if inWorkspaceMode() { if inWorkspaceMode() {
// Use rs.rootModules to pull in the go and toolchain roots // Use rs.rootModules to pull in the go and toolchain roots
// from the go.work file and preserve the invariant that all // from the go.work file and preserve the invariant that all
@ -186,7 +186,7 @@ func (rs *Requirements) initVendor(vendorList []module.Version) {
} }
if rs.pruning == pruned { if rs.pruning == pruned {
mainModule := MainModules.mustGetSingleMainModule() mainModule := LoaderState.MainModules.mustGetSingleMainModule()
// The roots of a single pruned module should already include every module in the // The roots of a single pruned module should already include every module in the
// vendor list, because the vendored modules are the same as those needed // vendor list, because the vendored modules are the same as those needed
// for graph pruning. // for graph pruning.
@ -219,14 +219,14 @@ func (rs *Requirements) initVendor(vendorList []module.Version) {
// dependencies. // dependencies.
vendorMod := module.Version{Path: "vendor/modules.txt", Version: ""} vendorMod := module.Version{Path: "vendor/modules.txt", Version: ""}
if inWorkspaceMode() { if inWorkspaceMode() {
for _, m := range MainModules.Versions() { for _, m := range LoaderState.MainModules.Versions() {
reqs, _ := rootsFromModFile(m, MainModules.ModFile(m), omitToolchainRoot) reqs, _ := rootsFromModFile(m, LoaderState.MainModules.ModFile(m), omitToolchainRoot)
mg.g.Require(m, append(reqs, vendorMod)) mg.g.Require(m, append(reqs, vendorMod))
} }
mg.g.Require(vendorMod, vendorList) mg.g.Require(vendorMod, vendorList)
} else { } else {
mainModule := MainModules.mustGetSingleMainModule() mainModule := LoaderState.MainModules.mustGetSingleMainModule()
mg.g.Require(mainModule, append(rs.rootModules, vendorMod)) mg.g.Require(mainModule, append(rs.rootModules, vendorMod))
mg.g.Require(vendorMod, vendorList) mg.g.Require(vendorMod, vendorList)
} }
@ -249,7 +249,7 @@ func (rs *Requirements) GoVersion() string {
// path, or the zero module.Version and ok=false if the module is not a root // path, or the zero module.Version and ok=false if the module is not a root
// dependency. // dependency.
func (rs *Requirements) rootSelected(path string) (version string, ok bool) { func (rs *Requirements) rootSelected(path string) (version string, ok bool) {
if MainModules.Contains(path) { if LoaderState.MainModules.Contains(path) {
return "", true return "", true
} }
if v, ok := rs.maxRootVersion[path]; ok { if v, ok := rs.maxRootVersion[path]; ok {
@ -264,7 +264,7 @@ func (rs *Requirements) rootSelected(path string) (version string, ok bool) {
// selection. // selection.
func (rs *Requirements) hasRedundantRoot() bool { func (rs *Requirements) hasRedundantRoot() bool {
for i, m := range rs.rootModules { for i, m := range rs.rootModules {
if MainModules.Contains(m.Path) || (i > 0 && m.Path == rs.rootModules[i-1].Path) { if LoaderState.MainModules.Contains(m.Path) || (i > 0 && m.Path == rs.rootModules[i-1].Path) {
return true return true
} }
} }
@ -346,7 +346,7 @@ func readModGraph(ctx context.Context, pruning modPruning, roots []module.Versio
if inWorkspaceMode() { if inWorkspaceMode() {
graphRoots = roots graphRoots = roots
} else { } else {
graphRoots = MainModules.Versions() graphRoots = LoaderState.MainModules.Versions()
} }
var ( var (
mu sync.Mutex // guards mg.g and hasError during loading mu sync.Mutex // guards mg.g and hasError during loading
@ -360,7 +360,7 @@ func readModGraph(ctx context.Context, pruning modPruning, roots []module.Versio
if inWorkspaceMode() { if inWorkspaceMode() {
panic("pruning is not workspace in workspace mode") panic("pruning is not workspace in workspace mode")
} }
mg.g.Require(MainModules.mustGetSingleMainModule(), roots) mg.g.Require(LoaderState.MainModules.mustGetSingleMainModule(), roots)
} }
type dedupKey struct { type dedupKey struct {
@ -540,9 +540,9 @@ func (mg *ModuleGraph) findError() error {
func (mg *ModuleGraph) allRootsSelected() bool { func (mg *ModuleGraph) allRootsSelected() bool {
var roots []module.Version var roots []module.Version
if inWorkspaceMode() { if inWorkspaceMode() {
roots = MainModules.Versions() roots = LoaderState.MainModules.Versions()
} else { } else {
roots, _ = mg.g.RequiredBy(MainModules.mustGetSingleMainModule()) roots, _ = mg.g.RequiredBy(LoaderState.MainModules.mustGetSingleMainModule())
} }
for _, m := range roots { for _, m := range roots {
if mg.Selected(m.Path) != m.Version { if mg.Selected(m.Path) != m.Version {
@ -776,7 +776,7 @@ func (c Conflict) String() string {
// both retain the same versions of all packages in pkgs and satisfy the // both retain the same versions of all packages in pkgs and satisfy the
// graph-pruning invariants (if applicable). // graph-pruning invariants (if applicable).
func tidyRoots(ctx context.Context, rs *Requirements, pkgs []*loadPkg) (*Requirements, error) { func tidyRoots(ctx context.Context, rs *Requirements, pkgs []*loadPkg) (*Requirements, error) {
mainModule := MainModules.mustGetSingleMainModule() mainModule := LoaderState.MainModules.mustGetSingleMainModule()
if rs.pruning == unpruned { if rs.pruning == unpruned {
return tidyUnprunedRoots(ctx, mainModule, rs, pkgs) return tidyUnprunedRoots(ctx, mainModule, rs, pkgs)
} }
@ -1168,7 +1168,7 @@ func updatePrunedRoots(ctx context.Context, direct map[string]bool, rs *Requirem
roots = make([]module.Version, 0, len(rs.rootModules)) roots = make([]module.Version, 0, len(rs.rootModules))
rootsUpgraded = false rootsUpgraded = false
inRootPaths := make(map[string]bool, len(rs.rootModules)+1) inRootPaths := make(map[string]bool, len(rs.rootModules)+1)
for _, mm := range MainModules.Versions() { for _, mm := range LoaderState.MainModules.Versions() {
inRootPaths[mm.Path] = true inRootPaths[mm.Path] = true
} }
for _, m := range rs.rootModules { for _, m := range rs.rootModules {
@ -1445,7 +1445,7 @@ func updateUnprunedRoots(ctx context.Context, direct map[string]bool, rs *Requir
// This is only for convenience and clarity for end users: in an unpruned module, // This is only for convenience and clarity for end users: in an unpruned module,
// the choice of explicit vs. implicit dependency has no impact on MVS // the choice of explicit vs. implicit dependency has no impact on MVS
// selection (for itself or any other module). // selection (for itself or any other module).
keep := append(mg.BuildList()[MainModules.Len():], add...) keep := append(mg.BuildList()[LoaderState.MainModules.Len():], add...)
for _, m := range keep { for _, m := range keep {
if direct[m.Path] && !inRootPaths[m.Path] { if direct[m.Path] && !inRootPaths[m.Path] {
rootPaths = append(rootPaths, m.Path) rootPaths = append(rootPaths, m.Path)
@ -1454,14 +1454,14 @@ func updateUnprunedRoots(ctx context.Context, direct map[string]bool, rs *Requir
} }
var roots []module.Version var roots []module.Version
for _, mainModule := range MainModules.Versions() { for _, mainModule := range LoaderState.MainModules.Versions() {
min, err := mvs.Req(mainModule, rootPaths, &mvsReqs{roots: keep}) min, err := mvs.Req(mainModule, rootPaths, &mvsReqs{roots: keep})
if err != nil { if err != nil {
return rs, err return rs, err
} }
roots = append(roots, min...) roots = append(roots, min...)
} }
if MainModules.Len() > 1 { if LoaderState.MainModules.Len() > 1 {
gover.ModSort(roots) gover.ModSort(roots)
} }
if rs.pruning == unpruned && slices.Equal(roots, rs.rootModules) && maps.Equal(direct, rs.direct) { if rs.pruning == unpruned && slices.Equal(roots, rs.rootModules) && maps.Equal(direct, rs.direct) {
@ -1501,5 +1501,5 @@ func convertPruning(ctx context.Context, rs *Requirements, pruning modPruning) (
if err != nil { if err != nil {
return rs, err return rs, err
} }
return newRequirements(pruned, mg.BuildList()[MainModules.Len():], rs.direct), nil return newRequirements(pruned, mg.BuildList()[LoaderState.MainModules.Len():], rs.direct), nil
} }

View file

@ -106,7 +106,7 @@ func editRequirements(ctx context.Context, rs *Requirements, tryUpgrade, mustSel
// to begin with, so we can't edit those requirements in a coherent way. // to begin with, so we can't edit those requirements in a coherent way.
return orig, false, err return orig, false, err
} }
bl := mg.BuildList()[MainModules.Len():] bl := mg.BuildList()[LoaderState.MainModules.Len():]
selectedRoot = make(map[string]string, len(bl)) selectedRoot = make(map[string]string, len(bl))
for _, m := range bl { for _, m := range bl {
selectedRoot[m.Path] = m.Version selectedRoot[m.Path] = m.Version
@ -513,7 +513,7 @@ func editRequirements(ctx context.Context, rs *Requirements, tryUpgrade, mustSel
// The modules in mustSelect are always promoted to be explicit. // The modules in mustSelect are always promoted to be explicit.
for _, m := range mustSelect { for _, m := range mustSelect {
if m.Version != "none" && !MainModules.Contains(m.Path) { if m.Version != "none" && !LoaderState.MainModules.Contains(m.Path) {
rootPaths = append(rootPaths, m.Path) rootPaths = append(rootPaths, m.Path)
} }
} }
@ -530,7 +530,7 @@ func editRequirements(ctx context.Context, rs *Requirements, tryUpgrade, mustSel
} }
} }
roots, err = mvs.Req(MainModules.mustGetSingleMainModule(), rootPaths, &mvsReqs{roots: roots}) roots, err = mvs.Req(LoaderState.MainModules.mustGetSingleMainModule(), rootPaths, &mvsReqs{roots: roots})
if err != nil { if err != nil {
return nil, false, err return nil, false, err
} }

View file

@ -82,8 +82,8 @@ func (e *ImportMissingError) Error() string {
if e.QueryErr != nil { if e.QueryErr != nil {
return fmt.Sprintf("%s: %v", message, e.QueryErr) return fmt.Sprintf("%s: %v", message, e.QueryErr)
} }
if e.ImportingMainModule.Path != "" && e.ImportingMainModule != MainModules.ModContainingCWD() { if e.ImportingMainModule.Path != "" && e.ImportingMainModule != LoaderState.MainModules.ModContainingCWD() {
return fmt.Sprintf("%s; to add it:\n\tcd %s\n\tgo get %s", message, MainModules.ModRoot(e.ImportingMainModule), e.Path) return fmt.Sprintf("%s; to add it:\n\tcd %s\n\tgo get %s", message, LoaderState.MainModules.ModRoot(e.ImportingMainModule), e.Path)
} }
return fmt.Sprintf("%s; to add it:\n\tgo get %s", message, e.Path) return fmt.Sprintf("%s; to add it:\n\tgo get %s", message, e.Path)
} }
@ -299,12 +299,12 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
// Is the package in the standard library? // Is the package in the standard library?
pathIsStd := search.IsStandardImportPath(path) pathIsStd := search.IsStandardImportPath(path)
if pathIsStd && modindex.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) { if pathIsStd && modindex.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) {
for _, mainModule := range MainModules.Versions() { for _, mainModule := range LoaderState.MainModules.Versions() {
if MainModules.InGorootSrc(mainModule) { if LoaderState.MainModules.InGorootSrc(mainModule) {
if dir, ok, err := dirInModule(path, MainModules.PathPrefix(mainModule), MainModules.ModRoot(mainModule), true); err != nil { if dir, ok, err := dirInModule(path, LoaderState.MainModules.PathPrefix(mainModule), LoaderState.MainModules.ModRoot(mainModule), true); err != nil {
return module.Version{}, MainModules.ModRoot(mainModule), dir, nil, err return module.Version{}, LoaderState.MainModules.ModRoot(mainModule), dir, nil, err
} else if ok { } else if ok {
return mainModule, MainModules.ModRoot(mainModule), dir, nil, nil return mainModule, LoaderState.MainModules.ModRoot(mainModule), dir, nil, nil
} }
} }
} }
@ -321,10 +321,10 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
// Everything must be in the main modules or the main module's or workspace's vendor directory. // Everything must be in the main modules or the main module's or workspace's vendor directory.
if cfg.BuildMod == "vendor" { if cfg.BuildMod == "vendor" {
var mainErr error var mainErr error
for _, mainModule := range MainModules.Versions() { for _, mainModule := range LoaderState.MainModules.Versions() {
modRoot := MainModules.ModRoot(mainModule) modRoot := LoaderState.MainModules.ModRoot(mainModule)
if modRoot != "" { if modRoot != "" {
dir, mainOK, err := dirInModule(path, MainModules.PathPrefix(mainModule), modRoot, true) dir, mainOK, err := dirInModule(path, LoaderState.MainModules.PathPrefix(mainModule), modRoot, true)
if mainErr == nil { if mainErr == nil {
mainErr = err mainErr = err
} }
@ -345,7 +345,7 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
// vendor/modules.txt does not exist or the user manually added directories to the vendor directory. // vendor/modules.txt does not exist or the user manually added directories to the vendor directory.
// Go 1.23 and later require vendored packages to be present in modules.txt to be imported. // Go 1.23 and later require vendored packages to be present in modules.txt to be imported.
_, ok := vendorPkgModule[path] _, ok := vendorPkgModule[path]
if ok || (gover.Compare(MainModules.GoVersion(), gover.ExplicitModulesTxtImportVersion) < 0) { if ok || (gover.Compare(LoaderState.MainModules.GoVersion(), gover.ExplicitModulesTxtImportVersion) < 0) {
mods = append(mods, vendorPkgModule[path]) mods = append(mods, vendorPkgModule[path])
dirs = append(dirs, dir) dirs = append(dirs, dir)
roots = append(roots, vendorDir) roots = append(roots, vendorDir)
@ -471,7 +471,7 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
// If the module graph is pruned and this is a test-only dependency // If the module graph is pruned and this is a test-only dependency
// of a package in "all", we didn't necessarily load that file // of a package in "all", we didn't necessarily load that file
// when we read the module graph, so do it now to be sure. // when we read the module graph, so do it now to be sure.
if !skipModFile && cfg.BuildMod != "vendor" && mods[0].Path != "" && !MainModules.Contains(mods[0].Path) { if !skipModFile && cfg.BuildMod != "vendor" && mods[0].Path != "" && !LoaderState.MainModules.Contains(mods[0].Path) {
if _, err := goModSummary(mods[0]); err != nil { if _, err := goModSummary(mods[0]); err != nil {
return module.Version{}, "", "", nil, err return module.Version{}, "", "", nil, err
} }
@ -511,8 +511,8 @@ func queryImport(ctx context.Context, path string, rs *Requirements) (module.Ver
// To avoid spurious remote fetches, try the latest replacement for each // To avoid spurious remote fetches, try the latest replacement for each
// module (golang.org/issue/26241). // module (golang.org/issue/26241).
var mods []module.Version var mods []module.Version
if MainModules != nil { // TODO(#48912): Ensure MainModules exists at this point, and remove the check. if LoaderState.MainModules != nil { // TODO(#48912): Ensure MainModules exists at this point, and remove the check.
for mp, mv := range MainModules.HighestReplaced() { for mp, mv := range LoaderState.MainModules.HighestReplaced() {
if !maybeInModule(path, mp) { if !maybeInModule(path, mp) {
continue continue
} }
@ -748,7 +748,7 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile
// The isLocal return value reports whether the replacement, // The isLocal return value reports whether the replacement,
// if any, is local to the filesystem. // if any, is local to the filesystem.
func fetch(ctx context.Context, mod module.Version) (dir string, isLocal bool, err error) { func fetch(ctx context.Context, mod module.Version) (dir string, isLocal bool, err error) {
if modRoot := MainModules.ModRoot(mod); modRoot != "" { if modRoot := LoaderState.MainModules.ModRoot(mod); modRoot != "" {
return modRoot, true, nil return modRoot, true, nil
} }
if r := Replacement(mod); r.Path != "" { if r := Replacement(mod); r.Path != "" {

View file

@ -58,7 +58,7 @@ var (
// EnterModule resets MainModules and requirements to refer to just this one module. // EnterModule resets MainModules and requirements to refer to just this one module.
func EnterModule(ctx context.Context, enterModroot string) { func EnterModule(ctx context.Context, enterModroot string) {
MainModules = nil // reset MainModules LoaderState.MainModules = nil // reset MainModules
requirements = nil requirements = nil
workFilePath = "" // Force module mode workFilePath = "" // Force module mode
modfetch.Reset() modfetch.Reset()
@ -73,7 +73,7 @@ func EnterModule(ctx context.Context, enterModroot string) {
// EnterWorkspace will modify the global state they depend on in a non-thread-safe way. // EnterWorkspace will modify the global state they depend on in a non-thread-safe way.
func EnterWorkspace(ctx context.Context) (exit func(), err error) { func EnterWorkspace(ctx context.Context) (exit func(), err error) {
// Find the identity of the main module that will be updated before we reset modload state. // Find the identity of the main module that will be updated before we reset modload state.
mm := MainModules.mustGetSingleMainModule() mm := LoaderState.MainModules.mustGetSingleMainModule()
// Get the updated modfile we will use for that module. // Get the updated modfile we will use for that module.
_, _, updatedmodfile, err := UpdateGoModFromReqs(ctx, WriteOpts{}) _, _, updatedmodfile, err := UpdateGoModFromReqs(ctx, WriteOpts{})
if err != nil { if err != nil {
@ -89,8 +89,8 @@ func EnterWorkspace(ctx context.Context) (exit func(), err error) {
LoadModFile(ctx) LoadModFile(ctx)
// Update the content of the previous main module, and recompute the requirements. // Update the content of the previous main module, and recompute the requirements.
*MainModules.ModFile(mm) = *updatedmodfile *LoaderState.MainModules.ModFile(mm) = *updatedmodfile
requirements = requirementsFromModFiles(ctx, MainModules.workFile, slices.Collect(maps.Values(MainModules.modFiles)), nil) requirements = requirementsFromModFiles(ctx, LoaderState.MainModules.workFile, slices.Collect(maps.Values(LoaderState.MainModules.modFiles)), nil)
return func() { return func() {
setState(oldstate) setState(oldstate)
@ -294,8 +294,6 @@ func (mms *MainModuleSet) WorkFileReplaceMap() map[module.Version]module.Version
return mms.workFileReplaceMap return mms.workFileReplaceMap
} }
var MainModules *MainModuleSet
type Root int type Root int
const ( const (
@ -324,7 +322,7 @@ const (
// in go.mod, edit it before loading. // in go.mod, edit it before loading.
func ModFile() *modfile.File { func ModFile() *modfile.File {
Init() Init()
modFile := MainModules.ModFile(MainModules.mustGetSingleMainModule()) modFile := LoaderState.MainModules.ModFile(LoaderState.MainModules.mustGetSingleMainModule())
if modFile == nil { if modFile == nil {
die() die()
} }
@ -396,7 +394,7 @@ func setState(s State) State {
RootMode: LoaderState.RootMode, RootMode: LoaderState.RootMode,
modRoots: LoaderState.modRoots, modRoots: LoaderState.modRoots,
modulesEnabled: cfg.ModulesEnabled, modulesEnabled: cfg.ModulesEnabled,
mainModules: MainModules, MainModules: LoaderState.MainModules,
requirements: requirements, requirements: requirements,
} }
LoaderState.initialized = s.initialized LoaderState.initialized = s.initialized
@ -404,7 +402,7 @@ func setState(s State) State {
LoaderState.RootMode = s.RootMode LoaderState.RootMode = s.RootMode
LoaderState.modRoots = s.modRoots LoaderState.modRoots = s.modRoots
cfg.ModulesEnabled = s.modulesEnabled cfg.ModulesEnabled = s.modulesEnabled
MainModules = s.mainModules LoaderState.MainModules = s.MainModules
requirements = s.requirements requirements = s.requirements
workFilePath = s.workFilePath workFilePath = s.workFilePath
// The modfetch package's global state is used to compute // The modfetch package's global state is used to compute
@ -431,7 +429,7 @@ type State struct {
// modRoots != nil implies len(modRoots) > 0 // modRoots != nil implies len(modRoots) > 0
modRoots []string modRoots []string
modulesEnabled bool modulesEnabled bool
mainModules *MainModuleSet MainModules *MainModuleSet
requirements *Requirements requirements *Requirements
workFilePath string workFilePath string
modfetchState modfetch.State modfetchState modfetch.State
@ -628,7 +626,7 @@ func VendorDir() string {
// Even if -mod=vendor, we could be operating with no mod root (and thus no // Even if -mod=vendor, we could be operating with no mod root (and thus no
// vendor directory). As long as there are no dependencies that is expected // vendor directory). As long as there are no dependencies that is expected
// to work. See script/vendor_outside_module.txt. // to work. See script/vendor_outside_module.txt.
modRoot := MainModules.ModRoot(MainModules.mustGetSingleMainModule()) modRoot := LoaderState.MainModules.ModRoot(LoaderState.MainModules.mustGetSingleMainModule())
if modRoot == "" { if modRoot == "" {
panic("vendor directory does not exist when in single module mode outside of a module") panic("vendor directory does not exist when in single module mode outside of a module")
} }
@ -914,7 +912,7 @@ func loadModFile(ctx context.Context, opts *PackageOpts) (*Requirements, error)
// make MainModules.Len() == 0 mean that we're in module mode but not inside // make MainModules.Len() == 0 mean that we're in module mode but not inside
// any module. // any module.
mainModule := module.Version{Path: "command-line-arguments"} mainModule := module.Version{Path: "command-line-arguments"}
MainModules = makeMainModules([]module.Version{mainModule}, []string{""}, []*modfile.File{nil}, []*modFileIndex{nil}, nil) LoaderState.MainModules = makeMainModules([]module.Version{mainModule}, []string{""}, []*modfile.File{nil}, []*modFileIndex{nil}, nil)
var ( var (
goVersion string goVersion string
pruning modPruning pruning modPruning
@ -925,7 +923,7 @@ func loadModFile(ctx context.Context, opts *PackageOpts) (*Requirements, error)
// Since we are in a workspace, the Go version for the synthetic // Since we are in a workspace, the Go version for the synthetic
// "command-line-arguments" module must not exceed the Go version // "command-line-arguments" module must not exceed the Go version
// for the workspace. // for the workspace.
goVersion = MainModules.GoVersion() goVersion = LoaderState.MainModules.GoVersion()
pruning = workspace pruning = workspace
roots = []module.Version{ roots = []module.Version{
mainModule, mainModule,
@ -1016,20 +1014,20 @@ func loadModFile(ctx context.Context, opts *PackageOpts) (*Requirements, error)
return nil, errors.Join(errs...) return nil, errors.Join(errs...)
} }
MainModules = makeMainModules(mainModules, LoaderState.modRoots, modFiles, indices, workFile) LoaderState.MainModules = makeMainModules(mainModules, LoaderState.modRoots, modFiles, indices, workFile)
setDefaultBuildMod() // possibly enable automatic vendoring setDefaultBuildMod() // possibly enable automatic vendoring
rs := requirementsFromModFiles(ctx, workFile, modFiles, opts) rs := requirementsFromModFiles(ctx, workFile, modFiles, opts)
if cfg.BuildMod == "vendor" { if cfg.BuildMod == "vendor" {
readVendorList(VendorDir()) readVendorList(VendorDir())
versions := MainModules.Versions() versions := LoaderState.MainModules.Versions()
indexes := make([]*modFileIndex, 0, len(versions)) indexes := make([]*modFileIndex, 0, len(versions))
modFiles := make([]*modfile.File, 0, len(versions)) modFiles := make([]*modfile.File, 0, len(versions))
modRoots := make([]string, 0, len(versions)) modRoots := make([]string, 0, len(versions))
for _, m := range versions { for _, m := range versions {
indexes = append(indexes, MainModules.Index(m)) indexes = append(indexes, LoaderState.MainModules.Index(m))
modFiles = append(modFiles, MainModules.ModFile(m)) modFiles = append(modFiles, LoaderState.MainModules.ModFile(m))
modRoots = append(modRoots, MainModules.ModRoot(m)) modRoots = append(modRoots, LoaderState.MainModules.ModRoot(m))
} }
checkVendorConsistency(indexes, modFiles, modRoots) checkVendorConsistency(indexes, modFiles, modRoots)
rs.initVendor(vendorList) rs.initVendor(vendorList)
@ -1041,7 +1039,7 @@ func loadModFile(ctx context.Context, opts *PackageOpts) (*Requirements, error)
return rs, nil return rs, nil
} }
mainModule := MainModules.mustGetSingleMainModule() mainModule := LoaderState.MainModules.mustGetSingleMainModule()
if rs.hasRedundantRoot() { if rs.hasRedundantRoot() {
// If any module path appears more than once in the roots, we know that the // If any module path appears more than once in the roots, we know that the
@ -1054,7 +1052,7 @@ func loadModFile(ctx context.Context, opts *PackageOpts) (*Requirements, error)
} }
} }
if MainModules.Index(mainModule).goVersion == "" && rs.pruning != workspace { if LoaderState.MainModules.Index(mainModule).goVersion == "" && rs.pruning != workspace {
// TODO(#45551): Do something more principled instead of checking // TODO(#45551): Do something more principled instead of checking
// cfg.CmdName directly here. // cfg.CmdName directly here.
if cfg.BuildMod == "mod" && cfg.CmdName != "mod graph" && cfg.CmdName != "mod why" { if cfg.BuildMod == "mod" && cfg.CmdName != "mod graph" && cfg.CmdName != "mod why" {
@ -1063,7 +1061,7 @@ func loadModFile(ctx context.Context, opts *PackageOpts) (*Requirements, error)
if opts != nil && opts.TidyGoVersion != "" { if opts != nil && opts.TidyGoVersion != "" {
v = opts.TidyGoVersion v = opts.TidyGoVersion
} }
addGoStmt(MainModules.ModFile(mainModule), mainModule, v) addGoStmt(LoaderState.MainModules.ModFile(mainModule), mainModule, v)
rs = overrideRoots(ctx, rs, []module.Version{{Path: "go", Version: v}}) rs = overrideRoots(ctx, rs, []module.Version{{Path: "go", Version: v}})
// We need to add a 'go' version to the go.mod file, but we must assume // We need to add a 'go' version to the go.mod file, but we must assume
@ -1156,7 +1154,7 @@ func CreateModFile(ctx context.Context, modPath string) {
fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", modPath) fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", modPath)
modFile := new(modfile.File) modFile := new(modfile.File)
modFile.AddModuleStmt(modPath) modFile.AddModuleStmt(modPath)
MainModules = makeMainModules([]module.Version{modFile.Module.Mod}, []string{modRoot}, []*modfile.File{modFile}, []*modFileIndex{nil}, nil) LoaderState.MainModules = makeMainModules([]module.Version{modFile.Module.Mod}, []string{modRoot}, []*modfile.File{modFile}, []*modFileIndex{nil}, nil)
addGoStmt(modFile, modFile.Module.Mod, gover.Local()) // Add the go directive before converted module requirements. addGoStmt(modFile, modFile.Module.Mod, gover.Local()) // Add the go directive before converted module requirements.
rs := requirementsFromModFiles(ctx, nil, []*modfile.File{modFile}, nil) rs := requirementsFromModFiles(ctx, nil, []*modfile.File{modFile}, nil)
@ -1380,8 +1378,8 @@ func requirementsFromModFiles(ctx context.Context, workFile *modfile.WorkFile, m
var pruning modPruning var pruning modPruning
if inWorkspaceMode() { if inWorkspaceMode() {
pruning = workspace pruning = workspace
roots = make([]module.Version, len(MainModules.Versions()), 2+len(MainModules.Versions())) roots = make([]module.Version, len(LoaderState.MainModules.Versions()), 2+len(LoaderState.MainModules.Versions()))
copy(roots, MainModules.Versions()) copy(roots, LoaderState.MainModules.Versions())
goVersion := gover.FromGoWork(workFile) goVersion := gover.FromGoWork(workFile)
var toolchain string var toolchain string
if workFile.Toolchain != nil { if workFile.Toolchain != nil {
@ -1390,12 +1388,12 @@ func requirementsFromModFiles(ctx context.Context, workFile *modfile.WorkFile, m
roots = appendGoAndToolchainRoots(roots, goVersion, toolchain, direct) roots = appendGoAndToolchainRoots(roots, goVersion, toolchain, direct)
direct = directRequirements(modFiles) direct = directRequirements(modFiles)
} else { } else {
pruning = pruningForGoVersion(MainModules.GoVersion()) pruning = pruningForGoVersion(LoaderState.MainModules.GoVersion())
if len(modFiles) != 1 { if len(modFiles) != 1 {
panic(fmt.Errorf("requirementsFromModFiles called with %v modfiles outside workspace mode", len(modFiles))) panic(fmt.Errorf("requirementsFromModFiles called with %v modfiles outside workspace mode", len(modFiles)))
} }
modFile := modFiles[0] modFile := modFiles[0]
roots, direct = rootsFromModFile(MainModules.mustGetSingleMainModule(), modFile, withToolchainRoot) roots, direct = rootsFromModFile(LoaderState.MainModules.mustGetSingleMainModule(), modFile, withToolchainRoot)
} }
gover.ModSort(roots) gover.ModSort(roots)
@ -1430,7 +1428,7 @@ func rootsFromModFile(m module.Version, modFile *modfile.File, addToolchainRoot
} }
roots = make([]module.Version, 0, padding+len(modFile.Require)) roots = make([]module.Version, 0, padding+len(modFile.Require))
for _, r := range modFile.Require { for _, r := range modFile.Require {
if index := MainModules.Index(m); index != nil && index.exclude[r.Mod] { if index := LoaderState.MainModules.Index(m); index != nil && index.exclude[r.Mod] {
if cfg.BuildMod == "mod" { if cfg.BuildMod == "mod" {
fmt.Fprintf(os.Stderr, "go: dropping requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version) fmt.Fprintf(os.Stderr, "go: dropping requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version)
} else { } else {
@ -1522,12 +1520,12 @@ func setDefaultBuildMod() {
var versionSource string var versionSource string
if inWorkspaceMode() { if inWorkspaceMode() {
versionSource = "go.work" versionSource = "go.work"
if wfg := MainModules.WorkFile().Go; wfg != nil { if wfg := LoaderState.MainModules.WorkFile().Go; wfg != nil {
goVersion = wfg.Version goVersion = wfg.Version
} }
} else { } else {
versionSource = "go.mod" versionSource = "go.mod"
index := MainModules.GetSingleIndexOrNil() index := LoaderState.MainModules.GetSingleIndexOrNil()
if index != nil { if index != nil {
goVersion = index.goVersion goVersion = index.goVersion
} }
@ -1812,12 +1810,12 @@ var errNoChange = errors.New("no update needed")
// UpdateGoModFromReqs returns a modified go.mod file using the current // UpdateGoModFromReqs returns a modified go.mod file using the current
// requirements. It does not commit these changes to disk. // requirements. It does not commit these changes to disk.
func UpdateGoModFromReqs(ctx context.Context, opts WriteOpts) (before, after []byte, modFile *modfile.File, err error) { func UpdateGoModFromReqs(ctx context.Context, opts WriteOpts) (before, after []byte, modFile *modfile.File, err error) {
if MainModules.Len() != 1 || MainModules.ModRoot(MainModules.Versions()[0]) == "" { if LoaderState.MainModules.Len() != 1 || LoaderState.MainModules.ModRoot(LoaderState.MainModules.Versions()[0]) == "" {
// We aren't in a module, so we don't have anywhere to write a go.mod file. // We aren't in a module, so we don't have anywhere to write a go.mod file.
return nil, nil, nil, errNoChange return nil, nil, nil, errNoChange
} }
mainModule := MainModules.mustGetSingleMainModule() mainModule := LoaderState.MainModules.mustGetSingleMainModule()
modFile = MainModules.ModFile(mainModule) modFile = LoaderState.MainModules.ModFile(mainModule)
if modFile == nil { if modFile == nil {
// command-line-arguments has no .mod file to write. // command-line-arguments has no .mod file to write.
return nil, nil, nil, errNoChange return nil, nil, nil, errNoChange
@ -1925,7 +1923,7 @@ func commitRequirements(ctx context.Context, opts WriteOpts) (err error) {
return err return err
} }
index := MainModules.GetSingleIndexOrNil() index := LoaderState.MainModules.GetSingleIndexOrNil()
dirty := index.modFileIsDirty(modFile) || len(opts.DropTools) > 0 || len(opts.AddTools) > 0 dirty := index.modFileIsDirty(modFile) || len(opts.DropTools) > 0 || len(opts.AddTools) > 0
if dirty && cfg.BuildMod != "mod" { if dirty && cfg.BuildMod != "mod" {
// If we're about to fail due to -mod=readonly, // If we're about to fail due to -mod=readonly,
@ -1946,8 +1944,8 @@ func commitRequirements(ctx context.Context, opts WriteOpts) (err error) {
return nil return nil
} }
mainModule := MainModules.mustGetSingleMainModule() mainModule := LoaderState.MainModules.mustGetSingleMainModule()
modFilePath := modFilePath(MainModules.ModRoot(mainModule)) modFilePath := modFilePath(LoaderState.MainModules.ModRoot(mainModule))
if fsys.Replaced(modFilePath) { if fsys.Replaced(modFilePath) {
if dirty { if dirty {
return errors.New("updates to go.mod needed, but go.mod is part of the overlay specified with -overlay") return errors.New("updates to go.mod needed, but go.mod is part of the overlay specified with -overlay")
@ -1956,7 +1954,7 @@ func commitRequirements(ctx context.Context, opts WriteOpts) (err error) {
} }
defer func() { defer func() {
// At this point we have determined to make the go.mod file on disk equal to new. // At this point we have determined to make the go.mod file on disk equal to new.
MainModules.SetIndex(mainModule, indexModFile(updatedGoMod, modFile, mainModule, false)) LoaderState.MainModules.SetIndex(mainModule, indexModFile(updatedGoMod, modFile, mainModule, false))
// Update go.sum after releasing the side lock and refreshing the index. // Update go.sum after releasing the side lock and refreshing the index.
// 'go mod init' shouldn't write go.sum, since it will be incomplete. // 'go mod init' shouldn't write go.sum, since it will be incomplete.
@ -2018,7 +2016,7 @@ func keepSums(ctx context.Context, ld *loader, rs *Requirements, which whichSums
// ambiguous import errors the next time we load the package. // ambiguous import errors the next time we load the package.
keepModSumsForZipSums := true keepModSumsForZipSums := true
if ld == nil { if ld == nil {
if gover.Compare(MainModules.GoVersion(), gover.TidyGoModSumVersion) < 0 && cfg.BuildMod != "mod" { if gover.Compare(LoaderState.MainModules.GoVersion(), gover.TidyGoModSumVersion) < 0 && cfg.BuildMod != "mod" {
keepModSumsForZipSums = false keepModSumsForZipSums = false
} }
} else { } else {

View file

@ -126,7 +126,7 @@ func ListModules(ctx context.Context, args []string, mode ListMode, reuseFile st
func listModules(ctx context.Context, rs *Requirements, args []string, mode ListMode, reuse map[module.Version]*modinfo.ModulePublic) (_ *Requirements, mods []*modinfo.ModulePublic, mgErr error) { func listModules(ctx context.Context, rs *Requirements, args []string, mode ListMode, reuse map[module.Version]*modinfo.ModulePublic) (_ *Requirements, mods []*modinfo.ModulePublic, mgErr error) {
if len(args) == 0 { if len(args) == 0 {
var ms []*modinfo.ModulePublic var ms []*modinfo.ModulePublic
for _, m := range MainModules.Versions() { for _, m := range LoaderState.MainModules.Versions() {
if gover.IsToolchain(m.Path) { if gover.IsToolchain(m.Path) {
continue continue
} }

View file

@ -273,7 +273,7 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
if m.Dirs == nil { if m.Dirs == nil {
matchModRoots := LoaderState.modRoots matchModRoots := LoaderState.modRoots
if opts.MainModule != (module.Version{}) { if opts.MainModule != (module.Version{}) {
matchModRoots = []string{MainModules.ModRoot(opts.MainModule)} matchModRoots = []string{LoaderState.MainModules.ModRoot(opts.MainModule)}
} }
matchLocalDirs(ctx, matchModRoots, m, rs) matchLocalDirs(ctx, matchModRoots, m, rs)
} }
@ -324,7 +324,7 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
matchPackages(ctx, m, opts.Tags, includeStd, mg.BuildList()) matchPackages(ctx, m, opts.Tags, includeStd, mg.BuildList())
case m.Pattern() == "work": case m.Pattern() == "work":
matchModules := MainModules.Versions() matchModules := LoaderState.MainModules.Versions()
if opts.MainModule != (module.Version{}) { if opts.MainModule != (module.Version{}) {
matchModules = []module.Version{opts.MainModule} matchModules = []module.Version{opts.MainModule}
} }
@ -335,12 +335,12 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
// The initial roots are the packages and tools in the main module. // The initial roots are the packages and tools in the main module.
// loadFromRoots will expand that to "all". // loadFromRoots will expand that to "all".
m.Errs = m.Errs[:0] m.Errs = m.Errs[:0]
matchModules := MainModules.Versions() matchModules := LoaderState.MainModules.Versions()
if opts.MainModule != (module.Version{}) { if opts.MainModule != (module.Version{}) {
matchModules = []module.Version{opts.MainModule} matchModules = []module.Version{opts.MainModule}
} }
matchPackages(ctx, m, opts.Tags, omitStd, matchModules) matchPackages(ctx, m, opts.Tags, omitStd, matchModules)
for tool := range MainModules.Tools() { for tool := range LoaderState.MainModules.Tools() {
m.Pkgs = append(m.Pkgs, tool) m.Pkgs = append(m.Pkgs, tool)
} }
} else { } else {
@ -355,7 +355,7 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
} }
case m.Pattern() == "tool": case m.Pattern() == "tool":
for tool := range MainModules.Tools() { for tool := range LoaderState.MainModules.Tools() {
m.Pkgs = append(m.Pkgs, tool) m.Pkgs = append(m.Pkgs, tool)
} }
default: default:
@ -596,13 +596,13 @@ func resolveLocalPackage(ctx context.Context, dir string, rs *Requirements) (str
} }
} }
for _, mod := range MainModules.Versions() { for _, mod := range LoaderState.MainModules.Versions() {
modRoot := MainModules.ModRoot(mod) modRoot := LoaderState.MainModules.ModRoot(mod)
if modRoot != "" && absDir == modRoot { if modRoot != "" && absDir == modRoot {
if absDir == cfg.GOROOTsrc { if absDir == cfg.GOROOTsrc {
return "", errPkgIsGorootSrc return "", errPkgIsGorootSrc
} }
return MainModules.PathPrefix(mod), nil return LoaderState.MainModules.PathPrefix(mod), nil
} }
} }
@ -611,8 +611,8 @@ func resolveLocalPackage(ctx context.Context, dir string, rs *Requirements) (str
// It's not strictly necessary but helpful to keep the checks. // It's not strictly necessary but helpful to keep the checks.
var pkgNotFoundErr error var pkgNotFoundErr error
pkgNotFoundLongestPrefix := "" pkgNotFoundLongestPrefix := ""
for _, mainModule := range MainModules.Versions() { for _, mainModule := range LoaderState.MainModules.Versions() {
modRoot := MainModules.ModRoot(mainModule) modRoot := LoaderState.MainModules.ModRoot(mainModule)
if modRoot != "" && str.HasFilePathPrefix(absDir, modRoot) && !strings.Contains(absDir[len(modRoot):], "@") { if modRoot != "" && str.HasFilePathPrefix(absDir, modRoot) && !strings.Contains(absDir[len(modRoot):], "@") {
suffix := filepath.ToSlash(str.TrimFilePathPrefix(absDir, modRoot)) suffix := filepath.ToSlash(str.TrimFilePathPrefix(absDir, modRoot))
if pkg, found := strings.CutPrefix(suffix, "vendor/"); found { if pkg, found := strings.CutPrefix(suffix, "vendor/"); found {
@ -627,7 +627,7 @@ func resolveLocalPackage(ctx context.Context, dir string, rs *Requirements) (str
return pkg, nil return pkg, nil
} }
mainModulePrefix := MainModules.PathPrefix(mainModule) mainModulePrefix := LoaderState.MainModules.PathPrefix(mainModule)
if mainModulePrefix == "" { if mainModulePrefix == "" {
pkg := suffix pkg := suffix
if pkg == "builtin" { if pkg == "builtin" {
@ -820,7 +820,7 @@ func (mms *MainModuleSet) DirImportPath(ctx context.Context, dir string) (path s
return mms.PathPrefix(v), v return mms.PathPrefix(v), v
} }
if str.HasFilePathPrefix(dir, modRoot) { if str.HasFilePathPrefix(dir, modRoot) {
pathPrefix := MainModules.PathPrefix(v) pathPrefix := LoaderState.MainModules.PathPrefix(v)
if pathPrefix > longestPrefix { if pathPrefix > longestPrefix {
longestPrefix = pathPrefix longestPrefix = pathPrefix
longestPrefixVersion = v longestPrefixVersion = v
@ -1068,7 +1068,7 @@ func (pkg *loadPkg) fromExternalModule() bool {
if pkg.mod.Path == "" { if pkg.mod.Path == "" {
return false // loaded from the standard library, not a module return false // loaded from the standard library, not a module
} }
return !MainModules.Contains(pkg.mod.Path) return !LoaderState.MainModules.Contains(pkg.mod.Path)
} }
var errMissing = errors.New("cannot find package") var errMissing = errors.New("cannot find package")
@ -1390,7 +1390,7 @@ func (ld *loader) updateRequirements(ctx context.Context) (changed bool, err err
} }
} }
} }
if pkg.mod.Version != "" || !MainModules.Contains(pkg.mod.Path) { if pkg.mod.Version != "" || !LoaderState.MainModules.Contains(pkg.mod.Path) {
continue continue
} }
@ -1587,7 +1587,7 @@ func (ld *loader) resolveMissingImports(ctx context.Context) (modAddedBy map[mod
var ime *ImportMissingError var ime *ImportMissingError
if errors.As(err, &ime) { if errors.As(err, &ime) {
for curstack := pkg.stack; curstack != nil; curstack = curstack.stack { for curstack := pkg.stack; curstack != nil; curstack = curstack.stack {
if MainModules.Contains(curstack.mod.Path) { if LoaderState.MainModules.Contains(curstack.mod.Path) {
ime.ImportingMainModule = curstack.mod ime.ImportingMainModule = curstack.mod
break break
} }
@ -1709,7 +1709,7 @@ func (ld *loader) applyPkgFlags(ctx context.Context, pkg *loadPkg, flags loadPkg
// so it's ok if we call it more than is strictly necessary. // so it's ok if we call it more than is strictly necessary.
wantTest := false wantTest := false
switch { switch {
case ld.allPatternIsRoot && MainModules.Contains(pkg.mod.Path): case ld.allPatternIsRoot && LoaderState.MainModules.Contains(pkg.mod.Path):
// We are loading the "all" pattern, which includes packages imported by // We are loading the "all" pattern, which includes packages imported by
// tests in the main module. This package is in the main module, so we // tests in the main module. This package is in the main module, so we
// need to identify the imports of its test even if LoadTests is not set. // need to identify the imports of its test even if LoadTests is not set.
@ -1730,7 +1730,7 @@ func (ld *loader) applyPkgFlags(ctx context.Context, pkg *loadPkg, flags loadPkg
if wantTest { if wantTest {
var testFlags loadPkgFlags var testFlags loadPkgFlags
if MainModules.Contains(pkg.mod.Path) || (ld.allClosesOverTests && new.has(pkgInAll)) { if LoaderState.MainModules.Contains(pkg.mod.Path) || (ld.allClosesOverTests && new.has(pkgInAll)) {
// Tests of packages in the main module are in "all", in the sense that // Tests of packages in the main module are in "all", in the sense that
// they cause the packages they import to also be in "all". So are tests // they cause the packages they import to also be in "all". So are tests
// of packages in "all" if "all" closes over test dependencies. // of packages in "all" if "all" closes over test dependencies.
@ -1858,7 +1858,7 @@ func (ld *loader) load(ctx context.Context, pkg *loadPkg) {
var modroot string var modroot string
pkg.mod, modroot, pkg.dir, pkg.altMods, pkg.err = importFromModules(ctx, pkg.path, ld.requirements, mg, ld.skipImportModFiles) pkg.mod, modroot, pkg.dir, pkg.altMods, pkg.err = importFromModules(ctx, pkg.path, ld.requirements, mg, ld.skipImportModFiles)
if MainModules.Tools()[pkg.path] { if LoaderState.MainModules.Tools()[pkg.path] {
// Tools declared by main modules are always in "all". // Tools declared by main modules are always in "all".
// We apply the package flags before returning so that missing // We apply the package flags before returning so that missing
// tool dependencies report an error https://go.dev/issue/70582 // tool dependencies report an error https://go.dev/issue/70582
@ -1867,7 +1867,7 @@ func (ld *loader) load(ctx context.Context, pkg *loadPkg) {
if pkg.dir == "" { if pkg.dir == "" {
return return
} }
if MainModules.Contains(pkg.mod.Path) { if LoaderState.MainModules.Contains(pkg.mod.Path) {
// Go ahead and mark pkg as in "all". This provides the invariant that a // Go ahead and mark pkg as in "all". This provides the invariant that a
// package that is *only* imported by other packages in "all" is always // package that is *only* imported by other packages in "all" is always
// marked as such before loading its imports. // marked as such before loading its imports.
@ -1975,14 +1975,14 @@ func (ld *loader) stdVendor(parentPath, path string) string {
} }
if str.HasPathPrefix(parentPath, "cmd") { if str.HasPathPrefix(parentPath, "cmd") {
if !ld.VendorModulesInGOROOTSrc || !MainModules.Contains("cmd") { if !ld.VendorModulesInGOROOTSrc || !LoaderState.MainModules.Contains("cmd") {
vendorPath := pathpkg.Join("cmd", "vendor", path) vendorPath := pathpkg.Join("cmd", "vendor", path)
if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil { if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil {
return vendorPath return vendorPath
} }
} }
} else if !ld.VendorModulesInGOROOTSrc || !MainModules.Contains("std") || str.HasPathPrefix(parentPath, "vendor") { } else if !ld.VendorModulesInGOROOTSrc || !LoaderState.MainModules.Contains("std") || str.HasPathPrefix(parentPath, "vendor") {
// If we are outside of the 'std' module, resolve imports from within 'std' // If we are outside of the 'std' module, resolve imports from within 'std'
// to the vendor directory. // to the vendor directory.
// //
@ -2067,7 +2067,7 @@ func (ld *loader) checkTidyCompatibility(ctx context.Context, rs *Requirements,
fmt.Fprintln(os.Stderr) fmt.Fprintln(os.Stderr)
goFlag := "" goFlag := ""
if goVersion != MainModules.GoVersion() { if goVersion != LoaderState.MainModules.GoVersion() {
goFlag = " -go=" + goVersion goFlag = " -go=" + goVersion
} }

View file

@ -156,8 +156,8 @@ var ErrDisallowed = errors.New("disallowed module version")
// CheckExclusions returns an error equivalent to ErrDisallowed if module m is // CheckExclusions returns an error equivalent to ErrDisallowed if module m is
// excluded by the main module's go.mod file. // excluded by the main module's go.mod file.
func CheckExclusions(ctx context.Context, m module.Version) error { func CheckExclusions(ctx context.Context, m module.Version) error {
for _, mainModule := range MainModules.Versions() { for _, mainModule := range LoaderState.MainModules.Versions() {
if index := MainModules.Index(mainModule); index != nil && index.exclude[m] { if index := LoaderState.MainModules.Index(mainModule); index != nil && index.exclude[m] {
return module.VersionError(m, errExcluded) return module.VersionError(m, errExcluded)
} }
} }
@ -349,19 +349,19 @@ func Replacement(mod module.Version) module.Version {
// and the source of the replacement. The replacement is relative to the go.work or go.mod file it appears in. // and the source of the replacement. The replacement is relative to the go.work or go.mod file it appears in.
func replacementFrom(mod module.Version) (r module.Version, modroot string, fromFile string) { func replacementFrom(mod module.Version) (r module.Version, modroot string, fromFile string) {
foundFrom, found, foundModRoot := "", module.Version{}, "" foundFrom, found, foundModRoot := "", module.Version{}, ""
if MainModules == nil { if LoaderState.MainModules == nil {
return module.Version{}, "", "" return module.Version{}, "", ""
} else if MainModules.Contains(mod.Path) && mod.Version == "" { } else if LoaderState.MainModules.Contains(mod.Path) && mod.Version == "" {
// Don't replace the workspace version of the main module. // Don't replace the workspace version of the main module.
return module.Version{}, "", "" return module.Version{}, "", ""
} }
if _, r, ok := replacement(mod, MainModules.WorkFileReplaceMap()); ok { if _, r, ok := replacement(mod, LoaderState.MainModules.WorkFileReplaceMap()); ok {
return r, "", workFilePath return r, "", workFilePath
} }
for _, v := range MainModules.Versions() { for _, v := range LoaderState.MainModules.Versions() {
if index := MainModules.Index(v); index != nil { if index := LoaderState.MainModules.Index(v); index != nil {
if from, r, ok := replacement(mod, index.replace); ok { if from, r, ok := replacement(mod, index.replace); ok {
modRoot := MainModules.ModRoot(v) modRoot := LoaderState.MainModules.ModRoot(v)
if foundModRoot != "" && foundFrom != from && found != r { if foundModRoot != "" && foundFrom != from && found != r {
base.Errorf("conflicting replacements found for %v in workspace modules defined by %v and %v", base.Errorf("conflicting replacements found for %v in workspace modules defined by %v and %v",
mod, modFilePath(foundModRoot), modFilePath(modRoot)) mod, modFilePath(foundModRoot), modFilePath(modRoot))
@ -378,7 +378,7 @@ func replaceRelativeTo() string {
if workFilePath := WorkFilePath(); workFilePath != "" { if workFilePath := WorkFilePath(); workFilePath != "" {
return filepath.Dir(workFilePath) return filepath.Dir(workFilePath)
} }
return MainModules.ModRoot(MainModules.mustGetSingleMainModule()) return LoaderState.MainModules.ModRoot(LoaderState.MainModules.mustGetSingleMainModule())
} }
// canonicalizeReplacePath ensures that relative, on-disk, replaced module paths // canonicalizeReplacePath ensures that relative, on-disk, replaced module paths
@ -572,7 +572,7 @@ type retraction struct {
// //
// The caller must not modify the returned summary. // The caller must not modify the returned summary.
func goModSummary(m module.Version) (*modFileSummary, error) { func goModSummary(m module.Version) (*modFileSummary, error) {
if m.Version == "" && !inWorkspaceMode() && MainModules.Contains(m.Path) { if m.Version == "" && !inWorkspaceMode() && LoaderState.MainModules.Contains(m.Path) {
panic("internal error: goModSummary called on a main module") panic("internal error: goModSummary called on a main module")
} }
if gover.IsToolchain(m.Path) { if gover.IsToolchain(m.Path) {
@ -639,8 +639,8 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
} }
} }
for _, mainModule := range MainModules.Versions() { for _, mainModule := range LoaderState.MainModules.Versions() {
if index := MainModules.Index(mainModule); index != nil && len(index.exclude) > 0 { if index := LoaderState.MainModules.Index(mainModule); index != nil && len(index.exclude) > 0 {
// Drop any requirements on excluded versions. // Drop any requirements on excluded versions.
// Don't modify the cached summary though, since we might need the raw // Don't modify the cached summary though, since we might need the raw
// summary separately. // summary separately.
@ -684,7 +684,7 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
} }
return &modFileSummary{module: m}, nil return &modFileSummary{module: m}, nil
} }
if m.Version == "" && !inWorkspaceMode() && MainModules.Contains(m.Path) { if m.Version == "" && !inWorkspaceMode() && LoaderState.MainModules.Contains(m.Path) {
// Calling rawGoModSummary implies that we are treating m as a module whose // Calling rawGoModSummary implies that we are treating m as a module whose
// requirements aren't the roots of the module graph and can't be modified. // requirements aren't the roots of the module graph and can't be modified.
// //
@ -697,13 +697,13 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
// If there are no modules in the workspace, we synthesize an empty // If there are no modules in the workspace, we synthesize an empty
// command-line-arguments module, which rawGoModData cannot read a go.mod for. // command-line-arguments module, which rawGoModData cannot read a go.mod for.
return &modFileSummary{module: m}, nil return &modFileSummary{module: m}, nil
} else if m.Version == "" && inWorkspaceMode() && MainModules.Contains(m.Path) { } else if m.Version == "" && inWorkspaceMode() && LoaderState.MainModules.Contains(m.Path) {
// When go get uses EnterWorkspace to check that the workspace loads properly, // When go get uses EnterWorkspace to check that the workspace loads properly,
// it will update the contents of the workspace module's modfile in memory. To use the updated // it will update the contents of the workspace module's modfile in memory. To use the updated
// contents of the modfile when doing the load, don't read from disk and instead // contents of the modfile when doing the load, don't read from disk and instead
// recompute a summary using the updated contents of the modfile. // recompute a summary using the updated contents of the modfile.
if mf := MainModules.ModFile(m); mf != nil { if mf := LoaderState.MainModules.ModFile(m); mf != nil {
return summaryFromModFile(m, MainModules.modFiles[m]) return summaryFromModFile(m, LoaderState.MainModules.modFiles[m])
} }
} }
return rawGoModSummaryCache.Do(m, func() (*modFileSummary, error) { return rawGoModSummaryCache.Do(m, func() (*modFileSummary, error) {
@ -783,8 +783,8 @@ func rawGoModData(m module.Version) (name string, data []byte, err error) {
if m.Version == "" { if m.Version == "" {
dir := m.Path dir := m.Path
if !filepath.IsAbs(dir) { if !filepath.IsAbs(dir) {
if inWorkspaceMode() && MainModules.Contains(m.Path) { if inWorkspaceMode() && LoaderState.MainModules.Contains(m.Path) {
dir = MainModules.ModRoot(m) dir = LoaderState.MainModules.ModRoot(m)
} else { } else {
// m is a replacement module with only a file path. // m is a replacement module with only a file path.
dir = filepath.Join(replaceRelativeTo(), dir) dir = filepath.Join(replaceRelativeTo(), dir)

View file

@ -43,7 +43,7 @@ type mvsReqs struct {
} }
func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) { func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
if mod.Version == "" && MainModules.Contains(mod.Path) { if mod.Version == "" && LoaderState.MainModules.Contains(mod.Path) {
// Use the build list as it existed when r was constructed, not the current // Use the build list as it existed when r was constructed, not the current
// global build list. // global build list.
return r.roots, nil return r.roots, nil
@ -112,7 +112,7 @@ func versions(ctx context.Context, path string, allowed AllowedFunc) (versions [
// Since the version of a main module is not found in the version list, // Since the version of a main module is not found in the version list,
// it has no previous version. // it has no previous version.
func previousVersion(ctx context.Context, m module.Version) (module.Version, error) { func previousVersion(ctx context.Context, m module.Version) (module.Version, error) {
if m.Version == "" && MainModules.Contains(m.Path) { if m.Version == "" && LoaderState.MainModules.Contains(m.Path) {
return module.Version{Path: m.Path, Version: "none"}, nil return module.Version{Path: m.Path, Version: "none"}, nil
} }

View file

@ -211,7 +211,7 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
allowed = func(context.Context, module.Version) error { return nil } allowed = func(context.Context, module.Version) error { return nil }
} }
if MainModules.Contains(path) && (query == "upgrade" || query == "patch") { if LoaderState.MainModules.Contains(path) && (query == "upgrade" || query == "patch") {
m := module.Version{Path: path} m := module.Version{Path: path}
if err := allowed(ctx, m); err != nil { if err := allowed(ctx, m); err != nil {
return nil, fmt.Errorf("internal error: main module version is not allowed: %w", err) return nil, fmt.Errorf("internal error: main module version is not allowed: %w", err)
@ -700,8 +700,8 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
match = func(mod module.Version, roots []string, isLocal bool) *search.Match { match = func(mod module.Version, roots []string, isLocal bool) *search.Match {
m := search.NewMatch(pattern) m := search.NewMatch(pattern)
prefix := mod.Path prefix := mod.Path
if MainModules.Contains(mod.Path) { if LoaderState.MainModules.Contains(mod.Path) {
prefix = MainModules.PathPrefix(module.Version{Path: mod.Path}) prefix = LoaderState.MainModules.PathPrefix(module.Version{Path: mod.Path})
} }
for _, root := range roots { for _, root := range roots {
if _, ok, err := dirInModule(pattern, prefix, root, isLocal); err != nil { if _, ok, err := dirInModule(pattern, prefix, root, isLocal); err != nil {
@ -715,7 +715,7 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
} }
var mainModuleMatches []module.Version var mainModuleMatches []module.Version
for _, mainModule := range MainModules.Versions() { for _, mainModule := range LoaderState.MainModules.Versions() {
m := match(mainModule, LoaderState.modRoots, true) m := match(mainModule, LoaderState.modRoots, true)
if len(m.Pkgs) > 0 { if len(m.Pkgs) > 0 {
if query != "upgrade" && query != "patch" { if query != "upgrade" && query != "patch" {
@ -842,7 +842,7 @@ func modulePrefixesExcludingTarget(path string) []string {
prefixes := make([]string, 0, strings.Count(path, "/")+1) prefixes := make([]string, 0, strings.Count(path, "/")+1)
mainModulePrefixes := make(map[string]bool) mainModulePrefixes := make(map[string]bool)
for _, m := range MainModules.Versions() { for _, m := range LoaderState.MainModules.Versions() {
mainModulePrefixes[m.Path] = true mainModulePrefixes[m.Path] = true
} }
@ -905,7 +905,7 @@ func queryPrefixModules(ctx context.Context, candidateModules []string, queryMod
case *PackageNotInModuleError: case *PackageNotInModuleError:
// Given the option, prefer to attribute “package not in module” // Given the option, prefer to attribute “package not in module”
// to modules other than the main one. // to modules other than the main one.
if noPackage == nil || MainModules.Contains(noPackage.Mod.Path) { if noPackage == nil || LoaderState.MainModules.Contains(noPackage.Mod.Path) {
noPackage = rErr noPackage = rErr
} }
case *NoMatchingVersionError: case *NoMatchingVersionError:
@ -1127,9 +1127,9 @@ func lookupRepo(ctx context.Context, proxy, path string) (repo versionRepo, err
repo = emptyRepo{path: path, err: err} repo = emptyRepo{path: path, err: err}
} }
if MainModules == nil { if LoaderState.MainModules == nil {
return repo, err return repo, err
} else if _, ok := MainModules.HighestReplaced()[path]; ok { } else if _, ok := LoaderState.MainModules.HighestReplaced()[path]; ok {
return &replacementRepo{repo: repo}, nil return &replacementRepo{repo: repo}, nil
} }
@ -1186,8 +1186,8 @@ func (rr *replacementRepo) Versions(ctx context.Context, prefix string) (*modfet
} }
versions := repoVersions.List versions := repoVersions.List
for _, mm := range MainModules.Versions() { for _, mm := range LoaderState.MainModules.Versions() {
if index := MainModules.Index(mm); index != nil && len(index.replace) > 0 { if index := LoaderState.MainModules.Index(mm); index != nil && len(index.replace) > 0 {
path := rr.ModulePath() path := rr.ModulePath()
for m := range index.replace { for m := range index.replace {
if m.Path == path && strings.HasPrefix(m.Version, prefix) && m.Version != "" && !module.IsPseudoVersion(m.Version) { if m.Path == path && strings.HasPrefix(m.Version, prefix) && m.Version != "" && !module.IsPseudoVersion(m.Version) {
@ -1215,8 +1215,8 @@ func (rr *replacementRepo) Stat(ctx context.Context, rev string) (*modfetch.RevI
return info, err return info, err
} }
var hasReplacements bool var hasReplacements bool
for _, v := range MainModules.Versions() { for _, v := range LoaderState.MainModules.Versions() {
if index := MainModules.Index(v); index != nil && len(index.replace) > 0 { if index := LoaderState.MainModules.Index(v); index != nil && len(index.replace) > 0 {
hasReplacements = true hasReplacements = true
} }
} }
@ -1249,7 +1249,7 @@ func (rr *replacementRepo) Latest(ctx context.Context) (*modfetch.RevInfo, error
info, err := rr.repo.Latest(ctx) info, err := rr.repo.Latest(ctx)
path := rr.ModulePath() path := rr.ModulePath()
if v, ok := MainModules.HighestReplaced()[path]; ok { if v, ok := LoaderState.MainModules.HighestReplaced()[path]; ok {
if v == "" { if v == "" {
// The only replacement is a wildcard that doesn't specify a version, so // The only replacement is a wildcard that doesn't specify a version, so
// synthesize a pseudo-version with an appropriate major version and a // synthesize a pseudo-version with an appropriate major version and a
@ -1290,7 +1290,7 @@ type QueryMatchesMainModulesError struct {
} }
func (e *QueryMatchesMainModulesError) Error() string { func (e *QueryMatchesMainModulesError) Error() string {
if MainModules.Contains(e.Pattern) { if LoaderState.MainModules.Contains(e.Pattern) {
return fmt.Sprintf("can't request version %q of the main module (%s)", e.Query, e.Pattern) return fmt.Sprintf("can't request version %q of the main module (%s)", e.Query, e.Pattern)
} }

View file

@ -171,9 +171,9 @@ func matchPackages(ctx context.Context, m *search.Match, tags map[string]bool, f
} }
if cfg.BuildMod == "vendor" { if cfg.BuildMod == "vendor" {
for _, mod := range MainModules.Versions() { for _, mod := range LoaderState.MainModules.Versions() {
if modRoot := MainModules.ModRoot(mod); modRoot != "" { if modRoot := LoaderState.MainModules.ModRoot(mod); modRoot != "" {
walkPkgs(modRoot, MainModules.PathPrefix(mod), pruneGoMod|pruneVendor) walkPkgs(modRoot, LoaderState.MainModules.PathPrefix(mod), pruneGoMod|pruneVendor)
} }
} }
if HasModRoot() { if HasModRoot() {
@ -191,12 +191,12 @@ func matchPackages(ctx context.Context, m *search.Match, tags map[string]bool, f
root, modPrefix string root, modPrefix string
isLocal bool isLocal bool
) )
if MainModules.Contains(mod.Path) { if LoaderState.MainModules.Contains(mod.Path) {
if MainModules.ModRoot(mod) == "" { if LoaderState.MainModules.ModRoot(mod) == "" {
continue // If there is no main module, we can't search in it. continue // If there is no main module, we can't search in it.
} }
root = MainModules.ModRoot(mod) root = LoaderState.MainModules.ModRoot(mod)
modPrefix = MainModules.PathPrefix(mod) modPrefix = LoaderState.MainModules.PathPrefix(mod)
isLocal = true isLocal = true
} else { } else {
var err error var err error
@ -330,12 +330,12 @@ func parseIgnorePatterns(ctx context.Context, treeCanMatch func(string) bool, mo
} }
var modRoot string var modRoot string
var ignorePatterns []string var ignorePatterns []string
if MainModules.Contains(mod.Path) { if LoaderState.MainModules.Contains(mod.Path) {
modRoot = MainModules.ModRoot(mod) modRoot = LoaderState.MainModules.ModRoot(mod)
if modRoot == "" { if modRoot == "" {
continue continue
} }
modIndex := MainModules.Index(mod) modIndex := LoaderState.MainModules.Index(mod)
if modIndex == nil { if modIndex == nil {
continue continue
} }

View file

@ -236,8 +236,8 @@ func checkVendorConsistency(indexes []*modFileIndex, modFiles []*modfile.File, m
for _, modFile := range modFiles { for _, modFile := range modFiles {
checkReplace(modFile.Replace) checkReplace(modFile.Replace)
} }
if MainModules.workFile != nil { if LoaderState.MainModules.workFile != nil {
checkReplace(MainModules.workFile.Replace) checkReplace(LoaderState.MainModules.workFile.Replace)
} }
for _, mod := range vendorList { for _, mod := range vendorList {

View file

@ -730,7 +730,7 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
// the module cache (or permanently alter the behavior of std tests for all // the module cache (or permanently alter the behavior of std tests for all
// users) by writing the failing input to the package's testdata directory. // users) by writing the failing input to the package's testdata directory.
// (See https://golang.org/issue/48495 and test_fuzz_modcache.txt.) // (See https://golang.org/issue/48495 and test_fuzz_modcache.txt.)
mainMods := modload.MainModules mainMods := modload.LoaderState.MainModules
if m := pkgs[0].Module; m != nil && m.Path != "" { if m := pkgs[0].Module; m != nil && m.Path != "" {
if !mainMods.Contains(m.Path) { if !mainMods.Contains(m.Path) {
base.Fatalf("cannot use -fuzz flag on package outside the main module") base.Fatalf("cannot use -fuzz flag on package outside the main module")

View file

@ -163,7 +163,7 @@ func listTools(ctx context.Context) {
modload.InitWorkfile() modload.InitWorkfile()
modload.LoadModFile(ctx) modload.LoadModFile(ctx)
modTools := slices.Sorted(maps.Keys(modload.MainModules.Tools())) modTools := slices.Sorted(maps.Keys(modload.LoaderState.MainModules.Tools()))
for _, tool := range modTools { for _, tool := range modTools {
fmt.Println(tool) fmt.Println(tool)
} }
@ -256,7 +256,7 @@ func loadModTool(ctx context.Context, name string) string {
modload.LoadModFile(ctx) modload.LoadModFile(ctx)
matches := []string{} matches := []string{}
for tool := range modload.MainModules.Tools() { for tool := range modload.LoaderState.MainModules.Tools() {
if tool == name || defaultExecName(tool) == name { if tool == name || defaultExecName(tool) == name {
matches = append(matches, tool) matches = append(matches, tool)
} }

View file

@ -60,7 +60,7 @@ func runSync(ctx context.Context, cmd *base.Command, args []string) {
} }
mustSelectFor := map[module.Version][]module.Version{} mustSelectFor := map[module.Version][]module.Version{}
mms := modload.MainModules mms := modload.LoaderState.MainModules
opts := modload.PackageOpts{ opts := modload.PackageOpts{
Tags: imports.AnyTags(), Tags: imports.AnyTags(),
@ -131,7 +131,7 @@ func runSync(ctx context.Context, cmd *base.Command, args []string) {
}, "all") }, "all")
modload.WriteGoMod(ctx, modload.WriteOpts{}) modload.WriteGoMod(ctx, modload.WriteOpts{})
} }
goV = gover.Max(goV, modload.MainModules.GoVersion()) goV = gover.Max(goV, modload.LoaderState.MainModules.GoVersion())
} }
wf, err := modload.ReadWorkFile(workFilePath) wf, err := modload.ReadWorkFile(workFilePath)