Skip to content

Commit 2db7582

Browse files
author
Sergey Vilgelm
committed
Support --fix for gofumpt
1 parent 6e7c317 commit 2db7582

File tree

11 files changed

+83
-35
lines changed

11 files changed

+83
-35
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ require (
3939
github.com/ryancurrah/gomodguard v1.1.0
4040
github.com/ryanrolds/sqlclosecheck v0.3.0
4141
github.com/securego/gosec/v2 v2.3.0
42+
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c
4243
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada // v2.19.8
4344
github.com/sirupsen/logrus v1.6.0
4445
github.com/sonatard/noctx v0.0.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
307307
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
308308
github.com/securego/gosec/v2 v2.3.0 h1:y/9mCF2WPDbSDpL3QDWZD3HHGrSYw0QSHnCqTfs4JPE=
309309
github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME=
310+
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=
311+
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
310312
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada h1:WokF3GuxBeL+n4Lk4Fa8v9mbdjlrl7bHuneF4N1bk2I=
311313
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
312314
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=

pkg/golinters/gofmt.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func NewGofmt() *goanalysis.Linter {
4646
continue
4747
}
4848

49-
is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, false)
49+
is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, gofmtName)
5050
if err != nil {
5151
return nil, errors.Wrapf(err, "can't extract issues from gofmt diff output %q", string(diff))
5252
}

pkg/golinters/gofmt_common.go

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,29 @@ func (p *hunkChangesParser) parse(h *diffpkg.Hunk) []Change {
207207
return p.ret
208208
}
209209

210-
func extractIssuesFromPatch(patch string, log logutils.Log, lintCtx *linter.Context, isGoimports bool) ([]result.Issue, error) {
210+
func getErrorTextForLinter(lintCtx *linter.Context, linterName string) string {
211+
text := "File is not formatted"
212+
switch linterName {
213+
case gofumptName:
214+
text = "File is not `gofumpt`-ed"
215+
if lintCtx.Settings().Gofumpt.ExtraRules {
216+
text += " with `-extra`"
217+
}
218+
case gofmtName:
219+
text = "File is not `gofmt`-ed"
220+
if lintCtx.Settings().Gofmt.Simplify {
221+
text += " with `-s`"
222+
}
223+
case goimportsName:
224+
text = "File is not `goimports`-ed"
225+
if lintCtx.Settings().Goimports.LocalPrefixes != "" {
226+
text += " with -local " + lintCtx.Settings().Goimports.LocalPrefixes
227+
}
228+
}
229+
return text
230+
}
231+
232+
func extractIssuesFromPatch(patch string, log logutils.Log, lintCtx *linter.Context, linterName string) ([]result.Issue, error) {
211233
diffs, err := diffpkg.ParseMultiFileDiff([]byte(patch))
212234
if err != nil {
213235
return nil, errors.Wrap(err, "can't parse patch")
@@ -225,35 +247,19 @@ func extractIssuesFromPatch(patch string, log logutils.Log, lintCtx *linter.Cont
225247
}
226248

227249
for _, hunk := range d.Hunks {
228-
var text string
229-
if isGoimports {
230-
text = "File is not `goimports`-ed"
231-
if lintCtx.Settings().Goimports.LocalPrefixes != "" {
232-
text += " with -local " + lintCtx.Settings().Goimports.LocalPrefixes
233-
}
234-
} else {
235-
text = "File is not `gofmt`-ed"
236-
if lintCtx.Settings().Gofmt.Simplify {
237-
text += " with `-s`"
238-
}
239-
}
240250
p := hunkChangesParser{
241251
log: log,
242252
}
243253
changes := p.parse(hunk)
244254
for _, change := range changes {
245255
change := change // fix scope
246-
linterName := gofmtName
247-
if isGoimports {
248-
linterName = goimportsName
249-
}
250256
i := result.Issue{
251257
FromLinter: linterName,
252258
Pos: token.Position{
253259
Filename: d.NewName,
254260
Line: change.LineRange.From,
255261
},
256-
Text: text,
262+
Text: getErrorTextForLinter(lintCtx, linterName),
257263
Replacement: &change.Replacement,
258264
}
259265
if change.LineRange.From != change.LineRange.To {

pkg/golinters/gofumpt.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@ package golinters
33
import (
44
"bytes"
55
"fmt"
6-
"go/token"
76
"io/ioutil"
8-
"strings"
97
"sync"
108

9+
"github.com/pkg/errors"
10+
"github.com/shazow/go-diff/difflib"
1111
"golang.org/x/tools/go/analysis"
1212
"mvdan.cc/gofumpt/format"
1313

1414
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
1515
"github.com/golangci/golangci-lint/pkg/lint/linter"
16-
"github.com/golangci/golangci-lint/pkg/result"
1716
)
1817

1918
const gofumptName = "gofumpt"
2019

2120
func NewGofumpt() *goanalysis.Linter {
2221
var mu sync.Mutex
2322
var resIssues []goanalysis.Issue
23+
differ := difflib.New()
2424

2525
analyzer := &analysis.Analyzer{
2626
Name: gofumptName,
@@ -53,14 +53,26 @@ func NewGofumpt() *goanalysis.Linter {
5353
return nil, fmt.Errorf("error while running gofumpt: %w", err)
5454
}
5555
if !bytes.Equal(input, output) {
56-
issues = append(issues, goanalysis.NewIssue(&result.Issue{
57-
FromLinter: gofumptName,
58-
Text: "File is not `gofumpt`-ed",
59-
Pos: token.Position{
60-
Filename: f,
61-
Line: strings.Count(string(input), "\n"),
62-
},
63-
}, pass))
56+
out := bytes.Buffer{}
57+
_, err = out.WriteString(fmt.Sprintf("--- %[1]s\n+++ %[1]s\n", f))
58+
if err != nil {
59+
return nil, fmt.Errorf("error while running gofumpt: %w", err)
60+
}
61+
62+
err = differ.Diff(&out, bytes.NewReader(input), bytes.NewReader(output))
63+
if err != nil {
64+
return nil, fmt.Errorf("error while running gofumpt: %w", err)
65+
}
66+
67+
diff := out.String()
68+
is, err := extractIssuesFromPatch(diff, lintCtx.Log, lintCtx, gofumptName)
69+
if err != nil {
70+
return nil, errors.Wrapf(err, "can't extract issues from gofumpt diff output %q", diff)
71+
}
72+
73+
for i := range is {
74+
issues = append(issues, goanalysis.NewIssue(&is[i], pass))
75+
}
6476
}
6577
}
6678

pkg/golinters/goimports.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func NewGoimports() *goanalysis.Linter {
4747
continue
4848
}
4949

50-
is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, true)
50+
is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, goimportsName)
5151
if err != nil {
5252
return nil, errors.Wrapf(err, "can't extract issues from gofmt diff output %q", string(diff))
5353
}

test/linters_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ func testSourcesFromDir(t *testing.T, dir string) {
5151
testshared.NewLintRunner(t).Install()
5252

5353
for _, s := range sources {
54+
if !strings.Contains(s, "gofumpt") {
55+
continue
56+
}
5457
s := s
5558
t.Run(filepath.Base(s), func(subTest *testing.T) {
5659
subTest.Parallel()

test/testdata/fix/in/gofumpt.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//args: -Egofumpt
2+
//config: linters-settings.gofumpt.extra-rules=true
3+
package testdata
4+
5+
import "fmt"
6+
7+
func GofmtNotExtra(bar string, baz string) {
8+
fmt.Print(bar, baz)
9+
}

test/testdata/fix/out/gofumpt.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//args: -Egofumpt
2+
//config: linters-settings.gofumpt.extra-rules=true
3+
package testdata
4+
5+
import "fmt"
6+
7+
func GofmtNotExtra(bar, baz string) {
8+
fmt.Print(bar, baz)
9+
}

test/testdata/gofumpt.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,5 @@ package testdata
44
import "fmt"
55

66
func GofumptNewLine() {
7-
8-
fmt.Println("foo")
7+
fmt.Println( "foo" ) // ERROR "File is not `gofumpt`-ed"
98
}
10-
11-
// ERROR "File is not `gofumpt`-ed"

test/testdata/gofumpt_with_extra.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//args: -Egofumpt
2+
//config: linters-settings.gofumpt.extra-rules=true
3+
package testdata
4+
5+
import "fmt"
6+
7+
func GofmtNotExtra(bar string, baz string) { // ERROR "File is not `gofumpt`-ed with `-extra`"
8+
fmt.Print("foo")
9+
}

0 commit comments

Comments
 (0)