[go] cmd/go: make 'go get' fail with an error when outside a module

721 views
Skip to first unread message

Jay Conrod (Gerrit)

unread,
Sep 28, 2021, 1:19:14 PM9/28/21
to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Go Bot, Bryan C. Mills, Michael Matloob, golang-co...@googlegroups.com

Jay Conrod submitted this change.

View Change



4 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:

```
The name of the file: src/cmd/go/internal/modload/load.go
Insertions: 1, Deletions: 1.

@@ -458,7 +458,7 @@
absDir = filepath.Join(base.Cwd(), dir)
}

- modRoot := FindModuleRoot(absDir)
+ modRoot := findModuleRoot(absDir)
found := false
for _, mod := range MainModules.Versions() {
if MainModules.ModRoot(mod) == modRoot {
```
```
The name of the file: src/cmd/go/internal/modget/get.go
Insertions: 4, Deletions: 4.

@@ -36,7 +36,6 @@
"sync"

"cmd/go/internal/base"
- "cmd/go/internal/fsys"
"cmd/go/internal/imports"
"cmd/go/internal/modfetch"
"cmd/go/internal/modload"
@@ -274,6 +273,8 @@
base.Fatalf("go: -insecure flag is no longer supported; use GOINSECURE instead")
}

+ modload.ForceUseModules = true
+
// Do not allow any updating of go.mod until we've applied
// all the requested changes and checked that the result matches
// what was requested.
@@ -287,9 +288,8 @@
// if there's no go.mod file.
// TODO(#40775): make modload.Init return ErrNoModRoot instead of exiting.
// We could handle that here by printing a different message.
- modload.RootMode = modload.NeedRoot
- fsys.Init(base.Cwd())
- if modload.FindModuleRoot(base.Cwd()) == "" {
+ modload.Init()
+ if !modload.HasModRoot() {
base.Fatalf("go: go.mod file not found in current directory or any parent directory.\n" +
"\t'go get' is no longer supported outside a module.\n" +
"\tTo build and install a command, use 'go install' with a version,\n" +
```
```
The name of the file: src/cmd/go/internal/modload/init.go
Insertions: 5, Deletions: 9.

@@ -360,7 +360,7 @@
} else if inWorkspaceMode() {
// We're in workspace mode.
} else {
- if modRoot := FindModuleRoot(base.Cwd()); modRoot == "" {
+ if modRoot := findModuleRoot(base.Cwd()); modRoot == "" {
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.")
}
@@ -467,7 +467,7 @@
return false
}

- if modRoot := FindModuleRoot(base.Cwd()); modRoot == "" {
+ if modRoot := findModuleRoot(base.Cwd()); modRoot == "" {
// GO111MODULE is 'auto', and we can't find a module root.
// Stay in GOPATH mode.
return false
@@ -524,7 +524,7 @@
// module, even if -modfile is set.
func ModFilePath() string {
MustHaveModRoot()
- return modFilePath(FindModuleRoot(base.Cwd()))
+ return modFilePath(findModuleRoot(base.Cwd()))
}

func modFilePath(modRoot string) string {
@@ -899,7 +899,7 @@
panic("mainModulesCalled with module.Version with non empty Version field: " + fmt.Sprintf("%#v", m))
}
}
- modRootContainingCWD := FindModuleRoot(base.Cwd())
+ modRootContainingCWD := findModuleRoot(base.Cwd())
mainModules := &MainModuleSet{
versions: ms[:len(ms):len(ms)],
inGorootSrc: map[module.Version]bool{},
@@ -1137,11 +1137,7 @@
".git/config",
}

-// FindModuleRoot returns the directory containing the go.mod file that defines
-// the module containing dir. go.mod may be in dir itself or in any parent.
-// The overlay should be initialized first in case go.mod only exists in the
-// overlay.
-func FindModuleRoot(dir string) string {
+func findModuleRoot(dir string) (roots string) {
if dir == "" {
panic("dir not set")
}
```

Approvals: Bryan C. Mills: Looks good to me, approved Jay Conrod: Trusted; Run TryBots Go Bot: TryBots succeeded
cmd/go: make 'go get' fail with an error when outside a module

There's no go.mod file for 'go get' to update, so it has no effect,
other than checking arguments and filling the module cache. That might
be useul in some cases, but it seems better to fail loudly in case the
user hasn't seen the deprecation warning, for example, inside a
script.

For #43684

Change-Id: I6e67c782e3a1cb7046eac5c9df17eda7a31c7bce
Reviewed-on: https://go-review.googlesource.com/c/go/+/352149
Trust: Jay Conrod <jayc...@google.com>
Run-TryBot: Jay Conrod <jayc...@google.com>
TryBot-Result: Go Bot <go...@golang.org>
Reviewed-by: Bryan C. Mills <bcm...@google.com>
---
M src/cmd/go/internal/modget/get.go
M src/cmd/go/testdata/script/get_404_meta.txt
M src/cmd/go/testdata/script/mod_cache_dir.txt
R src/cmd/go/testdata/script/mod_download_insecure_redirect.txt
R src/cmd/go/testdata/script/mod_download_private_vcs.txt
R src/cmd/go/testdata/script/mod_download_too_many_redirects.txt
M src/cmd/go/testdata/script/mod_get_deprecate_install.txt
M src/cmd/go/testdata/script/mod_get_fallback.txt
M src/cmd/go/testdata/script/mod_get_go_file.txt
M src/cmd/go/testdata/script/mod_getx.txt
M src/cmd/go/testdata/script/mod_missing_repo.txt
M src/cmd/go/testdata/script/mod_outside.txt
12 files changed, 73 insertions(+), 37 deletions(-)

diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go
index 674ee1c..4d87d26 100644
--- a/src/cmd/go/internal/modget/get.go
+++ b/src/cmd/go/internal/modget/get.go
@@ -273,6 +273,8 @@
base.Fatalf("go: -insecure flag is no longer supported; use GOINSECURE instead")
}

+ modload.ForceUseModules = true
+
// Do not allow any updating of go.mod until we've applied
// all the requested changes and checked that the result matches
// what was requested.
@@ -282,6 +284,20 @@
// 'go get' is expected to do this, unlike other commands.
modload.AllowMissingModuleImports()

+ // 'go get' no longer builds or installs packages, so there's nothing to do
+ // if there's no go.mod file.
+ // TODO(#40775): make modload.Init return ErrNoModRoot instead of exiting.
+ // We could handle that here by printing a different message.
+ modload.Init()
+ if !modload.HasModRoot() {
+ base.Fatalf("go: go.mod file not found in current directory or any parent directory.\n" +
+ "\t'go get' is no longer supported outside a module.\n" +
+ "\tTo build and install a command, use 'go install' with a version,\n" +
+ "\tlike 'go install example.com/cmd@latest'\n" +
+ "\tFor more information, see https://golang.org/doc/go-get-install-deprecation\n" +
+ "\tor run 'go help get' or 'go help install'.")
+ }
+
queries := parseArgs(ctx, args)

r := newResolver(ctx, queries)
@@ -351,10 +367,6 @@
}
r.checkPackageProblems(ctx, pkgPatterns)

- if !modload.HasModRoot() {
- return
- }
-
// Everything succeeded. Update go.mod.
oldReqs := reqsFromGoMod(modload.ModFile())

diff --git a/src/cmd/go/testdata/script/get_404_meta.txt b/src/cmd/go/testdata/script/get_404_meta.txt
index ec4f8d3..3caf0bf 100644
--- a/src/cmd/go/testdata/script/get_404_meta.txt
+++ b/src/cmd/go/testdata/script/get_404_meta.txt
@@ -10,3 +10,9 @@
env GO111MODULE=on
env GOPROXY=direct
go get -d bazil.org/fuse/fs/fstestutil
+
+
+-- go.mod --
+module m
+
+go 1.18
diff --git a/src/cmd/go/testdata/script/mod_cache_dir.txt b/src/cmd/go/testdata/script/mod_cache_dir.txt
index 7284ccf..4045928 100644
--- a/src/cmd/go/testdata/script/mod_cache_dir.txt
+++ b/src/cmd/go/testdata/script/mod_cache_dir.txt
@@ -3,9 +3,9 @@
# Go should reject relative paths in GOMODCACHE environment.

env GOMODCACHE="~/test"
-! go get example.com/tools/cmd/hello
+! go install example.com/tools/cmd/hello@latest
stderr 'must be absolute path'

env GOMODCACHE="./test"
-! go get example.com/tools/cmd/hello
+! go install example.com/tools/cmd/hello@latest
stderr 'must be absolute path'
diff --git a/src/cmd/go/testdata/script/mod_get_insecure_redirect.txt b/src/cmd/go/testdata/script/mod_download_insecure_redirect.txt
similarity index 65%
rename from src/cmd/go/testdata/script/mod_get_insecure_redirect.txt
rename to src/cmd/go/testdata/script/mod_download_insecure_redirect.txt
index 2e12834..46eb666 100644
--- a/src/cmd/go/testdata/script/mod_get_insecure_redirect.txt
+++ b/src/cmd/go/testdata/script/mod_download_insecure_redirect.txt
@@ -7,26 +7,26 @@
env GOPROXY=direct
env GOSUMDB=off

-! go get -d vcs-test.golang.org/insecure/go/insecure
+! go mod download vcs-test.golang.org/insecure/go/insecure@latest
stderr 'redirected .* to insecure URL'

# insecure host
env GOINSECURE=vcs-test.golang.org
go clean -modcache
-go get -d vcs-test.golang.org/insecure/go/insecure
+go mod download vcs-test.golang.org/insecure/go/insecure@latest

# insecure glob host
env GOINSECURE=*.golang.org
go clean -modcache
-go get -d vcs-test.golang.org/insecure/go/insecure
+go mod download vcs-test.golang.org/insecure/go/insecure@latest

# insecure multiple host
env GOINSECURE=somewhere-else.com,*.golang.org
go clean -modcache
-go get -d vcs-test.golang.org/insecure/go/insecure
+go mod download vcs-test.golang.org/insecure/go/insecure@latest

# different insecure host does not fetch
env GOINSECURE=somewhere-else.com
go clean -modcache
-! go get -d vcs-test.golang.org/insecure/go/insecure
+! go mod download vcs-test.golang.org/insecure/go/insecure@latest
stderr 'redirected .* to insecure URL'
diff --git a/src/cmd/go/testdata/script/mod_get_private_vcs.txt b/src/cmd/go/testdata/script/mod_download_private_vcs.txt
similarity index 88%
rename from src/cmd/go/testdata/script/mod_get_private_vcs.txt
rename to src/cmd/go/testdata/script/mod_download_private_vcs.txt
index c8862f4..e126793 100644
--- a/src/cmd/go/testdata/script/mod_get_private_vcs.txt
+++ b/src/cmd/go/testdata/script/mod_download_private_vcs.txt
@@ -5,18 +5,18 @@
[!exec:git] skip
env GOPROXY=direct

-! go get github.com/golang/nonexist
+! go mod download github.com/golang/nonexist@latest
stderr 'Confirm the import path was entered correctly.'
stderr 'If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.'
! stdout .

# Fetching a nonexistent commit should return an "unknown revision"
# error message.
-! go get github.com/golang/term@86186f3aba07ed0212cfb944f3398997d2d07c6b
+! go mod download github.com/golang/term@86186f3aba07ed0212cfb944f3398997d2d07c6b
stderr '^go: github.com/golang/term@86186f3aba07ed0212cfb944f3398997d2d07c6b: invalid version: unknown revision 86186f3aba07ed0212cfb944f3398997d2d07c6b$'
! stdout .

-! go get github.com/golang/nonexist@master
+! go mod download github.com/golang/nonexist@master
stderr '^Confirm the import path was entered correctly.$'
stderr '^If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.$'
! stderr 'unknown revision'
diff --git a/src/cmd/go/testdata/script/mod_get_too_many_redirects.txt b/src/cmd/go/testdata/script/mod_download_too_many_redirects.txt
similarity index 69%
rename from src/cmd/go/testdata/script/mod_get_too_many_redirects.txt
rename to src/cmd/go/testdata/script/mod_download_too_many_redirects.txt
index 9cbe0d2..a6b5a59 100644
--- a/src/cmd/go/testdata/script/mod_get_too_many_redirects.txt
+++ b/src/cmd/go/testdata/script/mod_download_too_many_redirects.txt
@@ -3,8 +3,8 @@
env GOPROXY=$GOPROXYBASE/redirect/11
env GOSUMDB=off

-! go get -d rsc.io/qu...@v1.2.0
+! go mod download rsc.io/qu...@v1.2.0
stderr 'stopped after 10 redirects'

env GOPROXY=$GOPROXYBASE/redirect/9
-go get -d rsc.io/qu...@v1.2.0
+go mod download rsc.io/qu...@v1.2.0
diff --git a/src/cmd/go/testdata/script/mod_get_deprecate_install.txt b/src/cmd/go/testdata/script/mod_get_deprecate_install.txt
index ab1d6a4..03258f5 100644
--- a/src/cmd/go/testdata/script/mod_get_deprecate_install.txt
+++ b/src/cmd/go/testdata/script/mod_get_deprecate_install.txt
@@ -2,7 +2,10 @@

env GO111MODULE=on

-# TODO(#43684): test message outside module.
+# 'go get' outside a module prints an error.
+! go get example.com/cmd/a
+stderr '^go: go.mod file not found in current directory or any parent directory.$'
+stderr '^\t''go get'' is no longer supported outside a module.$'

cp go.mod.orig go.mod

diff --git a/src/cmd/go/testdata/script/mod_get_fallback.txt b/src/cmd/go/testdata/script/mod_get_fallback.txt
index 9733fa3..a61d5cb 100644
--- a/src/cmd/go/testdata/script/mod_get_fallback.txt
+++ b/src/cmd/go/testdata/script/mod_get_fallback.txt
@@ -8,3 +8,8 @@
go get -x -v -d golang.org/x/tools/cmd/goimports
stderr '# get https://proxy.golang.org/golang.org/x/tools/@v/list'
! stderr '# get https://golang.org'
+
+-- go.mod --
+module m
+
+go 1.18
diff --git a/src/cmd/go/testdata/script/mod_get_go_file.txt b/src/cmd/go/testdata/script/mod_get_go_file.txt
index 35a77a9..c81e491 100644
--- a/src/cmd/go/testdata/script/mod_get_go_file.txt
+++ b/src/cmd/go/testdata/script/mod_get_go_file.txt
@@ -58,6 +58,11 @@
rm test/test_dir.go


+-- go.mod --
+module m
+
+go 1.18
+
-- test.go --
package main
func main() {println("test")}
diff --git a/src/cmd/go/testdata/script/mod_getx.txt b/src/cmd/go/testdata/script/mod_getx.txt
index ccb8d13..ce9ef0d 100644
--- a/src/cmd/go/testdata/script/mod_getx.txt
+++ b/src/cmd/go/testdata/script/mod_getx.txt
@@ -12,3 +12,8 @@
stderr '^# get https://golang.org/x/text\?go-get=1$'
stderr '^# get https://golang.org/x/text\?go-get=1: 200 OK \([0-9.]+s\)$'
! stderr '^# get //.*'
+
+-- go.mod --
+module m
+
+go 1.18
diff --git a/src/cmd/go/testdata/script/mod_missing_repo.txt b/src/cmd/go/testdata/script/mod_missing_repo.txt
index 8dae85f..b91a8db 100644
--- a/src/cmd/go/testdata/script/mod_missing_repo.txt
+++ b/src/cmd/go/testdata/script/mod_missing_repo.txt
@@ -9,7 +9,7 @@
env GOPROXY=direct
env GOSUMDB=off

-! go get -d vcs-test.golang.org/go/missingrepo/missingrepo-git
+! go mod download vcs-test.golang.org/go/missingrepo/missingrepo-git@latest
stderr 'vcs-test.golang.org/go/missingrepo/missingrepo-git: git ls-remote .*: exit status .*'

-go get -d vcs-test.golang.org/go/missingrepo/missingrepo-git/notmissing
+go mod download vcs-test.golang.org/go/missingrepo/missingrepo-git/notmissing@latest
diff --git a/src/cmd/go/testdata/script/mod_outside.txt b/src/cmd/go/testdata/script/mod_outside.txt
index e5318ee..d9d364c 100644
--- a/src/cmd/go/testdata/script/mod_outside.txt
+++ b/src/cmd/go/testdata/script/mod_outside.txt
@@ -123,30 +123,30 @@
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'


-# 'go get' without arguments implicitly operates on the main module, and thus
-# should fail.
+# 'go get' has no go.mod file to update outside a module and should fail.
! go get
-stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
+stderr '^go: go.mod file not found in current directory or any parent directory.$'
+stderr '^\t''go get'' is no longer supported outside a module.$'
! go get -u
-stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
+stderr '^go: go.mod file not found in current directory or any parent directory.$'
+stderr '^\t''go get'' is no longer supported outside a module.$'
! go get -u ./needmod
-stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
-
-# 'go get -u all' upgrades the transitive import graph of the main module,
-# which is empty.
+stderr '^go: go.mod file not found in current directory or any parent directory.$'
+stderr '^\t''go get'' is no longer supported outside a module.$'
! go get -u all
-stderr '^go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$'
-
-# 'go get' should check the proposed module graph for consistency,
-# even though we won't write it anywhere.
+stderr '^go: go.mod file not found in current directory or any parent directory.$'
+stderr '^\t''go get'' is no longer supported outside a module.$'
! go get -d example.com/printv...@v1.0.0 example.com/version@none
-stderr '^go: example.com/printv...@v1.0.0 requires example.com/ver...@v1.0.0, not example.com/version@none$'
+stderr '^go: go.mod file not found in current directory or any parent directory.$'
+stderr '^\t''go get'' is no longer supported outside a module.$'

-# 'go get -d' should download and extract the source code needed to build the requested version.
-rm -r $GOPATH/pkg/mod/example.com
-go get -d example.com/printv...@v1.0.0
-exists $GOPATH/pkg/mod/example.com/printv...@v1.0.0
-exists $GOPATH/pkg/mod/example.com/ver...@v1.0.0
+# 'go get -d' should not download anything.
+go clean -modcache
+! go get -d example.com/printv...@v1.0.0
+stderr '^go: go.mod file not found in current directory or any parent directory.$'
+stderr '^\t''go get'' is no longer supported outside a module.$'
+! exists $GOPATH/pkg/mod/example.com/printv...@v1.0.0
+! exists $GOPATH/pkg/mod/example.com/ver...@v1.0.0


# 'go build' without arguments implicitly operates on the current directory, and should fail.

To view, visit change 352149. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I6e67c782e3a1cb7046eac5c9df17eda7a31c7bce
Gerrit-Change-Number: 352149
Gerrit-PatchSet: 6
Gerrit-Owner: Jay Conrod <jayc...@google.com>
Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
Gerrit-Reviewer: Go Bot <go...@golang.org>
Gerrit-Reviewer: Jay Conrod <jayc...@google.com>
Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages