diff options
author | Michael Muré <batolettre@gmail.com> | 2022-08-18 23:34:05 +0200 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2022-08-18 23:44:06 +0200 |
commit | 5511c230b678a181cc596238bf6669428d1b1902 (patch) | |
tree | 8701efc87732439f993eb4f1d00585fc419b87ab /input/prompt.go | |
parent | 5ca686b59751e3c87740b84108c54fc675a074cf (diff) | |
download | git-bug-5511c230b678a181cc596238bf6669428d1b1902.tar.gz |
move {bug,identity} to /entities, move input to /commands
Diffstat (limited to 'input/prompt.go')
-rw-r--r-- | input/prompt.go | 265 |
1 files changed, 0 insertions, 265 deletions
diff --git a/input/prompt.go b/input/prompt.go deleted file mode 100644 index 576d45bb..00000000 --- a/input/prompt.go +++ /dev/null @@ -1,265 +0,0 @@ -package input - -import ( - "bufio" - "fmt" - "net/url" - "os" - "sort" - "strconv" - "strings" - "syscall" - "time" - - "golang.org/x/crypto/ssh/terminal" - - "github.com/MichaelMure/git-bug/bridge/core/auth" - "github.com/MichaelMure/git-bug/util/colors" - "github.com/MichaelMure/git-bug/util/interrupt" -) - -// PromptValidator is a validator for a user entry -// If complaint is "", value is considered valid, otherwise it's the error reported to the user -// If err != nil, a terminal error happened -type PromptValidator func(name string, value string) (complaint string, err error) - -// Required is a validator preventing a "" value -func Required(name string, value string) (string, error) { - if value == "" { - return fmt.Sprintf("%s is empty", name), nil - } - return "", nil -} - -// IsURL is a validator checking that the value is a fully formed URL -func IsURL(name string, value string) (string, error) { - u, err := url.Parse(value) - if err != nil { - return fmt.Sprintf("%s is invalid: %v", name, err), nil - } - if u.Scheme == "" { - return fmt.Sprintf("%s is missing a scheme", name), nil - } - if u.Host == "" { - return fmt.Sprintf("%s is missing a host", name), nil - } - return "", nil -} - -// Prompts - -// Prompt is a simple text input. -func Prompt(prompt, name string, validators ...PromptValidator) (string, error) { - return PromptDefault(prompt, name, "", validators...) -} - -// PromptDefault is a simple text input with a default value. -func PromptDefault(prompt, name, preValue string, validators ...PromptValidator) (string, error) { -loop: - for { - if preValue != "" { - _, _ = fmt.Fprintf(os.Stderr, "%s [%s]: ", prompt, preValue) - } else { - _, _ = fmt.Fprintf(os.Stderr, "%s: ", prompt) - } - - line, err := bufio.NewReader(os.Stdin).ReadString('\n') - if err != nil { - return "", err - } - - line = strings.TrimSpace(line) - - if preValue != "" && line == "" { - line = preValue - } - - for _, validator := range validators { - complaint, err := validator(name, line) - if err != nil { - return "", err - } - if complaint != "" { - _, _ = fmt.Fprintln(os.Stderr, complaint) - continue loop - } - } - - return line, nil - } -} - -// PromptPassword is a specialized text input that doesn't display the characters entered. -func PromptPassword(prompt, name string, validators ...PromptValidator) (string, error) { - termState, err := terminal.GetState(int(syscall.Stdin)) - if err != nil { - return "", err - } - - cancel := interrupt.RegisterCleaner(func() error { - return terminal.Restore(int(syscall.Stdin), termState) - }) - defer cancel() - -loop: - for { - _, _ = fmt.Fprintf(os.Stderr, "%s: ", prompt) - - bytePassword, err := terminal.ReadPassword(int(syscall.Stdin)) - // new line for coherent formatting, ReadPassword clip the normal new line - // entered by the user - fmt.Println() - - if err != nil { - return "", err - } - - pass := string(bytePassword) - - for _, validator := range validators { - complaint, err := validator(name, pass) - if err != nil { - return "", err - } - if complaint != "" { - _, _ = fmt.Fprintln(os.Stderr, complaint) - continue loop - } - } - - return pass, nil - } -} - -// PromptChoice is a prompt giving possible choices -// Return the index starting at zero of the choice selected. -func PromptChoice(prompt string, choices []string) (int, error) { - for { - for i, choice := range choices { - _, _ = fmt.Fprintf(os.Stderr, "[%d]: %s\n", i+1, choice) - } - _, _ = fmt.Fprintf(os.Stderr, "%s: ", prompt) - - line, err := bufio.NewReader(os.Stdin).ReadString('\n') - fmt.Println() - if err != nil { - return 0, err - } - - line = strings.TrimSpace(line) - - index, err := strconv.Atoi(line) - if err != nil || index < 1 || index > len(choices) { - _, _ = fmt.Fprintln(os.Stderr, "invalid input") - continue - } - - return index - 1, nil - } -} - -func PromptURLWithRemote(prompt, name string, validRemotes []string, validators ...PromptValidator) (string, error) { - if len(validRemotes) == 0 { - return Prompt(prompt, name, validators...) - } - - sort.Strings(validRemotes) - - for { - _, _ = fmt.Fprintln(os.Stderr, "\nDetected projects:") - - for i, remote := range validRemotes { - _, _ = fmt.Fprintf(os.Stderr, "[%d]: %v\n", i+1, remote) - } - - _, _ = fmt.Fprintf(os.Stderr, "\n[0]: Another project\n\n") - _, _ = fmt.Fprintf(os.Stderr, "Select option: ") - - line, err := bufio.NewReader(os.Stdin).ReadString('\n') - if err != nil { - return "", err - } - - line = strings.TrimSpace(line) - - index, err := strconv.Atoi(line) - if err != nil || index < 0 || index > len(validRemotes) { - _, _ = fmt.Fprintln(os.Stderr, "invalid input") - continue - } - - // if user want to enter another project url break this loop - if index == 0 { - break - } - - return validRemotes[index-1], nil - } - - return Prompt(prompt, name, validators...) -} - -func PromptCredential(target, name string, credentials []auth.Credential, choices []string) (auth.Credential, int, error) { - if len(credentials) == 0 && len(choices) == 0 { - return nil, 0, fmt.Errorf("no possible choice") - } - if len(credentials) == 0 && len(choices) == 1 { - return nil, 0, nil - } - - sort.Sort(auth.ById(credentials)) - - for { - _, _ = fmt.Fprintln(os.Stderr) - - offset := 0 - for i, choice := range choices { - _, _ = fmt.Fprintf(os.Stderr, "[%d]: %s\n", i+1, choice) - offset++ - } - - if len(credentials) > 0 { - _, _ = fmt.Fprintln(os.Stderr) - _, _ = fmt.Fprintf(os.Stderr, "Existing %s for %s:\n", name, target) - - for i, cred := range credentials { - meta := make([]string, 0, len(cred.Metadata())) - for k, v := range cred.Metadata() { - meta = append(meta, k+":"+v) - } - sort.Strings(meta) - metaFmt := strings.Join(meta, ",") - - fmt.Printf("[%d]: %s => (%s) (%s)\n", - i+1+offset, - colors.Cyan(cred.ID().Human()), - metaFmt, - cred.CreateTime().Format(time.RFC822), - ) - } - } - - _, _ = fmt.Fprintln(os.Stderr) - _, _ = fmt.Fprintf(os.Stderr, "Select option: ") - - line, err := bufio.NewReader(os.Stdin).ReadString('\n') - _, _ = fmt.Fprintln(os.Stderr) - if err != nil { - return nil, 0, err - } - - line = strings.TrimSpace(line) - index, err := strconv.Atoi(line) - if err != nil || index < 1 || index > len(choices)+len(credentials) { - _, _ = fmt.Fprintln(os.Stderr, "invalid input") - continue - } - - switch { - case index <= len(choices): - return nil, index - 1, nil - default: - return credentials[index-len(choices)-1], 0, nil - } - } -} |