cmd/go: make ImportMissingError work with local state

This change adds fields to the type `ImportMissingError` so
that the `Error()` method can be called without accessing the global
`LoaderState` variable.

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

Change-Id: Ib313faeb27ae44e9ac68086313633ce742f596dd
Reviewed-on: https://go-review.googlesource.com/c/go/+/711121
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Michael Matloob <matloob@google.com>
This commit is contained in:
Ian Alexander 2025-10-03 00:50:03 -04:00
parent f5403f15f0
commit ccf4192a31
2 changed files with 41 additions and 11 deletions

View file

@ -29,10 +29,14 @@ import (
) )
type ImportMissingError struct { type ImportMissingError struct {
Path string Path string
Module module.Version Module module.Version
QueryErr error QueryErr error
modContainingCWD module.Version
// modRoot is dependent on the value of ImportingMainModule and should be
// kept in sync.
modRoot string
ImportingMainModule module.Version ImportingMainModule module.Version
// isStd indicates whether we would expect to find the package in the standard // isStd indicates whether we would expect to find the package in the standard
@ -82,8 +86,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 != LoaderState.MainModules.ModContainingCWD() { if e.ImportingMainModule.Path != "" && e.ImportingMainModule != e.modContainingCWD {
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\tcd %s\n\tgo get %s", message, e.modRoot, 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)
} }
@ -368,7 +372,10 @@ func importFromModules(loaderstate *State, ctx context.Context, path string, rs
} }
if len(mods) == 0 { if len(mods) == 0 {
return module.Version{}, "", "", nil, &ImportMissingError{Path: path} return module.Version{}, "", "", nil, &ImportMissingError{
Path: path,
modContainingCWD: loaderstate.MainModules.ModContainingCWD(),
}
} }
return mods[0], roots[0], dirs[0], nil, nil return mods[0], roots[0], dirs[0], nil, nil
@ -486,7 +493,12 @@ func importFromModules(loaderstate *State, ctx context.Context, path string, rs
if !HasModRoot(loaderstate) { if !HasModRoot(loaderstate) {
queryErr = NewNoMainModulesError(loaderstate) queryErr = NewNoMainModulesError(loaderstate)
} }
return module.Version{}, "", "", nil, &ImportMissingError{Path: path, QueryErr: queryErr, isStd: pathIsStd} return module.Version{}, "", "", nil, &ImportMissingError{
Path: path,
QueryErr: queryErr,
isStd: pathIsStd,
modContainingCWD: loaderstate.MainModules.ModContainingCWD(),
}
} }
// So far we've checked the root dependencies. // So far we've checked the root dependencies.
@ -558,7 +570,11 @@ func queryImport(loaderstate *State, ctx context.Context, path string, rs *Requi
return m, err return m, err
} else if ok { } else if ok {
if cfg.BuildMod == "readonly" { if cfg.BuildMod == "readonly" {
return module.Version{}, &ImportMissingError{Path: path, replaced: m} return module.Version{}, &ImportMissingError{
Path: path,
replaced: m,
modContainingCWD: loaderstate.MainModules.ModContainingCWD(),
}
} }
return m, nil return m, nil
} }
@ -584,7 +600,11 @@ func queryImport(loaderstate *State, ctx context.Context, path string, rs *Requi
// QueryPattern cannot possibly find a module containing this package. // QueryPattern cannot possibly find a module containing this package.
// //
// Instead of trying QueryPattern, report an ImportMissingError immediately. // Instead of trying QueryPattern, report an ImportMissingError immediately.
return module.Version{}, &ImportMissingError{Path: path, isStd: true} return module.Version{}, &ImportMissingError{
Path: path,
isStd: true,
modContainingCWD: loaderstate.MainModules.ModContainingCWD(),
}
} }
if (cfg.BuildMod == "readonly" || cfg.BuildMod == "vendor") && !allowMissingModuleImports { if (cfg.BuildMod == "readonly" || cfg.BuildMod == "vendor") && !allowMissingModuleImports {
@ -599,7 +619,11 @@ func queryImport(loaderstate *State, ctx context.Context, path string, rs *Requi
} else if cfg.BuildModReason != "" { } else if cfg.BuildModReason != "" {
queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason) queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason)
} }
return module.Version{}, &ImportMissingError{Path: path, QueryErr: queryErr} return module.Version{}, &ImportMissingError{
Path: path,
QueryErr: queryErr,
modContainingCWD: loaderstate.MainModules.ModContainingCWD(),
}
} }
// Look up module containing the package, for addition to the build list. // Look up module containing the package, for addition to the build list.
@ -617,7 +641,11 @@ func queryImport(loaderstate *State, ctx context.Context, path string, rs *Requi
if errors.Is(err, fs.ErrNotExist) { if errors.Is(err, fs.ErrNotExist) {
// Return "cannot find module providing package […]" instead of whatever // Return "cannot find module providing package […]" instead of whatever
// low-level error QueryPattern produced. // low-level error QueryPattern produced.
return module.Version{}, &ImportMissingError{Path: path, QueryErr: err} return module.Version{}, &ImportMissingError{
Path: path,
QueryErr: err,
modContainingCWD: loaderstate.MainModules.ModContainingCWD(),
}
} else { } else {
return module.Version{}, err return module.Version{}, err
} }
@ -645,6 +673,7 @@ func queryImport(loaderstate *State, ctx context.Context, path string, rs *Requi
Path: path, Path: path,
Module: candidates[0].Mod, Module: candidates[0].Mod,
newMissingVersion: candidate0MissingVersion, newMissingVersion: candidate0MissingVersion,
modContainingCWD: loaderstate.MainModules.ModContainingCWD(),
} }
} }

View file

@ -1588,6 +1588,7 @@ func (ld *loader) resolveMissingImports(loaderstate *State, ctx context.Context)
for curstack := pkg.stack; curstack != nil; curstack = curstack.stack { for curstack := pkg.stack; curstack != nil; curstack = curstack.stack {
if loaderstate.MainModules.Contains(curstack.mod.Path) { if loaderstate.MainModules.Contains(curstack.mod.Path) {
ime.ImportingMainModule = curstack.mod ime.ImportingMainModule = curstack.mod
ime.modRoot = loaderstate.MainModules.ModRoot(ime.ImportingMainModule)
break break
} }
} }