cmd/go: use local state object in pkg workcmd

This commit modifies package `workcmd` 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/workcmd
rf '
  inject modload.LoaderState runUse
  add sync.go:/func runSync\(/-0 var moduleLoaderState *modload.State
  ex {
    import "cmd/go/internal/modload";
    modload.LoaderState -> moduleLoaderState
  }
  add runSync://+0 moduleLoaderState := modload.NewState()
  add runEditwork://+0 moduleLoaderState := modload.NewState()
  add runInit://+0 moduleLoaderState := modload.NewState()
  add runUse://+0 moduleLoaderState := modload.NewState()
  add runVendor://+0 moduleLoaderState := modload.NewState()
  rm sync.go:/var moduleLoaderState \*modload.State/
'

Change-Id: Iadc4ffd19d15f80a694285c86adfc01f0d26bac7
Reviewed-on: https://go-review.googlesource.com/c/go/+/711129
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-10-08 20:26:24 -04:00
parent 69673e9be2
commit 784700439a
5 changed files with 33 additions and 28 deletions

View file

@ -132,6 +132,7 @@ func init() {
} }
func runEditwork(ctx context.Context, cmd *base.Command, args []string) { func runEditwork(ctx context.Context, cmd *base.Command, args []string) {
moduleLoaderState := modload.NewState()
if *editJSON && *editPrint { if *editJSON && *editPrint {
base.Fatalf("go: cannot use both -json and -print") base.Fatalf("go: cannot use both -json and -print")
} }
@ -143,8 +144,8 @@ func runEditwork(ctx context.Context, cmd *base.Command, args []string) {
if len(args) == 1 { if len(args) == 1 {
gowork = args[0] gowork = args[0]
} else { } else {
modload.InitWorkfile(modload.LoaderState) modload.InitWorkfile(moduleLoaderState)
gowork = modload.WorkFilePath(modload.LoaderState) gowork = modload.WorkFilePath(moduleLoaderState)
} }
if gowork == "" { if gowork == "" {
base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)") base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")

View file

@ -44,11 +44,12 @@ func init() {
} }
func runInit(ctx context.Context, cmd *base.Command, args []string) { func runInit(ctx context.Context, cmd *base.Command, args []string) {
modload.InitWorkfile(modload.LoaderState) moduleLoaderState := modload.NewState()
modload.InitWorkfile(moduleLoaderState)
modload.LoaderState.ForceUseModules = true moduleLoaderState.ForceUseModules = true
gowork := modload.WorkFilePath(modload.LoaderState) gowork := modload.WorkFilePath(moduleLoaderState)
if gowork == "" { if gowork == "" {
gowork = filepath.Join(base.Cwd(), "go.work") gowork = filepath.Join(base.Cwd(), "go.work")
} }
@ -61,6 +62,6 @@ func runInit(ctx context.Context, cmd *base.Command, args []string) {
wf := new(modfile.WorkFile) wf := new(modfile.WorkFile)
wf.Syntax = new(modfile.FileSyntax) wf.Syntax = new(modfile.FileSyntax)
wf.AddGoStmt(goV) wf.AddGoStmt(goV)
workUse(ctx, gowork, wf, args) workUse(moduleLoaderState, ctx, gowork, wf, args)
modload.WriteWorkFile(gowork, wf) modload.WriteWorkFile(gowork, wf)
} }

View file

@ -48,19 +48,20 @@ func init() {
} }
func runSync(ctx context.Context, cmd *base.Command, args []string) { func runSync(ctx context.Context, cmd *base.Command, args []string) {
modload.LoaderState.ForceUseModules = true moduleLoaderState := modload.NewState()
modload.InitWorkfile(modload.LoaderState) moduleLoaderState.ForceUseModules = true
if modload.WorkFilePath(modload.LoaderState) == "" { modload.InitWorkfile(moduleLoaderState)
if modload.WorkFilePath(moduleLoaderState) == "" {
base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)") base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")
} }
_, err := modload.LoadModGraph(modload.LoaderState, ctx, "") _, err := modload.LoadModGraph(moduleLoaderState, ctx, "")
if err != nil { if err != nil {
toolchain.SwitchOrFatal(modload.LoaderState, ctx, err) toolchain.SwitchOrFatal(moduleLoaderState, ctx, err)
} }
mustSelectFor := map[module.Version][]module.Version{} mustSelectFor := map[module.Version][]module.Version{}
mms := modload.LoaderState.MainModules mms := moduleLoaderState.MainModules
opts := modload.PackageOpts{ opts := modload.PackageOpts{
Tags: imports.AnyTags(), Tags: imports.AnyTags(),
@ -73,7 +74,7 @@ func runSync(ctx context.Context, cmd *base.Command, args []string) {
} }
for _, m := range mms.Versions() { for _, m := range mms.Versions() {
opts.MainModule = m opts.MainModule = m
_, pkgs := modload.LoadPackages(modload.LoaderState, ctx, opts, "all") _, pkgs := modload.LoadPackages(moduleLoaderState, ctx, opts, "all")
opts.MainModule = module.Version{} // reset opts.MainModule = module.Version{} // reset
var ( var (
@ -91,7 +92,7 @@ func runSync(ctx context.Context, cmd *base.Command, args []string) {
mustSelectFor[m] = mustSelect mustSelectFor[m] = mustSelect
} }
workFilePath := modload.WorkFilePath(modload.LoaderState) // save go.work path because EnterModule clobbers it. workFilePath := modload.WorkFilePath(moduleLoaderState) // save go.work path because EnterModule clobbers it.
var goV string var goV string
for _, m := range mms.Versions() { for _, m := range mms.Versions() {
@ -104,7 +105,7 @@ func runSync(ctx context.Context, cmd *base.Command, args []string) {
// Use EnterModule to reset the global state in modload to be in // Use EnterModule to reset the global state in modload to be in
// single-module mode using the modroot of m. // single-module mode using the modroot of m.
modload.EnterModule(modload.LoaderState, ctx, mms.ModRoot(m)) modload.EnterModule(moduleLoaderState, ctx, mms.ModRoot(m))
// Edit the build list in the same way that 'go get' would if we // Edit the build list in the same way that 'go get' would if we
// requested the relevant module versions explicitly. // requested the relevant module versions explicitly.
@ -114,12 +115,12 @@ func runSync(ctx context.Context, cmd *base.Command, args []string) {
// so we don't write some go.mods with the "before" toolchain // so we don't write some go.mods with the "before" toolchain
// and others with the "after" toolchain. If nothing else, that // and others with the "after" toolchain. If nothing else, that
// discrepancy could show up in auto-recorded toolchain lines. // discrepancy could show up in auto-recorded toolchain lines.
changed, err := modload.EditBuildList(modload.LoaderState, ctx, nil, mustSelectFor[m]) changed, err := modload.EditBuildList(moduleLoaderState, ctx, nil, mustSelectFor[m])
if err != nil { if err != nil {
continue continue
} }
if changed { if changed {
modload.LoadPackages(modload.LoaderState, ctx, modload.PackageOpts{ modload.LoadPackages(moduleLoaderState, ctx, modload.PackageOpts{
Tags: imports.AnyTags(), Tags: imports.AnyTags(),
Tidy: true, Tidy: true,
VendorModulesInGOROOTSrc: true, VendorModulesInGOROOTSrc: true,
@ -129,9 +130,9 @@ func runSync(ctx context.Context, cmd *base.Command, args []string) {
SilenceMissingStdImports: true, SilenceMissingStdImports: true,
SilencePackageErrors: true, SilencePackageErrors: true,
}, "all") }, "all")
modload.WriteGoMod(modload.LoaderState, ctx, modload.WriteOpts{}) modload.WriteGoMod(moduleLoaderState, ctx, modload.WriteOpts{})
} }
goV = gover.Max(goV, modload.LoaderState.MainModules.GoVersion(modload.LoaderState)) goV = gover.Max(goV, moduleLoaderState.MainModules.GoVersion(moduleLoaderState))
} }
wf, err := modload.ReadWorkFile(workFilePath) wf, err := modload.ReadWorkFile(workFilePath)

View file

@ -61,9 +61,10 @@ func init() {
} }
func runUse(ctx context.Context, cmd *base.Command, args []string) { func runUse(ctx context.Context, cmd *base.Command, args []string) {
modload.LoaderState.ForceUseModules = true moduleLoaderState := modload.NewState()
modload.InitWorkfile(modload.LoaderState) moduleLoaderState.ForceUseModules = true
gowork := modload.WorkFilePath(modload.LoaderState) modload.InitWorkfile(moduleLoaderState)
gowork := modload.WorkFilePath(moduleLoaderState)
if gowork == "" { if gowork == "" {
base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)") base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")
} }
@ -71,11 +72,11 @@ func runUse(ctx context.Context, cmd *base.Command, args []string) {
if err != nil { if err != nil {
base.Fatal(err) base.Fatal(err)
} }
workUse(ctx, gowork, wf, args) workUse(moduleLoaderState, ctx, gowork, wf, args)
modload.WriteWorkFile(gowork, wf) modload.WriteWorkFile(gowork, wf)
} }
func workUse(ctx context.Context, gowork string, wf *modfile.WorkFile, args []string) { func workUse(loaderstate *modload.State, ctx context.Context, gowork string, wf *modfile.WorkFile, args []string) {
workDir := filepath.Dir(gowork) // absolute, since gowork itself is absolute workDir := filepath.Dir(gowork) // absolute, since gowork itself is absolute
haveDirs := make(map[string][]string) // absolute → original(s) haveDirs := make(map[string][]string) // absolute → original(s)
@ -94,7 +95,7 @@ func workUse(ctx context.Context, gowork string, wf *modfile.WorkFile, args []st
// all entries for the absolute path should be removed. // all entries for the absolute path should be removed.
keepDirs := make(map[string]string) keepDirs := make(map[string]string)
sw := toolchain.NewSwitcher(modload.LoaderState) sw := toolchain.NewSwitcher(loaderstate)
// lookDir updates the entry in keepDirs for the directory dir, // lookDir updates the entry in keepDirs for the directory dir,
// which is either absolute or relative to the current working directory // which is either absolute or relative to the current working directory

View file

@ -46,10 +46,11 @@ func init() {
} }
func runVendor(ctx context.Context, cmd *base.Command, args []string) { func runVendor(ctx context.Context, cmd *base.Command, args []string) {
modload.InitWorkfile(modload.LoaderState) moduleLoaderState := modload.NewState()
if modload.WorkFilePath(modload.LoaderState) == "" { modload.InitWorkfile(moduleLoaderState)
if modload.WorkFilePath(moduleLoaderState) == "" {
base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)") base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")
} }
modcmd.RunVendor(modload.LoaderState, ctx, vendorE, vendorO, args) modcmd.RunVendor(moduleLoaderState, ctx, vendorE, vendorO, args)
} }