]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/{go,cover}: fix for -coverprofile path capture with local pkg
authorThan McIntosh <thanm@google.com>
Wed, 26 Oct 2022 15:33:28 +0000 (11:33 -0400)
committerThan McIntosh <thanm@google.com>
Tue, 1 Nov 2022 14:11:54 +0000 (14:11 +0000)
When coverage testing a local package (defined by a relative import
path such as "./foo/bar") the convention when "-coverprofile" is used
has been to capture source files by full pathname, as opposed to
recording the full import path or the invented import path
("command-line-arguments/") created by the go command in the case of
building named Go files. Doing this makes it much easier to use
collected profiles with "go tool -cover -html=<profile>".

The support for this feature/convention wound up being inadvertantly
dropped during the GOEXPERIMENT=coverageredesign implementation; this
patch restores it.

Fixes #56433.

Change-Id: Ib9556fdc86011b00c155caa614ab23e5148f3eb4
Reviewed-on: https://go-review.googlesource.com/c/go/+/445917
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/cover/cover.go
src/cmd/go/internal/work/exec.go
src/cmd/go/testdata/script/cover_test_localpkg_filepath.txt [new file with mode: 0644]
src/internal/coverage/cmddefs.go

index 25574de7734ead7d90844455933ed6b9549f2ee1..53a5b6df41d2c8c2a89697bf5d1c98eceaf50ff6 100644 (file)
@@ -74,7 +74,7 @@ var (
 
 var pkgconfig coverage.CoverPkgConfig
 
-var outputfiles []string // set whe -pkgcfg is in use
+var outputfiles []string // set when -pkgcfg is in use
 
 var profile string // The profile to read; the value of -html or -func
 
@@ -484,6 +484,16 @@ func (f *File) postFunc(fn ast.Node, funcname string, flit bool, body *ast.Block
        ppath := pkgconfig.PkgPath
        filename := ppath + "/" + filepath.Base(fnpos.Filename)
 
+       // The convention for cmd/cover is that if the go command that
+       // kicks off coverage specifies a local import path (e.g. "go test
+       // -cover ./thispackage"), the tool will capture full pathnames
+       // for source files instead of relative paths, which tend to work
+       // more smoothly for "go tool cover -html". See also issue #56433
+       // for more details.
+       if pkgconfig.Local {
+               filename = f.name
+       }
+
        // Hand off function to meta-data builder.
        fd := coverage.FuncDesc{
                Funcname: funcname,
index d0b5cbb53c85fe5cd2ce00362aa3ae0410e086d2..59eb373eaef38df0ae4cfe702c7686e2d07e2526 100644 (file)
@@ -1978,6 +1978,7 @@ func (b *Builder) writeCoverPkgInputs(a *Action, pconfigfile string, covoutputsf
                // depending on user demand.
                Granularity: "perblock",
                OutConfig:   p.Internal.CoverageCfg,
+               Local:       p.Internal.Local,
        }
        if a.Package.Module != nil {
                pcfg.ModulePath = a.Package.Module.Path
diff --git a/src/cmd/go/testdata/script/cover_test_localpkg_filepath.txt b/src/cmd/go/testdata/script/cover_test_localpkg_filepath.txt
new file mode 100644 (file)
index 0000000..17c5808
--- /dev/null
@@ -0,0 +1,40 @@
+
+[short] skip
+
+# collect coverage profile in text format
+go test -coverprofile=blah.prof prog.go prog_test.go
+
+# should not contain cmd-line pseudo-import-path
+grep prog.go blah.prof
+grep $PWD blah.prof
+! grep command-line-arguments blah.prof
+
+-- prog.go --
+package main
+
+func Mumble(x int) int {
+       if x < 0 {
+               return -x
+       }
+       return 42
+}
+
+func Grumble(y int) int {
+       return -y
+}
+
+func main() {
+}
+
+-- prog_test.go --
+package main
+
+import (
+       "testing"
+)
+
+func TestMumble(t *testing.T) {
+       if x := Mumble(10); x != 42 {
+               t.Errorf("Mumble(%d): got %d want %d", 10, x, 42)
+       }
+}
index a146ca53e470884109bdf8c76cfebf6c2133dc7d..b30c37a08f7946c724ca75daef46c8fed8803a6f 100644 (file)
@@ -25,6 +25,13 @@ type CoverPkgConfig struct {
 
        // Module path for this package (empty if no go.mod in use)
        ModulePath string
+
+       // Local mode indicates we're doing a coverage build or test of a
+       // package selected via local import path, e.g. "./..." or
+       // "./foo/bar" as opposed to a non-relative import path. See the
+       // corresponding field in cmd/go's PackageInternal struct for more
+       // info.
+       Local bool
 }
 
 // CoverFixupConfig contains annotations/notes generated by the