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