prettify issue texts

This commit is contained in:
Denis Isaev 2018-08-18 22:15:24 +03:00 committed by Isaev Denis
parent e58c27e463
commit 284447fc07
19 changed files with 84 additions and 29 deletions

4
Gopkg.lock generated
View File

@ -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"

View File

@ -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 {

View File

@ -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(),

View File

@ -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

View File

@ -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(),
})
}

View File

@ -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(),
})
}

View File

@ -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(),

View File

@ -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(),
})
}

View File

@ -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
}

View File

@ -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(),
})
}

View File

@ -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))

View File

@ -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
}

View File

@ -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"
)

View File

@ -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`"
}

View File

@ -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"
)

View File

@ -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) {

View File

@ -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()
}

View File

@ -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
}

View File

@ -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
}