From 7b667a3ff1a552c671e584f8d0ec71af38e649f5 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 20 Nov 2024 14:58:44 -0600 Subject: [PATCH] feat: improve prompt --- prompt/README.md | 67 ++++++++++++++++++++++++++++++++ prompt/prompt.go | 99 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 135 insertions(+), 31 deletions(-) create mode 100644 prompt/README.md diff --git a/prompt/README.md b/prompt/README.md new file mode 100644 index 0000000..dcabda8 --- /dev/null +++ b/prompt/README.md @@ -0,0 +1,67 @@ +# Prompt Package + +The `prompt` package simplifies interactive CLI input using the `survey` library. It provides a consistent interface for user prompts such as single and multi-selection, text input, and confirmation. + +## Features + +- **Select**: Prompt users to select one option from a list. +- **MultiSelect**: Prompt users to select multiple options. +- **Input**: Prompt users to provide text input. +- **Confirm**: Prompt users for a yes/no confirmation. + +## Installation + +Add the package to your Go project: + +```bash +go get github.com/raystack/salt/prompt +``` + +## Usage + +Here’s an example of how to use the `prompt` package: + +```go +package main + +import ( + "fmt" + "github.com/raystack/salt/prompt" +) + +func main() { + p := prompt.New() + + // Single selection + index, err := p.Select("Choose an option:", "Option 1", []string{"Option 1", "Option 2", "Option 3"}) + if err != nil { + fmt.Println("Error:", err) + return + } + fmt.Println("Selected option index:", index) + + // Multi-selection + indices, err := p.MultiSelect("Choose multiple options:", nil, []string{"Option A", "Option B", "Option C"}) + if err != nil { + fmt.Println("Error:", err) + return + } + fmt.Println("Selected option indices:", indices) + + // Text input + input, err := p.Input("Enter your name:", "John Doe") + if err != nil { + fmt.Println("Error:", err) + return + } + fmt.Println("Input:", input) + + // Confirmation + confirm, err := p.Confirm("Do you want to proceed?", true) + if err != nil { + fmt.Println("Error:", err) + return + } + fmt.Println("Confirmation:", confirm) +} +``` \ No newline at end of file diff --git a/prompt/prompt.go b/prompt/prompt.go index ae63875..f69b8c6 100644 --- a/prompt/prompt.go +++ b/prompt/prompt.go @@ -6,13 +6,15 @@ import ( "github.com/AlecAivazis/survey/v2" ) +// Prompter defines an interface for user input interactions. type Prompter interface { - Select(string, string, []string) (int, error) - MultiSelect(string, string, []string) (int, error) - Input(string, string) (string, error) - Confirm(string, bool) (bool, error) + Select(message, defaultValue string, options []string) (int, error) + MultiSelect(message, defaultValue string, options []string) ([]int, error) + Input(message, defaultValue string) (string, error) + Confirm(message string, defaultValue bool) (bool, error) } +// New creates and returns a new Prompter instance. func New() Prompter { return &surveyPrompter{} } @@ -20,54 +22,89 @@ func New() Prompter { type surveyPrompter struct { } +// ask is a helper function to prompt the user and capture the response. func (p *surveyPrompter) ask(q survey.Prompt, response interface{}) error { err := survey.AskOne(q, response) - if err == nil { - return nil + if err != nil { + return fmt.Errorf("prompt error: %w", err) } - return fmt.Errorf("could not prompt: %w", err) + return nil } -func (p *surveyPrompter) Select(message, defaultValue string, options []string) (result int, err error) { - q := &survey.Select{ +// Select prompts the user to select one option from a list. +// +// Parameters: +// - message: The prompt message to display. +// - defaultValue: The default selected value. +// - options: The list of options to display. +// +// Returns: +// - The index of the selected option. +// - An error, if any. +func (p *surveyPrompter) Select(message, defaultValue string, options []string) (int, error) { + var result int + err := p.ask(&survey.Select{ Message: message, Default: defaultValue, Options: options, PageSize: 20, - } - - err = p.ask(q, &result) - - return + }, &result) + return result, err } -func (p *surveyPrompter) MultiSelect(message, defaultValue string, options []string) (result int, err error) { - q := &survey.MultiSelect{ +// MultiSelect prompts the user to select multiple options from a list. +// +// Parameters: +// - message: The prompt message to display. +// - defaultValue: The default selected values. +// - options: The list of options to display. +// +// Returns: +// - A slice of indices representing the selected options. +// - An error, if any. +func (p *surveyPrompter) MultiSelect(message, defaultValue string, options []string) ([]int, error) { + var result []int + err := p.ask(&survey.MultiSelect{ Message: message, Default: defaultValue, Options: options, PageSize: 20, - } - - err = p.ask(q, &result) - - return + }, &result) + return result, err } -func (p *surveyPrompter) Input(prompt, defaultValue string) (result string, err error) { - err = p.ask(&survey.Input{ - Message: prompt, +// Input prompts the user for a text input. +// +// Parameters: +// - message: The prompt message to display. +// - defaultValue: The default input value. +// +// Returns: +// - The user's input as a string. +// - An error, if any. +func (p *surveyPrompter) Input(message, defaultValue string) (string, error) { + var result string + err := p.ask(&survey.Input{ + Message: message, Default: defaultValue, }, &result) - - return + return result, err } -func (p *surveyPrompter) Confirm(prompt string, defaultValue bool) (result bool, err error) { - err = p.ask(&survey.Confirm{ - Message: prompt, +// Confirm prompts the user for a yes/no confirmation. +// +// Parameters: +// - message: The prompt message to display. +// - defaultValue: The default confirmation value. +// +// Returns: +// - A boolean indicating the user's choice. +// - An error, if any. +func (p *surveyPrompter) Confirm(message string, defaultValue bool) (bool, error) { + var result bool + err := p.ask(&survey.Confirm{ + Message: message, Default: defaultValue, }, &result) - - return + return result, err }