Skip to content

Commit f48bd17

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 Two tests are added for this change, one is a regression test attempting to directly replicate the behaviour described in the issue, the other is updating another test I saw fail when trialling other solutions to this issue so I thought it worthwhile to be explicit about the change there. See linked issue for a reproduction. Fixes #66038 [1] https://go.googlesource.com/go/+/16e5d24480dca7ddcbdffb78a8ed5de3e5155dec/src/cmd/doc/dirs.go#136
1 parent 94aeedc commit f48bd17

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

Diff for: src/cmd/go/internal/test/test.go

+37-1
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,10 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
858858
if cfg.BuildCoverPkg != nil {
859859
match := make([]func(*load.Package) bool, len(cfg.BuildCoverPkg))
860860
for i := range cfg.BuildCoverPkg {
861-
match[i] = load.MatchPackage(cfg.BuildCoverPkg[i], base.Cwd())
861+
match[i] = func(p *load.Package) bool {
862+
cwd := base.Cwd()
863+
return load.MatchPackage(cfg.BuildCoverPkg[i], cwd)(p) && !isUnderSpecial(cwd, p.Dir)
864+
}
862865
}
863866

864867
// Select for coverage all dependencies matching the -coverpkg
@@ -2112,3 +2115,36 @@ func testBinaryName(p *load.Package) string {
21122115

21132116
return elem + ".test"
21142117
}
2118+
2119+
// isUnderSpecial checks whether dir is contained within a 'special' directory under 'cwd'.
2120+
// A directory is special if it beings with "." or "_" , or is called "testdata"
2121+
func isUnderSpecial(cwd string, dir string) bool {
2122+
rel, err := filepath.Rel(cwd, dir)
2123+
if err != nil {
2124+
return false
2125+
}
2126+
2127+
hasAnyPrefix := func(dir string, prefixes ...string) bool {
2128+
for _, prefix := range prefixes {
2129+
if strings.HasPrefix(dir, prefix) {
2130+
return true
2131+
}
2132+
}
2133+
return false
2134+
}
2135+
2136+
sep := string(filepath.Separator)
2137+
if rel == "." || hasAnyPrefix(rel, ".."+sep) {
2138+
// Not a special directory under 'cwd', so can return immediately
2139+
return false
2140+
}
2141+
2142+
// Otherwise avoid special directories "testdata" or beginning with ".", "_".
2143+
pathComponents := strings.Split(rel, sep)
2144+
for _, elem := range pathComponents {
2145+
if hasAnyPrefix(elem, ".", "_") || elem == "testdata" {
2146+
return true
2147+
}
2148+
}
2149+
return false
2150+
}
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)