From: Ian Alexander Date: Fri, 3 Oct 2025 04:31:26 +0000 (-0400) Subject: cmd/go: make ErrNoModRoot work with local state X-Git-Tag: go1.26rc1~508 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c18fa69e52;p=gostls13.git cmd/go: make ErrNoModRoot work with local state This change reworks the sentinel error value ErrNoModRoot and the type noMainModulesError so that we can determine the appropriate error message to display based on the loader state without depending on the state directly. This commit is part of the overall effort to eliminate global modloader state. Change-Id: I64de433faca96ed90fad4c153766c50575a72157 Reviewed-on: https://go-review.googlesource.com/c/go/+/711120 Reviewed-by: Michael Matloob LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Matloob --- diff --git a/src/cmd/go/internal/modget/query.go b/src/cmd/go/internal/modget/query.go index d056c65cad..75d32dc633 100644 --- a/src/cmd/go/internal/modget/query.go +++ b/src/cmd/go/internal/modget/query.go @@ -185,7 +185,7 @@ func (q *query) validate(loaderstate *modload.State) error { if q.pattern == "all" { // If there is no main module, "all" is not meaningful. if !modload.HasModRoot(loaderstate) { - return fmt.Errorf(`cannot match "all": %v`, modload.ErrNoModRoot) + return fmt.Errorf(`cannot match "all": %v`, modload.NewNoMainModulesError(loaderstate)) } if !versionOkForMainModule(q.version) { // TODO(bcmills): "all@none" seems like a totally reasonable way to diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go index 461c18ef41..da73d35e44 100644 --- a/src/cmd/go/internal/modload/import.go +++ b/src/cmd/go/internal/modload/import.go @@ -63,7 +63,7 @@ func (e *ImportMissingError) Error() string { } return msg } - if e.QueryErr != nil && e.QueryErr != ErrNoModRoot { + if e.QueryErr != nil && !errors.Is(e.QueryErr, ErrNoModRoot) { return fmt.Sprintf("cannot find module providing package %s: %v", e.Path, e.QueryErr) } if cfg.BuildMod == "mod" || (cfg.BuildMod == "readonly" && allowMissingModuleImports) { @@ -484,7 +484,7 @@ func importFromModules(loaderstate *State, ctx context.Context, path string, rs // requested package. var queryErr error if !HasModRoot(loaderstate) { - queryErr = ErrNoModRoot + queryErr = NewNoMainModulesError(loaderstate) } return module.Version{}, "", "", nil, &ImportMissingError{Path: path, QueryErr: queryErr, isStd: pathIsStd} } diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go index 274589cbfd..e2116b7289 100644 --- a/src/cmd/go/internal/modload/init.go +++ b/src/cmd/go/internal/modload/init.go @@ -523,7 +523,7 @@ func Init(loaderstate *State) { base.Fatalf("go: cannot find main module, but -modfile was set.\n\t-modfile cannot be used to set the module root directory.") } if loaderstate.RootMode == NeedRoot { - base.Fatal(ErrNoModRoot) + base.Fatal(NewNoMainModulesError(loaderstate)) } if !mustUseModules { // GO111MODULE is 'auto', and we can't find a module root. @@ -538,7 +538,7 @@ func Init(loaderstate *State) { // when it happens. See golang.org/issue/26708. fmt.Fprintf(os.Stderr, "go: warning: ignoring go.mod in system temp root %v\n", os.TempDir()) if loaderstate.RootMode == NeedRoot { - base.Fatal(ErrNoModRoot) + base.Fatal(NewNoMainModulesError(loaderstate)) } if !mustUseModules { return @@ -560,7 +560,7 @@ func Init(loaderstate *State) { if _, err := fsys.Stat(filepath.Join(gopath, "go.mod")); err == nil { fmt.Fprintf(os.Stderr, "go: warning: ignoring go.mod in $GOPATH %v\n", gopath) if loaderstate.RootMode == NeedRoot { - base.Fatal(ErrNoModRoot) + base.Fatal(NewNoMainModulesError(loaderstate)) } if !mustUseModules { return @@ -731,21 +731,33 @@ func die(loaderstate *State) { base.Fatalf("go: cannot find main module, but found %s in %s\n\tto create a module there, run:\n\t%sgo mod init", name, dir, cdCmd) } } - base.Fatal(ErrNoModRoot) + base.Fatal(NewNoMainModulesError(loaderstate)) } +var ErrNoModRoot = errors.New("no module root") + // noMainModulesError returns the appropriate error if there is no main module or // main modules depending on whether the go command is in workspace mode. -type noMainModulesError struct{} +type noMainModulesError struct { + inWorkspaceMode bool +} func (e noMainModulesError) Error() string { - if inWorkspaceMode(LoaderState) { + if e.inWorkspaceMode { return "no modules were found in the current workspace; see 'go help work'" } return "go.mod file not found in current directory or any parent directory; see 'go help modules'" } -var ErrNoModRoot noMainModulesError +func (e noMainModulesError) Unwrap() error { + return ErrNoModRoot +} + +func NewNoMainModulesError(s *State) noMainModulesError { + return noMainModulesError{ + inWorkspaceMode: inWorkspaceMode(s), + } +} type goModDirtyError struct{} diff --git a/src/cmd/go/internal/modload/list.go b/src/cmd/go/internal/modload/list.go index ee31f06805..6a4d788824 100644 --- a/src/cmd/go/internal/modload/list.go +++ b/src/cmd/go/internal/modload/list.go @@ -146,7 +146,7 @@ func listModules(loaderstate *State, ctx context.Context, rs *Requirements, args if arg == "all" || strings.Contains(arg, "...") { needFullGraph = true if !HasModRoot(loaderstate) { - base.Fatalf("go: cannot match %q: %v", arg, ErrNoModRoot) + base.Fatalf("go: cannot match %q: %v", arg, NewNoMainModulesError(loaderstate)) } continue } @@ -155,7 +155,7 @@ func listModules(loaderstate *State, ctx context.Context, rs *Requirements, args if _, ok := rs.rootSelected(loaderstate, path); !ok || rs.pruning == unpruned { needFullGraph = true if !HasModRoot(loaderstate) { - base.Fatalf("go: cannot match %q: %v", arg, ErrNoModRoot) + base.Fatalf("go: cannot match %q: %v", arg, NewNoMainModulesError(loaderstate)) } } } @@ -164,7 +164,7 @@ func listModules(loaderstate *State, ctx context.Context, rs *Requirements, args if _, ok := rs.rootSelected(loaderstate, arg); !ok || rs.pruning == unpruned { needFullGraph = true if mode&ListVersions == 0 && !HasModRoot(loaderstate) { - base.Fatalf("go: cannot match %q without -versions or an explicit version: %v", arg, ErrNoModRoot) + base.Fatalf("go: cannot match %q without -versions or an explicit version: %v", arg, NewNoMainModulesError(loaderstate)) } } }