mirror of
https://github.com/1f349/dendrite.git
synced 2025-03-29 07:15:04 +00:00
* Update gometalinter config gometalinter now uses `maligned` instead of `aligncheck` (https://github.com/alecthomas/gometalinter/pull/367), so we need to update our config accordingly. * Update gometalinter * Disable gotype linter gotype does not seem to play nicely with the gb vendor directory. In particular, it wants each of our dependencies to be built and installed (see https://github.com/golang/go/issues/10969), but (empirically) it will not accept them being installed in `pkg` but insists on them being in `vendor/pkg`. This presents a problem because `gb build` builds the packages into `pkg` (which doesn't seem entirely unreasonable since `.` comes before `vendor` in `$GOPATH`). `go install github.com/x/y` does install in `vendor/pkg` but requires us to know the name of each package. The general conclusion of https://github.com/alecthomas/gometalinter/issues/91 seems to have been that the easiest thing to do is to disable `gotype` for now. * Fix `unparam` lint * Fix goshadow lint
115 lines
2.8 KiB
Go
115 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"sort"
|
|
"strings"
|
|
"text/template"
|
|
)
|
|
|
|
// DefaultIssueFormat used to print an issue
|
|
const DefaultIssueFormat = "{{.Path}}:{{.Line}}:{{if .Col}}{{.Col}}{{end}}:{{.Severity}}: {{.Message}} ({{.Linter}})"
|
|
|
|
// Severity of linter message
|
|
type Severity string
|
|
|
|
// Linter message severity levels.
|
|
const (
|
|
Error Severity = "error"
|
|
Warning Severity = "warning"
|
|
)
|
|
|
|
type Issue struct {
|
|
Linter string `json:"linter"`
|
|
Severity Severity `json:"severity"`
|
|
Path string `json:"path"`
|
|
Line int `json:"line"`
|
|
Col int `json:"col"`
|
|
Message string `json:"message"`
|
|
formatTmpl *template.Template
|
|
}
|
|
|
|
// NewIssue returns a new issue. Returns an error if formatTmpl is not a valid
|
|
// template for an Issue.
|
|
func NewIssue(linter string, formatTmpl *template.Template) (*Issue, error) {
|
|
issue := &Issue{
|
|
Line: 1,
|
|
Severity: Warning,
|
|
Linter: linter,
|
|
formatTmpl: formatTmpl,
|
|
}
|
|
err := formatTmpl.Execute(ioutil.Discard, issue)
|
|
return issue, err
|
|
}
|
|
|
|
func (i *Issue) String() string {
|
|
if i.formatTmpl == nil {
|
|
col := ""
|
|
if i.Col != 0 {
|
|
col = fmt.Sprintf("%d", i.Col)
|
|
}
|
|
return fmt.Sprintf("%s:%d:%s:%s: %s (%s)", strings.TrimSpace(i.Path), i.Line, col, i.Severity, strings.TrimSpace(i.Message), i.Linter)
|
|
}
|
|
buf := new(bytes.Buffer)
|
|
_ = i.formatTmpl.Execute(buf, i)
|
|
return buf.String()
|
|
}
|
|
|
|
type sortedIssues struct {
|
|
issues []*Issue
|
|
order []string
|
|
}
|
|
|
|
func (s *sortedIssues) Len() int { return len(s.issues) }
|
|
func (s *sortedIssues) Swap(i, j int) { s.issues[i], s.issues[j] = s.issues[j], s.issues[i] }
|
|
|
|
func (s *sortedIssues) Less(i, j int) bool {
|
|
l, r := s.issues[i], s.issues[j]
|
|
return CompareIssue(*l, *r, s.order)
|
|
}
|
|
|
|
// CompareIssue two Issues and return true if left should sort before right
|
|
// nolint: gocyclo
|
|
func CompareIssue(l, r Issue, order []string) bool {
|
|
for _, key := range order {
|
|
switch {
|
|
case key == "path" && l.Path != r.Path:
|
|
return l.Path < r.Path
|
|
case key == "line" && l.Line != r.Line:
|
|
return l.Line < r.Line
|
|
case key == "column" && l.Col != r.Col:
|
|
return l.Col < r.Col
|
|
case key == "severity" && l.Severity != r.Severity:
|
|
return l.Severity < r.Severity
|
|
case key == "message" && l.Message != r.Message:
|
|
return l.Message < r.Message
|
|
case key == "linter" && l.Linter != r.Linter:
|
|
return l.Linter < r.Linter
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// SortIssueChan reads issues from one channel, sorts them, and returns them to another
|
|
// channel
|
|
func SortIssueChan(issues chan *Issue, order []string) chan *Issue {
|
|
out := make(chan *Issue, 1000000)
|
|
sorted := &sortedIssues{
|
|
issues: []*Issue{},
|
|
order: order,
|
|
}
|
|
go func() {
|
|
for issue := range issues {
|
|
sorted.issues = append(sorted.issues, issue)
|
|
}
|
|
sort.Sort(sorted)
|
|
for _, issue := range sorted.issues {
|
|
out <- issue
|
|
}
|
|
close(out)
|
|
}()
|
|
return out
|
|
}
|