-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: new
fmt
command with dedicated formatter configuration (#5357)
- Loading branch information
Showing
24 changed files
with
952 additions
and
404 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package commands | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/fatih/color" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
|
||
"github.com/golangci/golangci-lint/pkg/config" | ||
"github.com/golangci/golangci-lint/pkg/goformat" | ||
"github.com/golangci/golangci-lint/pkg/goformatters" | ||
"github.com/golangci/golangci-lint/pkg/logutils" | ||
"github.com/golangci/golangci-lint/pkg/result/processors" | ||
) | ||
|
||
type fmtOptions struct { | ||
config.LoaderOptions | ||
|
||
diff bool // Flag only. | ||
} | ||
|
||
type fmtCommand struct { | ||
viper *viper.Viper | ||
cmd *cobra.Command | ||
|
||
opts fmtOptions | ||
|
||
cfg *config.Config | ||
|
||
buildInfo BuildInfo | ||
|
||
runner *goformat.Runner | ||
|
||
log logutils.Log | ||
debugf logutils.DebugFunc | ||
} | ||
|
||
func newFmtCommand(logger logutils.Log, info BuildInfo) *fmtCommand { | ||
c := &fmtCommand{ | ||
viper: viper.New(), | ||
log: logger, | ||
debugf: logutils.Debug(logutils.DebugKeyExec), | ||
cfg: config.NewDefault(), | ||
buildInfo: info, | ||
} | ||
|
||
fmtCmd := &cobra.Command{ | ||
Use: "fmt", | ||
Short: "Format Go source files", | ||
RunE: c.execute, | ||
PreRunE: c.preRunE, | ||
PersistentPreRunE: c.persistentPreRunE, | ||
PersistentPostRun: c.persistentPostRun, | ||
SilenceUsage: true, | ||
} | ||
|
||
fmtCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals | ||
fmtCmd.SetErr(logutils.StdErr) | ||
|
||
fs := fmtCmd.Flags() | ||
fs.SortFlags = false // sort them as they are defined here | ||
|
||
setupConfigFileFlagSet(fs, &c.opts.LoaderOptions) | ||
|
||
setupFormattersFlagSet(c.viper, fs) | ||
|
||
fs.BoolVarP(&c.opts.diff, "diff", "d", false, color.GreenString("Display diffs instead of rewriting files")) | ||
|
||
c.cmd = fmtCmd | ||
|
||
return c | ||
} | ||
|
||
func (c *fmtCommand) persistentPreRunE(cmd *cobra.Command, args []string) error { | ||
c.log.Infof("%s", c.buildInfo.String()) | ||
|
||
loader := config.NewLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args) | ||
|
||
err := loader.Load(config.LoadOptions{CheckDeprecation: true, Validation: true}) | ||
if err != nil { | ||
return fmt.Errorf("can't load config: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (c *fmtCommand) preRunE(_ *cobra.Command, _ []string) error { | ||
metaFormatter, err := goformatters.NewMetaFormatter(c.log, &c.cfg.Formatters, &c.cfg.Run) | ||
if err != nil { | ||
return fmt.Errorf("failed to create meta-formatter: %w", err) | ||
} | ||
|
||
matcher := processors.NewGeneratedFileMatcher(c.cfg.Formatters.Exclusions.Generated) | ||
|
||
opts, err := goformat.NewRunnerOptions(c.cfg, c.opts.diff) | ||
if err != nil { | ||
return fmt.Errorf("build walk options: %w", err) | ||
} | ||
|
||
c.runner = goformat.NewRunner(c.log, metaFormatter, matcher, opts) | ||
|
||
return nil | ||
} | ||
|
||
func (c *fmtCommand) execute(_ *cobra.Command, args []string) error { | ||
paths, err := cleanArgs(args) | ||
if err != nil { | ||
return fmt.Errorf("failed to clean arguments: %w", err) | ||
} | ||
|
||
c.log.Infof("Formatting Go files...") | ||
|
||
err = c.runner.Run(paths) | ||
if err != nil { | ||
return fmt.Errorf("failed to process files: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (c *fmtCommand) persistentPostRun(_ *cobra.Command, _ []string) { | ||
if c.runner.ExitCode() != 0 { | ||
os.Exit(c.runner.ExitCode()) | ||
} | ||
} | ||
|
||
func cleanArgs(args []string) ([]string, error) { | ||
if len(args) == 0 { | ||
abs, err := filepath.Abs(".") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return []string{abs}, nil | ||
} | ||
|
||
var expanded []string | ||
for _, arg := range args { | ||
abs, err := filepath.Abs(strings.ReplaceAll(arg, "...", "")) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
expanded = append(expanded, abs) | ||
} | ||
|
||
return expanded, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package config | ||
|
||
type Formatters struct { | ||
Enable []string `mapstructure:"enable"` | ||
Settings FormatterSettings `mapstructure:"settings"` | ||
Exclusions FormatterExclusions `mapstructure:"exclusions"` | ||
} | ||
|
||
type FormatterExclusions struct { | ||
Generated string `mapstructure:"generated"` | ||
Paths []string `mapstructure:"paths"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package config | ||
|
||
var defaultFormatterSettings = FormatterSettings{ | ||
GoFmt: GoFmtSettings{ | ||
Simplify: true, | ||
}, | ||
Gci: GciSettings{ | ||
Sections: []string{"standard", "default"}, | ||
SkipGenerated: true, | ||
}, | ||
} | ||
|
||
type FormatterSettings struct { | ||
Gci GciSettings `mapstructure:"gci"` | ||
GoFmt GoFmtSettings `mapstructure:"gofmt"` | ||
GoFumpt GoFumptSettings `mapstructure:"gofumpt"` | ||
GoImports GoImportsSettings `mapstructure:"goimports"` | ||
} | ||
|
||
type GciSettings struct { | ||
Sections []string `mapstructure:"sections"` | ||
NoInlineComments bool `mapstructure:"no-inline-comments"` | ||
NoPrefixComments bool `mapstructure:"no-prefix-comments"` | ||
SkipGenerated bool `mapstructure:"skip-generated"` | ||
CustomOrder bool `mapstructure:"custom-order"` | ||
NoLexOrder bool `mapstructure:"no-lex-order"` | ||
|
||
// Deprecated: use Sections instead. | ||
LocalPrefixes string `mapstructure:"local-prefixes"` | ||
} | ||
|
||
type GoFmtSettings struct { | ||
Simplify bool | ||
RewriteRules []GoFmtRewriteRule `mapstructure:"rewrite-rules"` | ||
} | ||
|
||
type GoFmtRewriteRule struct { | ||
Pattern string | ||
Replacement string | ||
} | ||
|
||
type GoFumptSettings struct { | ||
ModulePath string `mapstructure:"module-path"` | ||
ExtraRules bool `mapstructure:"extra-rules"` | ||
|
||
// Deprecated: use the global `run.go` instead. | ||
LangVersion string `mapstructure:"lang-version"` | ||
} | ||
|
||
type GoImportsSettings struct { | ||
LocalPrefixes string `mapstructure:"local-prefixes"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.