github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/client/prompter.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package client 5 6 import ( 7 "strings" 8 9 "github.com/keybase/client/go/libkb" 10 ) 11 12 type Field struct { 13 Name string 14 Prompt string 15 FirstPrompt string 16 Defval string 17 Hint string 18 Checker *libkb.Checker 19 Thrower func(key, value string) error 20 Disabled bool 21 Value *string 22 PromptDescriptor libkb.PromptDescriptor 23 } 24 25 func (f Field) GetValue() string { 26 if f.Value == nil { 27 return "" 28 } 29 return *f.Value 30 } 31 32 type Prompter struct { 33 Fields []*Field 34 tui libkb.TerminalUI 35 } 36 37 func NewPrompter(f []*Field, tui libkb.TerminalUI) *Prompter { 38 return &Prompter{Fields: f, tui: tui} 39 } 40 41 func (p *Prompter) Run() error { 42 for _, f := range p.Fields { 43 if f.Disabled { 44 continue 45 } 46 if err := p.ReadField(f); err != nil { 47 return err 48 } 49 } 50 return nil 51 } 52 53 func (f *Field) Clear() string { 54 old := f.GetValue() 55 f.Value = nil 56 return old 57 } 58 59 func (p *Prompter) ReadField(f *Field) (err error) { 60 61 done := false 62 first := true 63 64 var val string 65 66 if p.tui == nil { 67 return NoTerminalError{} 68 } 69 70 for !done && err == nil { 71 72 prompt := f.Prompt 73 if first { 74 if len(f.FirstPrompt) > 0 { 75 prompt += f.FirstPrompt 76 } 77 first = false 78 } else { 79 hint := f.Hint 80 if len(hint) == 0 { 81 hint = f.Checker.Hint 82 } 83 prompt += " (" + hint + ")" 84 } 85 86 var def string 87 if len(f.Defval) > 0 { 88 def = f.Defval 89 } else if f.Value != nil { 90 def = *f.Value 91 } 92 93 if len(def) > 0 { 94 prompt += " [" + def + "]" 95 } 96 prompt += ": " 97 98 if val, err = p.tui.Prompt(f.PromptDescriptor, prompt); err != nil { 99 break 100 } 101 102 if len(val) == 0 && len(def) > 0 { 103 val = def 104 } 105 106 if f.Checker == nil || !f.Checker.PreserveSpace { 107 val = strings.TrimSpace(val) 108 } 109 110 if f.Thrower != nil { 111 if err = f.Thrower(f.Name, val); err != nil { 112 break 113 } 114 } 115 if f.Checker != nil { 116 if f.Checker.Transform != nil { 117 val = f.Checker.Transform(val) 118 } 119 120 done = f.Checker.F(val) 121 } else { 122 done = true 123 } 124 if done { 125 f.Value = &val 126 } 127 } 128 129 if err == nil { 130 f.Value = &val 131 } 132 133 return 134 }