Skip to content

Commit

Permalink
Use prompt accessors instead of Confirm return values.
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchell-as committed Nov 18, 2024
1 parent b5451fc commit 1fdc129
Show file tree
Hide file tree
Showing 19 changed files with 55 additions and 66 deletions.
32 changes: 13 additions & 19 deletions internal/prompt/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,6 @@ import (
"github.com/ActiveState/cli/internal/output"
)

type ConfirmKind int

const (
// A confirm prompt was completed by the user.
User ConfirmKind = iota
// A confirm prompt was completed in non-interactive mode.
NonInteractive
// A confirm prompt was completed via --force.
Force
)

type EventDispatcher interface {
EventWithLabel(category, action string, label string, dim ...*dimensions.Values)
}
Expand All @@ -35,11 +24,12 @@ type Prompter interface {
Input(title, message string, defaultResponse *string, flags ...ValidatorFlag) (string, error)
InputAndValidate(title, message string, defaultResponse *string, validator ValidatorFunc, flags ...ValidatorFlag) (string, error)
Select(title, message string, choices []string, defaultResponse *string) (string, error)
Confirm(title, message string, defaultChoice *bool, forcedChoice *bool) (bool, ConfirmKind, error)
Confirm(title, message string, defaultChoice *bool, forcedChoice *bool) (bool, error)
InputSecret(title, message string, flags ...ValidatorFlag) (string, error)
IsInteractive() bool
SetInteractive(bool)
EnableForce()
IsForceEnabled() bool
}

// ValidatorFunc is a function pass to the Prompter to perform validation
Expand Down Expand Up @@ -76,6 +66,10 @@ func (p *Prompt) EnableForce() {
p.isForced = true
}

func (p *Prompt) IsForceEnabled() bool {
return p.isForced
}

// ValidatorFlag represents flags for prompt functions to change their behavior on.
type ValidatorFlag int

Expand Down Expand Up @@ -183,21 +177,21 @@ func (p *Prompt) Select(title, message string, choices []string, defaultChoice *
}

// Confirm prompts user for yes or no response.
func (p *Prompt) Confirm(title, message string, defaultChoice *bool, forcedChoice *bool) (bool, ConfirmKind, error) {
func (p *Prompt) Confirm(title, message string, defaultChoice *bool, forcedChoice *bool) (bool, error) {
if p.isForced {
if forcedChoice == nil {
return false, Force, errs.New("No force option given for force-enabled prompt")
return false, errs.New("No force option given for force-enabled prompt")
}
logging.Debug("Prompt %s confirmed with choice %v in force mode", title, forcedChoice)
return *forcedChoice, Force, nil
return *forcedChoice, nil
}

if !p.isInteractive {
if defaultChoice != nil {
logging.Debug("Prompt %s confirmed with default choice %v in non-interactive mode", title, defaultChoice)
return *defaultChoice, NonInteractive, nil
return *defaultChoice, nil
}
return false, NonInteractive, interactiveInputError(message)
return false, interactiveInputError(message)
}
if title != "" {
p.out.Notice(output.Emphasize(title))
Expand All @@ -219,11 +213,11 @@ func (p *Prompt) Confirm(title, message string, defaultChoice *bool, forcedChoic
if err == terminal.InterruptErr {
p.analytics.EventWithLabel(constants.CatPrompt, title, "interrupt")
}
return false, User, locale.NewInputError(err.Error())
return false, locale.NewInputError(err.Error())
}
p.analytics.EventWithLabel(constants.CatPrompt, title, translateConfirm(resp))

return resp, User, nil
return resp, nil
}

func translateConfirm(confirm bool) string {
Expand Down
5 changes: 1 addition & 4 deletions internal/runbits/auth/keypair.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,11 @@ func promptForPreviousPassphrase(prompt prompt.Prompter) (string, error) {
func promptUserToRegenerateKeypair(passphrase string, cfg keypairs.Configurable, out output.Outputer, prmpt prompt.Prompter, auth *authentication.Auth) error {
// previous passphrase is invalid, inform user and ask if they want to generate a new keypair
out.Notice(locale.T("auth_generate_new_keypair_message"))
yes, kind, err := prmpt.Confirm("", locale.T("auth_confirm_generate_new_keypair_prompt"), ptr.To(false), nil)
yes, err := prmpt.Confirm("", locale.T("auth_confirm_generate_new_keypair_prompt"), ptr.To(false), nil)
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !yes {
if kind == prompt.NonInteractive {
return locale.NewInputError("prompt_abort_non_interactive")
}
return locale.NewInputError("auth_err_unrecoverable_keypair")
}
_, err = keypairs.GenerateAndSaveEncodedKeypair(cfg, secretsapi.Get(auth), passphrase, constants.DefaultRSABitLength, auth)
Expand Down
2 changes: 1 addition & 1 deletion internal/runbits/auth/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ func authenticateWithBrowser(out output.Outputer, auth *authentication.Auth, pro
var cont bool
var err error
for !cont {
cont, _, err = prompt.Confirm(locale.Tl("continue", "Continue?"), locale.T("auth_press_enter"), ptr.To(false), nil)
cont, err = prompt.Confirm(locale.Tl("continue", "Continue?"), locale.T("auth_press_enter"), ptr.To(false), nil)
if err != nil {
return errs.Wrap(err, "Prompt failed")
}
Expand Down
7 changes: 3 additions & 4 deletions internal/runbits/cves/cves.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
configMediator "github.com/ActiveState/cli/internal/mediators/config"
"github.com/ActiveState/cli/internal/output"
"github.com/ActiveState/cli/internal/primer"
"github.com/ActiveState/cli/internal/prompt"
"github.com/ActiveState/cli/internal/rtutils/ptr"
"github.com/ActiveState/cli/pkg/buildplan"
vulnModel "github.com/ActiveState/cli/pkg/platform/api/vulnerabilities/model"
Expand Down Expand Up @@ -106,20 +105,20 @@ func (c *CveReport) Report(newBuildPlan *buildplan.BuildPlan, oldBuildPlan *buil

c.summarizeCVEs(vulnerabilities)

confirm, kind, err := c.prime.Prompt().Confirm("", locale.Tr("prompt_continue_pkg_operation"), ptr.To(false), ptr.To(true))
confirm, err := c.prime.Prompt().Confirm("", locale.Tr("prompt_continue_pkg_operation"), ptr.To(false), ptr.To(true))
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !confirm {
if kind == prompt.NonInteractive {
if !c.prime.Prompt().IsInteractive() {
return errs.AddTips(
locale.NewInputError("prompt_abort_non_interactive"),
locale.Tl("more_info_prompt", "To disable security prompting run: [ACTIONABLE]state config set security.prompt.enabled false[/RESET]"),
)
}
return locale.NewInputError("err_pkgop_security_prompt", "Operation aborted by user")
}
if kind == prompt.Force {
if c.prime.Prompt().IsForceEnabled() {
c.prime.Output().Notice(locale.T("prompt_continue_force"))
}
c.prime.Output().Notice("") // Empty line
Expand Down
8 changes: 4 additions & 4 deletions internal/runners/clean/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ func (c *Cache) Run(params *CacheParams) error {

func (c *Cache) removeCache(path string) error {
defaultValue := !c.prime.Prompt().IsInteractive()
ok, kind, err := c.prime.Prompt().Confirm(locale.T("confirm"), locale.T("clean_cache_confirm"), &defaultValue, nil)
ok, err := c.prime.Prompt().Confirm(locale.T("confirm"), locale.T("clean_cache_confirm"), &defaultValue, nil)
if err != nil {
return errs.Wrap(err, "Could not confirm")
}
if !ok {
return locale.NewInputError("err_clean_cache_not_confirmed", "Cleaning of cache aborted by user")
}
if kind == prompt.NonInteractive {
if !c.prime.Prompt().IsInteractive() {
c.prime.Output().Notice(locale.T("prompt_continue_non_interactive"))
}

Expand All @@ -101,14 +101,14 @@ func (c *Cache) removeCache(path string) error {

func (c *Cache) removeProjectCache(projectDir, namespace string) error {
defaultValue := !c.prime.Prompt().IsInteractive()
ok, kind, err := c.prime.Prompt().Confirm(locale.T("confirm"), locale.Tr("clean_cache_artifact_confirm", namespace), &defaultValue, nil)
ok, err := c.prime.Prompt().Confirm(locale.T("confirm"), locale.Tr("clean_cache_artifact_confirm", namespace), &defaultValue, nil)
if err != nil {
return errs.Wrap(err, "Could not confirm")
}
if !ok {
return locale.NewInputError("err_clean_cache_artifact_not_confirmed", "Cleaning of cached runtime aborted by user")
}
if kind == prompt.NonInteractive {
if !c.prime.Prompt().IsInteractive() {
c.prime.Output().Notice(locale.T("prompt_continue_non_interactive"))
}

Expand Down
8 changes: 4 additions & 4 deletions internal/runners/clean/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,17 @@ func (c *Config) Run(params *ConfigParams) error {
}

defaultChoice := !c.confirm.IsInteractive()
ok, kind, err := c.confirm.Confirm(locale.T("confirm"), locale.T("clean_config_confirm"), &defaultChoice, ptr.To(true))
ok, err := c.confirm.Confirm(locale.T("confirm"), locale.T("clean_config_confirm"), &defaultChoice, ptr.To(true))
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !ok {
return locale.NewInputError("err_clean_config_aborted", "Cleaning of config aborted by user")
}
switch kind {
case prompt.NonInteractive:
switch {
case !c.confirm.IsInteractive():
c.output.Notice(locale.T("prompt_continue_non_interactive"))
case prompt.Force:
case c.confirm.IsForceEnabled():
c.output.Notice(locale.T("prompt_continue_force"))
}

Expand Down
8 changes: 4 additions & 4 deletions internal/runners/clean/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,17 @@ func (u *Uninstall) Run(params *UninstallParams) error {
if params.All {
confirmMessage = locale.T("uninstall_confirm_all")
}
ok, kind, err := u.prompt.Confirm(locale.T("confirm"), confirmMessage, &defaultChoice, ptr.To(true))
ok, err := u.prompt.Confirm(locale.T("confirm"), confirmMessage, &defaultChoice, ptr.To(true))
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !ok {
return locale.NewInputError("err_uninstall_aborted", "Uninstall aborted by user")
}
switch kind {
case prompt.NonInteractive:
switch {
case !u.prompt.IsInteractive():
u.out.Notice(locale.T("prompt_continue_non_interactive"))
case prompt.Force:
case u.prompt.IsForceEnabled():
u.out.Notice(locale.T("prompt_continue_force"))
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/runners/projects/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ func (d *Delete) Run(params *DeleteParams) error {
}

defaultChoice := !d.prompt.IsInteractive()
confirm, kind, err := d.prompt.Confirm("", locale.Tl("project_delete_confim", "Are you sure you want to delete the project {{.V0}}?", params.Project.String()), &defaultChoice, nil)
confirm, err := d.prompt.Confirm("", locale.Tl("project_delete_confim", "Are you sure you want to delete the project {{.V0}}?", params.Project.String()), &defaultChoice, nil)
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !confirm {
return locale.NewInputError("err_project_delete_aborted", "Delete aborted by user")
}
if kind == prompt.NonInteractive {
if !d.prompt.IsInteractive() {
d.out.Notice(locale.T("prompt_continue_non_interactive"))
}

Expand Down
4 changes: 2 additions & 2 deletions internal/runners/projects/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ func (e *Edit) Run(params *EditParams) error {
editMsg += locale.Tl("edit_prompt_confirm", "Continue?")

defaultChoice := !e.prompt.IsInteractive()
edit, kind, err := e.prompt.Confirm("", editMsg, &defaultChoice, nil)
edit, err := e.prompt.Confirm("", editMsg, &defaultChoice, nil)
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !edit {
return locale.NewInputError("edit_cancelled", "Project edit cancelled")
}
if kind == prompt.NonInteractive {
if !e.prompt.IsInteractive() {
e.out.Notice(locale.T("prompt_continue_non_interactive"))
}

Expand Down
4 changes: 2 additions & 2 deletions internal/runners/projects/move.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ func (m *Move) Run(params *MoveParams) error {
}

defaultChoice := !m.prompt.IsInteractive()
move, kind, err := m.prompt.Confirm("", locale.Tr("move_prompt", params.Namespace.String(), params.NewOwner, params.Namespace.Project), &defaultChoice, nil)
move, err := m.prompt.Confirm("", locale.Tr("move_prompt", params.Namespace.String(), params.NewOwner, params.Namespace.Project), &defaultChoice, nil)
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !move {
return locale.NewInputError("move_cancelled", "Project move aborted by user")
}
if kind == prompt.NonInteractive {
if !m.prompt.IsInteractive() {
m.out.Notice(locale.T("prompt_continue_non_interactive"))
}

Expand Down
4 changes: 2 additions & 2 deletions internal/runners/publish/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func (r *Runner) Run(params *Params) error {
return errs.Wrap(err, "Could not marshal publish variables")
}

cont, kind, err := r.prompt.Confirm(
cont, err := r.prompt.Confirm(
"",
locale.Tl("uploadingredient_confirm", `Prepared the following ingredient:
Expand All @@ -232,7 +232,7 @@ Do you want to publish this ingredient?
if !cont {
return locale.NewInputError("uploadingredient_cancel", "Publish cancelled")
}
if kind == prompt.NonInteractive {
if !r.prompt.IsInteractive() {
r.out.Notice(locale.T("prompt_continue_non_interactive"))
}

Expand Down
8 changes: 4 additions & 4 deletions internal/runners/push/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,14 @@ func (r *Push) Run(params PushParams) (rerr error) {

// Ask to create a copy if the user does not have org permissions
if intend&pushFromNoPermission > 0 && !params.Namespace.IsValid() {
createCopy, kind, err := r.prompt.Confirm("", locale.T("push_prompt_not_authorized"), ptr.To(true), nil)
createCopy, err := r.prompt.Confirm("", locale.T("push_prompt_not_authorized"), ptr.To(true), nil)
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !createCopy {
return nil
}
if kind == prompt.NonInteractive {
if !r.prompt.IsInteractive() {
r.out.Notice(locale.T("prompt_continue_non_interactive"))
}
}
Expand Down Expand Up @@ -172,7 +172,7 @@ func (r *Push) Run(params PushParams) (rerr error) {

// If the user didn't necessarily intend to create the project we should ask them for confirmation
if intend&intendCreateProject == 0 {
createProject, kind, err := r.prompt.Confirm(
createProject, err := r.prompt.Confirm(
locale.Tl("create_project", "Create Project"),
locale.Tl("push_confirm_create_project", "You are about to create the project [NOTICE]{{.V0}}[/RESET]. Continue?", targetNamespace.String()),
ptr.To(true), nil)
Expand All @@ -182,7 +182,7 @@ func (r *Push) Run(params PushParams) (rerr error) {
if !createProject {
return rationalize.ErrActionAborted
}
if kind == prompt.NonInteractive {
if !r.prompt.IsInteractive() {
r.out.Notice(locale.T("prompt_continue_non_interactive"))
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/runners/reset/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,14 @@ func (r *Reset) Run(params *Params) error {
r.out.Notice(locale.Tl("reset_commit", "Your project will be reset to [ACTIONABLE]{{.V0}}[/RESET]\n", commitID.String()))
if commitID != localCommitID {
defaultChoice := !r.prime.Prompt().IsInteractive()
confirm, kind, err := r.prime.Prompt().Confirm("", locale.Tl("reset_confim", "Resetting is destructive. You will lose any changes that were not pushed. Are you sure you want to do this?"), &defaultChoice, nil)
confirm, err := r.prime.Prompt().Confirm("", locale.Tl("reset_confim", "Resetting is destructive. You will lose any changes that were not pushed. Are you sure you want to do this?"), &defaultChoice, nil)
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !confirm {
return locale.NewInputError("err_reset_aborted", "Reset aborted by user")
}
if kind == prompt.NonInteractive {
if !r.prime.Prompt().IsInteractive() {
r.prime.Output().Notice(locale.T("prompt_continue_non_interactive"))
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/runners/revert/revert.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,14 @@ func (r *Revert) Run(params *Params) (rerr error) {
}

defaultChoice := !r.prime.Prompt().IsInteractive()
revert, kind, err := r.prime.Prompt().Confirm("", locale.Tl("revert_confirm", "Continue?"), &defaultChoice, nil)
revert, err := r.prime.Prompt().Confirm("", locale.Tl("revert_confirm", "Continue?"), &defaultChoice, nil)
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !revert {
return locale.NewInputError("err_revert_aborted", "Revert aborted by user")
}
if kind == prompt.NonInteractive {
if !r.prime.Prompt().IsInteractive() {
r.prime.Output().Notice(locale.T("prompt_continue_non_interactive"))
}

Expand Down
2 changes: 1 addition & 1 deletion internal/runners/scripts/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func startInteractive(sw *scriptWatcher, scriptName string, output output.Output
go sw.run(scriptName, output, cfg, proj)

for {
doneEditing, _, err := prompt.Confirm("", locale.T("prompt_done_editing"), ptr.To(true), nil)
doneEditing, err := prompt.Confirm("", locale.T("prompt_done_editing"), ptr.To(true), nil)
if err != nil {
return errs.Wrap(err, "Prompter returned with failure.")
}
Expand Down
4 changes: 2 additions & 2 deletions internal/runners/update/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ func confirmLock(prom prompt.Prompter, out output.Outputer) error {
defaultChoice := !prom.IsInteractive()
msg := locale.T("confirm_update_locked_version_prompt")

confirmed, kind, err := prom.Confirm(locale.T("confirm"), msg, &defaultChoice, nil)
confirmed, err := prom.Confirm(locale.T("confirm"), msg, &defaultChoice, nil)
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !confirmed {
return locale.NewInputError("err_update_lock_noconfirm", "Cancelling by your request.")
}
if kind == prompt.NonInteractive {
if !prom.IsInteractive() {
out.Notice(locale.T("prompt_continue_non_interactive"))
}

Expand Down
4 changes: 2 additions & 2 deletions internal/runners/update/unlock.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ func confirmUnlock(prom prompt.Prompter, out output.Outputer) error {
msg := locale.T("confirm_update_unlocked_version_prompt")

defaultChoice := !prom.IsInteractive()
confirmed, kind, err := prom.Confirm(locale.T("confirm"), msg, &defaultChoice, nil)
confirmed, err := prom.Confirm(locale.T("confirm"), msg, &defaultChoice, nil)
if err != nil {
return errs.Wrap(err, "Unable to confirm")
}
if !confirmed {
return locale.NewInputError("err_update_lock_noconfirm", "Cancelling by your request.")
}
if kind == prompt.NonInteractive {
if !prom.IsInteractive() {
out.Notice(locale.T("prompt_continue_non_interactive"))
}

Expand Down
Loading

0 comments on commit 1fdc129

Please sign in to comment.