]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: use local state object in pkg `modcmd`
authorIan Alexander <jitsu@google.com>
Thu, 9 Oct 2025 00:03:54 +0000 (20:03 -0400)
committerIan Alexander <jitsu@google.com>
Sat, 25 Oct 2025 01:08:51 +0000 (18:08 -0700)
This commit modifies `modcmd.runDownload` to construct a new
modload.State object using the new constructor instead of the current
global `modload.LoaderState` variable.

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

[git-generate]
cd src/cmd/go/internal/modcmd
rf '
  add download.go:/func runDownload\(/-0 var moduleLoaderState *modload.State
  ex {
    import "cmd/go/internal/modload";
    modload.LoaderState -> moduleLoaderState
  }
  add runDownload://+0 moduleLoaderState := modload.NewState()
  add runEdit://+0 moduleLoaderState := modload.NewState()
  add runGraph://+0 moduleLoaderState := modload.NewState()
  add runInit://+0 moduleLoaderState := modload.NewState()
  add runTidy://+0 moduleLoaderState := modload.NewState()
  add runVendor://+0 moduleLoaderState := modload.NewState()
  add runVerify://+0 moduleLoaderState := modload.NewState()
  add runWhy://+0 moduleLoaderState := modload.NewState()
  rm download.go:/var moduleLoaderState \*modload.State/
'

Change-Id: Id69deba173032a4d6da228eae28e38bd87176db5
Reviewed-on: https://go-review.googlesource.com/c/go/+/711125
Reviewed-by: Michael Matloob <matloob@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/go/internal/modcmd/download.go
src/cmd/go/internal/modcmd/edit.go
src/cmd/go/internal/modcmd/graph.go
src/cmd/go/internal/modcmd/init.go
src/cmd/go/internal/modcmd/tidy.go
src/cmd/go/internal/modcmd/vendor.go
src/cmd/go/internal/modcmd/verify.go
src/cmd/go/internal/modcmd/why.go

index 1b2f850d1b483690d0e7c638c25f54bfe8d74113..7544e221d58f810ddcbbe5f14a5ccef1a46f8a5a 100644 (file)
@@ -109,18 +109,19 @@ type ModuleJSON struct {
 }
 
 func runDownload(ctx context.Context, cmd *base.Command, args []string) {
-       modload.InitWorkfile(modload.LoaderState)
+       moduleLoaderState := modload.NewState()
+       modload.InitWorkfile(moduleLoaderState)
 
        // Check whether modules are enabled and whether we're in a module.
-       modload.LoaderState.ForceUseModules = true
+       moduleLoaderState.ForceUseModules = true
        modload.ExplicitWriteGoMod = true
        haveExplicitArgs := len(args) > 0
 
-       if modload.HasModRoot(modload.LoaderState) || modload.WorkFilePath(modload.LoaderState) != "" {
-               modload.LoadModFile(modload.LoaderState, ctx) // to fill MainModules
+       if modload.HasModRoot(moduleLoaderState) || modload.WorkFilePath(moduleLoaderState) != "" {
+               modload.LoadModFile(moduleLoaderState, ctx) // to fill MainModules
 
                if haveExplicitArgs {
-                       for _, mainModule := range modload.LoaderState.MainModules.Versions() {
+                       for _, mainModule := range moduleLoaderState.MainModules.Versions() {
                                targetAtUpgrade := mainModule.Path + "@upgrade"
                                targetAtPatch := mainModule.Path + "@patch"
                                for _, arg := range args {
@@ -130,14 +131,14 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
                                        }
                                }
                        }
-               } else if modload.WorkFilePath(modload.LoaderState) != "" {
+               } else if modload.WorkFilePath(moduleLoaderState) != "" {
                        // TODO(#44435): Think about what the correct query is to download the
                        // right set of modules. Also see code review comment at
                        // https://go-review.googlesource.com/c/go/+/359794/comments/ce946a80_6cf53992.
                        args = []string{"all"}
                } else {
-                       mainModule := modload.LoaderState.MainModules.Versions()[0]
-                       modFile := modload.LoaderState.MainModules.ModFile(mainModule)
+                       mainModule := moduleLoaderState.MainModules.Versions()[0]
+                       modFile := moduleLoaderState.MainModules.ModFile(mainModule)
                        if modFile.Go == nil || gover.Compare(modFile.Go.Version, gover.ExplicitIndirectVersion) < 0 {
                                if len(modFile.Require) > 0 {
                                        args = []string{"all"}
@@ -153,12 +154,12 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
                                // However, we also need to load the full module graph, to ensure that
                                // we have downloaded enough of the module graph to run 'go list all',
                                // 'go mod graph', and similar commands.
-                               _, err := modload.LoadModGraph(modload.LoaderState, ctx, "")
+                               _, err := modload.LoadModGraph(moduleLoaderState, ctx, "")
                                if err != nil {
                                        // TODO(#64008): call base.Fatalf instead of toolchain.SwitchOrFatal
                                        // here, since we can only reach this point with an outdated toolchain
                                        // if the go.mod file is inconsistent.
-                                       toolchain.SwitchOrFatal(modload.LoaderState, ctx, err)
+                                       toolchain.SwitchOrFatal(moduleLoaderState, ctx, err)
                                }
 
                                for _, m := range modFile.Require {
@@ -169,7 +170,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
        }
 
        if len(args) == 0 {
-               if modload.HasModRoot(modload.LoaderState) {
+               if modload.HasModRoot(moduleLoaderState) {
                        os.Stderr.WriteString("go: no module dependencies to download\n")
                } else {
                        base.Errorf("go: no modules specified (see 'go help mod download')")
@@ -177,14 +178,14 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
                base.Exit()
        }
 
-       if *downloadReuse != "" && modload.HasModRoot(modload.LoaderState) {
+       if *downloadReuse != "" && modload.HasModRoot(moduleLoaderState) {
                base.Fatalf("go mod download -reuse cannot be used inside a module")
        }
 
        var mods []*ModuleJSON
        type token struct{}
        sem := make(chan token, runtime.GOMAXPROCS(0))
-       infos, infosErr := modload.ListModules(modload.LoaderState, ctx, args, 0, *downloadReuse)
+       infos, infosErr := modload.ListModules(moduleLoaderState, ctx, args, 0, *downloadReuse)
 
        // There is a bit of a chicken-and-egg problem here: ideally we need to know
        // which Go version to switch to download the requested modules, but if we
@@ -211,7 +212,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
        // toolchain version) or only one module (as is used by the Go Module Proxy).
 
        if infosErr != nil {
-               sw := toolchain.NewSwitcher(modload.LoaderState)
+               sw := toolchain.NewSwitcher(moduleLoaderState)
                sw.Error(infosErr)
                if sw.NeedSwitch() {
                        sw.Switch(ctx)
@@ -220,7 +221,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
                // when we can.
        }
 
-       if !haveExplicitArgs && modload.WorkFilePath(modload.LoaderState) == "" {
+       if !haveExplicitArgs && modload.WorkFilePath(moduleLoaderState) == "" {
                // 'go mod download' is sometimes run without arguments to pre-populate the
                // module cache. In modules that aren't at go 1.17 or higher, it may fetch
                // modules that aren't needed to build packages in the main module. This is
@@ -231,7 +232,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
                // TODO(#64008): In the future, report an error if go.mod or go.sum need to
                // be updated after loading the build list. This may require setting
                // the mode to "mod" or "readonly" depending on haveExplicitArgs.
-               if err := modload.WriteGoMod(modload.LoaderState, ctx, modload.WriteOpts{}); err != nil {
+               if err := modload.WriteGoMod(moduleLoaderState, ctx, modload.WriteOpts{}); err != nil {
                        base.Fatal(err)
                }
        }
@@ -291,8 +292,8 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
        // with no arguments we download the module pattern "all",
        // which may include dependencies that are normally pruned out
        // of the individual modules in the workspace.
-       if haveExplicitArgs || modload.WorkFilePath(modload.LoaderState) != "" {
-               sw := toolchain.NewSwitcher(modload.LoaderState)
+       if haveExplicitArgs || modload.WorkFilePath(moduleLoaderState) != "" {
+               sw := toolchain.NewSwitcher(moduleLoaderState)
                // Add errors to the Switcher in deterministic order so that they will be
                // logged deterministically.
                for _, m := range mods {
@@ -347,8 +348,8 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
        //
        // Don't save sums for 'go mod download' without arguments unless we're in
        // workspace mode; see comment above.
-       if haveExplicitArgs || modload.WorkFilePath(modload.LoaderState) != "" {
-               if err := modload.WriteGoMod(modload.LoaderState, ctx, modload.WriteOpts{}); err != nil {
+       if haveExplicitArgs || modload.WorkFilePath(moduleLoaderState) != "" {
+               if err := modload.WriteGoMod(moduleLoaderState, ctx, modload.WriteOpts{}); err != nil {
                        base.Error(err)
                }
        }
index d5774e98d76cce057fe7dee84422baa653344607..2e0d1a6dd8cd02def07d91181f7bf4d110c29fec 100644 (file)
@@ -209,6 +209,7 @@ func init() {
 }
 
 func runEdit(ctx context.Context, cmd *base.Command, args []string) {
+       moduleLoaderState := modload.NewState()
        anyFlags := *editModule != "" ||
                *editGo != "" ||
                *editToolchain != "" ||
@@ -232,7 +233,7 @@ func runEdit(ctx context.Context, cmd *base.Command, args []string) {
        if len(args) == 1 {
                gomod = args[0]
        } else {
-               gomod = modload.ModFilePath(modload.LoaderState)
+               gomod = modload.ModFilePath(moduleLoaderState)
        }
 
        if *editModule != "" {
index 2a1bad0e0efffd1e86df89b159b180ca4f9e8649..467da99b22961a259fcfda22a961352d9a2632e3 100644 (file)
@@ -52,23 +52,24 @@ func init() {
 }
 
 func runGraph(ctx context.Context, cmd *base.Command, args []string) {
-       modload.InitWorkfile(modload.LoaderState)
+       moduleLoaderState := modload.NewState()
+       modload.InitWorkfile(moduleLoaderState)
 
        if len(args) > 0 {
                base.Fatalf("go: 'go mod graph' accepts no arguments")
        }
-       modload.LoaderState.ForceUseModules = true
-       modload.LoaderState.RootMode = modload.NeedRoot
+       moduleLoaderState.ForceUseModules = true
+       moduleLoaderState.RootMode = modload.NeedRoot
 
        goVersion := graphGo.String()
        if goVersion != "" && gover.Compare(gover.Local(), goVersion) < 0 {
-               toolchain.SwitchOrFatal(modload.LoaderState, ctx, &gover.TooNewError{
+               toolchain.SwitchOrFatal(moduleLoaderState, ctx, &gover.TooNewError{
                        What:      "-go flag",
                        GoVersion: goVersion,
                })
        }
 
-       mg, err := modload.LoadModGraph(modload.LoaderState, ctx, goVersion)
+       mg, err := modload.LoadModGraph(moduleLoaderState, ctx, goVersion)
        if err != nil {
                base.Fatal(err)
        }
index 32eb5d06f9ee23177ce30e294081da3bb6bf6101..e8db3d005f7c589a25f2c2c890f09eb83c669748 100644 (file)
@@ -35,6 +35,7 @@ func init() {
 }
 
 func runInit(ctx context.Context, cmd *base.Command, args []string) {
+       moduleLoaderState := modload.NewState()
        if len(args) > 1 {
                base.Fatalf("go: 'go mod init' accepts at most one argument")
        }
@@ -43,6 +44,6 @@ func runInit(ctx context.Context, cmd *base.Command, args []string) {
                modPath = args[0]
        }
 
-       modload.LoaderState.ForceUseModules = true
-       modload.CreateModFile(modload.LoaderState, ctx, modPath) // does all the hard work
+       moduleLoaderState.ForceUseModules = true
+       modload.CreateModFile(moduleLoaderState, ctx, modPath) // does all the hard work
 }
index fb66bbcda3a17300ed186747e47d5c3ec9599aed..3ac0109625e67493b7a04050b9f1b417f65f020d 100644 (file)
@@ -105,6 +105,7 @@ func (f *goVersionFlag) Set(s string) error {
 }
 
 func runTidy(ctx context.Context, cmd *base.Command, args []string) {
+       moduleLoaderState := modload.NewState()
        if len(args) > 0 {
                base.Fatalf("go: 'go mod tidy' accepts no arguments")
        }
@@ -119,18 +120,18 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) {
        // those packages. In order to make 'go test' reproducible for the packages
        // that are in 'all' but outside of the main module, we must explicitly
        // request that their test dependencies be included.
-       modload.LoaderState.ForceUseModules = true
-       modload.LoaderState.RootMode = modload.NeedRoot
+       moduleLoaderState.ForceUseModules = true
+       moduleLoaderState.RootMode = modload.NeedRoot
 
        goVersion := tidyGo.String()
        if goVersion != "" && gover.Compare(gover.Local(), goVersion) < 0 {
-               toolchain.SwitchOrFatal(modload.LoaderState, ctx, &gover.TooNewError{
+               toolchain.SwitchOrFatal(moduleLoaderState, ctx, &gover.TooNewError{
                        What:      "-go flag",
                        GoVersion: goVersion,
                })
        }
 
-       modload.LoadPackages(modload.LoaderState, ctx, modload.PackageOpts{
+       modload.LoadPackages(moduleLoaderState, ctx, modload.PackageOpts{
                TidyGoVersion:            tidyGo.String(),
                Tags:                     imports.AnyTags(),
                Tidy:                     true,
@@ -141,6 +142,6 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) {
                LoadTests:                true,
                AllowErrors:              tidyE,
                SilenceMissingStdImports: true,
-               Switcher:                 toolchain.NewSwitcher(modload.LoaderState),
+               Switcher:                 toolchain.NewSwitcher(moduleLoaderState),
        }, "all")
 }
index f864d466bd3d227ba6079f7631eb1b3606037f9e..ef44ce41c04c7f990265738fededd63bfad5da83 100644 (file)
@@ -66,11 +66,12 @@ func init() {
 }
 
 func runVendor(ctx context.Context, cmd *base.Command, args []string) {
-       modload.InitWorkfile(modload.LoaderState)
-       if modload.WorkFilePath(modload.LoaderState) != "" {
+       moduleLoaderState := modload.NewState()
+       modload.InitWorkfile(moduleLoaderState)
+       if modload.WorkFilePath(moduleLoaderState) != "" {
                base.Fatalf("go: 'go mod vendor' cannot be run in workspace mode. Run 'go work vendor' to vendor the workspace or set 'GOWORK=off' to exit workspace mode.")
        }
-       RunVendor(modload.LoaderState, ctx, vendorE, vendorO, args)
+       RunVendor(moduleLoaderState, ctx, vendorE, vendorO, args)
 }
 
 func RunVendor(loaderstate *modload.State, ctx context.Context, vendorE bool, vendorO string, args []string) {
index 358d7dd2030169738ed1f9e3b64ef005a63458d1..e40a05ed5316489acdc43b4e5bae7cbc4ec720a4 100644 (file)
@@ -44,20 +44,21 @@ func init() {
 }
 
 func runVerify(ctx context.Context, cmd *base.Command, args []string) {
-       modload.InitWorkfile(modload.LoaderState)
+       moduleLoaderState := modload.NewState()
+       modload.InitWorkfile(moduleLoaderState)
 
        if len(args) != 0 {
                // NOTE(rsc): Could take a module pattern.
                base.Fatalf("go: verify takes no arguments")
        }
-       modload.LoaderState.ForceUseModules = true
-       modload.LoaderState.RootMode = modload.NeedRoot
+       moduleLoaderState.ForceUseModules = true
+       moduleLoaderState.RootMode = modload.NeedRoot
 
        // Only verify up to GOMAXPROCS zips at once.
        type token struct{}
        sem := make(chan token, runtime.GOMAXPROCS(0))
 
-       mg, err := modload.LoadModGraph(modload.LoaderState, ctx, "")
+       mg, err := modload.LoadModGraph(moduleLoaderState, ctx, "")
        if err != nil {
                base.Fatal(err)
        }
@@ -71,7 +72,7 @@ func runVerify(ctx context.Context, cmd *base.Command, args []string) {
                errsChans[i] = errsc
                mod := mod // use a copy to avoid data races
                go func() {
-                       errsc <- verifyMod(modload.LoaderState, ctx, mod)
+                       errsc <- verifyMod(moduleLoaderState, ctx, mod)
                        <-sem
                }()
        }
index d0ec2444653f22a91e5b37335554341d3fa65651..407a19d5c2104049673026b63a8ce968a26d964c 100644 (file)
@@ -63,9 +63,10 @@ func init() {
 }
 
 func runWhy(ctx context.Context, cmd *base.Command, args []string) {
-       modload.InitWorkfile(modload.LoaderState)
-       modload.LoaderState.ForceUseModules = true
-       modload.LoaderState.RootMode = modload.NeedRoot
+       moduleLoaderState := modload.NewState()
+       modload.InitWorkfile(moduleLoaderState)
+       moduleLoaderState.ForceUseModules = true
+       moduleLoaderState.RootMode = modload.NeedRoot
        modload.ExplicitWriteGoMod = true // don't write go.mod in ListModules
 
        loadOpts := modload.PackageOpts{
@@ -83,13 +84,13 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) {
                        }
                }
 
-               mods, err := modload.ListModules(modload.LoaderState, ctx, args, 0, "")
+               mods, err := modload.ListModules(moduleLoaderState, ctx, args, 0, "")
                if err != nil {
                        base.Fatal(err)
                }
 
                byModule := make(map[string][]string)
-               _, pkgs := modload.LoadPackages(modload.LoaderState, ctx, loadOpts, "all")
+               _, pkgs := modload.LoadPackages(moduleLoaderState, ctx, loadOpts, "all")
                for _, path := range pkgs {
                        m := modload.PackageModule(path)
                        if m.Path != "" {
@@ -120,9 +121,9 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) {
                }
        } else {
                // Resolve to packages.
-               matches, _ := modload.LoadPackages(modload.LoaderState, ctx, loadOpts, args...)
+               matches, _ := modload.LoadPackages(moduleLoaderState, ctx, loadOpts, args...)
 
-               modload.LoadPackages(modload.LoaderState, ctx, loadOpts, "all") // rebuild graph, from main module (not from named packages)
+               modload.LoadPackages(moduleLoaderState, ctx, loadOpts, "all") // rebuild graph, from main module (not from named packages)
 
                sep := ""
                for _, m := range matches {