Skip to content

Commit c541b18

Browse files
cmd/go: fix -coverpkg not ignoring special directories
The pattern passed to `-coverpkg` when running `go test` would not ignore directories usually ignored by the `go` command, i.e. those beginning with "." or "_" are ignored by the go tool, as are directories named "testdata". Fix this by adding an explicit check for these (by following a similar check in `src/cmd/doc/dirs.go`[1]) allowing us to ignore them. The scope of the change is limted to package matching to only the -coverpkg flag of `go test` to avoid impacting -gcflags and the other per package flags, e.g. we don't want to change behaviour for a user building something that imports a leading dot package who wants to set gcflags for it See linked issue for a reproduction. Fixes #66038 [1] https://go.googlesource.com/go/+/16e5d24480dca7ddcbdffb78a8ed5de3e5155dec/src/cmd/doc/dirs.go#136
1 parent 09d76e5 commit c541b18

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

src/cmd/go/internal/test/test.go

+37-1
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,10 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
861861
if cfg.BuildCoverPkg != nil {
862862
match := make([]func(*load.Package) bool, len(cfg.BuildCoverPkg))
863863
for i := range cfg.BuildCoverPkg {
864-
match[i] = load.MatchPackage(cfg.BuildCoverPkg[i], base.Cwd())
864+
match[i] = func(p *load.Package) bool {
865+
cwd := base.Cwd()
866+
return load.MatchPackage(cfg.BuildCoverPkg[i], cwd)(p) && !isUnderSpecial(cwd, p.Dir)
867+
}
865868
}
866869

867870
// Select for coverage all dependencies matching the -coverpkg
@@ -2211,3 +2214,36 @@ func testBinaryName(p *load.Package) string {
22112214

22122215
return elem + ".test"
22132216
}
2217+
2218+
// isUnderSpecial checks whether dir is contained within a 'special' directory under 'cwd'.
2219+
// A directory is special if it beings with "." or "_" , or is called "testdata"
2220+
func isUnderSpecial(cwd string, dir string) bool {
2221+
rel, err := filepath.Rel(cwd, dir)
2222+
if err != nil {
2223+
return false
2224+
}
2225+
2226+
hasAnyPrefix := func(dir string, prefixes ...string) bool {
2227+
for _, prefix := range prefixes {
2228+
if strings.HasPrefix(dir, prefix) {
2229+
return true
2230+
}
2231+
}
2232+
return false
2233+
}
2234+
2235+
sep := string(filepath.Separator)
2236+
if rel == "." || hasAnyPrefix(rel, ".."+sep) {
2237+
// Not a special directory under 'cwd', so can return immediately
2238+
return false
2239+
}
2240+
2241+
// Otherwise avoid special directories "testdata" or beginning with ".", "_".
2242+
pathComponents := strings.Split(rel, sep)
2243+
for _, elem := range pathComponents {
2244+
if hasAnyPrefix(elem, ".", "_") || elem == "testdata" {
2245+
return true
2246+
}
2247+
}
2248+
return false
2249+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# test for https://github.com/golang/go/issues/66038
2+
[short] skip
3+
4+
env GO111MODULE=off
5+
# files
6+
env GOPATH=$WORK/.dir${:}$WORK/_dir${:}$WORK/testdata
7+
8+
cd $WORK
9+
go test -coverpkg=./... ./...
10+
stdout 'coverage: 100.0%'
11+
12+
-- $WORK/a.go --
13+
package a
14+
15+
// trivial function with 100% test coverage
16+
17+
import (
18+
_ "dot_dir"
19+
_ "under_dir"
20+
_ "testdata_dir"
21+
)
22+
23+
func F(i int) int {
24+
return i*i
25+
}
26+
27+
-- $WORK/a_test.go --
28+
package a
29+
30+
import (
31+
"testing"
32+
)
33+
34+
func TestF(t *testing.T) {
35+
F(2)
36+
}
37+
38+
-- $WORK/.dir/src/dot_dir/b.go --
39+
package dot_dir
40+
41+
func G(i int) int {
42+
return i*i
43+
}
44+
45+
-- $WORK/_dir/src/under_dir/b.go --
46+
package dot_dir
47+
48+
func G(i int) int {
49+
return i*i
50+
}
51+
52+
-- $WORK/testdata/src/testdata_dir/b.go --
53+
package testdata_dir
54+
55+
func G(i int) int {
56+
return i*i
57+
}

0 commit comments

Comments
 (0)