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:
Rob Pike 2013-10-03 16:37:34 -07:00
parent 40ede1040a
commit 51613a10d7
3 changed files with 35 additions and 23 deletions

View File

@ -29,13 +29,7 @@ import (
// total: (statements) 91.4%
func funcOutput(profile, outputFile string) error {
pf, err := os.Open(profile)
if err != nil {
return err
}
defer pf.Close()
profiles, err := ParseProfiles(pf)
profiles, err := ParseProfiles(profile)
if err != nil {
return err
}
@ -57,7 +51,8 @@ func funcOutput(profile, outputFile string) error {
defer tabber.Flush()
var total, covered int64
for fn, profile := range profiles {
for _, profile := range profiles {
fn := profile.FileName
file, err := findFile(fn)
if err != nil {
return err

View File

@ -22,20 +22,15 @@ import (
// 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 {
pf, err := os.Open(profile)
if err != nil {
return err
}
defer pf.Close()
profiles, err := ParseProfiles(pf)
profiles, err := ParseProfiles(profile)
if err != nil {
return err
}
var d templateData
for fn, profile := range profiles {
for _, profile := range profiles {
fn := profile.FileName
if profile.Mode == "set" {
d.Set = true
}

View File

@ -8,8 +8,8 @@ import (
"bufio"
"fmt"
"go/build"
"io"
"math"
"os"
"path/filepath"
"regexp"
"sort"
@ -19,8 +19,9 @@ import (
// Profile represents the profiling data for a specific file.
type Profile struct {
Mode string
Blocks []ProfileBlock
FileName string
Mode string
Blocks []ProfileBlock
}
// ProfileBlock represents a single block of profiling data.
@ -30,11 +31,23 @@ type ProfileBlock struct {
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
// 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)
buf := bufio.NewReader(r)
buf := bufio.NewReader(pf)
// First line is "mode: foo", where foo is "set", "count", or "atomic".
// Rest of file is in the format
// 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]
p := files[fn]
if p == nil {
p = &Profile{Mode: mode}
p = &Profile{
FileName: fn,
Mode: mode,
}
files[fn] = p
}
p.Blocks = append(p.Blocks, ProfileBlock{
@ -76,7 +92,13 @@ func ParseProfiles(r io.Reader) (map[string]*Profile, error) {
for _, p := range files {
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