Skip to content

Commit 0652c80

Browse files
committed
cmd/go: emit an error for extraneous files in GOROOT/src in module mode
If there's a go file immediately in GOROOT/src, it was probably accidentally added by the user. Since that package shouldn't exist, return an error if a user tries to list it. We're only making this change for GOPATH mode because we don't want to break cases where users have been doing this historically, but want to fix this case for the future. This also leaves open the weird cases where files are placed directly in vendor directories. Fixes #36587 Change-Id: I9738e47b1e89fd5048cbb8dd28e44648834b8ea7 Reviewed-on: https://go-review.googlesource.com/c/go/+/216381 Run-TryBot: Michael Matloob <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Jay Conrod <[email protected]>
1 parent f0ee49b commit 0652c80

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

src/cmd/go/internal/modload/import.go

+2
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ func Import(path string) (m module.Version, dir string, err error) {
126126
}
127127
dir := filepath.Join(cfg.GOROOT, "src", path)
128128
return module.Version{}, dir, nil
129+
} else if pathIsStd && path == cfg.GOROOTsrc {
130+
return module.Version{}, dir, errors.New("directory should not directly contain source files")
129131
}
130132

131133
// -mod=vendor is special.

src/cmd/go/internal/modload/load.go

+6
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match {
126126
// It's not strictly necessary but helpful to keep the checks.
127127
if modRoot != "" && dir == modRoot {
128128
pkg = targetPrefix
129+
if modRoot == cfg.GOROOTsrc {
130+
// A package in GOROOT/src would have an empty path.
131+
// Keep the path as cfg.GOROOTsrc. We'll report an error in Import.
132+
// See golang.org/issue/36587.
133+
pkg = modRoot
134+
}
129135
} else if modRoot != "" && strings.HasPrefix(dir, modRoot+string(filepath.Separator)) && !strings.Contains(dir[len(modRoot):], "@") {
130136
suffix := filepath.ToSlash(dir[len(modRoot):])
131137
if strings.HasPrefix(suffix, "/vendor/") {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Return an error if the user tries to list a go source file directly in $GOROOT/src.
2+
# Tests golang.org/issue/36587
3+
4+
mkdir $WORK/fakegoroot/src
5+
mkdir $WORK/fakegopath/src
6+
7+
env GOROOT=$WORK/fakegoroot
8+
env GOPATH=$WORK/fakegopath
9+
10+
cp go.mod $GOROOT/src/go.mod
11+
cp foo.go $GOROOT/src/foo.go
12+
13+
go env GOROOT
14+
stdout $WORK(/|\\)fakegoroot
15+
16+
# switch to GOROOT/src
17+
cd $GOROOT/src
18+
19+
# GO111MODULE=on,GOROOT
20+
env GO111MODULE=on
21+
! go list ./...
22+
stderr 'directory should not directly contain source files'
23+
go list -e .
24+
go list -f '{{if .Error}}{{.Error.Err}}{{end}}' -e ./...
25+
stdout 'directory should not directly contain source files'
26+
27+
# GO111MODULE=off,GOROOT
28+
env GO111MODULE=off
29+
go list ./...
30+
[!windows] stdout _$WORK/fakegoroot/src
31+
[windows] stdout fakegoroot/src # On windows the ":" in the volume name is mangled
32+
33+
# switch to GOPATH/src
34+
cp $WORK/gopath/src/foo.go $GOPATH/src/foo.go
35+
cd $GOPATH/src
36+
37+
# GO111MODULE=off,GOPATH
38+
env GO111MODULE=off
39+
go list ./...
40+
41+
-- go.mod --
42+
module g
43+
44+
go 1.14
45+
-- foo.go --
46+
package foo

0 commit comments

Comments
 (0)