prettify issue texts
This commit is contained in:
parent
e58c27e463
commit
284447fc07
4
Gopkg.lock
generated
4
Gopkg.lock
generated
@ -146,7 +146,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:7d1f12e47120a4e50790f423446888ef01fcc1a3c17fcf9d5f1be7774cfd963c"
|
||||
digest = "1:bfaf14a1dd31e57f9b433739af5f0411558d9ba90566c7342c02da9a48ea8e75"
|
||||
name = "github.com/golangci/govet"
|
||||
packages = [
|
||||
".",
|
||||
@ -154,7 +154,7 @@
|
||||
"lib/whitelist",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "e3b43b6cb1916e0000f244f26ee752733e544429"
|
||||
revision = "44ddbe260190d79165f4150b828650780405d801"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -39,7 +39,7 @@ func (lint Gas) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issu
|
||||
|
||||
res := make([]result.Issue, 0, len(issues))
|
||||
for _, i := range issues {
|
||||
text := fmt.Sprintf("%s: %s", i.RuleID, i.What) // TODO: use severity and confidence
|
||||
text := fmt.Sprintf("%s: %s", i.RuleID, markIdentifiers(i.What)) // TODO: use severity and confidence
|
||||
var r *result.Range
|
||||
line, err := strconv.Atoi(i.Line)
|
||||
if err != nil {
|
||||
|
@ -83,9 +83,9 @@ func (g Gofmt) extractIssuesFromPatch(patch string, log logutils.Log) ([]result.
|
||||
}
|
||||
}
|
||||
|
||||
text := "File is not gofmt-ed with -s"
|
||||
text := "File is not `gofmt`-ed with `-s`"
|
||||
if g.UseGoimports {
|
||||
text = "File is not goimports-ed"
|
||||
text = "File is not `goimports`-ed"
|
||||
}
|
||||
i := result.Issue{
|
||||
FromLinter: g.Name(),
|
||||
|
@ -60,7 +60,7 @@ func (g Golint) lintPkg(minConfidence float64, files []*ast.File, fset *token.Fi
|
||||
if p.Confidence >= minConfidence {
|
||||
issues = append(issues, result.Issue{
|
||||
Pos: p.Position,
|
||||
Text: p.Text,
|
||||
Text: markIdentifiers(p.Text),
|
||||
FromLinter: g.Name(),
|
||||
})
|
||||
// TODO: use p.Link and p.Category
|
||||
|
@ -53,7 +53,7 @@ func (g Govet) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue
|
||||
for _, i := range govetIssues {
|
||||
res = append(res, result.Issue{
|
||||
Pos: i.Pos,
|
||||
Text: i.Message,
|
||||
Text: markIdentifiers(i.Message),
|
||||
FromLinter: g.Name(),
|
||||
})
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ func (lint Interfacer) Run(ctx context.Context, lintCtx *linter.Context) ([]resu
|
||||
pos := lintCtx.SSAProgram.Fset.Position(i.Pos())
|
||||
res = append(res, result.Issue{
|
||||
Pos: pos,
|
||||
Text: i.Message(),
|
||||
Text: markIdentifiers(i.Message()),
|
||||
FromLinter: lint.Name(),
|
||||
})
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ func (lint Lll) getIssuesForFile(filename string, maxLineLen int, tabSpaces stri
|
||||
Pos: token.Position{
|
||||
Filename: filename,
|
||||
Line: lineNumber,
|
||||
Column: 1,
|
||||
},
|
||||
Text: fmt.Sprintf("line is %d characters", lineLen),
|
||||
FromLinter: lint.Name(),
|
||||
|
@ -112,7 +112,7 @@ func (m Megacheck) Run(ctx context.Context, lintCtx *linter.Context) ([]result.I
|
||||
for _, i := range issues {
|
||||
res = append(res, result.Issue{
|
||||
Pos: i.Position,
|
||||
Text: i.Text,
|
||||
Text: markIdentifiers(i.Text),
|
||||
FromLinter: m.Name(),
|
||||
})
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func (lint TypeCheck) parseError(srcErr error) (*result.Issue, error) {
|
||||
Line: line,
|
||||
Column: column,
|
||||
},
|
||||
Text: message,
|
||||
Text: markIdentifiers(message),
|
||||
FromLinter: lint.Name(),
|
||||
}, nil
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ func (lint Unparam) Run(ctx context.Context, lintCtx *linter.Context) ([]result.
|
||||
for _, i := range unparamIssues {
|
||||
res = append(res, result.Issue{
|
||||
Pos: lintCtx.Program.Fset.Position(i.Pos()),
|
||||
Text: i.Message(),
|
||||
Text: markIdentifiers(i.Message()),
|
||||
FromLinter: lint.Name(),
|
||||
})
|
||||
}
|
||||
|
@ -4,7 +4,9 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/lint/linter"
|
||||
"github.com/golangci/golangci-lint/pkg/packages"
|
||||
@ -28,6 +30,65 @@ func formatCodeBlock(code string, _ *config.Config) string {
|
||||
return fmt.Sprintf("```\n%s\n```", code)
|
||||
}
|
||||
|
||||
type replacePattern struct {
|
||||
re string
|
||||
repl string
|
||||
}
|
||||
|
||||
type replaceRegexp struct {
|
||||
re *regexp.Regexp
|
||||
repl string
|
||||
}
|
||||
|
||||
var replaceRegexps []replaceRegexp
|
||||
var replaceRegexpsOnce sync.Once
|
||||
|
||||
var replacePatterns = []replacePattern{
|
||||
// unparam
|
||||
{`^(\S+) - (\S+) is unused$`, "`${1}` - `${2}` is unused"},
|
||||
{`^(\S+) - (\S+) always receives (\S+) \((.*)\)$`, "`${1}` - `${2}` always receives `${3}` (`${4}`)"},
|
||||
{`^(\S+) - (\S+) always receives (.*)$`, "`${1}` - `${2}` always receives `${3}`"},
|
||||
|
||||
// interfacer
|
||||
{`^(\S+) can be (\S+)$`, "`${1}` can be `${2}`"},
|
||||
|
||||
// govet
|
||||
{`^(\S+) arg list ends with redundant newline$`, "`${1}` arg list ends with redundant newline"},
|
||||
{`^(\S+) composite literal uses unkeyed fields$`, "`${1}` composite literal uses unkeyed fields"},
|
||||
|
||||
// gas
|
||||
{`^Blacklisted import (\S+): weak cryptographic primitive$`,
|
||||
"Blacklisted import `${1}`: weak cryptographic primitive"},
|
||||
{`^TLS InsecureSkipVerify set true.$`, "TLS `InsecureSkipVerify` set true."},
|
||||
|
||||
// megacheck
|
||||
{`^this value of (\S+) is never used$`, "this value of `${1}` is never used"},
|
||||
{`^should use time.Since instead of time.Now().Sub$`,
|
||||
"should use `time.Since` instead of `time.Now().Sub`"},
|
||||
{`^(func|const|field|type) (\S+) is unused$`, "${1} `${2}` is unused"},
|
||||
}
|
||||
|
||||
func markIdentifiers(s string) string {
|
||||
replaceRegexpsOnce.Do(func() {
|
||||
for _, p := range replacePatterns {
|
||||
r := replaceRegexp{
|
||||
re: regexp.MustCompile(p.re),
|
||||
repl: p.repl,
|
||||
}
|
||||
replaceRegexps = append(replaceRegexps, r)
|
||||
}
|
||||
})
|
||||
|
||||
for _, rr := range replaceRegexps {
|
||||
rs := rr.re.ReplaceAllString(s, rr.repl)
|
||||
if rs != s {
|
||||
return rs
|
||||
}
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func getASTFilesForPkg(ctx *linter.Context, pkg *packages.Package) ([]*ast.File, *token.FileSet, error) {
|
||||
filenames := pkg.Files(ctx.Cfg.Run.AnalyzeTests)
|
||||
files := make([]*ast.File, 0, len(filenames))
|
||||
|
@ -69,6 +69,7 @@ func (p Text) printSourceCode(i *result.Issue) {
|
||||
}
|
||||
|
||||
func (p Text) printUnderLinePointer(i *result.Issue) {
|
||||
// if column == 0 it means column is unknown (e.g. for gas)
|
||||
if len(i.SourceLines) != 1 || i.Pos.Column == 0 {
|
||||
return
|
||||
}
|
||||
|
2
test/testdata/gas.go
vendored
2
test/testdata/gas.go
vendored
@ -2,7 +2,7 @@
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"crypto/md5" // ERROR "G501: Blacklisted import crypto/md5: weak cryptographic primitive"
|
||||
"crypto/md5" // ERROR "G501: Blacklisted import `crypto/md5`: weak cryptographic primitive"
|
||||
"log"
|
||||
)
|
||||
|
||||
|
2
test/testdata/gofmt.go
vendored
2
test/testdata/gofmt.go
vendored
@ -5,5 +5,5 @@ import "fmt"
|
||||
|
||||
func GofmtNotSimplified() {
|
||||
var x []string
|
||||
fmt.Print(x[1:len(x)]) // ERROR "File is not gofmt-ed with -s"
|
||||
fmt.Print(x[1:len(x)]) // ERROR "File is not `gofmt`-ed with `-s`"
|
||||
}
|
||||
|
2
test/testdata/goimports.go
vendored
2
test/testdata/goimports.go
vendored
@ -2,7 +2,7 @@
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"fmt" // ERROR "File is not goimports-ed"
|
||||
"fmt" // ERROR "File is not `goimports`-ed"
|
||||
"github.com/golangci/golangci-lint/pkg/config"
|
||||
)
|
||||
|
||||
|
2
test/testdata/govet.go
vendored
2
test/testdata/govet.go
vendored
@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func Govet() error {
|
||||
return &os.PathError{"first", "path", os.ErrNotExist} // ERROR "os.PathError composite literal uses unkeyed fields"
|
||||
return &os.PathError{"first", "path", os.ErrNotExist} // ERROR "`os.PathError` composite literal uses unkeyed fields"
|
||||
}
|
||||
|
||||
func GovetShadow(f io.Reader, buf []byte) (err error) {
|
||||
|
2
test/testdata/interfacer.go
vendored
2
test/testdata/interfacer.go
vendored
@ -3,6 +3,6 @@ package testdata
|
||||
|
||||
import "io"
|
||||
|
||||
func InterfacerCheck(f io.ReadCloser) { // ERROR "f can be io.Closer"
|
||||
func InterfacerCheck(f io.ReadCloser) { // ERROR "`f` can be `io.Closer`"
|
||||
f.Close()
|
||||
}
|
||||
|
2
test/testdata/unparam.go
vendored
2
test/testdata/unparam.go
vendored
@ -1,7 +1,7 @@
|
||||
// args: -Eunparam
|
||||
package testdata
|
||||
|
||||
func unparamUnused(a, b uint) uint { // ERROR "unparamUnused - b is unused"
|
||||
func unparamUnused(a, b uint) uint { // ERROR "`unparamUnused` - `b` is unused"
|
||||
a++
|
||||
return a
|
||||
}
|
||||
|
16
vendor/github.com/golangci/govet/composite.go
generated
vendored
16
vendor/github.com/golangci/govet/composite.go
generated
vendored
@ -73,19 +73,13 @@ func checkUnkeyedLiteral(f *File, node ast.Node) {
|
||||
return
|
||||
}
|
||||
|
||||
f.Badf(cl.Pos(), "%s composite literal uses unkeyed fields", typeName)
|
||||
f.Badf(cl.Pos(), "%s composite literal uses unkeyed fields",
|
||||
types.TypeString(typ, func(pkg *types.Package) string {
|
||||
return pkg.Name()
|
||||
}))
|
||||
}
|
||||
|
||||
func isLocalType(f *File, typ types.Type) bool {
|
||||
structNameParts := strings.Split(typ.String(), ".")
|
||||
if len(structNameParts) >= 2 {
|
||||
structName := structNameParts[len(structNameParts)-1]
|
||||
firstLetter := string(structName[0])
|
||||
if firstLetter == strings.ToLower(firstLetter) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
switch x := typ.(type) {
|
||||
case *types.Struct:
|
||||
// struct literals are local types
|
||||
@ -94,7 +88,7 @@ func isLocalType(f *File, typ types.Type) bool {
|
||||
return isLocalType(f, x.Elem())
|
||||
case *types.Named:
|
||||
// names in package foo are local to foo_test too
|
||||
return strings.TrimSuffix(x.Obj().Pkg().Path(), "_test") == strings.TrimSuffix(f.pkg.path, "_test")
|
||||
return strings.TrimSuffix(x.Obj().Pkg().Path(), "_test") == strings.TrimSuffix(f.pkg.typesPkg.Path(), "_test")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user