diff --git a/cmd/root.go b/cmd/root.go index 6069591..14a506c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -52,6 +52,10 @@ func init() { // maybeDefaultToSpeak injects the "speak" subcommand when the user calls `sag` like macOS `say`. func maybeDefaultToSpeak() { if len(os.Args) <= 1 { + // Still default to speak if stdin has piped data + if !isStdinTTY() { + os.Args = append(os.Args, "speak") + } return } diff --git a/cmd/root_test.go b/cmd/root_test.go index 2ad30c8..95f8265 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -113,3 +113,33 @@ func TestExecuteHelp(t *testing.T) { t.Fatalf("unreachable") } } + +func TestMaybeDefaultToSpeak_PipedStdin(t *testing.T) { + defer keepArgs(t)() + + // Replace stdin with a pipe (non-TTY) + origStdin := os.Stdin + r, w, err := os.Pipe() + if err != nil { + t.Fatalf("failed to create pipe: %v", err) + } + os.Stdin = r + defer func() { + os.Stdin = origStdin + w.Close() + r.Close() + }() + + os.Args = []string{"sag"} + maybeDefaultToSpeak() + + want := []string{"sag", "speak"} + if len(os.Args) != len(want) { + t.Fatalf("expected %v, got %v", want, os.Args) + } + for i := range want { + if os.Args[i] != want[i] { + t.Fatalf("args mismatch at %d: got %q want %q", i, os.Args[i], want[i]) + } + } +}