github.com/supabase/cli@v1.168.1/internal/utils/console.go (about)

     1  package utils
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"strings"
     9  
    10  	"golang.org/x/term"
    11  )
    12  
    13  type Console struct {
    14  	IsTTY  bool
    15  	stdin  *bufio.Scanner
    16  	logger io.Writer
    17  }
    18  
    19  func NewConsole() Console {
    20  	return Console{
    21  		IsTTY:  term.IsTerminal(int(os.Stdin.Fd())),
    22  		stdin:  bufio.NewScanner(os.Stdin),
    23  		logger: GetDebugLogger(),
    24  	}
    25  }
    26  
    27  // PromptYesNo asks yes/no questions using the label.
    28  func (c Console) PromptYesNo(label string, def bool) bool {
    29  	choices := "Y/n"
    30  	if !def {
    31  		choices = "y/N"
    32  	}
    33  	labelWithChoice := fmt.Sprintf("%s [%s] ", label, choices)
    34  	// Any error will be handled as default value
    35  	if input := c.PromptText(labelWithChoice); len(input) > 0 {
    36  		if answer := parseYesNo(input); answer != nil {
    37  			return *answer
    38  		}
    39  	}
    40  	return def
    41  }
    42  
    43  func parseYesNo(s string) *bool {
    44  	s = strings.ToLower(s)
    45  	if s == "y" || s == "yes" {
    46  		return Ptr(true)
    47  	}
    48  	if s == "n" || s == "no" {
    49  		return Ptr(false)
    50  	}
    51  	return nil
    52  }
    53  
    54  // PromptText asks for input using the label.
    55  func (c Console) PromptText(label string) string {
    56  	fmt.Fprint(os.Stderr, label)
    57  	// Scan a single line from input or file
    58  	if !c.stdin.Scan() {
    59  		fmt.Fprintln(c.logger, io.EOF)
    60  	}
    61  	if err := c.stdin.Err(); err != nil {
    62  		fmt.Fprintln(c.logger, err)
    63  	}
    64  	token := strings.TrimSpace(c.stdin.Text())
    65  	// Echo input to stderr for non-interactive terminals
    66  	if !c.IsTTY {
    67  		fmt.Fprintln(os.Stderr, token)
    68  	}
    69  	return token
    70  }