Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
Expand All @@ -15,10 +16,17 @@ fitdown-style markdown; pass --format json for the full structured row.

LLM agents: run 'liftoff-export prime' for a one-screen orientation
(I/O contract, subcommands, date flags, jq recipes).`,
// Keep the output contract clean: stdout is for data only. By default
// cobra dumps the full usage/flags block to stderr on any RunE or
// flag-parse error, which clutters logs and buries the actual message.
// Silence both and print a single-line error ourselves in Execute. (#31)
SilenceUsage: true,
SilenceErrors: true,
}

func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, "Error:", err)
os.Exit(1)
}
}
Expand Down
34 changes: 34 additions & 0 deletions cmd/root_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cmd

import (
"bytes"
"strings"
"testing"
)

// On a flag-parse error the root command must not dump cobra's usage/flags
// block: stdout stays data-only and stderr stays a single error line that
// Execute prints itself. (#31)
func TestRootCmd_NoUsageDumpOnError(t *testing.T) {
var out, errBuf bytes.Buffer
rootCmd.SetOut(&out)
rootCmd.SetErr(&errBuf)
rootCmd.SetArgs([]string{"--this-flag-does-not-exist"})
t.Cleanup(func() {
rootCmd.SetArgs(nil)
rootCmd.SetOut(nil)
rootCmd.SetErr(nil)
})

err := rootCmd.Execute()
if err == nil {
t.Fatal("expected an error for an unknown flag, got nil")
}
combined := out.String() + errBuf.String()
if strings.Contains(combined, "Usage:") {
t.Errorf("usage block should be suppressed on error; got:\n%s", combined)
}
if strings.Contains(combined, "Available Commands:") {
t.Errorf("command list should be suppressed on error; got:\n%s", combined)
}
}
Loading