fix(cli): avoid hanging prompts on EOF
All checks were successful
Security Scan / security (push) Successful in 24s

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 06:01:35 +00:00
parent f376372630
commit 37310c7cbd
2 changed files with 27 additions and 5 deletions

View file

@ -68,6 +68,14 @@ func TestConfirm_Good(t *testing.T) {
assert.True(t, Confirm("Proceed?"))
}
func TestConfirm_Bad_EOFUsesDefault(t *testing.T) {
SetStdin(strings.NewReader(""))
defer SetStdin(nil)
assert.False(t, Confirm("Proceed?", Required()))
assert.True(t, Confirm("Proceed?", DefaultYes(), Required()))
}
func TestQuestion_Good(t *testing.T) {
SetStdin(strings.NewReader("alice\n"))
defer SetStdin(nil)
@ -76,6 +84,14 @@ func TestQuestion_Good(t *testing.T) {
assert.Equal(t, "alice", val)
}
func TestQuestion_Bad_EOFReturnsDefault(t *testing.T) {
SetStdin(strings.NewReader(""))
defer SetStdin(nil)
assert.Equal(t, "anonymous", Question("Name:", WithDefault("anonymous")))
assert.Equal(t, "", Question("Name:", RequiredInput()))
}
func TestChoose_Good_DefaultIndex(t *testing.T) {
SetStdin(strings.NewReader("\n"))
defer SetStdin(nil)

View file

@ -119,14 +119,18 @@ func Confirm(prompt string, opts ...ConfirmOption) bool {
return cfg.defaultYes
}
} else {
response, _ = reader.ReadString('\n')
line, err := reader.ReadString('\n')
if err != nil && line == "" {
return cfg.defaultYes
}
response = line
response = strings.ToLower(strings.TrimSpace(response))
}
// Handle empty response
if response == "" {
if cfg.required {
continue // Ask again
return cfg.defaultYes
}
return cfg.defaultYes
}
@ -224,14 +228,16 @@ func Question(prompt string, opts ...QuestionOption) string {
fmt.Printf("%s ", prompt)
}
response, _ := reader.ReadString('\n')
response, err := reader.ReadString('\n')
response = strings.TrimSpace(response)
if err != nil && response == "" {
return cfg.defaultValue
}
// Handle empty response
if response == "" {
if cfg.required {
fmt.Println("Response required")
continue
return cfg.defaultValue
}
response = cfg.defaultValue
}