diff --git a/cmd/cover/cover.go b/cmd/cover/cover.go index c62c5918..9c15f41b 100644 --- a/cmd/cover/cover.go +++ b/cmd/cover/cover.go @@ -83,7 +83,7 @@ func main() { // Generate coverage-annotated source. if *mode != "" { - cover(flag.Arg(0)) + annotate(flag.Arg(0)) return } @@ -319,7 +319,7 @@ func initialComments(content []byte) []byte { return content[:end] } -func cover(name string) { +func annotate(name string) { fset := token.NewFileSet() content, err := ioutil.ReadFile(name) if err != nil { diff --git a/cmd/cover/func.go b/cmd/cover/func.go index c94a01cb..649fc9e7 100644 --- a/cmd/cover/func.go +++ b/cmd/cover/func.go @@ -10,10 +10,14 @@ import ( "bufio" "fmt" "go/ast" + "go/build" "go/parser" "go/token" "os" + "path/filepath" "text/tabwriter" + + "code.google.com/p/go.tools/cover" ) // funcOutput takes two file names as arguments, a coverage profile to read as input and an output @@ -29,7 +33,7 @@ import ( // total: (statements) 91.4% func funcOutput(profile, outputFile string) error { - profiles, err := ParseProfiles(profile) + profiles, err := cover.ParseProfiles(profile) if err != nil { return err } @@ -126,7 +130,7 @@ func (v *FuncVisitor) Visit(node ast.Node) ast.Visitor { } // coverage returns the fraction of the statements in the function that were covered, as a numerator and denominator. -func (f *FuncExtent) coverage(profile *Profile) (num, den int64) { +func (f *FuncExtent) coverage(profile *cover.Profile) (num, den int64) { // We could avoid making this n^2 overall by doing a single scan and annotating the functions, // but the sizes of the data structures is never very large and the scan is almost instantaneous. var covered, total int64 @@ -150,3 +154,13 @@ func (f *FuncExtent) coverage(profile *Profile) (num, den int64) { } return covered, total } + +// findFile finds the location of the named file in GOROOT, GOPATH etc. +func findFile(file string) (string, error) { + dir, file := filepath.Split(file) + pkg, err := build.Import(dir, ".", build.FindOnly) + if err != nil { + return "", fmt.Errorf("can't find %q: %v", file, err) + } + return filepath.Join(pkg.Dir, file), nil +} diff --git a/cmd/cover/html.go b/cmd/cover/html.go index ae845940..c54ef4d3 100644 --- a/cmd/cover/html.go +++ b/cmd/cover/html.go @@ -16,13 +16,15 @@ import ( "os/exec" "path/filepath" "runtime" + + "code.google.com/p/go.tools/cover" ) // htmlOutput reads the profile data from profile and generates an HTML // coverage report, writing it to outfile. If outfile is empty, // it writes the report to a temporary file and opens it in a web browser. func htmlOutput(profile, outfile string) error { - profiles, err := ParseProfiles(profile) + profiles, err := cover.ParseProfiles(profile) if err != nil { return err } @@ -83,7 +85,7 @@ func htmlOutput(profile, outfile string) error { // htmlGen generates an HTML coverage report with the provided filename, // source code, and tokens, and writes it to the given Writer. -func htmlGen(w io.Writer, src []byte, boundaries []Boundary) error { +func htmlGen(w io.Writer, src []byte, boundaries []cover.Boundary) error { dst := bufio.NewWriter(w) for i := range src { for len(boundaries) > 0 && boundaries[0].Offset == i { diff --git a/cmd/cover/profile.go b/cover/profile.go similarity index 91% rename from cmd/cover/profile.go rename to cover/profile.go index 53c592f2..1cbd7398 100644 --- a/cmd/cover/profile.go +++ b/cover/profile.go @@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package main +// Package cover provides support for parsing coverage profiles +// generated by "go test -coverprofile=cover.out". +package cover import ( "bufio" "fmt" - "go/build" "math" "os" - "path/filepath" "regexp" "sort" "strconv" @@ -37,10 +37,10 @@ func (p byFileName) Len() int { return len(p) } func (p byFileName) Less(i, j int) bool { return p[i].FileName < p[j].FileName } func (p byFileName) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -// ParseProfiles parses profile data from the given Reader and returns a -// Profile for each file. +// ParseProfiles parses profile data in the specified file and returns a +// Profile for each source file described therein. func ParseProfiles(fileName string) ([]*Profile, error) { - pf, err := os.Open(profile) + pf, err := os.Open(fileName) if err != nil { return nil, err } @@ -188,13 +188,3 @@ func (b boundariesByPos) Less(i, j int) bool { } return b[i].Offset < b[j].Offset } - -// findFile finds the location of the named file in GOROOT, GOPATH etc. -func findFile(file string) (string, error) { - dir, file := filepath.Split(file) - pkg, err := build.Import(dir, ".", build.FindOnly) - if err != nil { - return "", fmt.Errorf("can't find %q: %v", file, err) - } - return filepath.Join(pkg.Dir, file), nil -}