diff --git a/cmd/authInit.go b/cmd/authInit.go index 206c0eb..cf5cbdf 100644 --- a/cmd/authInit.go +++ b/cmd/authInit.go @@ -20,6 +20,7 @@ import ( "fmt" "os" "strings" + "syscall" "golang.org/x/crypto/ssh/terminal" @@ -141,7 +142,7 @@ func fetchAuthDataInteractively() (writeConfig bool, err error) { // password for !havePasswordAnswer { fmt.Print("LiquidWeb password: ") - passwordBytes, err := terminal.ReadPassword(0) + passwordBytes, err := terminal.ReadPassword(int(syscall.Stdin)) if err != nil { userInputError <- err break WHILEMOREADDS diff --git a/cmd/root.go b/cmd/root.go index 3315290..5143f45 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -16,10 +16,11 @@ limitations under the License. package cmd import ( - "bufio" "fmt" "os" + "strings" + "github.com/c-bata/go-prompt" homedir "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -110,22 +111,22 @@ func dialogDesctructiveConfirmProceed() (proceed bool) { var haveConfirmationAnswer bool utils.PrintTeal("Tip: Avoid future confirmations by passing --force\n\n") - for !haveConfirmationAnswer { - utils.PrintRed("This is a destructive operation. Continue (yes/[no])?: ") - scanner := bufio.NewScanner(os.Stdin) - scanner.Scan() - answer := scanner.Text() - - if answer != "" && answer != "yes" && answer != "no" { - utils.PrintYellow("invalid input.\n") - continue + f := func(d prompt.Document) []prompt.Suggest { + s := []prompt.Suggest{ + {Text: "yes", Description: "I understand continue"}, + {Text: "no", Description: "I would like to cancel"}, } + return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true) + } - haveConfirmationAnswer = true - if answer == "no" || answer == "" { - proceed = false - } else if answer == "yes" { - proceed = true + for !haveConfirmationAnswer { + utils.PrintRed("This is a destructive operation. Continue? ") + answer := strings.ToLower(prompt.Input("> ", f, prompt.OptionShowCompletionAtStart())) + if answer == "yes" || answer == "no" { + haveConfirmationAnswer = true + if answer == "yes" { + proceed = true + } } } diff --git a/go.mod b/go.mod index acb94ac..91dd4ae 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.13 require ( github.com/c-bata/go-prompt v0.2.3 github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 github.com/liquidweb/go-lwApi v0.0.0-20190605172801-52a4864d2738 github.com/mattn/go-colorable v0.1.6 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect diff --git a/go.sum b/go.sum index 82e30ed..5143bd9 100644 --- a/go.sum +++ b/go.sum @@ -57,6 +57,8 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= diff --git a/utils/utils.go b/utils/utils.go index d0fca3b..887dfd8 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -21,6 +21,8 @@ import ( "net" "os" "time" + + "github.com/k0kubun/go-ansi" ) func IpIsValid(ip string) bool { @@ -54,32 +56,44 @@ func FileExists(file string) bool { func PrintRed(m string, args ...interface{}) { msg := fmt.Sprintf(m, args...) - fmt.Printf(red(msg)) + if _, err := ansi.Print(red(msg)); err != nil { + fmt.Printf("Error printing to console. Error was [%s] original message: [%s]\n", err, msg) + } } func PrintTeal(m string, args ...interface{}) { msg := fmt.Sprintf(m, args...) - fmt.Printf(teal(msg)) + if _, err := ansi.Print(teal(msg)); err != nil { + fmt.Printf("Error printing to console. Error was [%s] original message: [%s]\n", err, msg) + } } func PrintGreen(m string, args ...interface{}) { msg := fmt.Sprintf(m, args...) - fmt.Printf(green(msg)) + if _, err := ansi.Print(green(msg)); err != nil { + fmt.Printf("Error printing to console. Error was [%s] original message: [%s]\n", err, msg) + } } func PrintYellow(m string, args ...interface{}) { msg := fmt.Sprintf(m, args...) - fmt.Printf(yellow(msg)) + if _, err := ansi.Print(yellow(msg)); err != nil { + fmt.Printf("Error printing to console. Error was [%s] original message: [%s]\n", err, msg) + } } func PrintMagenta(m string, args ...interface{}) { msg := fmt.Sprintf(m, args...) - fmt.Printf(magenta(msg)) + if _, err := ansi.Print(magenta(msg)); err != nil { + fmt.Printf("Error printing to console. Error was [%s] original message: [%s]\n", err, msg) + } } func PrintPurple(m string, args ...interface{}) { msg := fmt.Sprintf(m, args...) - fmt.Printf(purple(msg)) + if _, err := ansi.Print(purple(msg)); err != nil { + fmt.Printf("Error printing to console. Error was [%s] original message: [%s]\n", err, msg) + } } // private