Initial commit.
This commit is contained in:
73
internal/prompt/example_test.go
Normal file
73
internal/prompt/example_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package prompt_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
// "github.com/wild-cloud/wild-central/wild/internal/prompt"
|
||||
)
|
||||
|
||||
// ExampleString demonstrates the String prompt function
|
||||
func ExampleString() {
|
||||
// This example shows the prompt output format
|
||||
// Actual usage would read from stdin interactively
|
||||
fmt.Println("Enter SMTP host [smtp.gmail.com]:")
|
||||
// User input: <empty> (returns default)
|
||||
// Result: "smtp.gmail.com"
|
||||
|
||||
fmt.Println("Enter SMTP host [smtp.gmail.com]:")
|
||||
// User input: "smtp.example.com"
|
||||
// Result: "smtp.example.com"
|
||||
}
|
||||
|
||||
// ExampleInt demonstrates the Int prompt function
|
||||
func ExampleInt() {
|
||||
// This example shows the prompt output format
|
||||
fmt.Println("Enter SMTP port [587]:")
|
||||
// User input: <empty> (returns default)
|
||||
// Result: 587
|
||||
|
||||
fmt.Println("Enter SMTP port [587]:")
|
||||
// User input: "465"
|
||||
// Result: 465
|
||||
}
|
||||
|
||||
// ExampleBool demonstrates the Bool prompt function
|
||||
func ExampleBool() {
|
||||
// This example shows the prompt output format
|
||||
fmt.Println("Enable TLS [Y/n]:")
|
||||
// User input: <empty> (returns default true)
|
||||
// Result: true
|
||||
|
||||
fmt.Println("Enable TLS [Y/n]:")
|
||||
// User input: "n"
|
||||
// Result: false
|
||||
|
||||
fmt.Println("Enable debug mode [y/N]:")
|
||||
// User input: <empty> (returns default false)
|
||||
// Result: false
|
||||
|
||||
fmt.Println("Enable debug mode [y/N]:")
|
||||
// User input: "yes"
|
||||
// Result: true
|
||||
}
|
||||
|
||||
// Example usage in a real command
|
||||
func ExampleUsage() {
|
||||
// Example of using prompt functions in a CLI command:
|
||||
//
|
||||
// host, err := prompt.String("Enter SMTP host", "smtp.gmail.com")
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// port, err := prompt.Int("Enter SMTP port", 587)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// useTLS, err := prompt.Bool("Enable TLS", true)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// fmt.Printf("Configuration: host=%s, port=%d, tls=%v\n", host, port, useTLS)
|
||||
}
|
||||
89
internal/prompt/prompt.go
Normal file
89
internal/prompt/prompt.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// Package prompt provides simple utilities for interactive CLI prompts
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// String prompts the user for a string value with a default
|
||||
func String(prompt, defaultValue string) (string, error) {
|
||||
if defaultValue != "" {
|
||||
fmt.Printf("%s [%s]: ", prompt, defaultValue)
|
||||
} else {
|
||||
fmt.Printf("%s: ", prompt)
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read input: %w", err)
|
||||
}
|
||||
|
||||
input = strings.TrimSpace(input)
|
||||
if input == "" {
|
||||
return defaultValue, nil
|
||||
}
|
||||
|
||||
return input, nil
|
||||
}
|
||||
|
||||
// Int prompts the user for an integer value with a default
|
||||
func Int(prompt string, defaultValue int) (int, error) {
|
||||
fmt.Printf("%s [%d]: ", prompt, defaultValue)
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to read input: %w", err)
|
||||
}
|
||||
|
||||
input = strings.TrimSpace(input)
|
||||
if input == "" {
|
||||
return defaultValue, nil
|
||||
}
|
||||
|
||||
value, err := strconv.Atoi(input)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid integer value: %s", input)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// Bool prompts the user for a boolean value with a default
|
||||
func Bool(prompt string, defaultValue bool) (bool, error) {
|
||||
defaultStr := "y/n"
|
||||
if defaultValue {
|
||||
defaultStr = "Y/n"
|
||||
} else {
|
||||
defaultStr = "y/N"
|
||||
}
|
||||
|
||||
fmt.Printf("%s [%s]: ", prompt, defaultStr)
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to read input: %w", err)
|
||||
}
|
||||
|
||||
input = strings.TrimSpace(input)
|
||||
input = strings.ToLower(input)
|
||||
|
||||
if input == "" {
|
||||
return defaultValue, nil
|
||||
}
|
||||
|
||||
switch input {
|
||||
case "y", "yes", "true":
|
||||
return true, nil
|
||||
case "n", "no", "false":
|
||||
return false, nil
|
||||
default:
|
||||
return false, fmt.Errorf("invalid boolean value: %s (expected y/n/yes/no/true/false)", input)
|
||||
}
|
||||
}
|
||||
64
internal/prompt/prompt_test.go
Normal file
64
internal/prompt/prompt_test.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Note: These are basic unit tests for the prompt package.
|
||||
// Interactive testing requires manual verification since the functions
|
||||
// read from stdin and write to stdout.
|
||||
|
||||
func TestBoolParsing(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected bool
|
||||
hasError bool
|
||||
}{
|
||||
{"yes", "yes", true, false},
|
||||
{"y", "y", true, false},
|
||||
{"true", "true", true, false},
|
||||
{"no", "no", false, false},
|
||||
{"n", "n", false, false},
|
||||
{"false", "false", false, false},
|
||||
{"invalid", "maybe", false, true},
|
||||
{"invalid", "xyz", false, true},
|
||||
}
|
||||
|
||||
// Test the parsing logic that would be used by Bool function
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
input := tt.input
|
||||
var result bool
|
||||
var err error
|
||||
|
||||
switch input {
|
||||
case "y", "yes", "true":
|
||||
result = true
|
||||
case "n", "no", "false":
|
||||
result = false
|
||||
default:
|
||||
err = &invalidBoolError{}
|
||||
}
|
||||
|
||||
if tt.hasError {
|
||||
if err == nil {
|
||||
t.Errorf("expected error for input %q, got nil", tt.input)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error for input %q: %v", tt.input, err)
|
||||
}
|
||||
if result != tt.expected {
|
||||
t.Errorf("expected %v for input %q, got %v", tt.expected, tt.input, result)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type invalidBoolError struct{}
|
||||
|
||||
func (e *invalidBoolError) Error() string {
|
||||
return "invalid boolean value"
|
||||
}
|
||||
Reference in New Issue
Block a user