go.tools/cmd/cover: sort the file names in the output presentation
Present the files in lexical order so the output is reproducible and easier to navigate. Do a little type rearrangement to simplify things while we're there. R=adg CC=golang-dev https://golang.org/cl/14357043
This commit is contained in:
parent
40ede1040a
commit
51613a10d7
|
@ -29,13 +29,7 @@ import (
|
||||||
// total: (statements) 91.4%
|
// total: (statements) 91.4%
|
||||||
|
|
||||||
func funcOutput(profile, outputFile string) error {
|
func funcOutput(profile, outputFile string) error {
|
||||||
pf, err := os.Open(profile)
|
profiles, err := ParseProfiles(profile)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer pf.Close()
|
|
||||||
|
|
||||||
profiles, err := ParseProfiles(pf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -57,7 +51,8 @@ func funcOutput(profile, outputFile string) error {
|
||||||
defer tabber.Flush()
|
defer tabber.Flush()
|
||||||
|
|
||||||
var total, covered int64
|
var total, covered int64
|
||||||
for fn, profile := range profiles {
|
for _, profile := range profiles {
|
||||||
|
fn := profile.FileName
|
||||||
file, err := findFile(fn)
|
file, err := findFile(fn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -22,20 +22,15 @@ import (
|
||||||
// coverage report, writing it to outfile. If outfile is empty,
|
// 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.
|
// it writes the report to a temporary file and opens it in a web browser.
|
||||||
func htmlOutput(profile, outfile string) error {
|
func htmlOutput(profile, outfile string) error {
|
||||||
pf, err := os.Open(profile)
|
profiles, err := ParseProfiles(profile)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer pf.Close()
|
|
||||||
|
|
||||||
profiles, err := ParseProfiles(pf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var d templateData
|
var d templateData
|
||||||
|
|
||||||
for fn, profile := range profiles {
|
for _, profile := range profiles {
|
||||||
|
fn := profile.FileName
|
||||||
if profile.Mode == "set" {
|
if profile.Mode == "set" {
|
||||||
d.Set = true
|
d.Set = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/build"
|
"go/build"
|
||||||
"io"
|
|
||||||
"math"
|
"math"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -19,8 +19,9 @@ import (
|
||||||
|
|
||||||
// Profile represents the profiling data for a specific file.
|
// Profile represents the profiling data for a specific file.
|
||||||
type Profile struct {
|
type Profile struct {
|
||||||
Mode string
|
FileName string
|
||||||
Blocks []ProfileBlock
|
Mode string
|
||||||
|
Blocks []ProfileBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProfileBlock represents a single block of profiling data.
|
// ProfileBlock represents a single block of profiling data.
|
||||||
|
@ -30,11 +31,23 @@ type ProfileBlock struct {
|
||||||
NumStmt, Count int
|
NumStmt, Count int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type byFileName []*Profile
|
||||||
|
|
||||||
|
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
|
// ParseProfiles parses profile data from the given Reader and returns a
|
||||||
// Profile for each file.
|
// Profile for each file.
|
||||||
func ParseProfiles(r io.Reader) (map[string]*Profile, error) {
|
func ParseProfiles(fileName string) ([]*Profile, error) {
|
||||||
|
pf, err := os.Open(profile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer pf.Close()
|
||||||
|
|
||||||
files := make(map[string]*Profile)
|
files := make(map[string]*Profile)
|
||||||
buf := bufio.NewReader(r)
|
buf := bufio.NewReader(pf)
|
||||||
// First line is "mode: foo", where foo is "set", "count", or "atomic".
|
// First line is "mode: foo", where foo is "set", "count", or "atomic".
|
||||||
// Rest of file is in the format
|
// Rest of file is in the format
|
||||||
// encoding/base64/base64.go:34.44,37.40 3 1
|
// encoding/base64/base64.go:34.44,37.40 3 1
|
||||||
|
@ -58,7 +71,10 @@ func ParseProfiles(r io.Reader) (map[string]*Profile, error) {
|
||||||
fn := m[1]
|
fn := m[1]
|
||||||
p := files[fn]
|
p := files[fn]
|
||||||
if p == nil {
|
if p == nil {
|
||||||
p = &Profile{Mode: mode}
|
p = &Profile{
|
||||||
|
FileName: fn,
|
||||||
|
Mode: mode,
|
||||||
|
}
|
||||||
files[fn] = p
|
files[fn] = p
|
||||||
}
|
}
|
||||||
p.Blocks = append(p.Blocks, ProfileBlock{
|
p.Blocks = append(p.Blocks, ProfileBlock{
|
||||||
|
@ -76,7 +92,13 @@ func ParseProfiles(r io.Reader) (map[string]*Profile, error) {
|
||||||
for _, p := range files {
|
for _, p := range files {
|
||||||
sort.Sort(blocksByStart(p.Blocks))
|
sort.Sort(blocksByStart(p.Blocks))
|
||||||
}
|
}
|
||||||
return files, nil
|
// Generate a sorted slice.
|
||||||
|
profiles := make([]*Profile, 0, len(files))
|
||||||
|
for _, profile := range files {
|
||||||
|
profiles = append(profiles, profile)
|
||||||
|
}
|
||||||
|
sort.Sort(byFileName(profiles))
|
||||||
|
return profiles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type blocksByStart []ProfileBlock
|
type blocksByStart []ProfileBlock
|
||||||
|
|
Loading…
Reference in New Issue