50fbc2eec2
* CI: use staticcheck for linting This commit switches the linter for Go code from golint to staticcheck. Golint has been deprecated since last year and staticcheck is a recommended replacement. Signed-off-by: Lucas Servén Marín <lserven@gmail.com> * revendor Signed-off-by: Lucas Servén Marín <lserven@gmail.com> * cmd,pkg: fix lint warnings Signed-off-by: Lucas Servén Marín <lserven@gmail.com>
162 lines
3.4 KiB
Go
162 lines
3.4 KiB
Go
package lintcmd
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"go/token"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"text/tabwriter"
|
|
|
|
"honnef.co/go/tools/analysis/lint"
|
|
)
|
|
|
|
func shortPath(path string) string {
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
return path
|
|
}
|
|
if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
|
|
return rel
|
|
}
|
|
return path
|
|
}
|
|
|
|
func relativePositionString(pos token.Position) string {
|
|
s := shortPath(pos.Filename)
|
|
if pos.IsValid() {
|
|
if s != "" {
|
|
s += ":"
|
|
}
|
|
s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
|
|
}
|
|
if s == "" {
|
|
s = "-"
|
|
}
|
|
return s
|
|
}
|
|
|
|
type statter interface {
|
|
Stats(total, errors, warnings, ignored int)
|
|
}
|
|
|
|
type formatter interface {
|
|
Format(checks []*lint.Analyzer, diagnostics []diagnostic)
|
|
}
|
|
|
|
type textFormatter struct {
|
|
W io.Writer
|
|
}
|
|
|
|
func (o textFormatter) Format(_ []*lint.Analyzer, ps []diagnostic) {
|
|
for _, p := range ps {
|
|
fmt.Fprintf(o.W, "%s: %s\n", relativePositionString(p.Position), p.String())
|
|
for _, r := range p.Related {
|
|
fmt.Fprintf(o.W, "\t%s: %s\n", relativePositionString(r.Position), r.Message)
|
|
}
|
|
}
|
|
}
|
|
|
|
type nullFormatter struct{}
|
|
|
|
func (nullFormatter) Format([]*lint.Analyzer, []diagnostic) {}
|
|
|
|
type jsonFormatter struct {
|
|
W io.Writer
|
|
}
|
|
|
|
func (o jsonFormatter) Format(_ []*lint.Analyzer, ps []diagnostic) {
|
|
type location struct {
|
|
File string `json:"file"`
|
|
Line int `json:"line"`
|
|
Column int `json:"column"`
|
|
}
|
|
type related struct {
|
|
Location location `json:"location"`
|
|
End location `json:"end"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
enc := json.NewEncoder(o.W)
|
|
for _, p := range ps {
|
|
jp := struct {
|
|
Code string `json:"code"`
|
|
Severity string `json:"severity,omitempty"`
|
|
Location location `json:"location"`
|
|
End location `json:"end"`
|
|
Message string `json:"message"`
|
|
Related []related `json:"related,omitempty"`
|
|
}{
|
|
Code: p.Category,
|
|
Severity: p.Severity.String(),
|
|
Location: location{
|
|
File: p.Position.Filename,
|
|
Line: p.Position.Line,
|
|
Column: p.Position.Column,
|
|
},
|
|
End: location{
|
|
File: p.End.Filename,
|
|
Line: p.End.Line,
|
|
Column: p.End.Column,
|
|
},
|
|
Message: p.Message,
|
|
}
|
|
for _, r := range p.Related {
|
|
jp.Related = append(jp.Related, related{
|
|
Location: location{
|
|
File: r.Position.Filename,
|
|
Line: r.Position.Line,
|
|
Column: r.Position.Column,
|
|
},
|
|
End: location{
|
|
File: r.End.Filename,
|
|
Line: r.End.Line,
|
|
Column: r.End.Column,
|
|
},
|
|
Message: r.Message,
|
|
})
|
|
}
|
|
_ = enc.Encode(jp)
|
|
}
|
|
}
|
|
|
|
type stylishFormatter struct {
|
|
W io.Writer
|
|
|
|
prevFile string
|
|
tw *tabwriter.Writer
|
|
}
|
|
|
|
func (o *stylishFormatter) Format(_ []*lint.Analyzer, ps []diagnostic) {
|
|
for _, p := range ps {
|
|
pos := p.Position
|
|
if pos.Filename == "" {
|
|
pos.Filename = "-"
|
|
}
|
|
|
|
if pos.Filename != o.prevFile {
|
|
if o.prevFile != "" {
|
|
o.tw.Flush()
|
|
fmt.Fprintln(o.W)
|
|
}
|
|
fmt.Fprintln(o.W, pos.Filename)
|
|
o.prevFile = pos.Filename
|
|
o.tw = tabwriter.NewWriter(o.W, 0, 4, 2, ' ', 0)
|
|
}
|
|
fmt.Fprintf(o.tw, " (%d, %d)\t%s\t%s\n", pos.Line, pos.Column, p.Category, p.Message)
|
|
for _, r := range p.Related {
|
|
fmt.Fprintf(o.tw, " (%d, %d)\t\t %s\n", r.Position.Line, r.Position.Column, r.Message)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (o *stylishFormatter) Stats(total, errors, warnings, ignored int) {
|
|
if o.tw != nil {
|
|
o.tw.Flush()
|
|
fmt.Fprintln(o.W)
|
|
}
|
|
fmt.Fprintf(o.W, " ✖ %d problems (%d errors, %d warnings, %d ignored)\n",
|
|
total, errors, warnings, ignored)
|
|
}
|