diff --git a/commands/root.go b/commands/root.go index 0db2a8240..ab609a4f8 100644 --- a/commands/root.go +++ b/commands/root.go @@ -60,7 +60,7 @@ func newRootCommand(cnf *config.Config, assets *vendorization.VendorAssets) *cob // Completions must be fast and quiet. return } - quiet := viper.GetBool("quiet") && !viper.GetBool("debug") && !viper.GetBool("verbose") + quiet := isQuiet() if quiet { viper.Set("no-interaction", true) cmd.SetErr(io.Discard) @@ -294,6 +294,11 @@ func debugLogf(format string, v ...any) { fmt.Fprintf(color.Error, prefix+" "+strings.TrimSpace(format)+"\n", v...) } +// isQuiet reports whether quiet mode is on, which --debug and --verbose override. +func isQuiet() bool { + return viper.GetBool("quiet") && !viper.GetBool("debug") && !viper.GetBool("verbose") +} + func exitWithError(err error) { var execErr *exec.ExitError if errors.As(err, &execErr) { @@ -301,7 +306,7 @@ func exitWithError(err error) { debugLogf(err.Error()) os.Exit(exitCode) } - if !viper.GetBool("quiet") { + if !isQuiet() { fmt.Fprintln(color.Error, color.RedString(err.Error())) } os.Exit(1) diff --git a/integration-tests/quiet_errors_test.go b/integration-tests/quiet_errors_test.go new file mode 100644 index 000000000..679e9a4f3 --- /dev/null +++ b/integration-tests/quiet_errors_test.go @@ -0,0 +1,38 @@ +package tests + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestQuietErrors checks that --verbose and --debug override --quiet for errors before the legacy CLI runs. +func TestQuietErrors(t *testing.T) { + f := newCommandFactory(t, "", "") + // A file in place of the temporary directory makes the legacy CLI fail to start. + tmpFile := filepath.Join(t.TempDir(), "file") + require.NoError(t, os.WriteFile(tmpFile, nil, 0o600)) + f.extraEnv = append(f.extraEnv, EnvPrefix+"TMP="+tmpFile) + + cases := []struct { + args []string + wantError bool + }{ + {[]string{"-q"}, false}, + {[]string{"-qv"}, true}, + {[]string{"-q", "--debug"}, true}, + {nil, true}, + } + for _, c := range cases { + _, stderr, err := f.RunCombinedOutput(append([]string{"project:list"}, c.args...)...) + assertExitCode(t, 1, err) + if c.wantError { + assert.Contains(t, stderr, "failed to initialize PHP CLI", "args: %v", c.args) + } else { + assert.Empty(t, stderr, "args: %v", c.args) + } + } +} diff --git a/integration-tests/tests.go b/integration-tests/tests.go index 3db1ccb12..208f7c075 100644 --- a/integration-tests/tests.go +++ b/integration-tests/tests.go @@ -192,7 +192,10 @@ func (f *cmdFactory) fakeBrowser() { f.t.Skip("the fake browser is a shell script") } dir := f.t.TempDir() - require.NoError(f.t, os.WriteFile(filepath.Join(dir, "xdg-open"), []byte("#!/bin/sh\nexit 0\n"), 0o755)) + // The CLI uses "open" on macOS, and "xdg-open" on Linux. + for _, name := range []string{"open", "xdg-open"} { + require.NoError(f.t, os.WriteFile(filepath.Join(dir, name), []byte("#!/bin/sh\nexit 0\n"), 0o755)) + } f.extraEnv = append(f.extraEnv, "DISPLAY=:0", "PATH="+dir+string(os.PathListSeparator)+os.Getenv("PATH")) }