1package commands 2 3import ( 4 "bufio" 5 "fmt" 6 "io" 7 "os" 8 "strings" 9) 10 11// retrieveUserInput is a function that can retrieve user input in form of string. By default, 12// it will prompt the user. In test, you can replace this with code that returns the appropriate response. 13var retrieveUserInput = func(message string) (string, error) { 14 return readUserInput(os.Stdin, message) 15} 16 17// readUserInput is similar to retrieveUserInput but takes an explicit 18// io.Reader to read user input from. It is meant to allow simplified testing 19// as to-be-read inputs can be injected conveniently. 20func readUserInput(in io.Reader, message string) (string, error) { 21 reader := bufio.NewReader(in) 22 warnConfirm("Are you sure you want to " + message + " (y/N) ? ") 23 answer, err := reader.ReadString('\n') 24 if err != nil { 25 return "", err 26 } 27 28 answer = strings.TrimRight(answer, "\r\n") 29 30 return strings.ToLower(answer), nil 31} 32 33// AskForConfirm parses and verifies user input for confirmation. 34func AskForConfirm(message string) error { 35 answer, err := retrieveUserInput(message) 36 if err != nil { 37 return fmt.Errorf("Unable to parse users input: %s", err) 38 } 39 40 if answer != "y" && answer != "ye" && answer != "yes" { 41 return fmt.Errorf("Invalid user input") 42 } 43 44 return nil 45} 46 47// AskForConfirmDelete builds a message to ask the user to confirm deleting 48// one or multiple resources and then sends it through to AskForConfirm to 49// parses and verifies user input. 50func AskForConfirmDelete(resourceType string, count int) error { 51 message := fmt.Sprintf("delete this %s?", resourceType) 52 if count > 1 { 53 resourceType = resourceType + "s" 54 message = fmt.Sprintf("delete %d %s?", count, resourceType) 55 } 56 57 err := AskForConfirm(message) 58 if err != nil { 59 return err 60 } 61 62 return nil 63} 64