From 87d1833c66aa25a7e495987b066bdd22d1fe3105 Mon Sep 17 00:00:00 2001 From: Michael Matloob Date: Tue, 25 Mar 2025 14:10:31 -0400 Subject: [PATCH] cmd/go/internal/modload: improve ErrNoModRoot error text Before this change, in several cases where HasModRoot() returned false, we'd return ErrNoModRoot. ErrNoModRoot would say that there was no go.mod file but would not mention workspaces. With this change, ErrNoModRoot will return error text that's different if we're in a workspace, saying that there are no modules in the workspace. Fixes #54419 Change-Id: I77c94d0011947bf8e33c066416ab3762502fd2e6 Reviewed-on: https://go-review.googlesource.com/c/go/+/660675 LUCI-TryBot-Result: Go LUCI Reviewed-by: Alan Donovan --- src/cmd/go/internal/modload/init.go | 38 ++++++++++++------- .../script/work_no_mod_root_issue54419.txt | 13 +++++++ 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 src/cmd/go/testdata/script/work_no_mod_root_issue54419.txt diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go index 1ffe5052fb..41b3b9df1b 100644 --- a/src/cmd/go/internal/modload/init.go +++ b/src/cmd/go/internal/modload/init.go @@ -610,7 +610,7 @@ func inWorkspaceMode() bool { return workFilePath != "" } -// HasModRoot reports whether a main module is present. +// HasModRoot reports whether a main module or main modules are present. // HasModRoot may return false even if Enabled returns true: for example, 'get' // does not require a main module. func HasModRoot() bool { @@ -646,24 +646,34 @@ func die() { if cfg.Getenv("GO111MODULE") == "off" { base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") } - if inWorkspaceMode() { - base.Fatalf("go: no modules were found in the current workspace; see 'go help work'") - } - if dir, name := findAltConfig(base.Cwd()); dir != "" { - rel, err := filepath.Rel(base.Cwd(), dir) - if err != nil { - rel = dir - } - cdCmd := "" - if rel != "." { - cdCmd = fmt.Sprintf("cd %s && ", rel) + if !inWorkspaceMode() { + if dir, name := findAltConfig(base.Cwd()); dir != "" { + rel, err := filepath.Rel(base.Cwd(), dir) + if err != nil { + rel = dir + } + cdCmd := "" + if rel != "." { + cdCmd = fmt.Sprintf("cd %s && ", rel) + } + 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.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) } -var ErrNoModRoot = errors.New("go.mod file not found in current directory or any parent directory; see 'go help modules'") +// 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{} + +func (e noMainModulesError) Error() string { + if 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 type goModDirtyError struct{} diff --git a/src/cmd/go/testdata/script/work_no_mod_root_issue54419.txt b/src/cmd/go/testdata/script/work_no_mod_root_issue54419.txt new file mode 100644 index 0000000000..385044d863 --- /dev/null +++ b/src/cmd/go/testdata/script/work_no_mod_root_issue54419.txt @@ -0,0 +1,13 @@ +cd m +! go mod download +stderr 'no modules were found in the current workspace' + +! go list -m all +stderr 'no modules were found in the current workspace' + +-- go.work -- +go 1.25 +-- m/go.mod -- +module example.com/m + +go 1.25 -- 2.50.0