Skip to content

Commit

Permalink
feat: apply formatters after the suggested fixes (#5246)
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez authored Dec 26, 2024
1 parent 7806463 commit 8e47515
Show file tree
Hide file tree
Showing 11 changed files with 337 additions and 25 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ require (
github.com/gofrs/flock v0.12.1
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a
github.com/golangci/go-printf-func-name v0.1.0
github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9
github.com/golangci/gofmt v0.0.0-20241223200906-057b0627d9b9
github.com/golangci/misspell v0.6.0
github.com/golangci/plugin-module-register v0.1.1
github.com/golangci/revgrep v0.5.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 34 additions & 22 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,32 +93,15 @@ func detectGoVersion() string {
// else it returns `go` version if present,
// else it returns empty.
func detectGoVersionFromGoMod() string {
info, err := gomod.GetModuleInfo()
if err != nil {
return ""
}

wd, err := os.Getwd()
modPath, err := gomod.GetGoModPath()
if err != nil {
return ""
}

slices.SortFunc(info, func(a, b gomod.ModInfo) int {
return cmp.Compare(len(b.Path), len(a.Path))
})

goMod := info[0]
for _, m := range info {
if !strings.HasPrefix(wd, m.Dir) {
continue
modPath = detectGoModFallback()
if modPath == "" {
return ""
}

goMod = m

break
}

file, err := parseGoMod(goMod.GoMod)
file, err := parseGoMod(modPath)
if err != nil {
return ""
}
Expand All @@ -144,3 +127,32 @@ func parseGoMod(goMod string) (*modfile.File, error) {

return modfile.Parse("go.mod", raw, nil)
}

func detectGoModFallback() string {
info, err := gomod.GetModuleInfo()
if err != nil {
return ""
}

wd, err := os.Getwd()
if err != nil {
return ""
}

slices.SortFunc(info, func(a, b gomod.ModInfo) int {
return cmp.Compare(len(b.Path), len(a.Path))
})

goMod := info[0]
for _, m := range info {
if !strings.HasPrefix(wd, m.Dir) {
continue
}

goMod = m

break
}

return goMod.GoMod
}
6 changes: 6 additions & 0 deletions pkg/goformatters/formatters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package goformatters

type Formatter interface {
Name() string
Format(filename string, src []byte) ([]byte, error)
}
48 changes: 48 additions & 0 deletions pkg/goformatters/gci/gci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package gci

import (
gcicfg "github.com/daixiang0/gci/pkg/config"
"github.com/daixiang0/gci/pkg/gci"
"github.com/ldez/grignotin/gomod"

"github.com/golangci/golangci-lint/pkg/config"
)

const Name = "gci"

type Formatter struct {
config *gcicfg.Config
}

func New(cfg config.GciSettings) (*Formatter, error) {
modPath, err := gomod.GetModulePath()
if err != nil {
return nil, err
}

parsedCfg, err := gcicfg.YamlConfig{
Cfg: gcicfg.BoolConfig{
NoInlineComments: cfg.NoInlineComments,
NoPrefixComments: cfg.NoPrefixComments,
SkipGenerated: cfg.SkipGenerated,
CustomOrder: cfg.CustomOrder,
NoLexOrder: cfg.NoLexOrder,
},
SectionStrings: cfg.Sections,
ModPath: modPath,
}.Parse()
if err != nil {
return nil, err
}

return &Formatter{config: parsedCfg}, nil
}

func (*Formatter) Name() string {
return Name
}

func (f *Formatter) Format(filename string, src []byte) ([]byte, error) {
_, formatted, err := gci.LoadFormat(src, filename, *f.config)
return formatted, err
}
35 changes: 35 additions & 0 deletions pkg/goformatters/gofmt/gofmt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package gofmt

import (
"github.com/golangci/gofmt/gofmt"

"github.com/golangci/golangci-lint/pkg/config"
)

const Name = "gofmt"

type Formatter struct {
options gofmt.Options
}

func New(cfg config.GoFmtSettings) *Formatter {
var rewriteRules []gofmt.RewriteRule
for _, rule := range cfg.RewriteRules {
rewriteRules = append(rewriteRules, gofmt.RewriteRule(rule))
}

return &Formatter{
options: gofmt.Options{
NeedSimplify: cfg.Simplify,
RewriteRules: rewriteRules,
},
}
}

func (*Formatter) Name() string {
return Name
}

func (f *Formatter) Format(filename string, src []byte) ([]byte, error) {
return gofmt.Source(filename, src, f.options)
}
43 changes: 43 additions & 0 deletions pkg/goformatters/gofumpt/gofumpt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package gofumpt

import (
"strings"

gofumpt "mvdan.cc/gofumpt/format"

"github.com/golangci/golangci-lint/pkg/config"
)

const Name = "gofumpt"

type Formatter struct {
options gofumpt.Options
}

func New(cfg config.GofumptSettings, goVersion string) *Formatter {
return &Formatter{
options: gofumpt.Options{
LangVersion: getLangVersion(goVersion),
ModulePath: cfg.ModulePath,
ExtraRules: cfg.ExtraRules,
},
}
}

func (*Formatter) Name() string {
return Name
}

func (f *Formatter) Format(_ string, src []byte) ([]byte, error) {
return gofumpt.Source(src, f.options)
}

// modified copy of pkg/golinters/gofumpt/gofumpt.go
func getLangVersion(v string) string {
if v == "" {
// TODO: defaults to "1.15", in the future (v2) must be removed.
return "go1.15"
}

return "go" + strings.TrimPrefix(v, "go")
}
22 changes: 22 additions & 0 deletions pkg/goformatters/goimports/goimports.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package goimports

import (
"golang.org/x/tools/imports"
)

const Name = "goimports"

type Formatter struct{}

func New() *Formatter {
return &Formatter{}
}

func (*Formatter) Name() string {
return Name
}

func (*Formatter) Format(filename string, src []byte) ([]byte, error) {
// The `imports.LocalPrefix` (`settings.LocalPrefixes`) is a global var.
return imports.Process(filename, src, nil)
}
7 changes: 7 additions & 0 deletions pkg/lint/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *gouti
return nil, fmt.Errorf("failed to get enabled linters: %w", err)
}

formatter, err := processors.NewFormatter(log, cfg, enabledLinters)
if err != nil {
return nil, fmt.Errorf("failed to create formatter: %w", err)
}

return &Runner{
Processors: []processors.Processor{
processors.NewCgo(goenv),
Expand Down Expand Up @@ -95,6 +100,8 @@ func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *gouti

// The fixer still needs to see paths for the issues that are relative to the current directory.
processors.NewFixer(cfg, log, fileCache),
// The formatter needs to be after the fixer and the last processor that write files.
formatter,

// Now we can modify the issues for output.
processors.NewPathPrefixer(cfg.Output.PathPrefix),
Expand Down
11 changes: 11 additions & 0 deletions pkg/result/processors/fixer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ import (
"github.com/golangci/golangci-lint/internal/x/tools/diff"
"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/fsutils"
"github.com/golangci/golangci-lint/pkg/goformatters/gci"
"github.com/golangci/golangci-lint/pkg/goformatters/gofmt"
"github.com/golangci/golangci-lint/pkg/goformatters/gofumpt"
"github.com/golangci/golangci-lint/pkg/goformatters/goimports"
"github.com/golangci/golangci-lint/pkg/logutils"
"github.com/golangci/golangci-lint/pkg/result"
"github.com/golangci/golangci-lint/pkg/timeutils"
Expand Down Expand Up @@ -71,11 +75,18 @@ func (p Fixer) process(issues []result.Issue) ([]result.Issue, error) {
// filenames / linters / edits
editsByLinter := make(map[string]map[string][]diff.Edit)

formatters := []string{gofumpt.Name, goimports.Name, gofmt.Name, gci.Name}

var notFixableIssues []result.Issue

for i := range issues {
issue := issues[i]

if slices.Contains(formatters, issue.FromLinter) {
notFixableIssues = append(notFixableIssues, issue)
continue
}

if issue.SuggestedFixes == nil || skipNoTextEdit(&issue) {
notFixableIssues = append(notFixableIssues, issue)
continue
Expand Down
Loading

0 comments on commit 8e47515

Please sign in to comment.