cliverage/coverage/reader.go

117 lines
2.6 KiB
Go

package coverage
import (
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
// Parse creates a coverage files struct from a coverage file format
// you must provide @gopkg which is the package name
func Parse(r io.Reader, gopkg string) (*Files, error) {
reader := bufio.NewReader(r)
eof := false
var n uint = 0
files := &Files{
Files: make(map[string]File),
packagePath: gopkg,
}
// read loop
for true {
n++
if eof {
break
}
notrim, err := reader.ReadString('\n')
if err == io.EOF {
if len(notrim) > 0 {
eof = true
} else {
break
}
}
line := strings.Trim(notrim, " \t\r\n")
if len(line) < 1 {
continue
}
// ignore first line
if n == 1 && line == "mode: set" {
continue
}
// extract features from line
var cover = Coverage{}
// format: filename:startLine.startColumn,endLine.endColumn occurences count
splitFile := strings.Split(line, ":")
if len(splitFile) != 2 {
return nil, fmt.Errorf("invalid format line %d", n)
}
filename := splitFile[0]
if !strings.HasPrefix(filename, gopkg) {
return nil, fmt.Errorf("invalid package name '%s' on line %d", gopkg, n)
}
filename = strings.TrimPrefix(filename, gopkg)
if len(filename) < 2 {
return nil, fmt.Errorf("invalid format line %d", n)
}
// remove starting '/'
if filename[0] == '/' {
filename = filename[1:]
}
splitSpace := strings.Split(splitFile[1], " ")
if len(splitSpace) != 3 {
return nil, fmt.Errorf("invalid format line %d", n)
}
separators := strings.Split(splitSpace[0], ",")
if len(separators) != 2 {
return nil, fmt.Errorf("invalid format line %d", n)
}
splitStart := strings.Split(separators[0], ".")
if len(splitStart) != 2 {
return nil, fmt.Errorf("invalid format line %d", n)
}
cover.StartLine, err = strconv.ParseUint(splitStart[0], 10, 64)
if err != nil {
return nil, fmt.Errorf("invalid format line %d", n)
}
cover.StartColumn, err = strconv.ParseUint(splitStart[1], 10, 64)
if err != nil {
return nil, fmt.Errorf("invalid format line %d", n)
}
splitEnd := strings.Split(separators[1], ".")
if len(splitEnd) != 2 {
return nil, fmt.Errorf("invalid format line %d", n)
}
cover.EndLine, err = strconv.ParseUint(splitEnd[0], 10, 64)
if err != nil {
return nil, fmt.Errorf("invalid format line %d", n)
}
cover.EndColumn, err = strconv.ParseUint(splitEnd[1], 10, 64)
if err != nil {
return nil, fmt.Errorf("invalid format line %d", n)
}
// append to files
_, isset := files.Files[filename]
if !isset {
files.Files[filename] = make(File, 0)
}
files.Files[filename] = append(files.Files[filename], cover)
}
return files, nil
}