cmd/go: inject State parameter into modcmd.runVendor

This command modifies the call tree starting at `modcmd.runVendor` to
inject a `State` parameter to every function that is currently using
the global `modload.LoaderState` variable.  By explicilty passing a
`State` parameter, we can begin to eliminate the usage of the global
`modload.LoaderState`.

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

[git-generate]
cd src/cmd/go/internal/modcmd
rf 'inject modload.LoaderState runVendor'
cd ..
./rf-cleanup.zsh

Change-Id: I0572e165d291e34d212ded9a420871688b7915ad
Reviewed-on: https://go-review.googlesource.com/c/go/+/709984
Reviewed-by: Michael Matloob <matloob@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
Ian Alexander 2025-10-01 23:18:10 -04:00
parent 92aa3e9e98
commit 0f820aca29
4 changed files with 29 additions and 29 deletions

View file

@ -70,15 +70,15 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) {
if modload.WorkFilePath(modload.LoaderState) != "" { if modload.WorkFilePath(modload.LoaderState) != "" {
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.") 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(ctx, vendorE, vendorO, args) RunVendor(modload.LoaderState, ctx, vendorE, vendorO, args)
} }
func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string) { func RunVendor(loaderstate *modload.State, ctx context.Context, vendorE bool, vendorO string, args []string) {
if len(args) != 0 { if len(args) != 0 {
base.Fatalf("go: 'go mod vendor' accepts no arguments") base.Fatalf("go: 'go mod vendor' accepts no arguments")
} }
modload.LoaderState.ForceUseModules = true loaderstate.ForceUseModules = true
modload.LoaderState.RootMode = modload.NeedRoot loaderstate.RootMode = modload.NeedRoot
loadOpts := modload.PackageOpts{ loadOpts := modload.PackageOpts{
Tags: imports.AnyTags(), Tags: imports.AnyTags(),
@ -88,7 +88,7 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
AllowErrors: vendorE, AllowErrors: vendorE,
SilenceMissingStdImports: true, SilenceMissingStdImports: true,
} }
_, pkgs := modload.LoadPackages(modload.LoaderState, ctx, loadOpts, "all") _, pkgs := modload.LoadPackages(loaderstate, ctx, loadOpts, "all")
var vdir string var vdir string
switch { switch {
@ -97,7 +97,7 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
case vendorO != "": case vendorO != "":
vdir = filepath.Join(base.Cwd(), vendorO) vdir = filepath.Join(base.Cwd(), vendorO)
default: default:
vdir = filepath.Join(modload.VendorDir(modload.LoaderState)) vdir = filepath.Join(modload.VendorDir(loaderstate))
} }
if err := os.RemoveAll(vdir); err != nil { if err := os.RemoveAll(vdir); err != nil {
base.Fatal(err) base.Fatal(err)
@ -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.LoaderState.MainModules.Contains(m.Path) { if m.Path == "" || 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.LoaderState.MainModules.GoVersion(modload.LoaderState) gv := loaderstate.MainModules.GoVersion(loaderstate)
if gover.Compare(gv, "1.14") >= 0 && (modload.FindGoWork(modload.LoaderState, base.Cwd()) != "" || modload.ModFile().Go != nil) { if gover.Compare(gv, "1.14") >= 0 && (modload.FindGoWork(loaderstate, base.Cwd()) != "" || modload.ModFile(loaderstate).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.LoaderState.MainModules.Versions() { for _, m := range loaderstate.MainModules.Versions() {
if modFile := modload.LoaderState.MainModules.ModFile(m); modFile != nil { if modFile := 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,20 +156,20 @@ 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.LoaderState.MainModules.WorkFile() != nil { if loaderstate.MainModules.WorkFile() != nil {
fmt.Fprintf(w, "## workspace\n") fmt.Fprintf(w, "## workspace\n")
} }
replacementWritten := make(map[module.Version]bool) replacementWritten := make(map[module.Version]bool)
for _, m := range vendorMods { for _, m := range vendorMods {
replacement := modload.Replacement(modload.LoaderState, m) replacement := modload.Replacement(loaderstate, m)
line := moduleLine(m, replacement) line := moduleLine(m, replacement)
replacementWritten[m] = true replacementWritten[m] = true
io.WriteString(w, line) io.WriteString(w, line)
goVersion := "" goVersion := ""
if includeGoVersions { if includeGoVersions {
goVersion = modload.ModuleInfo(modload.LoaderState, ctx, m.Path).GoVersion goVersion = modload.ModuleInfo(loaderstate, ctx, m.Path).GoVersion
} }
switch { switch {
case isExplicit[m] && goVersion != "": case isExplicit[m] && goVersion != "":
@ -184,7 +184,7 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
sort.Strings(pkgs) sort.Strings(pkgs)
for _, pkg := range pkgs { for _, pkg := range pkgs {
fmt.Fprintf(w, "%s\n", pkg) fmt.Fprintf(w, "%s\n", pkg)
vendorPkg(vdir, pkg) vendorPkg(loaderstate, vdir, pkg)
} }
} }
@ -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.LoaderState.MainModules.Versions() { for _, m := range loaderstate.MainModules.Versions() {
if workFile := modload.LoaderState.MainModules.WorkFile(); workFile != nil { if workFile := 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,14 +208,14 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
} }
} }
} }
if modFile := modload.LoaderState.MainModules.ModFile(m); modFile != nil { if modFile := 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.
continue continue
} }
replacementWritten[r.Old] = true replacementWritten[r.Old] = true
rNew := modload.Replacement(modload.LoaderState, r.Old) rNew := modload.Replacement(loaderstate, r.Old)
if rNew == (module.Version{}) { if rNew == (module.Version{}) {
// There is no replacement. Don't try to write it. // There is no replacement. Don't try to write it.
continue continue
@ -268,8 +268,8 @@ func moduleLine(m, r module.Version) string {
return b.String() return b.String()
} }
func vendorPkg(vdir, pkg string) { func vendorPkg(loaderstate *modload.State, vdir, pkg string) {
src, realPath, _ := modload.Lookup(modload.LoaderState, "", false, pkg) src, realPath, _ := modload.Lookup(loaderstate, "", false, pkg)
if src == "" { if src == "" {
base.Errorf("internal error: no pkg for %s\n", pkg) base.Errorf("internal error: no pkg for %s\n", pkg)
return return
@ -315,7 +315,7 @@ func vendorPkg(vdir, pkg string) {
} }
} }
var embedPatterns []string var embedPatterns []string
if gover.Compare(modload.LoaderState.MainModules.GoVersion(modload.LoaderState), "1.22") >= 0 { if gover.Compare(loaderstate.MainModules.GoVersion(loaderstate), "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

View file

@ -410,7 +410,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
} }
// Everything succeeded. Update go.mod. // Everything succeeded. Update go.mod.
oldReqs := reqsFromGoMod(modload.ModFile()) oldReqs := reqsFromGoMod(modload.ModFile(modload.LoaderState))
if err := modload.WriteGoMod(modload.LoaderState, ctx, opts); err != nil { if err := modload.WriteGoMod(modload.LoaderState, ctx, opts); err != nil {
// A TooNewError can happen for 'go get go@newversion' // A TooNewError can happen for 'go get go@newversion'
@ -421,7 +421,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
toolchain.SwitchOrFatal(modload.LoaderState, ctx, err) toolchain.SwitchOrFatal(modload.LoaderState, ctx, err)
} }
newReqs := reqsFromGoMod(modload.ModFile()) newReqs := reqsFromGoMod(modload.ModFile(modload.LoaderState))
r.reportChanges(oldReqs, newReqs) r.reportChanges(oldReqs, newReqs)
if gowork := modload.FindGoWork(modload.LoaderState, base.Cwd()); gowork != "" { if gowork := modload.FindGoWork(modload.LoaderState, base.Cwd()); gowork != "" {

View file

@ -314,11 +314,11 @@ const (
// will be lost at the next call to WriteGoMod. // will be lost at the next call to WriteGoMod.
// To make permanent changes to the require statements // To make permanent changes to the require statements
// in go.mod, edit it before loading. // in go.mod, edit it before loading.
func ModFile() *modfile.File { func ModFile(loaderstate *State) *modfile.File {
Init(LoaderState) Init(loaderstate)
modFile := LoaderState.MainModules.ModFile(LoaderState.MainModules.mustGetSingleMainModule(LoaderState)) modFile := loaderstate.MainModules.ModFile(loaderstate.MainModules.mustGetSingleMainModule(loaderstate))
if modFile == nil { if modFile == nil {
die(LoaderState) die(loaderstate)
} }
return modFile return modFile
} }

View file

@ -51,5 +51,5 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) {
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(ctx, vendorE, vendorO, args) modcmd.RunVendor(modload.LoaderState, ctx, vendorE, vendorO, args)
} }