From 131a8b65d801ef467696371af82d04cec88ae042 Mon Sep 17 00:00:00 2001 From: Somtochi Onyekwere Date: Tue, 24 Oct 2023 13:43:44 +0100 Subject: [PATCH] use promptui for displaying prompt Signed-off-by: Somtochi Onyekwere --- cmd/flux/bootstrap.go | 2 +- cmd/flux/bootstrap_bitbucket_server.go | 6 ++- cmd/flux/bootstrap_git.go | 2 +- cmd/flux/bootstrap_github.go | 6 ++- cmd/flux/bootstrap_gitlab.go | 6 ++- cmd/flux/cluster_info.go | 34 ++++--------- cmd/flux/cluster_info_test.go | 70 -------------------------- cmd/flux/install.go | 8 ++- 8 files changed, 34 insertions(+), 100 deletions(-) diff --git a/cmd/flux/bootstrap.go b/cmd/flux/bootstrap.go index 45a8fcb055..467b5f0b65 100644 --- a/cmd/flux/bootstrap.go +++ b/cmd/flux/bootstrap.go @@ -131,7 +131,7 @@ func init() { bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.commitMessageAppendix, "commit-message-appendix", "", "string to add to the commit messages, e.g. '[ci skip]'") - bootstrapCmd.PersistentFlags().BoolVarP(&bootstrapArgs.force, "force", "f", false, "overwrite existing Flux installation on the cluster") + bootstrapCmd.PersistentFlags().BoolVar(&bootstrapArgs.force, "force", false, "overwrite existing Flux installation on the cluster") bootstrapCmd.PersistentFlags().MarkHidden("manifests") rootCmd.AddCommand(bootstrapCmd) diff --git a/cmd/flux/bootstrap_bitbucket_server.go b/cmd/flux/bootstrap_bitbucket_server.go index 68e4bbca52..fe174bb99a 100644 --- a/cmd/flux/bootstrap_bitbucket_server.go +++ b/cmd/flux/bootstrap_bitbucket_server.go @@ -24,6 +24,7 @@ import ( "github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/git/gogit" + "github.com/manifoldco/promptui" "github.com/spf13/cobra" "github.com/fluxcd/flux2/v2/internal/flags" @@ -130,8 +131,11 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("cluster info unavailable: %w", err) } - err = confirmFluxInstallOverride(os.Stdin, info) + err = confirmFluxInstallOverride(info) if err != nil { + if err == promptui.ErrAbort { + return fmt.Errorf("bootstrap cancelled") + } return err } } diff --git a/cmd/flux/bootstrap_git.go b/cmd/flux/bootstrap_git.go index 0a77f4b861..f895217b57 100644 --- a/cmd/flux/bootstrap_git.go +++ b/cmd/flux/bootstrap_git.go @@ -152,7 +152,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("cluster info unavailable: %w", err) } - err = confirmFluxInstallOverride(os.Stdin, info) + err = confirmFluxInstallOverride(info) if err != nil { return err } diff --git a/cmd/flux/bootstrap_github.go b/cmd/flux/bootstrap_github.go index 5390d2fccf..90655ce382 100644 --- a/cmd/flux/bootstrap_github.go +++ b/cmd/flux/bootstrap_github.go @@ -24,6 +24,7 @@ import ( "github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/git/gogit" + "github.com/manifoldco/promptui" "github.com/spf13/cobra" "github.com/fluxcd/flux2/v2/internal/flags" @@ -133,8 +134,11 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("cluster info unavailable: %w", err) } if !bootstrapArgs.force { - err := confirmFluxInstallOverride(os.Stdin, info) + err := confirmFluxInstallOverride(info) if err != nil { + if err == promptui.ErrAbort { + return fmt.Errorf("bootstrap cancelled") + } return err } } diff --git a/cmd/flux/bootstrap_gitlab.go b/cmd/flux/bootstrap_gitlab.go index 85fbc96d53..0f860b61ec 100644 --- a/cmd/flux/bootstrap_gitlab.go +++ b/cmd/flux/bootstrap_gitlab.go @@ -26,6 +26,7 @@ import ( "github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/git/gogit" + "github.com/manifoldco/promptui" "github.com/spf13/cobra" "github.com/fluxcd/flux2/v2/internal/flags" @@ -151,8 +152,11 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("cluster info unavailable: %w", err) } - err = confirmFluxInstallOverride(os.Stdin, info) + err = confirmFluxInstallOverride(info) if err != nil { + if err == promptui.ErrAbort { + return fmt.Errorf("bootstrap cancelled") + } return err } } diff --git a/cmd/flux/cluster_info.go b/cmd/flux/cluster_info.go index 4860d3d2de..6b0fc4c714 100644 --- a/cmd/flux/cluster_info.go +++ b/cmd/flux/cluster_info.go @@ -17,13 +17,10 @@ limitations under the License. package main import ( - "bufio" "context" "fmt" - "io" - "os" - "strings" + "github.com/manifoldco/promptui" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -52,10 +49,6 @@ type fluxClusterInfo struct { version string } -// ErrInstallCancelled is an error that indicates the user cancelled a Flux installation -// to prevent overriding an existing one. -var ErrInstallCancelled = fmt.Errorf("install cancelled") - // getFluxClusterInfo returns information on the Flux installation running on the cluster. // If an error occurred, the returned error will be non-nil. // @@ -97,26 +90,21 @@ func getFluxClusterInfo(ctx context.Context, c client.Client) (fluxClusterInfo, } // confirmFluxInstallOverride displays a prompt to the user so that they can confirm before overriding -// a Flux installation. It reads a response from the io.Reader and returns nil if the installation should continue, -// ErrInstallCancelled if the user doesn't confirm, or an error encountered. -func confirmFluxInstallOverride(reader io.Reader, info fluxClusterInfo) error { - var overridePrompt = `Flux %[1]s has been installed on this cluster with %[2]s! -Are you sure you want to proceed with overriding the %[2]s installation? Y/N: ` - +// a Flux installation. It returns nil if the installation should continue, +// promptui.ErrAbort if the user doesn't confirm, or an error encountered. +func confirmFluxInstallOverride(info fluxClusterInfo) error { // no need to display prompt if flux is not installed or installation is // managed by Flux if !info.installed || info.managedBy == "" || info.managedBy == "flux" { return nil } - fmt.Fprintf(os.Stdout, fmt.Sprintf(overridePrompt, info.version, info.managedBy)) - ans, err := bufio.NewReader(reader).ReadString('\n') - if err != nil { - return fmt.Errorf("could not read from stdin: %w", err) - } - ans = strings.TrimRight(ans, "\r\n") - if ans == "Y" { - return nil + display := fmt.Sprintf("Flux %[1]s has been installed on this cluster with %s", info.version, info.managedBy) + fmt.Fprintln(rootCmd.ErrOrStderr(), display) + prompt := promptui.Prompt{ + Label: fmt.Sprintf("Are you sure you want to override the %s installation? Y/N", info.managedBy), + IsConfirm: true, } - return ErrInstallCancelled + _, err := prompt.Run() + return err } diff --git a/cmd/flux/cluster_info_test.go b/cmd/flux/cluster_info_test.go index 4c63b1367a..d4c7ab27ed 100644 --- a/cmd/flux/cluster_info_test.go +++ b/cmd/flux/cluster_info_test.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "os" - "strings" "testing" . "github.com/onsi/gomega" @@ -132,72 +131,3 @@ func Test_getFluxClusterInfo(t *testing.T) { }) } } - -func Test_confirmFluxInstallOverride(t *testing.T) { - - tests := []struct { - name string - input string - info fluxClusterInfo - wantErr error - }{ - { - name: "Flux not installed", - wantErr: nil, - }, - { - name: "Installation managed by flux - empty manager", - info: fluxClusterInfo{ - installed: true, - }, - }, - { - name: "Installation managed by different manager - confirm override", - input: "Y\n", - info: fluxClusterInfo{ - version: "v2.1.0", - installed: true, - managedBy: "helm", - }, - }, - { - name: "Installation managed by different manager - deny override", - input: "no\n", - info: fluxClusterInfo{ - version: "v2.1.0", - managedBy: "helm", - installed: true, - }, - wantErr: ErrInstallCancelled, - }, - { - name: "Installation managed by different manager - unspecified input", - input: "no\n", - info: fluxClusterInfo{ - version: "v2.1.0", - managedBy: "helm", - installed: true, - }, - wantErr: ErrInstallCancelled, - }, - } - - // suppress output to stdout during tests - stdout := os.Stdout - os.Stdout, _ = os.Open(os.DevNull) - t.Cleanup(func() { - os.Stdout = stdout - }) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - g := NewWithT(t) - err := confirmFluxInstallOverride(strings.NewReader(tt.input), tt.info) - if tt.wantErr == nil { - g.Expect(err).To(BeNil()) - } else { - g.Expect(err).To(Not(BeNil())) - g.Expect(err).To(BeEquivalentTo(tt.wantErr)) - } - }) - } -} diff --git a/cmd/flux/install.go b/cmd/flux/install.go index b48e90bdfe..99273c92e3 100644 --- a/cmd/flux/install.go +++ b/cmd/flux/install.go @@ -23,6 +23,7 @@ import ( "path/filepath" "time" + "github.com/manifoldco/promptui" "github.com/spf13/cobra" "github.com/fluxcd/flux2/v2/internal/flags" @@ -99,7 +100,7 @@ func init() { installCmd.Flags().StringVar(&installArgs.clusterDomain, "cluster-domain", rootArgs.defaults.ClusterDomain, "internal cluster domain") installCmd.Flags().StringSliceVar(&installArgs.tolerationKeys, "toleration-keys", nil, "list of toleration keys used to schedule the components pods onto nodes with matching taints") - installCmd.Flags().BoolVarP(&installArgs.force, "force", "f", false, "overwrite existing Flux installation on the cluster") + installCmd.Flags().BoolVar(&installArgs.force, "force", false, "overwrite existing Flux installation on the cluster") installCmd.Flags().MarkHidden("manifests") rootCmd.AddCommand(installCmd) @@ -201,8 +202,11 @@ func installCmdRun(cmd *cobra.Command, args []string) error { } if !installArgs.force { - err := confirmFluxInstallOverride(os.Stdin, info) + err := confirmFluxInstallOverride(info) if err != nil { + if err == promptui.ErrAbort { + return fmt.Errorf("bootstrap cancelled") + } return err } }