From ca258ccbaf311d68c5072e85bceb315b8c928397 Mon Sep 17 00:00:00 2001 From: Rita Zerrizuela Date: Fri, 16 Jul 2021 22:17:37 -0300 Subject: [PATCH] Refactor editor prompt to unblock tests (#330) --- internal/cli/actions.go | 8 +++- internal/cli/branding.go | 2 +- internal/cli/email_templates.go | 6 ++- internal/cli/flags.go | 80 ++++++++------------------------- internal/cli/input.go | 50 +++++++++++++++++++-- internal/cli/rules.go | 8 +++- internal/prompt/prompt.go | 25 ++++++++++- 7 files changed, 106 insertions(+), 73 deletions(-) diff --git a/internal/cli/actions.go b/internal/cli/actions.go index 6f923e962..ee06d6330 100644 --- a/internal/cli/actions.go +++ b/internal/cli/actions.go @@ -188,7 +188,7 @@ auth0 actions create --n myaction -t post-login -d "lodash=4.0.0" -s "API_KEY=va // TODO(cyx): we can re-think this once we have // `--stdin` based commands. For now we don't have // those yet, so keeping this simple. - if err := actionCode.EditorPrompt( + if err := actionCode.OpenEditor( cmd, &inputs.Code, actionTemplate(inputs.Trigger), @@ -292,7 +292,7 @@ auth0 actions update --n myaction -t post-login -d "lodash=4.0.0" -s "API_K // TODO(cyx): we can re-think this once we have // `--stdin` based commands. For now we don't have // those yet, so keeping this simple. - if err := actionCode.EditorPromptU( + if err := actionCode.OpenEditorU( cmd, &inputs.Code, current.GetCode(), @@ -313,6 +313,10 @@ auth0 actions update --n myaction -t post-login -d "lodash=4.0.0" -s "API_K inputs.Trigger = currentTriggerId } + if inputs.Code == "" { + inputs.Code = current.GetCode() + } + // Prepare action payload for update. This will also be // re-hydrated by the SDK, which we'll use below during // display. diff --git a/internal/cli/branding.go b/internal/cli/branding.go index ca36d4533..b0273c2c3 100644 --- a/internal/cli/branding.go +++ b/internal/cli/branding.go @@ -368,7 +368,7 @@ func (cli *cli) customTemplateEditorPromptWithPreview(cmd *cobra.Command, body * } } - return templateBody.EditorPromptW( + return templateBody.OpenEditorW( cmd, body, templateData.Body, diff --git a/internal/cli/email_templates.go b/internal/cli/email_templates.go index 896e027fb..10080acef 100644 --- a/internal/cli/email_templates.go +++ b/internal/cli/email_templates.go @@ -184,7 +184,7 @@ auth0 branding emails update welcome`, // TODO(cyx): we can re-think this once we have // `--stdin` based commands. For now we don't have // those yet, so keeping this simple. - if err := emailTemplateBody.EditorPromptU( + if err := emailTemplateBody.OpenEditorU( cmd, &inputs.Body, current.GetBody(), @@ -205,6 +205,10 @@ auth0 branding emails update welcome`, return err } + if inputs.Body == "" { + inputs.Body = current.GetBody() + } + if inputs.From == "" { inputs.From = current.GetFrom() } diff --git a/internal/cli/flags.go b/internal/cli/flags.go index 92a24e9c4..b523897d3 100644 --- a/internal/cli/flags.go +++ b/internal/cli/flags.go @@ -3,10 +3,8 @@ package cli import ( "fmt" - "github.com/AlecAivazis/survey/v2" "github.com/auth0/auth0-cli/internal/ansi" "github.com/auth0/auth0-cli/internal/auth0" - "github.com/auth0/auth0-cli/internal/prompt" "github.com/spf13/cobra" ) @@ -93,70 +91,16 @@ func (f *Flag) Pick(cmd *cobra.Command, result *string, fn pickerOptionsFunc) er return nil } -func (f *Flag) EditorPrompt(cmd *cobra.Command, value *string, initialValue, filename string, infoFn func()) error { - out, err := prompt.CaptureInputViaEditor( - initialValue, - filename, - infoFn, - nil, - ) - if err != nil { - return err - } - - *value = out - return nil +func (f *Flag) OpenEditor(cmd *cobra.Command, value *string, defaultValue, filename string, infoFn func()) error { + return openEditorFlag(cmd, f, value, defaultValue, filename, infoFn, nil, false) } -func (f *Flag) EditorPromptW(cmd *cobra.Command, value *string, initialValue, filename string, infoFn func(), tempFileCreatedFn func(string)) error { - out, err := prompt.CaptureInputViaEditor( - initialValue, - filename, - infoFn, - tempFileCreatedFn, - ) - if err != nil { - return err - } - - *value = out - return nil +func (f *Flag) OpenEditorW(cmd *cobra.Command, value *string, defaultValue, filename string, infoFn func(), tempFileFn func(string)) error { + return openEditorFlag(cmd, f, value, defaultValue, filename, infoFn, tempFileFn, false) } -func (f *Flag) EditorPromptU(cmd *cobra.Command, value *string, initialValue, filename string, infoFn func()) error { - response := map[string]interface{}{} - - questions := []*survey.Question{ - { - Name: f.Name, - Prompt: &prompt.Editor{ - BlankAllowed: true, - Editor: &survey.Editor{ - Help: f.Help, - Message: f.Name, - FileName: filename, - Default: initialValue, - HideDefault: true, - AppendDefault: true, - }, - }, - }, - } - - if err := survey.Ask(questions, &response, prompt.Icons); err != nil { - return err - } - - // Since we have BlankAllowed=true, an empty answer means we'll use the - // initialValue provided since this path is for the Update path. - answer, ok := response[f.Name].(string) - if ok && answer != "" { - *value = answer - } else { - *value = initialValue - } - - return nil +func (f *Flag) OpenEditorU(cmd *cobra.Command, value *string, defaultValue string, filename string, infoFn func()) error { + return openEditorFlag(cmd, f, value, defaultValue, filename, nil, nil, true) } func (f *Flag) AskPassword(cmd *cobra.Command, value *string, defaultValue *string) error { @@ -255,6 +199,18 @@ func askPasswordFlag(cmd *cobra.Command, f *Flag, value *string, defaultValue *s return nil } +func openEditorFlag(cmd *cobra.Command, f *Flag, value *string, defaultValue string, filename string, infoFn func(), tempFileFn func(string), isUpdate bool) error { + if shouldAsk(cmd, f, false) { // Always open the editor on update + if isUpdate { + return openUpdateEditor(cmd, f, value, defaultValue, filename) + } else { + return openCreateEditor(cmd, f, value, defaultValue, filename, infoFn, tempFileFn) + } + } + + return nil +} + func registerString(cmd *cobra.Command, f *Flag, value *string, defaultValue string, isUpdate bool) { cmd.Flags().StringVarP(value, f.LongForm, f.ShortForm, defaultValue, f.Help) diff --git a/internal/cli/input.go b/internal/cli/input.go index aa249baa8..e94ac55e8 100644 --- a/internal/cli/input.go +++ b/internal/cli/input.go @@ -18,7 +18,7 @@ type commandInput interface { } func ask(cmd *cobra.Command, i commandInput, value interface{}, defaultValue *string, isUpdate bool) error { - isRequired := !isUpdate && i.GetIsRequired() + isRequired := isInputRequired(i, isUpdate) input := prompt.TextInput("", i.GetLabel(), i.GetHelp(), auth0.StringValue(defaultValue), isRequired) if err := prompt.AskOne(input, value); err != nil { @@ -37,8 +37,8 @@ func askBool(cmd *cobra.Command, i commandInput, value *bool, defaultValue *bool } func askPassword(cmd *cobra.Command, i commandInput, value interface{}, defaultValue *string, isUpdate bool) error { - isRequired := !isUpdate && i.GetIsRequired() - input := prompt.Password("", i.GetLabel(), auth0.StringValue(defaultValue), isRequired) + isRequired := isInputRequired(i, isUpdate) + input := prompt.PasswordInput("", i.GetLabel(), auth0.StringValue(defaultValue), isRequired) if err := prompt.AskOne(input, value); err != nil { return handleInputError(err) @@ -48,7 +48,7 @@ func askPassword(cmd *cobra.Command, i commandInput, value interface{}, defaultV } func _select(cmd *cobra.Command, i commandInput, value interface{}, options []string, defaultValue *string, isUpdate bool) error { - isRequired := !isUpdate && i.GetIsRequired() + isRequired := isInputRequired(i, isUpdate) // If there is no provided default value, we'll use the first option in // the selector by default. @@ -65,10 +65,52 @@ func _select(cmd *cobra.Command, i commandInput, value interface{}, options []st return nil } +func openCreateEditor(cmd *cobra.Command, i commandInput, value *string, defaultValue string, filename string, infoFn func(), tempFileFn func(string)) error { + out, err := prompt.CaptureInputViaEditor( + defaultValue, + filename, + infoFn, + tempFileFn, + ) + + if err != nil { + return handleInputError(err) + } + + *value = out + + return nil +} + +func openUpdateEditor(cmd *cobra.Command, i commandInput, value *string, defaultValue string, filename string) error { + isRequired := isInputRequired(i, true) + response := map[string]interface{}{} + input := prompt.EditorInput(i.GetName(), i.GetLabel(), i.GetHelp(), filename, defaultValue, isRequired) + + if err := prompt.AskOne(input, &response); err != nil { + return handleInputError(err) + } + + // Since we have BlankAllowed=true, an empty answer means we'll use the + // initialValue provided since this path is for the Update path. + answer, ok := response[i.GetName()].(string) + if ok && answer != "" { + *value = answer + } else { + *value = defaultValue + } + + return nil +} + func inputLabel(name string) string { return fmt.Sprintf("%s:", name) } +func isInputRequired(i commandInput, isUpdate bool) bool { + return !isUpdate && i.GetIsRequired() +} + func handleInputError(err error) error { if err == terminal.InterruptErr { os.Exit(0) diff --git a/internal/cli/rules.go b/internal/cli/rules.go index 12dce093a..ec7c47a42 100644 --- a/internal/cli/rules.go +++ b/internal/cli/rules.go @@ -139,7 +139,7 @@ auth0 rules create -n "My Rule" -t "Empty rule" --enabled=false`, // TODO(cyx): we can re-think this once we have // `--stdin` based commands. For now we don't have // those yet, so keeping this simple. - err := ruleScript.EditorPrompt( + err := ruleScript.OpenEditor( cmd, &inputs.Script, ruleTemplateOptions.getValue(inputs.Template), @@ -312,7 +312,7 @@ auth0 rules update -n "My Updated Rule" --enabled=false`, // TODO(cyx): we can re-think this once we have // `--stdin` based commands. For now we don't have // those yet, so keeping this simple. - err = ruleScript.EditorPromptU( + err = ruleScript.OpenEditorU( cmd, &inputs.Script, rule.GetScript(), @@ -328,6 +328,10 @@ auth0 rules update -n "My Updated Rule" --enabled=false`, inputs.Name = rule.GetName() } + if inputs.Script == "" { + inputs.Script = rule.GetScript() + } + // Prepare rule payload for update. This will also be // re-hydrated by the SDK, which we'll use below during // display. diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index 486d67f98..37ddfeb80 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -93,7 +93,7 @@ func SelectInput(name string, message string, help string, options []string, def return input } -func Password(name string, message string, defaultValue string, required bool) *survey.Question { +func PasswordInput(name string, message string, defaultValue string, required bool) *survey.Question { input := &survey.Question{ Name: name, Prompt: &survey.Password{Message: message}, @@ -105,3 +105,26 @@ func Password(name string, message string, defaultValue string, required bool) * return input } + +func EditorInput(name string, message string, help string, filename string, defaultValue string, required bool) *survey.Question { + input := &survey.Question{ + Name: name, + Prompt: &Editor{ + BlankAllowed: true, + Editor: &survey.Editor{ + Help: help, + Message: message, + FileName: filename, + Default: defaultValue, + HideDefault: true, + AppendDefault: true, + }, + }, + } + + if required { + input.Validate = survey.Required + } + + return input +}