dev: dedicated package about IllTypedError parsing (#4675)

This commit is contained in:
Ludovic Fernandez 2024-04-24 14:51:20 +02:00 committed by GitHub
parent 54bfac8c62
commit 8bea8e7de8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 35 additions and 30 deletions

View File

@ -1,4 +1,4 @@
package goanalysis
package pkgerrors
import (
"errors"
@ -7,7 +7,6 @@ import (
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/pkg/lint/linter"
libpackages "github.com/golangci/golangci-lint/pkg/packages"
"github.com/golangci/golangci-lint/pkg/result"
)
@ -19,7 +18,7 @@ func (e *IllTypedError) Error() string {
return fmt.Sprintf("errors in package: %v", e.Pkg.Errors)
}
func buildIssuesFromIllTypedError(errs []error, lintCtx *linter.Context) ([]result.Issue, error) {
func BuildIssuesFromIllTypedError(errs []error, lintCtx *linter.Context) ([]result.Issue, error) {
var issues []result.Issue
uniqReportedIssues := map[string]bool{}
@ -36,8 +35,8 @@ func buildIssuesFromIllTypedError(errs []error, lintCtx *linter.Context) ([]resu
continue
}
for _, err := range libpackages.ExtractErrors(ill.Pkg) {
i, perr := parseError(err)
for _, err := range extractErrors(ill.Pkg) {
issue, perr := parseError(err)
if perr != nil { // failed to parse
if uniqReportedIssues[err.Msg] {
continue
@ -45,8 +44,8 @@ func buildIssuesFromIllTypedError(errs []error, lintCtx *linter.Context) ([]resu
uniqReportedIssues[err.Msg] = true
lintCtx.Log.Errorf("typechecking error: %s", err.Msg)
} else {
i.Pkg = ill.Pkg // to save to cache later
issues = append(issues, *i)
issue.Pkg = ill.Pkg // to save to cache later
issues = append(issues, *issue)
}
}
}
@ -57,16 +56,3 @@ func buildIssuesFromIllTypedError(errs []error, lintCtx *linter.Context) ([]resu
return issues, nil
}
func parseError(srcErr packages.Error) (*result.Issue, error) {
pos, err := libpackages.ParseErrorPosition(srcErr.Pos)
if err != nil {
return nil, err
}
return &result.Issue{
Pos: *pos,
Text: srcErr.Msg,
FromLinter: "typecheck",
}, nil
}

View File

@ -1,4 +1,4 @@
package packages
package pkgerrors
import (
"fmt"
@ -12,7 +12,7 @@ import (
// ex: `/example/main.go:11:17: foobar`
var reFile = regexp.MustCompile(`^.+\.go:\d+:\d+: .+`)
func ExtractErrors(pkg *packages.Package) []packages.Error {
func extractErrors(pkg *packages.Package) []packages.Error {
errors := extractErrorsImpl(pkg, map[*packages.Package]bool{})
if len(errors) == 0 {
return errors
@ -38,7 +38,7 @@ func ExtractErrors(pkg *packages.Package) []packages.Error {
if len(pkg.GoFiles) != 0 {
// errors were extracted from deps and have at least one file in package
for i := range uniqErrors {
if _, parseErr := ParseErrorPosition(uniqErrors[i].Pos); parseErr == nil {
if _, parseErr := parseErrorPosition(uniqErrors[i].Pos); parseErr == nil {
continue
}

View File

@ -1,4 +1,4 @@
package packages
package pkgerrors
import (
"testing"

View File

@ -1,4 +1,4 @@
package packages
package pkgerrors
import (
"errors"
@ -6,9 +6,26 @@ import (
"go/token"
"strconv"
"strings"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/pkg/result"
)
func ParseErrorPosition(pos string) (*token.Position, error) {
func parseError(srcErr packages.Error) (*result.Issue, error) {
pos, err := parseErrorPosition(srcErr.Pos)
if err != nil {
return nil, err
}
return &result.Issue{
Pos: *pos,
Text: srcErr.Msg,
FromLinter: "typecheck",
}, nil
}
func parseErrorPosition(pos string) (*token.Position, error) {
// file:line(<optional>:colon)
parts := strings.Split(pos, ":")
if len(parts) == 1 {

View File

@ -1,4 +1,4 @@
package goanalysis
package pkgerrors
import (
"fmt"
@ -8,7 +8,7 @@ import (
"golang.org/x/tools/go/packages"
)
func TestParseError(t *testing.T) {
func Test_parseError(t *testing.T) {
cases := []struct {
in, out string
good bool

View File

@ -15,6 +15,7 @@ import (
"github.com/golangci/golangci-lint/internal/errorutil"
"github.com/golangci/golangci-lint/internal/pkgcache"
"github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors"
)
type actionAllocator struct {
@ -184,7 +185,7 @@ func (act *action) analyze() {
// It looks like there should be !pass.Analyzer.RunDespiteErrors
// but govet's cgocall crashes on it. Govet itself contains !pass.Analyzer.RunDespiteErrors condition here,
// but it exits before it if packages.Load have failed.
act.err = fmt.Errorf("analysis skipped: %w", &IllTypedError{Pkg: act.pkg})
act.err = fmt.Errorf("analysis skipped: %w", &pkgerrors.IllTypedError{Pkg: act.pkg})
} else {
startedAt = time.Now()
act.result, act.err = pass.Analyzer.Run(pass)

View File

@ -13,6 +13,7 @@ import (
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/internal/pkgcache"
"github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/logutils"
"github.com/golangci/golangci-lint/pkg/result"
@ -74,7 +75,7 @@ func runAnalyzers(cfg runAnalyzersConfig, lintCtx *linter.Context) ([]result.Iss
return retIssues
}
errIssues, err := buildIssuesFromIllTypedError(errs, lintCtx)
errIssues, err := pkgerrors.BuildIssuesFromIllTypedError(errs, lintCtx)
if err != nil {
return nil, err
}