13 func shortPath(path string) string {
14 cwd, err := os.Getwd()
18 if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
24 func relativePositionString(pos token.Position) string {
25 s := shortPath(pos.Filename)
30 s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
38 type statter interface {
39 Stats(total, errors, warnings, ignored int)
42 type formatter interface {
46 type textFormatter struct {
50 func (o textFormatter) Format(p problem) {
51 fmt.Fprintf(o.W, "%s: %s\n", relativePositionString(p.Position), p.String())
52 for _, r := range p.Related {
53 fmt.Fprintf(o.W, "\t%s: %s\n", relativePositionString(r.Position), r.Message)
57 type nullFormatter struct{}
59 func (nullFormatter) Format(problem) {}
61 type jsonFormatter struct {
65 func (o jsonFormatter) Format(p problem) {
66 type location struct {
67 File string `json:"file"`
68 Line int `json:"line"`
69 Column int `json:"column"`
72 Location location `json:"location"`
73 End location `json:"end"`
74 Message string `json:"message"`
77 Code string `json:"code"`
78 Severity string `json:"severity,omitempty"`
79 Location location `json:"location"`
80 End location `json:"end"`
81 Message string `json:"message"`
82 Related []related `json:"related,omitempty"`
85 Severity: p.Severity.String(),
87 File: p.Position.Filename,
88 Line: p.Position.Line,
89 Column: p.Position.Column,
98 for _, r := range p.Related {
99 jp.Related = append(jp.Related, related{
101 File: r.Position.Filename,
102 Line: r.Position.Line,
103 Column: r.Position.Column,
106 File: r.End.Filename,
108 Column: r.End.Column,
113 _ = json.NewEncoder(o.W).Encode(jp)
116 type stylishFormatter struct {
123 func (o *stylishFormatter) Format(p problem) {
125 if pos.Filename == "" {
129 if pos.Filename != o.prevFile {
130 if o.prevFile != "" {
134 fmt.Fprintln(o.W, pos.Filename)
135 o.prevFile = pos.Filename
136 o.tw = tabwriter.NewWriter(o.W, 0, 4, 2, ' ', 0)
138 fmt.Fprintf(o.tw, " (%d, %d)\t%s\t%s\n", pos.Line, pos.Column, p.Category, p.Message)
139 for _, r := range p.Related {
140 fmt.Fprintf(o.tw, " (%d, %d)\t\t %s\n", r.Position.Line, r.Position.Column, r.Message)
144 func (o *stylishFormatter) Stats(total, errors, warnings, ignored int) {
149 fmt.Fprintf(o.W, " ✖ %d problems (%d errors, %d warnings, %d ignored)\n",
150 total, errors, warnings, ignored)