diff --git a/cmd/doctor.go b/cmd/doctor.go index f14373b..cb1f2f9 100644 --- a/cmd/doctor.go +++ b/cmd/doctor.go @@ -38,18 +38,27 @@ func runDoctor(w io.Writer) bool { } hasError := false + lastFail := false + emit := func(level, msg string) { var code string switch level { case "ok": code = "32" + lastFail = false case "WARN": code = "33" + lastFail = false case "FAIL": code = "31" hasError = true + lastFail = true + } + if lastFail && tty { + fmt.Fprintf(w, "%s \033[1m%s\033[0m\n", keyword(code, level, tty), msg) + } else { + fmt.Fprintf(w, "%s %s\n", keyword(code, level, tty), msg) } - fmt.Fprintf(w, "%s %s\n", keyword(code, level, tty), msg) } tree := func(items []string) { @@ -58,7 +67,11 @@ func runDoctor(w io.Writer) bool { if i == len(items)-1 { connector = "└── " } - fmt.Fprintf(w, " %s%s\n", connector, item) + if lastFail && tty { + fmt.Fprintf(w, "\033[1m %s%s\033[0m\n", connector, item) + } else { + fmt.Fprintf(w, " %s%s\n", connector, item) + } } } @@ -117,6 +130,7 @@ func runDoctor(w io.Writer) bool { } if configErr != nil { issues = append(issues, fmt.Sprintf("Parse error: %v", configErr)) + issues = append(issues, "While broken, ONLY 'doctor', 'config edit', and 'config init' will function") issues = append(issues, "Fix with 'pda config edit' or 'pda config init --new'") } if unexpectedFiles(cfgDir, map[string]bool{ diff --git a/cmd/doctor_test.go b/cmd/doctor_test.go index 22780d9..4516bc7 100644 --- a/cmd/doctor_test.go +++ b/cmd/doctor_test.go @@ -14,6 +14,9 @@ func TestDoctorCleanEnv(t *testing.T) { configDir := t.TempDir() t.Setenv("PDA_DATA", dataDir) t.Setenv("PDA_CONFIG", configDir) + saved := configErr + configErr = nil + t.Cleanup(func() { configErr = saved }) var buf bytes.Buffer hasError := runDoctor(&buf) @@ -40,6 +43,9 @@ func TestDoctorWithStores(t *testing.T) { configDir := t.TempDir() t.Setenv("PDA_DATA", dataDir) t.Setenv("PDA_CONFIG", configDir) + saved := configErr + configErr = nil + t.Cleanup(func() { configErr = saved }) content := "{\"key\":\"foo\",\"value\":\"bar\",\"encoding\":\"text\"}\n" + "{\"key\":\"baz\",\"value\":\"qux\",\"encoding\":\"text\"}\n" diff --git a/cmd/msg.go b/cmd/msg.go index ea1d7d6..20dff20 100644 --- a/cmd/msg.go +++ b/cmd/msg.go @@ -31,24 +31,33 @@ func stdoutIsTerminal() bool { } // keyword returns a right-aligned, colored keyword (color only on TTY). +// All keywords are bold except dim (code "2"). // -// FAIL red (stderr) +// FAIL bold red (stderr) // hint dim (stderr) -// WARN yellow (stderr) -// info blue (stderr) -// ok green (stderr) -// ? cyan (stdout) +// WARN bold yellow (stderr) +// info bold blue (stderr) +// ok bold green (stderr) +// ? bold cyan (stdout) // > dim (stdout) func keyword(code, word string, tty bool) string { padded := fmt.Sprintf("%4s", word) if tty { + if code != "2" { + code = "1;" + code + } return fmt.Sprintf("\033[%sm%s\033[0m", code, padded) } return padded } func printError(err error) { - fmt.Fprintf(os.Stderr, "%s %s\n", keyword("31", "FAIL", stderrIsTerminal()), err) + tty := stderrIsTerminal() + if tty { + fmt.Fprintf(os.Stderr, "%s \033[1m%s\033[0m\n", keyword("31", "FAIL", true), err) + } else { + fmt.Fprintf(os.Stderr, "%s %s\n", keyword("31", "FAIL", false), err) + } } func printHint(format string, args ...any) { diff --git a/cmd/root.go b/cmd/root.go index e718397..5c01bf8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -23,6 +23,7 @@ THE SOFTWARE. package cmd import ( + "fmt" "os" "github.com/spf13/cobra" @@ -40,7 +41,7 @@ func Execute() { if configErr != nil { cmd, _, _ := rootCmd.Find(os.Args[1:]) if !configSafeCmd(cmd) { - infof("Running pda! doctor") + printError(fmt.Errorf("fatal problem: running pda! doctor automatically")) runDoctor(os.Stderr) os.Exit(1) }