Skip to content

Commit 10c9a72

Browse files
committed
feat: add a quiet flag to suppress all output except for errors
Signed-off-by: Brian McGee <[email protected]> diff --git a/cmd/root.go b/cmd/root.go index 72348f1..cd3f8f7 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -144,13 +144,19 @@ func runE(v *viper.Viper, statz *stats.Stats, cmd *cobra.Command, args []string) log.SetOutput(os.Stderr) log.SetReportTimestamp(false) - switch v.GetInt("verbose") { - case 0: - log.SetLevel(log.WarnLevel) - case 1: - log.SetLevel(log.InfoLevel) - default: - log.SetLevel(log.DebugLevel) + if v.GetBool("quiet") { + // if quiet, we only log errors + log.SetLevel(log.ErrorLevel) + } else { + // otherwise, the verbose flag controls the log level + switch v.GetInt("verbose") { + case 0: + log.SetLevel(log.WarnLevel) + case 1: + log.SetLevel(log.InfoLevel) + default: + log.SetLevel(log.DebugLevel) + } } // format diff --git a/cmd/root_test.go b/cmd/root_test.go index 2846504..628a69b 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -131,6 +131,33 @@ func TestOnUnmatched(t *testing.T) { }) } +func TestQuiet(t *testing.T) { + as := require.New(t) + tempDir := test.TempExamples(t) + + test.ChangeWorkDir(t, tempDir) + + // allow missing formatter + t.Setenv("TREEFMT_ALLOW_MISSING_FORMATTER", "true") + + noOutput := func(out []byte) { + as.Empty(out) + } + + treefmt(t, withArgs("-q"), withNoError(t), withStdout(noOutput), withStderr(noOutput)) + treefmt(t, withArgs("--quiet"), withNoError(t), withStdout(noOutput), withStderr(noOutput)) + + t.Setenv("TREEFMT_QUIET", "true") + treefmt(t, withNoError(t), withStdout(noOutput), withStderr(noOutput)) + + t.Setenv("TREEFMT_ALLOW_MISSING_FORMATTER", "false") + + // check it doesn't suppress errors + treefmt(t, withError(func(err error) { + as.ErrorContains(err, "error looking up 'foo-fmt'") + })) +} + func TestCpuProfile(t *testing.T) { as := require.New(t) tempDir := test.TempExamples(t) diff --git a/config/config.go b/config/config.go index f5d8e7a..c10df3f 100644 --- a/config/config.go +++ b/config/config.go @@ -22,6 +22,7 @@ type Config struct { Formatters []string `mapstructure:"formatters" toml:"formatters,omitempty"` NoCache bool `mapstructure:"no-cache" toml:"-"` // not allowed in config OnUnmatched string `mapstructure:"on-unmatched" toml:"on-unmatched,omitempty"` + Quiet bool `mapstructure:"quiet" toml:"-"` // not allowed in config TreeRoot string `mapstructure:"tree-root" toml:"tree-root,omitempty"` TreeRootFile string `mapstructure:"tree-root-file" toml:"tree-root-file,omitempty"` Verbose uint8 `mapstructure:"verbose" toml:"verbose,omitempty"` @@ -110,6 +111,9 @@ func SetFlags(fs *pflag.FlagSet) { "verbose", "v", "Set the verbosity of logs e.g. -vv. (env $TREEFMT_VERBOSE)", ) + fs.BoolP( + "quiet", "q", false, "Disable all logs except errors. (env $TREEFMT_QUIET)", + ) fs.String( "walk", "auto", "The method used to traverse the files within the tree root. Currently supports "+ diff --git a/config/config_test.go b/config/config_test.go index 281e18a..ae6dc83 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -323,6 +323,36 @@ func TestNoCache(t *testing.T) { checkValue(true) } +func TestQuiet(t *testing.T) { + as := require.New(t) + + cfg := &config.Config{} + v, flags := newViper(t) + + checkValue := func(expected bool) { + readValue(t, v, cfg, func(cfg *config.Config) { + as.Equal(expected, cfg.Quiet) + }) + } + + // default with no flag, env or config + checkValue(false) + + // set config value and check that it has no effect + // you are not allowed to set no-cache in config + cfg.Quiet = true + + checkValue(false) + + // env override + t.Setenv("TREEFMT_QUIET", "false") + checkValue(false) + + // flag override + as.NoError(flags.Set("quiet", "true")) + checkValue(true) +} + func TestOnUnmatched(t *testing.T) { as := require.New(t) diff --git a/docs/content/getting-started/configure.md b/docs/content/getting-started/configure.md index efc8f2b..623077e 100644 --- a/docs/content/getting-started/configure.md +++ b/docs/content/getting-started/configure.md @@ -254,6 +254,22 @@ Possible values are `<debug|info|warn|error|fatal>`. on-unmatched = "debug" ``` +### `quiet` + +Suppress all output except for errors. + +=== "Flag" + + ```console + treefmt --quiet + ``` + +=== "Env" + + ```console + TREEFMT_QUIET=true treefmt + ``` + ### `stdin` Format the context passed in via stdin.
1 parent b76d839 commit 10c9a72

File tree

5 files changed

+90
-7
lines changed

5 files changed

+90
-7
lines changed

cmd/root.go

+13-7
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,19 @@ func runE(v *viper.Viper, statz *stats.Stats, cmd *cobra.Command, args []string)
144144
log.SetOutput(os.Stderr)
145145
log.SetReportTimestamp(false)
146146

147-
switch v.GetInt("verbose") {
148-
case 0:
149-
log.SetLevel(log.WarnLevel)
150-
case 1:
151-
log.SetLevel(log.InfoLevel)
152-
default:
153-
log.SetLevel(log.DebugLevel)
147+
if v.GetBool("quiet") {
148+
// if quiet, we only log errors
149+
log.SetLevel(log.ErrorLevel)
150+
} else {
151+
// otherwise, the verbose flag controls the log level
152+
switch v.GetInt("verbose") {
153+
case 0:
154+
log.SetLevel(log.WarnLevel)
155+
case 1:
156+
log.SetLevel(log.InfoLevel)
157+
default:
158+
log.SetLevel(log.DebugLevel)
159+
}
154160
}
155161

156162
// format

cmd/root_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,33 @@ func TestOnUnmatched(t *testing.T) {
131131
})
132132
}
133133

134+
func TestQuiet(t *testing.T) {
135+
as := require.New(t)
136+
tempDir := test.TempExamples(t)
137+
138+
test.ChangeWorkDir(t, tempDir)
139+
140+
// allow missing formatter
141+
t.Setenv("TREEFMT_ALLOW_MISSING_FORMATTER", "true")
142+
143+
noOutput := func(out []byte) {
144+
as.Empty(out)
145+
}
146+
147+
treefmt(t, withArgs("-q"), withNoError(t), withStdout(noOutput), withStderr(noOutput))
148+
treefmt(t, withArgs("--quiet"), withNoError(t), withStdout(noOutput), withStderr(noOutput))
149+
150+
t.Setenv("TREEFMT_QUIET", "true")
151+
treefmt(t, withNoError(t), withStdout(noOutput), withStderr(noOutput))
152+
153+
t.Setenv("TREEFMT_ALLOW_MISSING_FORMATTER", "false")
154+
155+
// check it doesn't suppress errors
156+
treefmt(t, withError(func(err error) {
157+
as.ErrorContains(err, "error looking up 'foo-fmt'")
158+
}))
159+
}
160+
134161
func TestCpuProfile(t *testing.T) {
135162
as := require.New(t)
136163
tempDir := test.TempExamples(t)

config/config.go

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type Config struct {
2222
Formatters []string `mapstructure:"formatters" toml:"formatters,omitempty"`
2323
NoCache bool `mapstructure:"no-cache" toml:"-"` // not allowed in config
2424
OnUnmatched string `mapstructure:"on-unmatched" toml:"on-unmatched,omitempty"`
25+
Quiet bool `mapstructure:"quiet" toml:"-"` // not allowed in config
2526
TreeRoot string `mapstructure:"tree-root" toml:"tree-root,omitempty"`
2627
TreeRootFile string `mapstructure:"tree-root-file" toml:"tree-root-file,omitempty"`
2728
Verbose uint8 `mapstructure:"verbose" toml:"verbose,omitempty"`
@@ -110,6 +111,9 @@ func SetFlags(fs *pflag.FlagSet) {
110111
"verbose", "v",
111112
"Set the verbosity of logs e.g. -vv. (env $TREEFMT_VERBOSE)",
112113
)
114+
fs.BoolP(
115+
"quiet", "q", false, "Disable all logs except errors. (env $TREEFMT_QUIET)",
116+
)
113117
fs.String(
114118
"walk", "auto",
115119
"The method used to traverse the files within the tree root. Currently supports "+

config/config_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,36 @@ func TestNoCache(t *testing.T) {
323323
checkValue(true)
324324
}
325325

326+
func TestQuiet(t *testing.T) {
327+
as := require.New(t)
328+
329+
cfg := &config.Config{}
330+
v, flags := newViper(t)
331+
332+
checkValue := func(expected bool) {
333+
readValue(t, v, cfg, func(cfg *config.Config) {
334+
as.Equal(expected, cfg.Quiet)
335+
})
336+
}
337+
338+
// default with no flag, env or config
339+
checkValue(false)
340+
341+
// set config value and check that it has no effect
342+
// you are not allowed to set no-cache in config
343+
cfg.Quiet = true
344+
345+
checkValue(false)
346+
347+
// env override
348+
t.Setenv("TREEFMT_QUIET", "false")
349+
checkValue(false)
350+
351+
// flag override
352+
as.NoError(flags.Set("quiet", "true"))
353+
checkValue(true)
354+
}
355+
326356
func TestOnUnmatched(t *testing.T) {
327357
as := require.New(t)
328358

docs/content/getting-started/configure.md

+16
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,22 @@ Possible values are `<debug|info|warn|error|fatal>`.
254254
on-unmatched = "debug"
255255
```
256256

257+
### `quiet`
258+
259+
Suppress all output except for errors.
260+
261+
=== "Flag"
262+
263+
```console
264+
treefmt --quiet
265+
```
266+
267+
=== "Env"
268+
269+
```console
270+
TREEFMT_QUIET=true treefmt
271+
```
272+
257273
### `stdin`
258274

259275
Format the context passed in via stdin.

0 commit comments

Comments
 (0)