- Move remaining beach packages and embedded admin assets\n- Rewrite framework, example, build, and gate paths
134 lines
2.6 KiB
Go
134 lines
2.6 KiB
Go
package bonfire
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"golang.org/x/term"
|
|
)
|
|
|
|
func (c *console) Ask(question, def string) (string, error) {
|
|
c.writeQuestion(question, def)
|
|
line, err := c.readLine()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
return def, nil
|
|
}
|
|
return "", err
|
|
}
|
|
if line == "" {
|
|
return def, nil
|
|
}
|
|
return line, nil
|
|
}
|
|
|
|
func (c *console) Confirm(question string, def bool) (bool, error) {
|
|
if !c.interactive {
|
|
return def, nil
|
|
}
|
|
hint := "y/N"
|
|
if def {
|
|
hint = "Y/n"
|
|
}
|
|
line, err := c.Ask(question+" ["+hint+"]", "")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if line == "" {
|
|
return def, nil
|
|
}
|
|
switch strings.ToLower(line) {
|
|
case "y", "yes":
|
|
return true, nil
|
|
case "n", "no":
|
|
return false, nil
|
|
default:
|
|
return def, nil
|
|
}
|
|
}
|
|
|
|
func (c *console) Choice(question string, choices []string, def int) (string, error) {
|
|
if len(choices) == 0 {
|
|
return "", fmt.Errorf("bonfire: choice has no options")
|
|
}
|
|
if def < 0 || def >= len(choices) {
|
|
def = 0
|
|
}
|
|
c.Println(c.style(ansiCyan, symPrompt) + " " + question)
|
|
for i, choice := range choices {
|
|
mark := " "
|
|
if i == def {
|
|
mark = "*"
|
|
}
|
|
c.Printf(" %s %d) %s\n", mark, i+1, choice)
|
|
}
|
|
line, err := c.readLine()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
return choices[def], nil
|
|
}
|
|
return "", err
|
|
}
|
|
if line == "" {
|
|
return choices[def], nil
|
|
}
|
|
n, convErr := strconv.Atoi(line)
|
|
if convErr != nil || n < 1 || n > len(choices) {
|
|
return choices[def], nil
|
|
}
|
|
return choices[n-1], nil
|
|
}
|
|
|
|
// Secret reads a hidden password on a TTY via term.ReadPassword.
|
|
// When stdin is not a terminal it reads a plain line and never logs the value.
|
|
func (c *console) Secret(question string) (string, error) {
|
|
c.writeQuestion(question, "")
|
|
if f, ok := c.in.(*os.File); ok && term.IsTerminal(int(f.Fd())) {
|
|
b, err := term.ReadPassword(int(f.Fd()))
|
|
c.Println()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(b), nil
|
|
}
|
|
line, err := c.readLine()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
return "", nil
|
|
}
|
|
return "", err
|
|
}
|
|
return line, nil
|
|
}
|
|
|
|
func (c *console) writeQuestion(question, def string) {
|
|
suffix := ""
|
|
if def != "" {
|
|
suffix = " " + c.dim("("+def+")")
|
|
}
|
|
c.Printf("%s %s%s %s ", c.style(ansiCyan, symPrompt), question, suffix, symArrow)
|
|
}
|
|
|
|
func (c *console) readLine() (string, error) {
|
|
if c.in == nil {
|
|
return "", io.EOF
|
|
}
|
|
reader, ok := c.in.(*bufio.Reader)
|
|
if !ok {
|
|
reader = bufio.NewReader(c.in)
|
|
}
|
|
line, err := reader.ReadString('\n')
|
|
line = strings.TrimRight(line, "\r\n")
|
|
if err != nil && err != io.EOF {
|
|
return "", err
|
|
}
|
|
if err == io.EOF && line == "" {
|
|
return "", io.EOF
|
|
}
|
|
return strings.TrimSpace(line), nil
|
|
}
|