1 // Package format provides formatters for linter problems.
13 "honnef.co/go/tools/lint"
16 func shortPath(path string) string {
17 cwd, err := os.Getwd()
21 if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
27 func relativePositionString(pos token.Position) string {
28 s := shortPath(pos.Filename)
33 s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
41 type Statter interface {
42 Stats(total, errors, warnings, ignored int)
45 type Formatter interface {
46 Format(p lint.Problem)
53 func (o Text) Format(p lint.Problem) {
54 fmt.Fprintf(o.W, "%s: %s\n", relativePositionString(p.Pos), p.String())
55 for _, r := range p.Related {
56 fmt.Fprintf(o.W, "\t%s: %s\n", relativePositionString(r.Pos), r.Message)
64 func severity(s lint.Severity) string {
76 func (o JSON) Format(p lint.Problem) {
77 type location struct {
78 File string `json:"file"`
79 Line int `json:"line"`
80 Column int `json:"column"`
83 Location location `json:"location"`
84 End location `json:"end"`
85 Message string `json:"message"`
88 Code string `json:"code"`
89 Severity string `json:"severity,omitempty"`
90 Location location `json:"location"`
91 End location `json:"end"`
92 Message string `json:"message"`
93 Related []related `json:"related,omitempty"`
96 Severity: severity(p.Severity),
100 Column: p.Pos.Column,
103 File: p.End.Filename,
105 Column: p.End.Column,
109 for _, r := range p.Related {
110 jp.Related = append(jp.Related, related{
112 File: r.Pos.Filename,
114 Column: r.Pos.Column,
117 File: r.End.Filename,
119 Column: r.End.Column,
124 _ = json.NewEncoder(o.W).Encode(jp)
127 type Stylish struct {
134 func (o *Stylish) Format(p lint.Problem) {
136 if pos.Filename == "" {
140 if pos.Filename != o.prevFile {
141 if o.prevFile != "" {
145 fmt.Fprintln(o.W, pos.Filename)
146 o.prevFile = pos.Filename
147 o.tw = tabwriter.NewWriter(o.W, 0, 4, 2, ' ', 0)
149 fmt.Fprintf(o.tw, " (%d, %d)\t%s\t%s\n", pos.Line, pos.Column, p.Check, p.Message)
150 for _, r := range p.Related {
151 fmt.Fprintf(o.tw, " (%d, %d)\t\t %s\n", r.Pos.Line, r.Pos.Column, r.Message)
155 func (o *Stylish) Stats(total, errors, warnings, ignored int) {
160 fmt.Fprintf(o.W, " ✖ %d problems (%d errors, %d warnings, %d ignored)\n",
161 total, errors, warnings, ignored)