github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/internal/prompter/prompter.go (about) 1 package prompter 2 3 import ( 4 "fmt" 5 "io" 6 "strings" 7 8 "github.com/AlecAivazis/survey/v2" 9 "github.com/ungtb10d/cli/v2/internal/ghinstance" 10 "github.com/ungtb10d/cli/v2/pkg/surveyext" 11 ) 12 13 //go:generate moq -rm -out prompter_mock.go . Prompter 14 type Prompter interface { 15 Select(string, string, []string) (int, error) 16 MultiSelect(string, string, []string) (int, error) 17 Input(string, string) (string, error) 18 InputHostname() (string, error) 19 Password(string) (string, error) 20 AuthToken() (string, error) 21 Confirm(string, bool) (bool, error) 22 ConfirmDeletion(string) error 23 MarkdownEditor(string, string, bool) (string, error) 24 } 25 26 type fileWriter interface { 27 io.Writer 28 Fd() uintptr 29 } 30 31 type fileReader interface { 32 io.Reader 33 Fd() uintptr 34 } 35 36 func New(editorCmd string, stdin fileReader, stdout fileWriter, stderr io.Writer) Prompter { 37 return &surveyPrompter{ 38 editorCmd: editorCmd, 39 stdin: stdin, 40 stdout: stdout, 41 stderr: stderr, 42 } 43 } 44 45 type surveyPrompter struct { 46 editorCmd string 47 stdin fileReader 48 stdout fileWriter 49 stderr io.Writer 50 } 51 52 func (p *surveyPrompter) Select(message, defaultValue string, options []string) (result int, err error) { 53 q := &survey.Select{ 54 Message: message, 55 Options: options, 56 PageSize: 20, 57 } 58 59 if defaultValue != "" { 60 q.Default = defaultValue 61 } 62 63 err = p.ask(q, &result) 64 65 return 66 } 67 68 func (p *surveyPrompter) MultiSelect(message, defaultValue string, options []string) (result int, err error) { 69 q := &survey.MultiSelect{ 70 Message: message, 71 Options: options, 72 PageSize: 20, 73 } 74 75 if defaultValue != "" { 76 q.Default = defaultValue 77 } 78 79 err = p.ask(q, &result) 80 81 return 82 } 83 84 func (p *surveyPrompter) ask(q survey.Prompt, response interface{}, opts ...survey.AskOpt) error { 85 opts = append(opts, survey.WithStdio(p.stdin, p.stdout, p.stderr)) 86 err := survey.AskOne(q, response, opts...) 87 if err == nil { 88 return nil 89 } 90 return fmt.Errorf("could not prompt: %w", err) 91 } 92 93 func (p *surveyPrompter) Input(prompt, defaultValue string) (result string, err error) { 94 err = p.ask(&survey.Input{ 95 Message: prompt, 96 Default: defaultValue, 97 }, &result) 98 99 return 100 } 101 102 func (p *surveyPrompter) ConfirmDeletion(requiredValue string) error { 103 var result string 104 return p.ask( 105 &survey.Input{ 106 Message: fmt.Sprintf("Type %s to confirm deletion:", requiredValue), 107 }, 108 &result, 109 survey.WithValidator( 110 func(val interface{}) error { 111 if str := val.(string); !strings.EqualFold(str, requiredValue) { 112 return fmt.Errorf("You entered %s", str) 113 } 114 return nil 115 })) 116 } 117 118 func (p *surveyPrompter) InputHostname() (result string, err error) { 119 err = p.ask( 120 &survey.Input{ 121 Message: "GHE hostname:", 122 }, &result, survey.WithValidator(func(v interface{}) error { 123 return ghinstance.HostnameValidator(v.(string)) 124 })) 125 126 return 127 } 128 129 func (p *surveyPrompter) Password(prompt string) (result string, err error) { 130 err = p.ask(&survey.Password{ 131 Message: prompt, 132 }, &result) 133 134 return 135 } 136 137 func (p *surveyPrompter) Confirm(prompt string, defaultValue bool) (result bool, err error) { 138 err = p.ask(&survey.Confirm{ 139 Message: prompt, 140 Default: defaultValue, 141 }, &result) 142 143 return 144 } 145 func (p *surveyPrompter) MarkdownEditor(message, defaultValue string, blankAllowed bool) (result string, err error) { 146 147 err = p.ask(&surveyext.GhEditor{ 148 BlankAllowed: blankAllowed, 149 EditorCommand: p.editorCmd, 150 Editor: &survey.Editor{ 151 Message: message, 152 Default: defaultValue, 153 FileName: "*.md", 154 HideDefault: true, 155 AppendDefault: true, 156 }, 157 }, &result) 158 159 return 160 } 161 162 func (p *surveyPrompter) AuthToken() (result string, err error) { 163 err = p.ask(&survey.Password{ 164 Message: "Paste your authentication token:", 165 }, &result, survey.WithValidator(survey.Required)) 166 167 return 168 }