diff --git a/go.mod b/go.mod index bf92c5112000..403f4796e4eb 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 github.com/OpenPeeDeeP/depguard/v2 v2.2.1 + github.com/alecthomas/chroma/v2 v2.15.0 github.com/alecthomas/go-check-sumtype v0.3.1 github.com/alexkohler/nakedret/v2 v2.0.6 github.com/alexkohler/prealloc v1.0.0 @@ -148,6 +149,7 @@ require ( github.com/chavacava/garif v0.1.0 // indirect github.com/dave/dst v0.27.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dlclark/regexp2 v1.11.4 // indirect github.com/ebitengine/purego v0.8.2 // indirect github.com/ettle/strcase v0.2.0 // indirect github.com/fatih/structtag v1.2.0 // indirect diff --git a/go.sum b/go.sum index 58f9e777a774..524549f6890b 100644 --- a/go.sum +++ b/go.sum @@ -61,6 +61,8 @@ github.com/OpenPeeDeeP/depguard/v2 v2.2.1 h1:vckeWVESWp6Qog7UZSARNqfu/cZqvki8zsu github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc= +github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio= github.com/alecthomas/go-check-sumtype v0.3.1 h1:u9aUvbGINJxLVXiFvHUlPEaD7VDULsrxJb4Aq31NLkU= github.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= @@ -148,8 +150,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8= github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY= -github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= -github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= +github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= diff --git a/pkg/commands/fmt.go b/pkg/commands/fmt.go index c6b10a62b652..502dcebdfe9c 100644 --- a/pkg/commands/fmt.go +++ b/pkg/commands/fmt.go @@ -20,8 +20,9 @@ import ( type fmtOptions struct { config.LoaderOptions - diff bool // Flag only. - stdin bool // Flag only. + diff bool // Flag only. + diffColored bool // Flag only. + stdin bool // Flag only. } type fmtCommand struct { @@ -70,6 +71,7 @@ func newFmtCommand(logger logutils.Log, info BuildInfo) *fmtCommand { setupFormattersFlagSet(c.viper, fs) fs.BoolVarP(&c.opts.diff, "diff", "d", false, color.GreenString("Display diffs instead of rewriting files")) + fs.BoolVar(&c.opts.diffColored, "diff-colored", false, color.GreenString("Display diffs instead of rewriting files (with colors)")) fs.BoolVar(&c.opts.stdin, "stdin", false, color.GreenString("Use standard input for piping source files")) c.cmd = fmtCmd @@ -102,7 +104,7 @@ func (c *fmtCommand) preRunE(_ *cobra.Command, _ []string) error { matcher := processors.NewGeneratedFileMatcher(c.cfg.Formatters.Exclusions.Generated) - opts, err := goformat.NewRunnerOptions(c.cfg, c.opts.diff, c.opts.stdin) + opts, err := goformat.NewRunnerOptions(c.cfg, c.opts.diff, c.opts.diffColored, c.opts.stdin) if err != nil { return fmt.Errorf("build walk options: %w", err) } diff --git a/pkg/goformat/runner.go b/pkg/goformat/runner.go index 3207f117d552..5e1a2a6b1075 100644 --- a/pkg/goformat/runner.go +++ b/pkg/goformat/runner.go @@ -12,6 +12,7 @@ import ( "regexp" "strings" + "github.com/alecthomas/chroma/v2/quick" rpdiff "github.com/rogpeppe/go-internal/diff" "github.com/golangci/golangci-lint/v2/pkg/config" @@ -128,9 +129,19 @@ func (c *Runner) process(path string, stdout io.Writer, in io.Reader) error { if c.opts.diff { newName := filepath.ToSlash(path) oldName := newName + ".orig" - _, err = stdout.Write(rpdiff.Diff(oldName, input, newName, output)) - if err != nil { - return err + + patch := rpdiff.Diff(oldName, input, newName, output) + + if c.opts.colors { + err = quick.Highlight(stdout, string(patch), "diff", "terminal", "native") + if err != nil { + return err + } + } else { + _, err = stdout.Write(patch) + if err != nil { + return err + } } c.exitCode = 1 @@ -168,10 +179,11 @@ type RunnerOptions struct { patterns []*regexp.Regexp generated string diff bool + colors bool stdin bool } -func NewRunnerOptions(cfg *config.Config, diff, stdin bool) (RunnerOptions, error) { +func NewRunnerOptions(cfg *config.Config, diff, diffColored, stdin bool) (RunnerOptions, error) { basePath, err := fsutils.GetBasePath(context.Background(), cfg.Run.RelativePathMode, cfg.GetConfigDir()) if err != nil { return RunnerOptions{}, fmt.Errorf("get base path: %w", err) @@ -180,7 +192,8 @@ func NewRunnerOptions(cfg *config.Config, diff, stdin bool) (RunnerOptions, erro opts := RunnerOptions{ basePath: basePath, generated: cfg.Formatters.Exclusions.Generated, - diff: diff, + diff: diff || diffColored, + colors: diffColored, stdin: stdin, }