@@ -26,16 +26,23 @@ import (
2626 "go/build"
2727 "go/parser"
2828 "go/token"
29+ "os"
2930 "path/filepath"
30-
31- "golang.org/x/tools/cover"
31+ "strings"
3232
3333 "github.com/axw/gocov"
3434 "github.com/axw/gocov/gocovutil"
35+ "golang.org/x/tools/cover"
3536)
3637
38+ type packagesCache map [string ]* build.Package
39+
3740func convertProfiles (filenames ... string ) error {
38- var ps gocovutil.Packages
41+ var (
42+ ps gocovutil.Packages
43+ packages = make (packagesCache )
44+ )
45+
3946 for i := range filenames {
4047 converter := converter {
4148 packages : make (map [string ]* gocov.Package ),
@@ -45,7 +52,7 @@ func convertProfiles(filenames ...string) error {
4552 return err
4653 }
4754 for _ , p := range profiles {
48- if err := converter .convertProfile (p ); err != nil {
55+ if err := converter .convertProfile (packages , p ); err != nil {
4956 return err
5057 }
5158 }
@@ -54,11 +61,9 @@ func convertProfiles(filenames ...string) error {
5461 ps .AddPackage (pkg )
5562 }
5663 }
57- bytes , err := marshalJson (ps )
58- if err != nil {
64+ if err := marshalJson (os .Stdout , ps ); err != nil {
5965 return err
6066 }
61- fmt .Println (string (bytes ))
6267 return nil
6368}
6469
@@ -72,8 +77,8 @@ type statement struct {
7277 * StmtExtent
7378}
7479
75- func (c * converter ) convertProfile (p * cover.Profile ) error {
76- file , pkgpath , err := findFile (p .FileName )
80+ func (c * converter ) convertProfile (packages packagesCache , p * cover.Profile ) error {
81+ file , pkgpath , err := findFile (packages , p .FileName )
7782 if err != nil {
7883 return err
7984 }
@@ -130,15 +135,20 @@ func (c *converter) convertProfile(p *cover.Profile) error {
130135}
131136
132137// findFile finds the location of the named file in GOROOT, GOPATH etc.
133- func findFile (file string ) (filename string , pkgpath string , err error ) {
138+ func findFile (packages packagesCache , file string ) (filename , pkgpath string , err error ) {
134139 dir , file := filepath .Split (file )
135140 if dir != "" {
136- dir = dir [: len (dir ) - 1 ] // drop trailing '/'
141+ dir = strings . TrimSuffix (dir , "/" )
137142 }
138- pkg , err := build .Import (dir , "." , build .FindOnly )
139- if err != nil {
140- return "" , "" , fmt .Errorf ("can't find %q: %v" , file , err )
143+ pkg , ok := packages [dir ]
144+ if ! ok {
145+ pkg , err = build .Import (dir , "." , build .FindOnly )
146+ if err != nil {
147+ return "" , "" , fmt .Errorf ("can't find %q: %w" , file , err )
148+ }
149+ packages [dir ] = pkg
141150 }
151+
142152 return filepath .Join (pkg .Dir , file ), pkg .ImportPath , nil
143153}
144154
0 commit comments