cmd/go: add modload.NeedRoot mode for commands that need module root
This makes error reporting a bit more consistent for 'go mod'
subcommands. Most of these commands only work in module mode when a
go.mod file is present.
Setting modload.ForceUseModules reports an error when GO111MODULE=off.
Setting modload.RootMode to modload.NeedRoot reports an error when no
go.mod file is present.
Change-Id: I1daa8d2971cb8658e0c804765839d903734a412e
Reviewed-on: https://go-review.googlesource.com/c/go/+/254369
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
diff --git a/src/cmd/go/internal/modcmd/download.go b/src/cmd/go/internal/modcmd/download.go
index 6227fd9..050a2e0 100644
--- a/src/cmd/go/internal/modcmd/download.go
+++ b/src/cmd/go/internal/modcmd/download.go
@@ -80,9 +80,7 @@
func runDownload(ctx context.Context, cmd *base.Command, args []string) {
// Check whether modules are enabled and whether we're in a module.
- if cfg.Getenv("GO111MODULE") == "off" {
- base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
- }
+ modload.ForceUseModules = true
if !modload.HasModRoot() && len(args) == 0 {
base.Fatalf("go mod download: no modules specified (see 'go help mod download')")
}
diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go
index a149b65..3277548 100644
--- a/src/cmd/go/internal/modcmd/graph.go
+++ b/src/cmd/go/internal/modcmd/graph.go
@@ -13,7 +13,6 @@
"sort"
"cmd/go/internal/base"
- "cmd/go/internal/cfg"
"cmd/go/internal/modload"
"golang.org/x/mod/module"
@@ -39,14 +38,8 @@
if len(args) > 0 {
base.Fatalf("go mod graph: graph takes no arguments")
}
- // Checks go mod expected behavior
- if !modload.Enabled() {
- if cfg.Getenv("GO111MODULE") == "off" {
- base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
- } else {
- base.Fatalf("go: cannot find main module; see 'go help modules'")
- }
- }
+ modload.ForceUseModules = true
+ modload.RootMode = modload.NeedRoot
modload.LoadAllModules(ctx)
reqs := modload.MinReqs()
diff --git a/src/cmd/go/internal/modcmd/init.go b/src/cmd/go/internal/modcmd/init.go
index 21b2356..7cfc0e6 100644
--- a/src/cmd/go/internal/modcmd/init.go
+++ b/src/cmd/go/internal/modcmd/init.go
@@ -40,9 +40,7 @@
if len(args) == 1 {
modload.CmdModModule = args[0]
}
- if os.Getenv("GO111MODULE") == "off" {
- base.Fatalf("go mod init: modules disabled by GO111MODULE=off; see 'go help modules'")
- }
+ modload.ForceUseModules = true
modFilePath := modload.ModFilePath()
if _, err := os.Stat(modFilePath); err == nil {
base.Fatalf("go mod init: go.mod already exists")
diff --git a/src/cmd/go/internal/modcmd/tidy.go b/src/cmd/go/internal/modcmd/tidy.go
index 30df674..cbe3ded 100644
--- a/src/cmd/go/internal/modcmd/tidy.go
+++ b/src/cmd/go/internal/modcmd/tidy.go
@@ -50,6 +50,8 @@
// that are in 'all' but outside of the main module, we must explicitly
// request that their test dependencies be included.
modload.LoadTests = true
+ modload.ForceUseModules = true
+ modload.RootMode = modload.NeedRoot
modload.LoadALL(ctx)
modload.TidyBuildList()
diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go
index 91d2509..44094b7 100644
--- a/src/cmd/go/internal/modcmd/vendor.go
+++ b/src/cmd/go/internal/modcmd/vendor.go
@@ -47,6 +47,8 @@
if len(args) != 0 {
base.Fatalf("go mod vendor: vendor takes no arguments")
}
+ modload.ForceUseModules = true
+ modload.RootMode = modload.NeedRoot
pkgs := modload.LoadVendor(ctx)
vdir := filepath.Join(modload.ModRoot(), "vendor")
diff --git a/src/cmd/go/internal/modcmd/verify.go b/src/cmd/go/internal/modcmd/verify.go
index 7700588..bd591d3 100644
--- a/src/cmd/go/internal/modcmd/verify.go
+++ b/src/cmd/go/internal/modcmd/verify.go
@@ -14,7 +14,6 @@
"runtime"
"cmd/go/internal/base"
- "cmd/go/internal/cfg"
"cmd/go/internal/modfetch"
"cmd/go/internal/modload"
@@ -45,14 +44,8 @@
// NOTE(rsc): Could take a module pattern.
base.Fatalf("go mod verify: verify takes no arguments")
}
- // Checks go mod expected behavior
- if !modload.Enabled() || !modload.HasModRoot() {
- if cfg.Getenv("GO111MODULE") == "off" {
- base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
- } else {
- base.Fatalf("go: cannot find main module; see 'go help modules'")
- }
- }
+ modload.ForceUseModules = true
+ modload.RootMode = modload.NeedRoot
// Only verify up to GOMAXPROCS zips at once.
type token struct{}
diff --git a/src/cmd/go/internal/modcmd/why.go b/src/cmd/go/internal/modcmd/why.go
index 8454fdf..ea7c28e 100644
--- a/src/cmd/go/internal/modcmd/why.go
+++ b/src/cmd/go/internal/modcmd/why.go
@@ -61,6 +61,8 @@
}
func runWhy(ctx context.Context, cmd *base.Command, args []string) {
+ modload.ForceUseModules = true
+ modload.RootMode = modload.NeedRoot
loadALL := modload.LoadALL
if *whyVendor {
loadALL = modload.LoadVendor
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index 2f0f60b..f93abee 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -77,8 +77,9 @@
// file the current directory or in parent directories.
NoRoot
- // TODO(jayconrod): add NeedRoot for commands like 'go mod vendor' that
- // don't make sense without a main module.
+ // NeedRoot is used for commands that must run in module mode and don't
+ // make sense without a main module.
+ NeedRoot
)
// ModFile returns the parsed go.mod file.
@@ -172,6 +173,9 @@
if cfg.ModFile != "" {
base.Fatalf("go: cannot find main module, but -modfile was set.\n\t-modfile cannot be used to set the module root directory.")
}
+ if RootMode == NeedRoot {
+ base.Fatalf("go: cannot find main module; see 'go help modules'")
+ }
if !mustUseModules {
// GO111MODULE is 'auto', and we can't find a module root.
// Stay in GOPATH mode.
diff --git a/src/cmd/go/testdata/script/mod_off.txt b/src/cmd/go/testdata/script/mod_off.txt
index cada6de..a73a58d 100644
--- a/src/cmd/go/testdata/script/mod_off.txt
+++ b/src/cmd/go/testdata/script/mod_off.txt
@@ -4,7 +4,7 @@
# GO111MODULE=off when outside of GOPATH will fatal
# with an error message, even with some source code in the directory and a go.mod.
! go mod init
-stderr 'go mod init: modules disabled by GO111MODULE=off; see ''go help modules'''
+stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules'''
! go mod graph
stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules'''
! go mod verify
@@ -16,7 +16,7 @@
mkdir z
cd z
! go mod init
-stderr 'go mod init: modules disabled by GO111MODULE=off; see ''go help modules'''
+stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules'''
! go mod graph
stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules'''
! go mod verify
diff --git a/src/cmd/go/testdata/script/mod_off_init.txt b/src/cmd/go/testdata/script/mod_off_init.txt
index 1339c8a..2aec0b3 100644
--- a/src/cmd/go/testdata/script/mod_off_init.txt
+++ b/src/cmd/go/testdata/script/mod_off_init.txt
@@ -2,4 +2,4 @@
# ignored anyway due to GO111MODULE=off.
env GO111MODULE=off
! go mod init
-stderr 'go mod init: modules disabled by GO111MODULE=off; see ''go help modules'''
+stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules'''