Skip to content

Commit

Permalink
feat: improve prompt
Browse files Browse the repository at this point in the history
  • Loading branch information
ravisuhag committed Nov 20, 2024
1 parent 66b084a commit 7b667a3
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 31 deletions.
67 changes: 67 additions & 0 deletions prompt/README.md
Original file line number Diff line number Diff line change
@@ -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)
}
```
99 changes: 68 additions & 31 deletions prompt/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,68 +6,105 @@ 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{}
}

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
}

0 comments on commit 7b667a3

Please sign in to comment.