1
0
mirror of https://github.com/golang/go synced 2024-11-21 16:34:42 -07:00

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
This commit is contained in:
Matthew Hughes 2024-03-05 20:24:38 +00:00
parent 071b8d51c1
commit 1c0d215b93
2 changed files with 94 additions and 1 deletions

View File

@ -858,7 +858,10 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
if cfg.BuildCoverPkg != nil { if cfg.BuildCoverPkg != nil {
match := make([]func(*load.Package) bool, len(cfg.BuildCoverPkg)) match := make([]func(*load.Package) bool, len(cfg.BuildCoverPkg))
for i := range cfg.BuildCoverPkg { for i := range cfg.BuildCoverPkg {
match[i] = load.MatchPackage(cfg.BuildCoverPkg[i], base.Cwd()) match[i] = func(p *load.Package) bool {
cwd := base.Cwd()
return load.MatchPackage(cfg.BuildCoverPkg[i], cwd)(p) && !isUnderSpecial(cwd, p.Dir)
}
} }
// Select for coverage all dependencies matching the -coverpkg // Select for coverage all dependencies matching the -coverpkg
@ -2112,3 +2115,36 @@ func testBinaryName(p *load.Package) string {
return elem + ".test" return elem + ".test"
} }
// isUnderSpecial checks whether dir is contained within a 'special' directory under 'cwd'.
// A directory is special if it beings with "." or "_" , or is called "testdata"
func isUnderSpecial(cwd string, dir string) bool {
rel, err := filepath.Rel(cwd, dir)
if err != nil {
return false
}
hasAnyPrefix := func(dir string, prefixes ...string) bool {
for _, prefix := range prefixes {
if strings.HasPrefix(dir, prefix) {
return true
}
}
return false
}
sep := string(filepath.Separator)
if rel == "." || hasAnyPrefix(rel, ".."+sep) {
// Not a special directory under 'cwd', so can return immediately
return false
}
// Otherwise avoid special directories "testdata" or beginning with ".", "_".
pathComponents := strings.Split(rel, sep)
for _, elem := range pathComponents {
if hasAnyPrefix(elem, ".", "_") || elem == "testdata" {
return true
}
}
return false
}

View File

@ -0,0 +1,57 @@
# test for https://github.com/golang/go/issues/66038
[short] skip
env GO111MODULE=off
# files
env GOPATH=$WORK/.dir${:}$WORK/_dir${:}$WORK/testdata
cd $WORK
go test -coverpkg=./... ./...
stdout 'coverage: 100.0%'
-- $WORK/a.go --
package a
// trivial function with 100% test coverage
import (
_ "dot_dir"
_ "under_dir"
_ "testdata_dir"
)
func F(i int) int {
return i*i
}
-- $WORK/a_test.go --
package a
import (
"testing"
)
func TestF(t *testing.T) {
F(2)
}
-- $WORK/.dir/src/dot_dir/b.go --
package dot_dir
func G(i int) int {
return i*i
}
-- $WORK/_dir/src/under_dir/b.go --
package dot_dir
func G(i int) int {
return i*i
}
-- $WORK/testdata/src/testdata_dir/b.go --
package testdata_dir
func G(i int) int {
return i*i
}