diff --git a/cmd/cli/app/auth/auth_delete.go b/cmd/cli/app/auth/auth_delete.go index 89988c8196..4a9bdc9b5b 100644 --- a/cmd/cli/app/auth/auth_delete.go +++ b/cmd/cli/app/auth/auth_delete.go @@ -58,10 +58,11 @@ var auth_deleteCmd = &cobra.Command{ // Confirm user wants to delete their account yes := cli.PrintYesNoPrompt(cmd, fmt.Sprintf( - "Are you sure you want to permanently delete your account? (yes/no): \n\nName: %s\nEmail: %s", + "You are about to permanently delete your account. \n\nName: %s\nEmail: %s", userDetails.Name, userDetails.Email, ), + "Are you sure?", "Delete account operation cancelled.") if !yes { return diff --git a/cmd/cli/app/auth/auth_revoke_provider.go b/cmd/cli/app/auth/auth_revoke_provider.go index 481ca76ede..a867df4afa 100644 --- a/cmd/cli/app/auth/auth_revoke_provider.go +++ b/cmd/cli/app/auth/auth_revoke_provider.go @@ -56,7 +56,8 @@ var Auth_revokeproviderCmd = &cobra.Command{ if all { yes := cli.PrintYesNoPrompt(cmd, - "Are you sure you want to revoke all access tokens for your provider? (yes/no): ", + "You are about to revoke the access tokens for your provider.", + "Are you sure?", "Delete provider access tokens cancelled.") if !yes { return diff --git a/cmd/cli/app/provider/provider_enroll.go b/cmd/cli/app/provider/provider_enroll.go index 1aae34427f..6d6ebf40ef 100644 --- a/cmd/cli/app/provider/provider_enroll.go +++ b/cmd/cli/app/provider/provider_enroll.go @@ -135,7 +135,8 @@ actions such as adding repositories.`, ownerPromptStr = fmt.Sprintf("the %s organisation", owner) } yes := cli.PrintYesNoPrompt(cmd, - fmt.Sprintf("You are about to enroll repositories from %s. Confirm? (yes/no): \n", ownerPromptStr), + fmt.Sprintf("You are about to enroll repositories from %s.", ownerPromptStr), + "Do you confirm?", "Enroll operation cancelled.") if !yes { return diff --git a/cmd/cli/app/rule_type/rule_type_delete.go b/cmd/cli/app/rule_type/rule_type_delete.go index f30c9465b6..d6638fc2f2 100644 --- a/cmd/cli/app/rule_type/rule_type_delete.go +++ b/cmd/cli/app/rule_type/rule_type_delete.go @@ -56,7 +56,8 @@ minder control plane.`, if deleteAll { // Ask for confirmation if deleteAll is set on purpose yes := cli.PrintYesNoPrompt(cmd, - "Are you sure you want to permanently delete all of your rule types? (yes/no): ", + "You are about to permanently delete all of your rule types.", + "Are you sure?", "Delete all rule types operation cancelled.") if !yes { return diff --git a/go.mod b/go.mod index a65e270e72..7a6dfcec37 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/charmbracelet/bubbles v0.16.1 github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/lipgloss v0.9.1 + github.com/erikgeiser/promptkit v0.9.0 github.com/evanphx/json-patch/v5 v5.7.0 github.com/fergusstrange/embedded-postgres v1.24.0 github.com/go-git/go-billy/v5 v5.5.0 @@ -69,6 +70,7 @@ require ( ) require ( + github.com/atotto/clipboard v0.1.4 // indirect github.com/aws/aws-sdk-go-v2/service/ecr v1.15.0 // indirect github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.12.0 // indirect github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795 // indirect diff --git a/go.sum b/go.sum index d2e14f85c5..8fe5d66621 100644 --- a/go.sum +++ b/go.sum @@ -175,6 +175,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aws/aws-sdk-go v1.45.26 h1:PJ2NJNY5N/yeobLYe1Y+xLdavBi67ZI8gvph6ftwVCg= github.com/aws/aws-sdk-go v1.45.26/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2KxJyNVab250= @@ -358,6 +360,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/erikgeiser/promptkit v0.9.0 h1:3qL1mS/ntCrXdb8sTP/ka82CJ9kEQaGuYXNrYJkWYBc= +github.com/erikgeiser/promptkit v0.9.0/go.mod h1:pU9dtogSe3Jlc2AY77EP7R4WFP/vgD4v+iImC83KsCo= github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= diff --git a/internal/util/cli/cli.go b/internal/util/cli/cli.go index 48029d1c65..98112a45f1 100644 --- a/internal/util/cli/cli.go +++ b/internal/util/cli/cli.go @@ -23,13 +23,10 @@ package cli import ( - "bufio" "fmt" - "io" - "os" - "strings" - + "github.com/erikgeiser/promptkit/confirmation" "github.com/spf13/cobra" + "io" ) // PrintCmd prints a message using the output defined in the cobra Command @@ -43,21 +40,21 @@ func Print(out io.Writer, msg string, args ...interface{}) { } // PrintYesNoPrompt prints a yes/no prompt to the user and returns false if the user did not respond with yes or y -func PrintYesNoPrompt(cmd *cobra.Command, promptMsg, fallbackMsg string) bool { - reader := bufio.NewReader(os.Stdin) +func PrintYesNoPrompt(cmd *cobra.Command, promptMsg, confirmMsg, fallbackMsg string) bool { // Print the warning banner with the prompt message PrintCmd(cmd, WarningBanner.Render(promptMsg)) - // Read the response - response, _ := reader.ReadString('\n') + // Prompt the user for confirmation + input := confirmation.New(confirmMsg, confirmation.No) + ok, err := input.RunPrompt() + if err != nil { + PrintCmd(cmd, WarningBanner.Render(fmt.Sprintf("Error reading input: %v", err))) + ok = false + } - // Normalise the response - response = strings.ToLower(strings.TrimSpace(response)) - if response != "yes" && response != "y" { - // Prompt was not confirmed, print the fallback message and return false + // If the user did not confirm, print the fallback message + if !ok { PrintCmd(cmd, Header.Render(fallbackMsg)) - return false } - // Prompt was confirmed, return true - return true + return ok }