Skip to content

Commit 45e5cb5

Browse files
authored
Add options for seeing which files were formatted (#249)
* Add options for seeing which files were formatted This PR adds two features for keeping track of which files were edited by yamlfmt: `-verbose`, `-v`: When formatting with verbose mode on, the modified paths will be printed. `-debug diffs`: When formatting with `diffs` debug code, all formatting diffs will be printed. Additionally: * Fixed the `tempfile` bug that wouldn't replicate subdirectories properly * Added `-q` short version of the `-quiet` flag * fix integration tests
1 parent ea03c83 commit 45e5cb5

File tree

31 files changed

+253
-113
lines changed

31 files changed

+253
-113
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ integrationtest_stdout:
4141
.PHONY: integrationtest_update
4242
integrationtest_update:
4343
$(MAKE) build
44-
go test -tags=integration_test ./integrationtest/command -update
44+
go test -tags=integration_test -v ./integrationtest/command -update
4545

4646
.PHONY: command_test_case
4747
command_test_case:

cmd/yamlfmt/flags.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ operation without performing it.`)
3737
flagPrintConf *bool = flag.Bool("print_conf", false, "Print config")
3838
flagDoublestar *bool = flag.Bool("dstar", false, "Use doublestar globs for include and exclude")
3939
flagQuiet *bool = flag.Bool("quiet", false, "Print minimal output to stdout")
40+
flagQuietShort *bool = flag.Bool("q", false, "Print minimal output to stdout")
41+
flagVerbose *bool = flag.Bool("verbose", false, "Print additional output to stdout.")
42+
flagVerboseShort *bool = flag.Bool("v", false, "Print additional output to stdout.")
4043
flagContinueOnError *bool = flag.Bool("continue_on_error", false, "Continue to format files that didn't fail instead of exiting with code 1.")
4144
flagGitignoreExcludes *bool = flag.Bool("gitignore_excludes", false, "Use a gitignore file for excludes")
4245
flagGitignorePath *string = flag.String("gitignore_path", ".gitignore", "Path to gitignore file to use")

cmd/yamlfmt/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ func run() error {
5555
c := &command.Command{
5656
Operation: getOperationFromFlag(),
5757
Registry: getFullRegistry(),
58-
Quiet: *flagQuiet,
58+
Quiet: *flagQuiet || *flagQuietShort,
59+
Verbose: *flagVerbose || *flagVerboseShort,
5960
}
6061

6162
configData := map[string]any{}

command/command.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type Command struct {
5757
Registry *yamlfmt.Registry
5858
Config *Config
5959
Quiet bool
60+
Verbose bool
6061
}
6162

6263
func (c *Command) Run() error {
@@ -74,6 +75,7 @@ func (c *Command) Run() error {
7475
LineSepCharacter: lineSepChar,
7576
Formatter: formatter,
7677
Quiet: c.Quiet,
78+
Verbose: c.Verbose,
7779
ContinueOnError: c.Config.ContinueOnError,
7880
OutputFormat: c.Config.OutputFormat,
7981
}

docs/command-usage.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,16 @@ All flags must be specified **before** any path arguments.
5959

6060
These flags adjust the command's mode of operation. All of these flags are booleans.
6161

62-
| Name | Flag | Example | Description |
63-
| :------------ | :------------ | :-------------------------- | :-------------------------------------------------------- |
64-
| Help | `-help` | `yamlfmt -help` | Print the command usage information. |
65-
| Print Version | `-version` | `yamlfmt -version` | Print the yamlfmt version. |
66-
| Print Config | `-print_conf` | `yamlfmt -print_conf` | Print the merged configuration to use. |
67-
| Dry Run | `-dry` | `yamlfmt -dry .` | Use [Dry Run](#dry-run) mode |
68-
| Lint | `-lint` | `yamlfmt -lint .` | Use [Lint](#lint) mode |
69-
| Quiet Mode | `-quiet` | `yamlfmt -dry -quiet .` | Use quiet mode. Only has effect in Dry Run or Lint modes. |
70-
| Read Stdin | `-in` | `cat x.yaml \| yamlfmt -in` | Read input from stdin and output result to stdout. |
62+
| Name | Flag | Example | Description |
63+
| :------------ | :--------------- | :-------------------------- | :-------------------------------------------------------- |
64+
| Help | `-help` | `yamlfmt -help` | Print the command usage information. |
65+
| Print Version | `-version` | `yamlfmt -version` | Print the yamlfmt version. |
66+
| Print Config | `-print_conf` | `yamlfmt -print_conf` | Print the merged configuration to use. |
67+
| Dry Run | `-dry` | `yamlfmt -dry .` | Use [Dry Run](#dry-run) mode |
68+
| Lint | `-lint` | `yamlfmt -lint .` | Use [Lint](#lint) mode |
69+
| Read Stdin | `-in` | `cat x.yaml \| yamlfmt -in` | Read input from stdin and output result to stdout. |
70+
| Quiet Mode | `-quiet`, `-q` | `yamlfmt -dry -q .` | Use quiet mode. Only has effect in Dry Run or Lint modes. |
71+
| Verbose Mode | `-verbose`, `-v` | `yamlfmt -v .` | Use verbose mode. Only has effect in Format mode. |
7172

7273
### Configuration Flags
7374

@@ -111,5 +112,7 @@ Debug logging can be enabled through the `-debug` [array flag](#string-array-fla
111112
- Log the details for the path discovery process. Use it to debug your include/exclude patterns.
112113
* `config`
113114
- Log the details for the configuration loading process. Use it to figure out which config file yamlfmt uses and why.
115+
* `diffs`
116+
- Log each diff for all formatted files.
114117
* `all`
115118
- Enable all available debug codes.

engine.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package yamlfmt
1717
import (
1818
"fmt"
1919
"os"
20+
"slices"
2021

2122
"github.com/google/yamlfmt/internal/collections"
2223
"github.com/google/yamlfmt/internal/multilinediff"
@@ -88,7 +89,9 @@ func (fds FileDiffs) Add(diff *FileDiff) error {
8889

8990
func (fds FileDiffs) StrOutput() string {
9091
result := ""
91-
for _, fd := range fds {
92+
sortedPaths := fds.sortedPaths()
93+
for _, path := range sortedPaths {
94+
fd := fds[path]
9295
if fd.Diff.Changed() {
9396
result += fd.StrOutput()
9497
}
@@ -98,7 +101,9 @@ func (fds FileDiffs) StrOutput() string {
98101

99102
func (fds FileDiffs) StrOutputQuiet() string {
100103
result := ""
101-
for _, fd := range fds {
104+
sortedPaths := fds.sortedPaths()
105+
for _, path := range sortedPaths {
106+
fd := fds[path]
102107
if fd.Diff.Changed() {
103108
result += fd.StrOutputQuiet()
104109
}
@@ -125,3 +130,12 @@ func (fds FileDiffs) ChangedCount() int {
125130
}
126131
return changed
127132
}
133+
134+
func (fds FileDiffs) sortedPaths() []string {
135+
pathKeys := []string{}
136+
for path := range fds {
137+
pathKeys = append(pathKeys, path)
138+
}
139+
slices.Sort(pathKeys)
140+
return pathKeys
141+
}

engine/consecutive_engine.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@ import (
1919
"os"
2020

2121
"github.com/google/yamlfmt"
22+
"github.com/google/yamlfmt/internal/logger"
2223
)
2324

2425
// Engine that will process each file one by one consecutively.
2526
type ConsecutiveEngine struct {
2627
LineSepCharacter string
2728
Formatter yamlfmt.Formatter
28-
Quiet bool
2929
ContinueOnError bool
3030
OutputFormat EngineOutputFormat
31+
Quiet bool
32+
Verbose bool
3133
}
3234

3335
func (e *ConsecutiveEngine) FormatContent(content []byte) ([]byte, error) {
@@ -36,6 +38,13 @@ func (e *ConsecutiveEngine) FormatContent(content []byte) ([]byte, error) {
3638

3739
func (e *ConsecutiveEngine) Format(paths []string) (fmt.Stringer, error) {
3840
formatDiffs, formatErrs := e.formatAll(paths)
41+
42+
// Debug format diff output.
43+
logger.Debug(
44+
logger.DebugCodeDiffs,
45+
fmt.Sprintf("The following files were modified:\n%s", formatDiffs.StrOutput()),
46+
)
47+
3948
if len(formatErrs) > 0 {
4049
if e.ContinueOnError {
4150
fmt.Print(formatErrs)
@@ -44,7 +53,11 @@ func (e *ConsecutiveEngine) Format(paths []string) (fmt.Stringer, error) {
4453
return nil, formatErrs
4554
}
4655
}
47-
return nil, formatDiffs.ApplyAll()
56+
applyErr := formatDiffs.ApplyAll()
57+
if applyErr != nil {
58+
return nil, applyErr
59+
}
60+
return getEngineOutput(e.OutputFormat, yamlfmt.OperationFormat, formatDiffs, e.Quiet, e.Verbose)
4861
}
4962

5063
func (e *ConsecutiveEngine) Lint(paths []string) (fmt.Stringer, error) {
@@ -55,7 +68,7 @@ func (e *ConsecutiveEngine) Lint(paths []string) (fmt.Stringer, error) {
5568
if formatDiffs.ChangedCount() == 0 {
5669
return nil, nil
5770
}
58-
return getEngineOutput(e.OutputFormat, yamlfmt.OperationLint, formatDiffs, e.Quiet)
71+
return getEngineOutput(e.OutputFormat, yamlfmt.OperationLint, formatDiffs, e.Quiet, e.Verbose)
5972
}
6073

6174
func (e *ConsecutiveEngine) DryRun(paths []string) (fmt.Stringer, error) {
@@ -66,7 +79,7 @@ func (e *ConsecutiveEngine) DryRun(paths []string) (fmt.Stringer, error) {
6679
if formatDiffs.ChangedCount() == 0 {
6780
return nil, nil
6881
}
69-
return getEngineOutput(e.OutputFormat, yamlfmt.OperationDry, formatDiffs, e.Quiet)
82+
return getEngineOutput(e.OutputFormat, yamlfmt.OperationDry, formatDiffs, e.Quiet, e.Verbose)
7083
}
7184

7285
func (e *ConsecutiveEngine) formatAll(paths []string) (yamlfmt.FileDiffs, FormatErrors) {

engine/output.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ const (
3232
EngineOutputGitlab EngineOutputFormat = "gitlab"
3333
)
3434

35-
func getEngineOutput(t EngineOutputFormat, operation yamlfmt.Operation, files yamlfmt.FileDiffs, quiet bool) (fmt.Stringer, error) {
35+
func getEngineOutput(t EngineOutputFormat, operation yamlfmt.Operation, files yamlfmt.FileDiffs, quiet bool, verbose bool) (fmt.Stringer, error) {
3636
switch t {
3737
case EngineOutputDefault:
38-
return engineOutput{Operation: operation, Files: files, Quiet: quiet}, nil
38+
return engineOutput{Operation: operation, Files: files, Quiet: quiet, Verbose: verbose}, nil
3939
case EngineOutputSingeLine:
4040
return engineOutputSingleLine{Operation: operation, Files: files, Quiet: quiet}, nil
4141
case EngineOutputGitlab:
@@ -49,11 +49,21 @@ type engineOutput struct {
4949
Operation yamlfmt.Operation
5050
Files yamlfmt.FileDiffs
5151
Quiet bool
52+
Verbose bool
5253
}
5354

5455
func (eo engineOutput) String() string {
5556
var msg string
5657
switch eo.Operation {
58+
case yamlfmt.OperationFormat:
59+
// Formatting only produces output in verbose mode.
60+
if !eo.Verbose {
61+
return ""
62+
}
63+
64+
msg = "The following files were modified:\n"
65+
msg += eo.Files.StrOutputQuiet()
66+
return msg
5767
case yamlfmt.OperationLint:
5868
msg = "The following formatting differences were found:"
5969
if eo.Quiet {
@@ -65,7 +75,7 @@ func (eo engineOutput) String() string {
6575
msg = "The following files would be formatted:"
6676
}
6777
} else {
68-
return "No files will formatted."
78+
return "No files will be formatted."
6979
}
7080
}
7181
var result string

integrationtest/command/command_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,19 @@ func TestForceFlowStyle(t *testing.T) {
187187
Update: *updateFlag,
188188
}.Run(t)
189189
}
190+
191+
func TestVerboseFormat(t *testing.T) {
192+
TestCase{
193+
Dir: "verbose_format",
194+
Command: yamlfmtWithArgs("-v ."),
195+
Update: *updateFlag,
196+
}.Run(t)
197+
}
198+
199+
func TestDebugDiffs(t *testing.T) {
200+
TestCase{
201+
Dir: "debug_diffs",
202+
Command: yamlfmtWithArgs("-debug diffs ."),
203+
Update: *updateFlag,
204+
}.Run(t)
205+
}

integrationtest/command/testcase.go

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ import (
2929
)
3030

3131
const (
32-
stdoutGoldenFile = "stdout.txt"
33-
stderrGoldenFile = "stderr.txt"
32+
stdoutGoldenFileName = "stdout.txt"
33+
stderrGoldenFileName = "stderr.txt"
3434
)
3535

3636
type TestCase struct {
@@ -39,6 +39,8 @@ type TestCase struct {
3939
IsError bool
4040
Update bool
4141
ShowStdout bool
42+
43+
tempDir string
4244
}
4345

4446
func (tc TestCase) Run(t *testing.T) {
@@ -48,16 +50,16 @@ func (tc TestCase) Run(t *testing.T) {
4850

4951
func (tc TestCase) run(t *testing.T) {
5052
// Replicate the "before" directory in the test temp directory.
51-
tempDir := t.TempDir()
52-
paths, err := tempfile.ReplicateDirectory(tc.testFolderBeforePath(), tempDir)
53+
tc.tempDir = t.TempDir()
54+
paths, err := tempfile.ReplicateDirectory(tc.testFolderBeforePath(), tc.tempDir)
5355
assert.NilErr(t, err)
5456
err = paths.CreateAll()
5557
assert.NilErr(t, err)
5658

5759
// Run the command for the test in the temp directory.
5860
var stdoutBuf bytes.Buffer
5961
var stderrBuf bytes.Buffer
60-
cmd := tc.command(tempDir, &stdoutBuf, &stderrBuf)
62+
cmd := tc.command(&stdoutBuf, &stderrBuf)
6163
err = cmd.Run()
6264
if tc.IsError {
6365
assert.NotNilErr(t, err)
@@ -71,15 +73,15 @@ func (tc TestCase) run(t *testing.T) {
7173
assert.NilErr(t, err)
7274
err = tc.goldenStderr(stderrBuf.Bytes())
7375
assert.NilErr(t, err)
74-
err = tc.goldenAfter(tempDir)
76+
err = tc.goldenAfter(tc.tempDir)
7577
assert.NilErr(t, err)
7678
}
7779

7880
func (tc TestCase) testFolderBeforePath() string {
7981
return tc.testdataDirPath() + "/before"
8082
}
8183

82-
func (tc TestCase) command(wd string, stdoutBuf *bytes.Buffer, stderrBuf *bytes.Buffer) *exec.Cmd {
84+
func (tc TestCase) command(stdoutBuf *bytes.Buffer, stderrBuf *bytes.Buffer) *exec.Cmd {
8385
cmdArgs := []string{}
8486
for _, arg := range strings.Split(tc.Command, " ") {
8587
// This is to handle potential typos in args with extra spaces.
@@ -92,7 +94,7 @@ func (tc TestCase) command(wd string, stdoutBuf *bytes.Buffer, stderrBuf *bytes.
9294
Args: cmdArgs, // Args needs to be an array of everything including the command
9395
Stdout: stdoutBuf,
9496
Stderr: stderrBuf,
95-
Dir: wd,
97+
Dir: tc.tempDir,
9698
}
9799
}
98100

@@ -102,10 +104,14 @@ func (tc TestCase) goldenStdout(stdoutResult []byte) error {
102104
return nil
103105
}
104106
goldenCtx := tempfile.GoldenCtx{
105-
Dir: tc.testFolderStdoutPath(),
106-
Update: tc.Update,
107+
GoldenDir: tc.testFolderStdoutPath(),
108+
ResultDir: tc.tempDir,
109+
Update: tc.Update,
107110
}
108-
return goldenCtx.CompareGoldenFile(stdoutGoldenFile, stdoutResult)
111+
return goldenCtx.CompareGoldenFile(
112+
filepath.Join(tc.tempDir, stdoutGoldenFileName),
113+
stdoutResult,
114+
)
109115
}
110116

111117
func (tc TestCase) goldenStderr(stderrResult []byte) error {
@@ -114,16 +120,21 @@ func (tc TestCase) goldenStderr(stderrResult []byte) error {
114120
return nil
115121
}
116122
goldenCtx := tempfile.GoldenCtx{
117-
Dir: tc.testFolderStdoutPath(),
118-
Update: tc.Update,
123+
GoldenDir: tc.testFolderStdoutPath(),
124+
ResultDir: tc.tempDir,
125+
Update: tc.Update,
119126
}
120-
return goldenCtx.CompareGoldenFile(stderrGoldenFile, stderrResult)
127+
return goldenCtx.CompareGoldenFile(
128+
filepath.Join(tc.tempDir, stderrGoldenFileName),
129+
stderrResult,
130+
)
121131
}
122132

123133
func (tc TestCase) goldenAfter(wd string) error {
124134
goldenCtx := tempfile.GoldenCtx{
125-
Dir: tc.testFolderAfterPath(),
126-
Update: tc.Update,
135+
GoldenDir: tc.testFolderAfterPath(),
136+
ResultDir: tc.tempDir,
137+
Update: tc.Update,
127138
}
128139
return goldenCtx.CompareDirectory(wd)
129140
}

0 commit comments

Comments
 (0)