cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.10.1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/reporter/console.go

121lines · modecode

1package reporter
2
3import (
4 "fmt"
5 "io"
6 "os"
7 "sort"
8 "strconv"
9 "strings"
10
11 "github.com/rs/zerolog/log"
12
13 "github.com/cloudflare/pint/internal/checks"
14 "github.com/cloudflare/pint/internal/output"
15)
16
17func NewConsoleReporter(output io.Writer) ConsoleReporter {
18 return ConsoleReporter{output: output}
19}
20
21type ConsoleReporter struct {
22 output io.Writer
23}
24
25func (cr ConsoleReporter) Submit(summary Summary) error {
26 reports := summary.Reports
27 reps := reports[:]
28 sort.Slice(reps, func(i, j int) bool {
29 if reports[i].Path < reports[j].Path {
30 return true
31 }
32 if reports[i].Path > reports[j].Path {
33 return false
34 }
35 if reports[i].Problem.Lines[0] < reports[j].Problem.Lines[0] {
36 return true
37 }
38 if reports[i].Problem.Lines[0] > reports[j].Problem.Lines[0] {
39 return false
40 }
41 if reports[i].Problem.Reporter < reports[j].Problem.Reporter {
42 return true
43 }
44 if reports[i].Problem.Reporter > reports[j].Problem.Reporter {
45 return false
46 }
47 return reports[i].Problem.Text < reports[j].Problem.Text
48 })
49
50 perFile := map[string][]string{}
51 for _, report := range reps {
52 if _, ok := perFile[report.Path]; !ok {
53 perFile[report.Path] = []string{}
54 }
55
56 content, err := readFile(report.Path)
57 if err != nil {
58 return err
59 }
60
61 msg := []string{}
62 firstLine, lastLine := report.Problem.LineRange()
63 msg = append(msg, output.MakeBlue("%s:%s: ", report.Path, printLineRange(firstLine, lastLine)))
64 switch report.Problem.Severity {
65 case checks.Bug, checks.Fatal:
66 msg = append(msg, output.MakeRed(report.Problem.Text))
67 case checks.Warning:
68 msg = append(msg, output.MakeYellow(report.Problem.Text))
69 default:
70 msg = append(msg, output.MakeGray(report.Problem.Text))
71 }
72 msg = append(msg, output.MakeMagneta(" (%s)\n", report.Problem.Reporter))
73
74 lines := strings.Split(content, "\n")
75 if lastLine > len(lines)-1 {
76 lastLine = len(lines) - 1
77 log.Warn().Str("path", report.Path).Msgf("Tried to read more lines than present in the source file, this is likely due to '\n' usage in some rules, see https://github.com/cloudflare/pint/issues/20 for details")
78 }
79 for _, c := range lines[firstLine-1 : lastLine] {
80 msg = append(msg, output.MakeWhite("%s\n", c))
81 }
82 perFile[report.Path] = append(perFile[report.Path], strings.Join(msg, ""))
83 }
84
85 paths := []string{}
86 for path := range perFile {
87 paths = append(paths, path)
88 }
89 sort.Strings(paths)
90
91 for _, path := range paths {
92 msgs := perFile[path]
93 for _, msg := range msgs {
94 fmt.Fprintln(cr.output, msg)
95 }
96 }
97
98 return nil
99}
100
101func readFile(path string) (string, error) {
102 f, err := os.Open(path)
103 if err != nil {
104 return "", err
105 }
106 defer f.Close()
107
108 content, err := io.ReadAll(f)
109 if err != nil {
110 return "", err
111 }
112
113 return string(content), nil
114}
115
116func printLineRange(s, e int) string {
117 if s == e {
118 return strconv.Itoa(s)
119 }
120 return fmt.Sprintf("%d-%d", s, e)
121}
122