1
0
mirror of https://github.com/rancher/os.git synced 2025-07-15 15:51:36 +00:00
os/pkg/questions/questions.go
2021-10-02 16:08:48 -07:00

143 lines
2.5 KiB
Go

package questions
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"github.com/mattn/go-isatty"
)
func PromptFormattedOptions(text string, def int, options ...string) (int, error) {
var newOptions []string
for i := range options {
newOptions = append(newOptions, fmt.Sprintf("%d. %s\n", i+1, options[i]))
}
return PromptOptions(text+"\n", def, newOptions...)
}
func PromptOptions(text string, def int, options ...string) (int, error) {
if len(options) == 1 {
return 0, nil
}
PrintToTerm(text)
for _, option := range options {
PrintToTerm(option)
}
defString := ""
if def >= 0 {
defString = strconv.Itoa(def + 1)
}
for {
ans, err := Prompt(fmt.Sprintf("Select Number [%s]: ", defString), defString)
if err != nil {
return 0, err
}
num, err := strconv.Atoi(ans)
if err != nil {
PrintfToTerm("Invalid number: %s\n", ans)
continue
}
num--
if num < 0 || num >= len(options) {
PrintlnToTerm("Select a number between 1 and", +len(options))
continue
}
return num, nil
}
}
func PromptBool(text string, def bool) (bool, error) {
msg := fmt.Sprintf("%s [y/N]: ", text)
defStr := "n"
if def {
msg = fmt.Sprintf("%s [Y/n]: ", text)
defStr = "y"
}
for {
yn, err := Prompt(msg, defStr)
if err != nil {
return false, err
}
switch strings.ToLower(yn) {
case "y":
return true, nil
case "n":
return false, nil
default:
fmt.Println("Enter y or n")
}
}
}
func PrintToTerm(text ...interface{}) {
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Print(text...)
} else {
fmt.Fprint(os.Stderr, text...)
}
}
func PrintlnToTerm(text ...interface{}) {
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Println(text...)
} else {
fmt.Fprintln(os.Stderr, text...)
}
}
func PrintfToTerm(msg string, format ...interface{}) {
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Printf(msg, format...)
} else {
fmt.Fprintf(os.Stderr, msg, format...)
}
}
func Prompt(text, def string) (string, error) {
for {
PrintToTerm(text)
answer, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
return "", err
}
answer = strings.TrimSpace(answer)
if answer == "" {
answer = def
}
if answer == "" {
continue
}
return answer, nil
}
}
func PromptOptional(text, def string) (string, error) {
for {
PrintToTerm(text)
answer, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
return "", err
}
answer = strings.TrimSpace(answer)
if answer == "" {
answer = def
}
return answer, nil
}
}