Support --fix for gofumpt (#1239)
This commit is contained in:
parent
90bce10fcf
commit
c8bd9549a5
1
go.mod
1
go.mod
@ -39,6 +39,7 @@ require (
|
|||||||
github.com/ryancurrah/gomodguard v1.1.0
|
github.com/ryancurrah/gomodguard v1.1.0
|
||||||
github.com/ryanrolds/sqlclosecheck v0.3.0
|
github.com/ryanrolds/sqlclosecheck v0.3.0
|
||||||
github.com/securego/gosec/v2 v2.3.0
|
github.com/securego/gosec/v2 v2.3.0
|
||||||
|
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c
|
||||||
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada // v2.19.8
|
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada // v2.19.8
|
||||||
github.com/sirupsen/logrus v1.6.0
|
github.com/sirupsen/logrus v1.6.0
|
||||||
github.com/sonatard/noctx v0.0.1
|
github.com/sonatard/noctx v0.0.1
|
||||||
|
2
go.sum
2
go.sum
@ -307,6 +307,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
|
|||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/securego/gosec/v2 v2.3.0 h1:y/9mCF2WPDbSDpL3QDWZD3HHGrSYw0QSHnCqTfs4JPE=
|
github.com/securego/gosec/v2 v2.3.0 h1:y/9mCF2WPDbSDpL3QDWZD3HHGrSYw0QSHnCqTfs4JPE=
|
||||||
github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME=
|
github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME=
|
||||||
|
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=
|
||||||
|
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
|
||||||
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada h1:WokF3GuxBeL+n4Lk4Fa8v9mbdjlrl7bHuneF4N1bk2I=
|
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada h1:WokF3GuxBeL+n4Lk4Fa8v9mbdjlrl7bHuneF4N1bk2I=
|
||||||
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
|
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
|
||||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
|
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
|
||||||
|
@ -46,7 +46,7 @@ func NewGofmt() *goanalysis.Linter {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, false)
|
is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, gofmtName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "can't extract issues from gofmt diff output %q", string(diff))
|
return nil, errors.Wrapf(err, "can't extract issues from gofmt diff output %q", string(diff))
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,29 @@ func (p *hunkChangesParser) parse(h *diffpkg.Hunk) []Change {
|
|||||||
return p.ret
|
return p.ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractIssuesFromPatch(patch string, log logutils.Log, lintCtx *linter.Context, isGoimports bool) ([]result.Issue, error) {
|
func getErrorTextForLinter(lintCtx *linter.Context, linterName string) string {
|
||||||
|
text := "File is not formatted"
|
||||||
|
switch linterName {
|
||||||
|
case gofumptName:
|
||||||
|
text = "File is not `gofumpt`-ed"
|
||||||
|
if lintCtx.Settings().Gofumpt.ExtraRules {
|
||||||
|
text += " with `-extra`"
|
||||||
|
}
|
||||||
|
case gofmtName:
|
||||||
|
text = "File is not `gofmt`-ed"
|
||||||
|
if lintCtx.Settings().Gofmt.Simplify {
|
||||||
|
text += " with `-s`"
|
||||||
|
}
|
||||||
|
case goimportsName:
|
||||||
|
text = "File is not `goimports`-ed"
|
||||||
|
if lintCtx.Settings().Goimports.LocalPrefixes != "" {
|
||||||
|
text += " with -local " + lintCtx.Settings().Goimports.LocalPrefixes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractIssuesFromPatch(patch string, log logutils.Log, lintCtx *linter.Context, linterName string) ([]result.Issue, error) {
|
||||||
diffs, err := diffpkg.ParseMultiFileDiff([]byte(patch))
|
diffs, err := diffpkg.ParseMultiFileDiff([]byte(patch))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "can't parse patch")
|
return nil, errors.Wrap(err, "can't parse patch")
|
||||||
@ -225,35 +247,19 @@ func extractIssuesFromPatch(patch string, log logutils.Log, lintCtx *linter.Cont
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, hunk := range d.Hunks {
|
for _, hunk := range d.Hunks {
|
||||||
var text string
|
|
||||||
if isGoimports {
|
|
||||||
text = "File is not `goimports`-ed"
|
|
||||||
if lintCtx.Settings().Goimports.LocalPrefixes != "" {
|
|
||||||
text += " with -local " + lintCtx.Settings().Goimports.LocalPrefixes
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
text = "File is not `gofmt`-ed"
|
|
||||||
if lintCtx.Settings().Gofmt.Simplify {
|
|
||||||
text += " with `-s`"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p := hunkChangesParser{
|
p := hunkChangesParser{
|
||||||
log: log,
|
log: log,
|
||||||
}
|
}
|
||||||
changes := p.parse(hunk)
|
changes := p.parse(hunk)
|
||||||
for _, change := range changes {
|
for _, change := range changes {
|
||||||
change := change // fix scope
|
change := change // fix scope
|
||||||
linterName := gofmtName
|
|
||||||
if isGoimports {
|
|
||||||
linterName = goimportsName
|
|
||||||
}
|
|
||||||
i := result.Issue{
|
i := result.Issue{
|
||||||
FromLinter: linterName,
|
FromLinter: linterName,
|
||||||
Pos: token.Position{
|
Pos: token.Position{
|
||||||
Filename: d.NewName,
|
Filename: d.NewName,
|
||||||
Line: change.LineRange.From,
|
Line: change.LineRange.From,
|
||||||
},
|
},
|
||||||
Text: text,
|
Text: getErrorTextForLinter(lintCtx, linterName),
|
||||||
Replacement: &change.Replacement,
|
Replacement: &change.Replacement,
|
||||||
}
|
}
|
||||||
if change.LineRange.From != change.LineRange.To {
|
if change.LineRange.From != change.LineRange.To {
|
||||||
|
@ -3,17 +3,16 @@ package golinters
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/token"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/shazow/go-diff/difflib"
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"mvdan.cc/gofumpt/format"
|
"mvdan.cc/gofumpt/format"
|
||||||
|
|
||||||
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
|
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
|
||||||
"github.com/golangci/golangci-lint/pkg/lint/linter"
|
"github.com/golangci/golangci-lint/pkg/lint/linter"
|
||||||
"github.com/golangci/golangci-lint/pkg/result"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const gofumptName = "gofumpt"
|
const gofumptName = "gofumpt"
|
||||||
@ -21,6 +20,7 @@ const gofumptName = "gofumpt"
|
|||||||
func NewGofumpt() *goanalysis.Linter {
|
func NewGofumpt() *goanalysis.Linter {
|
||||||
var mu sync.Mutex
|
var mu sync.Mutex
|
||||||
var resIssues []goanalysis.Issue
|
var resIssues []goanalysis.Issue
|
||||||
|
differ := difflib.New()
|
||||||
|
|
||||||
analyzer := &analysis.Analyzer{
|
analyzer := &analysis.Analyzer{
|
||||||
Name: gofumptName,
|
Name: gofumptName,
|
||||||
@ -53,14 +53,26 @@ func NewGofumpt() *goanalysis.Linter {
|
|||||||
return nil, fmt.Errorf("error while running gofumpt: %w", err)
|
return nil, fmt.Errorf("error while running gofumpt: %w", err)
|
||||||
}
|
}
|
||||||
if !bytes.Equal(input, output) {
|
if !bytes.Equal(input, output) {
|
||||||
issues = append(issues, goanalysis.NewIssue(&result.Issue{
|
out := bytes.Buffer{}
|
||||||
FromLinter: gofumptName,
|
_, err = out.WriteString(fmt.Sprintf("--- %[1]s\n+++ %[1]s\n", f))
|
||||||
Text: "File is not `gofumpt`-ed",
|
if err != nil {
|
||||||
Pos: token.Position{
|
return nil, fmt.Errorf("error while running gofumpt: %w", err)
|
||||||
Filename: f,
|
}
|
||||||
Line: strings.Count(string(input), "\n"),
|
|
||||||
},
|
err = differ.Diff(&out, bytes.NewReader(input), bytes.NewReader(output))
|
||||||
}, pass))
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error while running gofumpt: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
diff := out.String()
|
||||||
|
is, err := extractIssuesFromPatch(diff, lintCtx.Log, lintCtx, gofumptName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "can't extract issues from gofumpt diff output %q", diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range is {
|
||||||
|
issues = append(issues, goanalysis.NewIssue(&is[i], pass))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ func NewGoimports() *goanalysis.Linter {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, true)
|
is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, goimportsName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "can't extract issues from gofmt diff output %q", string(diff))
|
return nil, errors.Wrapf(err, "can't extract issues from gofmt diff output %q", string(diff))
|
||||||
}
|
}
|
||||||
|
9
test/testdata/fix/in/gofumpt.go
vendored
Normal file
9
test/testdata/fix/in/gofumpt.go
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//args: -Egofumpt
|
||||||
|
//config: linters-settings.gofumpt.extra-rules=true
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func GofmtNotExtra(bar string, baz string) {
|
||||||
|
fmt.Print(bar, baz)
|
||||||
|
}
|
9
test/testdata/fix/out/gofumpt.go
vendored
Normal file
9
test/testdata/fix/out/gofumpt.go
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//args: -Egofumpt
|
||||||
|
//config: linters-settings.gofumpt.extra-rules=true
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func GofmtNotExtra(bar, baz string) {
|
||||||
|
fmt.Print(bar, baz)
|
||||||
|
}
|
5
test/testdata/gofumpt.go
vendored
5
test/testdata/gofumpt.go
vendored
@ -4,8 +4,5 @@ package testdata
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func GofumptNewLine() {
|
func GofumptNewLine() {
|
||||||
|
fmt.Println( "foo" ) // ERROR "File is not `gofumpt`-ed"
|
||||||
fmt.Println("foo")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ERROR "File is not `gofumpt`-ed"
|
|
||||||
|
9
test/testdata/gofumpt_with_extra.go
vendored
Normal file
9
test/testdata/gofumpt_with_extra.go
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//args: -Egofumpt
|
||||||
|
//config: linters-settings.gofumpt.extra-rules=true
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func GofmtNotExtra(bar string, baz string) { // ERROR "File is not `gofumpt`-ed with `-extra`"
|
||||||
|
fmt.Print("foo")
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user