cliverage/print.go

145 lines
3.3 KiB
Go

package main
import (
"bufio"
"fmt"
"io"
"sort"
"git.xdrm.io/go/cliverage/coverage"
)
func bold(str string) string {
return fmt.Sprintf("\x1b[1m%s\x1b[0m", str)
}
func success(str string) string {
return fmt.Sprintf("\x1b[38;2;26;221;120m%s\x1b[0m", str)
}
func warning(str string) string {
return fmt.Sprintf("\x1b[38;2;221;26;120m%s\x1b[0m", str)
}
func printCoverage(r io.Reader, w io.Writer, chunks []coverage.Coverage) error {
reader := bufio.NewReader(r)
linen := uint64(0)
eof := false
coverPrefix := "\x1b[38;2;26;221;120m"
coverSuffix := "\x1b[0m"
// coverPrefix := "<<<"
// coverSuffix := ">>>"
for true {
linen++
if eof {
break
}
line, err := reader.ReadString('\n')
if err == io.EOF {
if len(line) < 1 {
break
} else {
eof = true
}
} else if err != nil {
return err
}
// check if we got a chunk start
concerned := make([]coverage.Coverage, 0)
for _, c := range chunks {
if c.StartLine == linen || c.EndLine == linen {
concerned = append(concerned, c)
}
}
// sort by max column before
sort.Slice(concerned, sortChunksByColumn(concerned, linen))
// if no coverage, write directly
if len(concerned) < 1 {
_, err := w.Write([]byte(fmt.Sprintf("%d\t| %s", linen, line)))
if err != nil {
return err
}
continue
}
// position each column with its prefix/suffix
for _, chunk := range concerned {
isStart := chunk.StartLine == linen
isEnd := chunk.EndLine == linen
if isStart && isEnd {
firstColumn := chunk.StartColumn
prefix := coverPrefix
lastColumn := chunk.EndColumn
suffix := coverSuffix
if chunk.EndColumn > chunk.StartColumn {
firstColumn = chunk.EndColumn
prefix = coverSuffix
lastColumn = chunk.StartColumn
suffix = coverPrefix
}
line = line[0:firstColumn-1] + prefix + line[firstColumn-1:]
if firstColumn != lastColumn {
line = line[0:lastColumn-1] + suffix + line[lastColumn-1:]
}
continue
}
if isEnd {
line = line[0:chunk.EndColumn-1] + coverSuffix + line[chunk.EndColumn-1:]
} else if isStart {
line = line[0:chunk.StartColumn-1] + coverPrefix + line[chunk.StartColumn-1:]
continue
}
}
_, err = w.Write([]byte(fmt.Sprintf("%d\t| %s", linen, line)))
if err != nil {
return err
}
}
return nil
}
func sortChunksByColumn(chunks []coverage.Coverage, lineNumber uint64) func(i, j int) bool {
return func(i, j int) bool {
// if start is concerned
iConcernedColumn := chunks[i].StartColumn
if chunks[i].EndLine == lineNumber {
iConcernedColumn = chunks[i].EndColumn
if chunks[i].StartLine == lineNumber && chunks[i].StartColumn > iConcernedColumn {
iConcernedColumn = chunks[i].StartColumn
}
}
jConcernedColumn := chunks[j].StartColumn
if chunks[j].EndLine == lineNumber {
jConcernedColumn = chunks[j].EndColumn
if chunks[j].StartLine == lineNumber && chunks[j].StartColumn > jConcernedColumn {
jConcernedColumn = chunks[j].StartColumn
}
}
if iConcernedColumn == jConcernedColumn {
// return the closing chunk before
if chunks[i].StartLine == lineNumber && chunks[j].EndLine == lineNumber {
return true
}
if chunks[i].EndLine == lineNumber && chunks[j].StartLine == lineNumber {
return false
}
}
return iConcernedColumn >= jConcernedColumn
}
}