diff --git a/clients/cli/cmd/internal/init.go b/clients/cli/cmd/internal/init.go index d308c6a1c..fbad2e428 100644 --- a/clients/cli/cmd/internal/init.go +++ b/clients/cli/cmd/internal/init.go @@ -221,7 +221,7 @@ func (cmd *InitCommand) newProject() error { } for { - err := prompt.P("Enter the name of the new project:", ¶ms.Name) + err := prompt.Line("Enter the name of the new project:", ¶ms.Name) if err == nil { break } diff --git a/clients/cli/cmd/internal/prompt/prompt.go b/clients/cli/cmd/internal/prompt/prompt.go index 0c99afc7c..972723364 100644 --- a/clients/cli/cmd/internal/prompt/prompt.go +++ b/clients/cli/cmd/internal/prompt/prompt.go @@ -3,8 +3,8 @@ package prompt import ( "bufio" "fmt" - "io" "os" + "strings" ) var stdin = bufio.NewReader(os.Stdin) @@ -26,11 +26,27 @@ func P(msg string, args ...interface{}) error { return err } +// Line prints msg, then reads a line of user input. The input line is then cleaned of whitespace and assigned to val. +func Line(msg string, val *string) error { + fmt.Print(msg + " ") + + line, err := stdin.ReadString('\n') + if err != nil { + return err + } + + *val = strings.TrimSpace(line) + if *val == "" { + return fmt.Errorf("empty input") + } + return nil +} + // WithDefault prints msg, then parses a line of user input into func WithDefault(msg string, arg *string, defaultValue string) error { - err := P(msg+" "+fmt.Sprintf("[default %v]", defaultValue), arg) + err := Line(msg+" "+fmt.Sprintf("[default %v]", defaultValue), arg) - if err == io.EOF { + if err != nil { *arg = defaultValue return nil } diff --git a/clients/cli/cmd/internal/prompt/prompt_test.go b/clients/cli/cmd/internal/prompt/prompt_test.go new file mode 100644 index 000000000..b60a5ca4d --- /dev/null +++ b/clients/cli/cmd/internal/prompt/prompt_test.go @@ -0,0 +1,78 @@ +package prompt + +import ( + "bufio" + "strings" + "testing" +) + +func TestLine(t *testing.T) { + input := " My Project Name \n" + reader := bufio.NewReader(strings.NewReader(input)) + oldStdin := stdin + defer func() { stdin = oldStdin }() + stdin = reader + + var result string + err := Line("Prompt:", &result) + if err != nil { + t.Errorf("Line returned error: %v", err) + } + + expected := "My Project Name" + if result != expected { + t.Errorf("Expected '%s', got '%s'", expected, result) + } +} + +func TestLine_Empty(t *testing.T) { + input := "\n" + reader := bufio.NewReader(strings.NewReader(input)) + oldStdin := stdin + defer func() { stdin = oldStdin }() + stdin = reader + + var result string + err := Line("Prompt:", &result) + if err == nil { + t.Error("Line expected error for empty input, got nil") + } +} + +func TestWithDefault_Default(t *testing.T) { + input := "\n" + reader := bufio.NewReader(strings.NewReader(input)) + oldStdin := stdin + defer func() { stdin = oldStdin }() + stdin = reader + + var result string + err := WithDefault("Prompt:", &result, "default") + if err != nil { + t.Errorf("WithDefault returned error: %v", err) + } + + expected := "default" + if result != expected { + t.Errorf("Expected '%s', got '%s'", expected, result) + } +} + +func TestWithDefault_Input(t *testing.T) { + input := "user input\n" + reader := bufio.NewReader(strings.NewReader(input)) + oldStdin := stdin + defer func() { stdin = oldStdin }() + stdin = reader + + var result string + err := WithDefault("Prompt:", &result, "default") + if err != nil { + t.Errorf("WithDefault returned error: %v", err) + } + + expected := "user input" + if result != expected { + t.Errorf("Expected '%s', got '%s'", expected, result) + } +}