90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package printers
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"time"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/golangci/golangci-lint/pkg/result"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type Text struct {
|
|
printIssuedLine bool
|
|
useColors bool
|
|
}
|
|
|
|
func NewText(printIssuedLine bool, useColors bool) *Text {
|
|
return &Text{
|
|
printIssuedLine: printIssuedLine,
|
|
useColors: useColors,
|
|
}
|
|
}
|
|
|
|
type linesCache [][]byte
|
|
type filesCache map[string]linesCache
|
|
|
|
func (p Text) SprintfColored(ca color.Attribute, format string, args ...interface{}) string {
|
|
if !p.useColors {
|
|
return fmt.Sprintf(format, args...)
|
|
}
|
|
|
|
c := color.New(ca)
|
|
return c.Sprintf(format, args...)
|
|
}
|
|
|
|
func (p Text) Print(issues chan result.Issue) (bool, error) {
|
|
var issuedLineExtractingDuration time.Duration
|
|
defer func() {
|
|
logrus.Infof("Extracting issued lines took %s", issuedLineExtractingDuration)
|
|
}()
|
|
|
|
gotAnyIssue := false
|
|
cache := filesCache{}
|
|
out := getOutWriter()
|
|
for i := range issues {
|
|
gotAnyIssue = true
|
|
text := p.SprintfColored(color.FgRed, "%s", i.Text)
|
|
pos := p.SprintfColored(color.Bold, "%s:%d", i.FilePath(), i.Line())
|
|
fmt.Fprintf(out, "%s: %s\n", pos, text)
|
|
|
|
if !p.printIssuedLine {
|
|
continue
|
|
}
|
|
|
|
fc := cache[i.FilePath()]
|
|
if fc == nil {
|
|
startedAt := time.Now()
|
|
// TODO: make more optimal algorithm: don't load all files into memory
|
|
fileBytes, err := ioutil.ReadFile(i.FilePath())
|
|
if err != nil {
|
|
return false, fmt.Errorf("can't read file %s for printing issued line: %s", i.FilePath(), err)
|
|
}
|
|
lines := bytes.Split(fileBytes, []byte("\n")) // TODO: what about \r\n?
|
|
fc = lines
|
|
cache[i.FilePath()] = fc
|
|
issuedLineExtractingDuration += time.Since(startedAt)
|
|
}
|
|
|
|
lineRange := i.GetLineRange()
|
|
for line := lineRange.From; line <= lineRange.To; line++ {
|
|
zeroIndexedLine := line - 1
|
|
if zeroIndexedLine >= len(fc) {
|
|
logrus.Warnf("No line %d in file %s", line, i.FilePath())
|
|
break
|
|
}
|
|
|
|
fmt.Fprintln(out, string(bytes.Trim(fc[zeroIndexedLine], "\r")))
|
|
}
|
|
}
|
|
|
|
if !gotAnyIssue {
|
|
outStr := p.SprintfColored(color.FgGreen, "Congrats! No issues were found.")
|
|
fmt.Fprintln(out, outStr)
|
|
}
|
|
|
|
return gotAnyIssue, nil
|
|
}
|