Skip to content

Commit e68d278

Browse files
authored
dev: standardization of the integration of formatters (#5301)
1 parent bed0513 commit e68d278

32 files changed

+183
-338
lines changed

.golangci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ issues:
178178
- path: pkg/golinters/godot/godot.go
179179
linters: [staticcheck]
180180
text: "SA1019: settings.CheckAll is deprecated: use Scope instead"
181-
- path: pkg/golinters/gci/gci.go
181+
- path: pkg/goformatters/gci/gci.go
182182
linters: [staticcheck]
183183
text: "SA1019: settings.LocalPrefixes is deprecated: use Sections instead."
184184
- path: pkg/golinters/mnd/mnd.go

go.mod

+1-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ require (
4545
github.com/gofrs/flock v0.12.1
4646
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a
4747
github.com/golangci/go-printf-func-name v0.1.0
48-
github.com/golangci/gofmt v0.0.0-20241223200906-057b0627d9b9
48+
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d
4949
github.com/golangci/misspell v0.6.0
5050
github.com/golangci/plugin-module-register v0.1.1
5151
github.com/golangci/revgrep v0.5.3
@@ -95,7 +95,6 @@ require (
9595
github.com/sashamelentyev/interfacebloat v1.1.0
9696
github.com/sashamelentyev/usestdlibvars v1.28.0
9797
github.com/securego/gosec/v2 v2.21.4
98-
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c
9998
github.com/shirou/gopsutil/v4 v4.24.12
10099
github.com/sirupsen/logrus v1.9.3
101100
github.com/sivchari/containedctx v1.0.3

go.sum

+2-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/goformatters/analyzer.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package goformatters
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
9+
"github.com/rogpeppe/go-internal/diff"
10+
"golang.org/x/tools/go/analysis"
11+
12+
"github.com/golangci/golangci-lint/pkg/goanalysis"
13+
"github.com/golangci/golangci-lint/pkg/goformatters/internal"
14+
"github.com/golangci/golangci-lint/pkg/logutils"
15+
)
16+
17+
// NewAnalyzer converts a [Formatter] to an [analysis.Analyzer].
18+
func NewAnalyzer(logger logutils.Log, doc string, formatter Formatter) *analysis.Analyzer {
19+
return &analysis.Analyzer{
20+
Name: formatter.Name(),
21+
Doc: doc,
22+
Run: func(pass *analysis.Pass) (any, error) {
23+
for _, file := range pass.Files {
24+
position, isGoFiles := goanalysis.GetGoFilePosition(pass, file)
25+
if !isGoFiles {
26+
continue
27+
}
28+
29+
input, err := os.ReadFile(position.Filename)
30+
if err != nil {
31+
return nil, fmt.Errorf("unable to open file %s: %w", position.Filename, err)
32+
}
33+
34+
output, err := formatter.Format(position.Filename, input)
35+
if err != nil {
36+
return nil, fmt.Errorf("error while running %s: %w", formatter.Name(), err)
37+
}
38+
39+
if !bytes.Equal(input, output) {
40+
newName := filepath.ToSlash(position.Filename)
41+
oldName := newName + ".orig"
42+
43+
theDiff := diff.Diff(oldName, input, newName, output)
44+
45+
err = internal.ExtractDiagnosticFromPatch(pass, file, string(theDiff), logger)
46+
if err != nil {
47+
return nil, fmt.Errorf("can't extract issues from %s diff output %q: %w", formatter.Name(), string(theDiff), err)
48+
}
49+
}
50+
}
51+
52+
return nil, nil
53+
},
54+
}
55+
}

pkg/goformatters/gci/gci.go

+27-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package gci
22

33
import (
4+
"fmt"
5+
46
gcicfg "github.com/daixiang0/gci/pkg/config"
57
"github.com/daixiang0/gci/pkg/gci"
8+
"github.com/daixiang0/gci/pkg/log"
69
"github.com/ldez/grignotin/gomod"
710

811
"github.com/golangci/golangci-lint/pkg/config"
12+
"github.com/golangci/golangci-lint/pkg/goformatters/internal"
913
)
1014

1115
const Name = "gci"
@@ -14,23 +18,36 @@ type Formatter struct {
1418
config *gcicfg.Config
1519
}
1620

17-
func New(cfg config.GciSettings) (*Formatter, error) {
21+
func New(settings *config.GciSettings) (*Formatter, error) {
22+
log.InitLogger()
23+
_ = log.L().Sync()
24+
1825
modPath, err := gomod.GetModulePath()
1926
if err != nil {
20-
return nil, err
27+
internal.FormatterLogger.Errorf("gci: %v", err)
2128
}
2229

23-
parsedCfg, err := gcicfg.YamlConfig{
30+
cfg := gcicfg.YamlConfig{
2431
Cfg: gcicfg.BoolConfig{
25-
NoInlineComments: cfg.NoInlineComments,
26-
NoPrefixComments: cfg.NoPrefixComments,
27-
SkipGenerated: cfg.SkipGenerated,
28-
CustomOrder: cfg.CustomOrder,
29-
NoLexOrder: cfg.NoLexOrder,
32+
NoInlineComments: settings.NoInlineComments,
33+
NoPrefixComments: settings.NoPrefixComments,
34+
SkipGenerated: settings.SkipGenerated,
35+
CustomOrder: settings.CustomOrder,
36+
NoLexOrder: settings.NoLexOrder,
3037
},
31-
SectionStrings: cfg.Sections,
38+
SectionStrings: settings.Sections,
3239
ModPath: modPath,
33-
}.Parse()
40+
}
41+
42+
if settings.LocalPrefixes != "" {
43+
cfg.SectionStrings = []string{
44+
"standard",
45+
"default",
46+
fmt.Sprintf("prefix(%s)", settings.LocalPrefixes),
47+
}
48+
}
49+
50+
parsedCfg, err := cfg.Parse()
3451
if err != nil {
3552
return nil, err
3653
}

pkg/goformatters/gofmt/gofmt.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@ type Formatter struct {
1212
options gofmt.Options
1313
}
1414

15-
func New(cfg config.GoFmtSettings) *Formatter {
16-
var rewriteRules []gofmt.RewriteRule
17-
for _, rule := range cfg.RewriteRules {
18-
rewriteRules = append(rewriteRules, gofmt.RewriteRule(rule))
19-
}
15+
func New(settings *config.GoFmtSettings) *Formatter {
16+
options := gofmt.Options{}
17+
18+
if settings != nil {
19+
options.NeedSimplify = settings.Simplify
2020

21-
return &Formatter{
22-
options: gofmt.Options{
23-
NeedSimplify: cfg.Simplify,
24-
RewriteRules: rewriteRules,
25-
},
21+
for _, rule := range settings.RewriteRules {
22+
options.RewriteRules = append(options.RewriteRules, gofmt.RewriteRule(rule))
23+
}
2624
}
25+
26+
return &Formatter{options: options}
2727
}
2828

2929
func (*Formatter) Name() string {

pkg/goformatters/gofumpt/gofumpt.go

+10-7
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ type Formatter struct {
1414
options gofumpt.Options
1515
}
1616

17-
func New(cfg config.GofumptSettings, goVersion string) *Formatter {
18-
return &Formatter{
19-
options: gofumpt.Options{
17+
func New(settings *config.GofumptSettings, goVersion string) *Formatter {
18+
var options gofumpt.Options
19+
20+
if settings != nil {
21+
options = gofumpt.Options{
2022
LangVersion: getLangVersion(goVersion),
21-
ModulePath: cfg.ModulePath,
22-
ExtraRules: cfg.ExtraRules,
23-
},
23+
ModulePath: settings.ModulePath,
24+
ExtraRules: settings.ExtraRules,
25+
}
2426
}
27+
28+
return &Formatter{options: options}
2529
}
2630

2731
func (*Formatter) Name() string {
@@ -32,7 +36,6 @@ func (f *Formatter) Format(_ string, src []byte) ([]byte, error) {
3236
return gofumpt.Source(src, f.options)
3337
}
3438

35-
// modified copy of pkg/golinters/gofumpt/gofumpt.go
3639
func getLangVersion(v string) string {
3740
if v == "" {
3841
// TODO: defaults to "1.15", in the future (v2) must be removed.

pkg/goformatters/goimports/goimports.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@ package goimports
22

33
import (
44
"golang.org/x/tools/imports"
5+
6+
"github.com/golangci/golangci-lint/pkg/config"
57
)
68

79
const Name = "goimports"
810

911
type Formatter struct{}
1012

11-
func New() *Formatter {
13+
func New(settings *config.GoImportsSettings) *Formatter {
14+
if settings != nil {
15+
imports.LocalPrefix = settings.LocalPrefixes
16+
}
17+
1218
return &Formatter{}
1319
}
1420

pkg/goformatters/internal/commons.go

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package internal
2+
3+
import "github.com/golangci/golangci-lint/pkg/logutils"
4+
5+
// FormatterLogger must be use only when the context logger is not available.
6+
var FormatterLogger = logutils.NewStderrLog(logutils.DebugKeyFormatter)

pkg/golinters/internal/diff.go renamed to pkg/goformatters/internal/diff.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"golang.org/x/tools/go/analysis"
1313

1414
"github.com/golangci/golangci-lint/pkg/goanalysis"
15-
"github.com/golangci/golangci-lint/pkg/lint/linter"
1615
"github.com/golangci/golangci-lint/pkg/logutils"
1716
)
1817

@@ -215,7 +214,7 @@ func ExtractDiagnosticFromPatch(
215214
pass *analysis.Pass,
216215
file *ast.File,
217216
patch string,
218-
lintCtx *linter.Context,
217+
logger logutils.Log,
219218
) error {
220219
diffs, err := diffpkg.ParseMultiFileDiff([]byte(patch))
221220
if err != nil {
@@ -232,12 +231,12 @@ func ExtractDiagnosticFromPatch(
232231

233232
for _, d := range diffs {
234233
if len(d.Hunks) == 0 {
235-
lintCtx.Log.Warnf("Got no hunks in diff %+v", d)
234+
logger.Warnf("Got no hunks in diff %+v", d)
236235
continue
237236
}
238237

239238
for _, hunk := range d.Hunks {
240-
p := hunkChangesParser{log: lintCtx.Log}
239+
p := hunkChangesParser{log: logger}
241240

242241
changes := p.parse(hunk)
243242

pkg/goformatters/meta_formatter.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,20 @@ func NewMetaFormatter(log logutils.Log, cfg *config.Config, enabledLinters map[s
2323
m := &MetaFormatter{log: log}
2424

2525
if _, ok := enabledLinters[gofmt.Name]; ok {
26-
m.formatters = append(m.formatters, gofmt.New(cfg.LintersSettings.Gofmt))
26+
m.formatters = append(m.formatters, gofmt.New(&cfg.LintersSettings.Gofmt))
2727
}
2828

2929
if _, ok := enabledLinters[gofumpt.Name]; ok {
30-
m.formatters = append(m.formatters, gofumpt.New(cfg.LintersSettings.Gofumpt, cfg.Run.Go))
30+
m.formatters = append(m.formatters, gofumpt.New(&cfg.LintersSettings.Gofumpt, cfg.Run.Go))
3131
}
3232

3333
if _, ok := enabledLinters[goimports.Name]; ok {
34-
m.formatters = append(m.formatters, goimports.New())
34+
m.formatters = append(m.formatters, goimports.New(&cfg.LintersSettings.Goimports))
3535
}
3636

3737
// gci is a last because the only goal of gci is to handle imports.
3838
if _, ok := enabledLinters[gci.Name]; ok {
39-
formatter, err := gci.New(cfg.LintersSettings.Gci)
39+
formatter, err := gci.New(&cfg.LintersSettings.Gci)
4040
if err != nil {
4141
return nil, fmt.Errorf("gci: creating formatter: %w", err)
4242
}

0 commit comments

Comments
 (0)