]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: make ErrNoModRoot work with local state
authorIan Alexander <jitsu@google.com>
Fri, 3 Oct 2025 04:31:26 +0000 (00:31 -0400)
committerIan Alexander <jitsu@google.com>
Fri, 24 Oct 2025 14:25:52 +0000 (07:25 -0700)
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 <matloob@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
src/cmd/go/internal/modget/query.go
src/cmd/go/internal/modload/import.go
src/cmd/go/internal/modload/init.go
src/cmd/go/internal/modload/list.go

index d056c65cadf305230f4e98bea572254e13f24c30..75d32dc633a4204e386869b17d5f27d17c7d6e2a 100644 (file)
@@ -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
index 461c18ef419351730390dbddfe9dec07591ed07f..da73d35e44d72a31b230d0153887e9b802d46405 100644 (file)
@@ -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}
                }
index 274589cbfdb0f8ab7e1e4d165ef1517d89b6b353..e2116b728933cfbde9112817cf5cf4119c5fe77a 100644 (file)
@@ -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{}
 
index ee31f06805941a53d205138a586e3d1772fb6e1e..6a4d788824caa91e7b4c8d1438f1e0beec0b4b20 100644 (file)
@@ -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))
                        }
                }
        }