-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
lcov.go
129 lines (121 loc) · 2.51 KB
/
lcov.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package coverage
import (
"bufio"
"errors"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
)
var _ Processor = (*Lcov)(nil)
var LcovDefaultPath = []string{"coverage", "lcov.info"}
type Lcov struct{}
func NewLcov() *Lcov {
return &Lcov{}
}
func (l *Lcov) Name() string {
return "LCOV"
}
func (l *Lcov) ParseReport(path string) (*Coverage, string, error) {
rp, err := l.detectReportPath(path)
if err != nil {
return nil, "", err
}
r, err := os.Open(filepath.Clean(rp))
if err != nil {
return nil, "", err
}
scanner := bufio.NewScanner(r)
var (
fileName string
total, covered int
)
cov := New()
cov.Type = TypeLOC
cov.Format = l.Name()
parsed := false
blocks := BlockCoverages{}
for scanner.Scan() {
l := scanner.Text()
if l == "end_of_record" {
fcov, err := cov.Files.FindByFile(fileName)
if err != nil {
fcov = NewFileCoverage(fileName, TypeLOC)
}
fcov.Total += total
fcov.Covered += covered
fcov.Blocks = blocks
cov.Total += total
cov.Covered += covered
cov.Files = append(cov.Files, fcov)
total = 0
covered = 0
parsed = true
blocks = BlockCoverages{}
continue
}
splitted := strings.Split(l, ":")
if len(splitted) != 2 {
continue
}
switch splitted[0] {
case "SF":
fileName = splitted[1]
case "DA":
total += 1
nums := strings.Split(splitted[1], ",")
if len(nums) != 2 {
_ = r.Close() //nostyle:handlerrors
return nil, "", fmt.Errorf("can not parse: %s", l)
}
line, err := strconv.Atoi(nums[0])
if err != nil {
_ = r.Close() //nostyle:handlerrors
return nil, "", err
}
count, err := strconv.Atoi(nums[1])
if err != nil {
_ = r.Close() //nostyle:handlerrors
return nil, "", err
}
if count > 0 {
covered += 1
}
blocks = append(blocks, &BlockCoverage{
Type: TypeLOC,
StartLine: &line,
EndLine: &line,
Count: &count,
})
default:
// not implemented
}
}
if err := r.Close(); err != nil {
return nil, "", err
}
if !parsed {
return nil, "", errors.New("can not parse")
}
return cov, rp, nil
}
func (l *Lcov) detectReportPath(path string) (string, error) {
p, err := os.Stat(path)
if err != nil {
return "", err
}
if p.IsDir() {
// path/to/coverage/lcov.info
np := filepath.Join(path, LcovDefaultPath[0], LcovDefaultPath[1])
if _, err := os.Stat(np); err != nil {
// path/to/lcov.info
np = filepath.Join(path, LcovDefaultPath[1])
if _, err := os.Stat(np); err != nil {
return "", err
}
}
path = np
}
return path, nil
}