github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/terminal/ui.go (about) 1 package terminal 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "strings" 8 "time" 9 10 . "github.com/cloudfoundry/cli/cf/i18n" 11 12 "github.com/cloudfoundry/cli/cf" 13 "github.com/cloudfoundry/cli/cf/configuration/core_config" 14 "github.com/cloudfoundry/cli/cf/trace" 15 ) 16 17 type ColoringFunction func(value string, row int, col int) string 18 19 func NotLoggedInText() string { 20 return fmt.Sprintf(T("Not logged in. Use '{{.CFLoginCommand}}' to log in.", map[string]interface{}{"CFLoginCommand": CommandColor(cf.Name() + " " + "login")})) 21 } 22 23 type UI interface { 24 PrintPaginator(rows []string, err error) 25 Say(message string, args ...interface{}) 26 PrintCapturingNoOutput(message string, args ...interface{}) 27 Warn(message string, args ...interface{}) 28 Ask(prompt string, args ...interface{}) (answer string) 29 AskForPassword(prompt string, args ...interface{}) (answer string) 30 Confirm(message string, args ...interface{}) bool 31 ConfirmDelete(modelType, modelName string) bool 32 ConfirmDeleteWithAssociations(modelType, modelName string) bool 33 Ok() 34 Failed(message string, args ...interface{}) 35 PanicQuietly() 36 ShowConfiguration(core_config.Reader) 37 LoadingIndication() 38 Wait(duration time.Duration) 39 Table(headers []string) Table 40 NotifyUpdateIfNeeded(core_config.Reader) 41 } 42 43 type terminalUI struct { 44 stdin io.Reader 45 printer Printer 46 } 47 48 func NewUI(r io.Reader, printer Printer) UI { 49 return &terminalUI{ 50 stdin: r, 51 printer: printer, 52 } 53 } 54 55 func (c *terminalUI) PrintPaginator(rows []string, err error) { 56 if err != nil { 57 c.Failed(err.Error()) 58 return 59 } 60 61 for _, row := range rows { 62 c.Say(row) 63 } 64 } 65 66 func (c *terminalUI) PrintCapturingNoOutput(message string, args ...interface{}) { 67 if len(args) == 0 { 68 fmt.Printf("%s", message) 69 } else { 70 fmt.Printf(message, args...) 71 } 72 } 73 74 func (c *terminalUI) Say(message string, args ...interface{}) { 75 if len(args) == 0 { 76 c.printer.Printf("%s\n", message) 77 } else { 78 c.printer.Printf(message+"\n", args...) 79 } 80 } 81 82 func (c *terminalUI) Warn(message string, args ...interface{}) { 83 message = fmt.Sprintf(message, args...) 84 c.Say(WarningColor(message)) 85 return 86 } 87 88 func (c *terminalUI) ConfirmDeleteWithAssociations(modelType, modelName string) bool { 89 return c.confirmDelete(T("Really delete the {{.ModelType}} {{.ModelName}} and everything associated with it?", 90 map[string]interface{}{ 91 "ModelType": modelType, 92 "ModelName": EntityNameColor(modelName), 93 })) 94 } 95 96 func (c *terminalUI) ConfirmDelete(modelType, modelName string) bool { 97 return c.confirmDelete(T("Really delete the {{.ModelType}} {{.ModelName}}?", 98 map[string]interface{}{ 99 "ModelType": modelType, 100 "ModelName": EntityNameColor(modelName), 101 })) 102 } 103 104 func (c *terminalUI) confirmDelete(message string) bool { 105 result := c.Confirm(message) 106 107 if !result { 108 c.Warn(T("Delete cancelled")) 109 } 110 111 return result 112 } 113 114 func (c *terminalUI) Confirm(message string, args ...interface{}) bool { 115 response := c.Ask(message, args...) 116 switch strings.ToLower(response) { 117 case "y", "yes", T("yes"): 118 return true 119 } 120 return false 121 } 122 123 func (c *terminalUI) Ask(prompt string, args ...interface{}) (answer string) { 124 fmt.Println("") 125 fmt.Printf(prompt+PromptColor(">")+" ", args...) 126 127 rd := bufio.NewReader(c.stdin) 128 line, err := rd.ReadString('\n') 129 if err == nil { 130 return strings.TrimSpace(line) 131 } 132 return "" 133 } 134 135 func (c *terminalUI) Ok() { 136 c.Say(SuccessColor(T("OK"))) 137 } 138 139 const QuietPanic = "This shouldn't print anything" 140 141 func (c *terminalUI) Failed(message string, args ...interface{}) { 142 message = fmt.Sprintf(message, args...) 143 144 if T == nil { 145 c.Say(FailureColor("FAILED")) 146 c.Say(message) 147 148 trace.Logger.Print("FAILED") 149 trace.Logger.Print(message) 150 c.PanicQuietly() 151 } else { 152 c.Say(FailureColor(T("FAILED"))) 153 c.Say(message) 154 155 trace.Logger.Print(T("FAILED")) 156 trace.Logger.Print(message) 157 c.PanicQuietly() 158 } 159 } 160 161 func (c *terminalUI) PanicQuietly() { 162 panic(QuietPanic) 163 } 164 165 func (ui *terminalUI) ShowConfiguration(config core_config.Reader) { 166 table := NewTable(ui, []string{"", ""}) 167 168 if config.HasAPIEndpoint() { 169 table.Add( 170 T("API endpoint:"), 171 T("{{.ApiEndpoint}} (API version: {{.ApiVersionString}})", 172 map[string]interface{}{ 173 "ApiEndpoint": EntityNameColor(config.ApiEndpoint()), 174 "ApiVersionString": EntityNameColor(config.ApiVersion()), 175 }), 176 ) 177 } 178 179 if !config.IsLoggedIn() { 180 table.Print() 181 ui.Say(NotLoggedInText()) 182 return 183 } else { 184 table.Add( 185 T("User:"), 186 EntityNameColor(config.UserEmail()), 187 ) 188 } 189 190 if !config.HasOrganization() && !config.HasSpace() { 191 table.Print() 192 command := fmt.Sprintf("%s target -o ORG -s SPACE", cf.Name()) 193 ui.Say(T("No org or space targeted, use '{{.CFTargetCommand}}'", 194 map[string]interface{}{ 195 "CFTargetCommand": CommandColor(command), 196 })) 197 return 198 } 199 200 if config.HasOrganization() { 201 table.Add( 202 T("Org:"), 203 EntityNameColor(config.OrganizationFields().Name), 204 ) 205 } else { 206 command := fmt.Sprintf("%s target -o Org", cf.Name()) 207 table.Add( 208 T("Org:"), 209 T("No org targeted, use '{{.CFTargetCommand}}'", 210 map[string]interface{}{ 211 "CFTargetCommand": CommandColor(command), 212 }), 213 ) 214 } 215 216 if config.HasSpace() { 217 table.Add( 218 T("Space:"), 219 EntityNameColor(config.SpaceFields().Name), 220 ) 221 } else { 222 command := fmt.Sprintf("%s target -s SPACE", cf.Name()) 223 table.Add( 224 T("Space:"), 225 T("No space targeted, use '{{.CFTargetCommand}}'", map[string]interface{}{"CFTargetCommand": CommandColor(command)}), 226 ) 227 } 228 229 table.Print() 230 } 231 232 func (c *terminalUI) LoadingIndication() { 233 c.printer.Print(".") 234 } 235 236 func (c *terminalUI) Wait(duration time.Duration) { 237 time.Sleep(duration) 238 } 239 240 func (ui *terminalUI) Table(headers []string) Table { 241 return NewTable(ui, headers) 242 } 243 244 func (ui *terminalUI) NotifyUpdateIfNeeded(config core_config.Reader) { 245 if !config.IsMinCliVersion(cf.Version) { 246 ui.Say("") 247 ui.Say(T("Cloud Foundry API version {{.ApiVer}} requires CLI version {{.CliMin}}. You are currently on version {{.CliVer}}. To upgrade your CLI, please visit: https://github.com/cloudfoundry/cli#downloads", 248 map[string]interface{}{ 249 "ApiVer": config.ApiVersion(), 250 "CliMin": config.MinCliVersion(), 251 "CliVer": cf.Version, 252 })) 253 } 254 }