github.com/elek/golangci-lint@v1.42.2-0.20211208090441-c05b7fcb3a9a/pkg/printers/text.go (about) 1 package printers 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/fatih/color" 9 10 "github.com/elek/golangci-lint/pkg/logutils" 11 "github.com/elek/golangci-lint/pkg/result" 12 ) 13 14 type Text struct { 15 printIssuedLine bool 16 useColors bool 17 printLinterName bool 18 19 log logutils.Log 20 } 21 22 func NewText(printIssuedLine, useColors, printLinterName bool, log logutils.Log) *Text { 23 return &Text{ 24 printIssuedLine: printIssuedLine, 25 useColors: useColors, 26 printLinterName: printLinterName, 27 log: log, 28 } 29 } 30 31 func (p Text) SprintfColored(ca color.Attribute, format string, args ...interface{}) string { 32 if !p.useColors { 33 return fmt.Sprintf(format, args...) 34 } 35 36 c := color.New(ca) 37 return c.Sprintf(format, args...) 38 } 39 40 func (p *Text) Print(ctx context.Context, issues []result.Issue) error { 41 for i := range issues { 42 p.printIssue(&issues[i]) 43 44 if !p.printIssuedLine { 45 continue 46 } 47 48 p.printSourceCode(&issues[i]) 49 p.printUnderLinePointer(&issues[i]) 50 } 51 52 return nil 53 } 54 55 func (p Text) printIssue(i *result.Issue) { 56 text := p.SprintfColored(color.FgRed, "%s", strings.TrimSpace(i.Text)) 57 if p.printLinterName { 58 text += fmt.Sprintf(" (%s)", i.FromLinter) 59 } 60 pos := p.SprintfColored(color.Bold, "%s:%d", i.FilePath(), i.Line()) 61 if i.Pos.Column != 0 { 62 pos += fmt.Sprintf(":%d", i.Pos.Column) 63 } 64 fmt.Fprintf(logutils.StdOut, "%s: %s\n", pos, text) 65 } 66 67 func (p Text) printSourceCode(i *result.Issue) { 68 for _, line := range i.SourceLines { 69 fmt.Fprintln(logutils.StdOut, line) 70 } 71 } 72 73 func (p Text) printUnderLinePointer(i *result.Issue) { 74 // if column == 0 it means column is unknown (e.g. for gosec) 75 if len(i.SourceLines) != 1 || i.Pos.Column == 0 { 76 return 77 } 78 79 col0 := i.Pos.Column - 1 80 line := i.SourceLines[0] 81 prefixRunes := make([]rune, 0, len(line)) 82 for j := 0; j < len(line) && j < col0; j++ { 83 if line[j] == '\t' { 84 prefixRunes = append(prefixRunes, '\t') 85 } else { 86 prefixRunes = append(prefixRunes, ' ') 87 } 88 } 89 90 fmt.Fprintf(logutils.StdOut, "%s%s\n", string(prefixRunes), p.SprintfColored(color.FgYellow, "^")) 91 }