Skip to content

Commit ecffc29

Browse files
committed
Set prompt interactive and force modes immediately upon parsing flags.
Commands should not be responsible for setting these modes before invoking runners.
1 parent ee56104 commit ecffc29

11 files changed

Lines changed: 38 additions & 59 deletions

File tree

cmd/state/internal/cmdtree/clean.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,13 @@ func newCleanUninstallCommand(prime *primer.Values, globals *globalOptions) *cap
5353
return err
5454
}
5555

56-
if globals.NonInteractive {
57-
prime.Prompt().SetInteractive(false)
58-
}
59-
if globals.Force {
60-
prime.Prompt().SetForce(true)
61-
params.Force = true
62-
}
56+
params.Force = globals.Force
6357
return runner.Run(&params)
6458
},
6559
)
6660
}
6761

68-
func newCleanCacheCommand(prime *primer.Values, globals *globalOptions) *captain.Command {
62+
func newCleanCacheCommand(prime *primer.Values) *captain.Command {
6963
runner := clean.NewCache(prime)
7064
params := clean.CacheParams{}
7165
return captain.NewCommand(
@@ -83,9 +77,6 @@ func newCleanCacheCommand(prime *primer.Values, globals *globalOptions) *captain
8377
},
8478
},
8579
func(ccmd *captain.Command, _ []string) error {
86-
if globals.NonInteractive {
87-
prime.Prompt().SetInteractive(false)
88-
}
8980
return runner.Run(&params)
9081
},
9182
)
@@ -102,10 +93,7 @@ func newCleanConfigCommand(prime *primer.Values, globals *globalOptions) *captai
10293
[]*captain.Flag{},
10394
[]*captain.Argument{},
10495
func(ccmd *captain.Command, _ []string) error {
105-
if globals.Force {
106-
prime.Prompt().SetForce(true)
107-
params.Force = true
108-
}
96+
params.Force = globals.Force
10997
return runner.Run(&params)
11098
},
11199
)

cmd/state/internal/cmdtree/cmdtree.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func New(prime *primer.Values, args ...string) *CmdTree {
7979
cleanCmd := newCleanCommand(prime)
8080
cleanCmd.AddChildren(
8181
newCleanUninstallCommand(prime, globals),
82-
newCleanCacheCommand(prime, globals),
82+
newCleanCacheCommand(prime),
8383
newCleanConfigCommand(prime, globals),
8484
)
8585

@@ -95,7 +95,7 @@ func New(prime *primer.Values, args ...string) *CmdTree {
9595
eventsCmd := newEventsCommand(prime)
9696
eventsCmd.AddChildren(newEventsLogCommand(prime))
9797

98-
installCmd := newInstallCommand(prime, globals)
98+
installCmd := newInstallCommand(prime)
9999
uninstallCmd := newUninstallCommand(prime)
100100
importCmd := newImportCommand(prime, globals)
101101
searchCmd := newSearchCommand(prime)
@@ -137,8 +137,8 @@ func New(prime *primer.Values, args ...string) *CmdTree {
137137

138138
updateCmd := newUpdateCommand(prime)
139139
updateCmd.AddChildren(
140-
newUpdateLockCommand(prime, globals),
141-
newUpdateUnlockCommand(prime, globals))
140+
newUpdateLockCommand(prime),
141+
newUpdateUnlockCommand(prime))
142142

143143
branchCmd := newBranchCommand(prime)
144144
branchCmd.AddChildren(
@@ -157,7 +157,7 @@ func New(prime *primer.Values, args ...string) *CmdTree {
157157

158158
useCmd := newUseCommand(prime)
159159
useCmd.AddChildren(
160-
newUseResetCommand(prime, globals),
160+
newUseResetCommand(prime),
161161
newUseShowCommand(prime),
162162
)
163163

@@ -204,8 +204,8 @@ func New(prime *primer.Values, args ...string) *CmdTree {
204204
prepareCmd,
205205
newProtocolCommand(prime),
206206
newExecCommand(prime, args...),
207-
newRevertCommand(prime, globals),
208-
newResetCommand(prime, globals),
207+
newRevertCommand(prime),
208+
newResetCommand(prime),
209209
secretsCmd,
210210
branchCmd,
211211
newLearnCommand(prime),
@@ -302,12 +302,14 @@ func newStateCommand(globals *globalOptions, prime *primer.Values) *captain.Comm
302302
Description: locale.T("flag_state_non_interactive_description"),
303303
Shorthand: "n",
304304
Persist: true,
305+
OnUse: func() { prime.Prompt().SetInteractive(false) },
305306
Value: &globals.NonInteractive,
306307
},
307308
{
308309
Name: "force",
309310
Description: locale.T("flag_state_force_description"),
310311
Persist: true,
312+
OnUse: func() { prime.Prompt().SetForce(true) },
311313
Value: &globals.Force,
312314
},
313315
{
@@ -325,10 +327,6 @@ func newStateCommand(globals *globalOptions, prime *primer.Values) *captain.Comm
325327
},
326328
[]*captain.Argument{},
327329
func(ccmd *captain.Command, args []string) error {
328-
if globals.Verbose {
329-
logging.CurrentHandler().SetVerbose(true)
330-
}
331-
332330
return runner.Run(ccmd.Usage)
333331
},
334332
)

cmd/state/internal/cmdtree/packages.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func newPackagesCommand(prime *primer.Values) *captain.Command {
5050
return cmd
5151
}
5252

53-
func newInstallCommand(prime *primer.Values, globals *globalOptions) *captain.Command {
53+
func newInstallCommand(prime *primer.Values) *captain.Command {
5454
runner := install.New(prime, model.NamespacePackage)
5555

5656
params := install.Params{}
@@ -82,9 +82,6 @@ func newInstallCommand(prime *primer.Values, globals *globalOptions) *captain.Co
8282
return locale.WrapInputError(err, "err_install_packages_args", "Invalid install arguments")
8383
}
8484
}
85-
if globals.Force {
86-
prime.Prompt().SetForce(true)
87-
}
8885
return runner.Run(params)
8986
},
9087
)

cmd/state/internal/cmdtree/reset.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/ActiveState/cli/internal/runners/reset"
88
)
99

10-
func newResetCommand(prime *primer.Values, globals *globalOptions) *captain.Command {
10+
func newResetCommand(prime *primer.Values) *captain.Command {
1111
runner := reset.New(prime)
1212
params := &reset.Params{}
1313

@@ -25,9 +25,6 @@ func newResetCommand(prime *primer.Values, globals *globalOptions) *captain.Comm
2525
},
2626
},
2727
func(ccmd *captain.Command, args []string) error {
28-
if globals.NonInteractive {
29-
prime.Prompt().SetInteractive(false)
30-
}
3128
return runner.Run(params)
3229
},
3330
).SetGroup(VCSGroup).SetSupportsStructuredOutput()

cmd/state/internal/cmdtree/revert.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/ActiveState/cli/internal/runners/revert"
88
)
99

10-
func newRevertCommand(prime *primer.Values, globals *globalOptions) *captain.Command {
10+
func newRevertCommand(prime *primer.Values) *captain.Command {
1111
runner := revert.New(prime)
1212
params := &revert.Params{}
1313

@@ -32,9 +32,6 @@ func newRevertCommand(prime *primer.Values, globals *globalOptions) *captain.Com
3232
},
3333
},
3434
func(ccmd *captain.Command, args []string) error {
35-
if globals.NonInteractive {
36-
prime.Prompt().SetInteractive(false)
37-
}
3835
return runner.Run(params)
3936
},
4037
).SetGroup(VCSGroup).SetSupportsStructuredOutput()

cmd/state/internal/cmdtree/update.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func newUpdateCommand(prime *primer.Values) *captain.Command {
3434
return cmd
3535
}
3636

37-
func newUpdateLockCommand(prime *primer.Values, globals *globalOptions) *captain.Command {
37+
func newUpdateLockCommand(prime *primer.Values) *captain.Command {
3838
runner := update.NewLock(prime)
3939
params := update.LockParams{}
4040

@@ -52,9 +52,6 @@ func newUpdateLockCommand(prime *primer.Values, globals *globalOptions) *captain
5252
},
5353
[]*captain.Argument{},
5454
func(cmd *captain.Command, args []string) error {
55-
if globals.NonInteractive {
56-
prime.Prompt().SetInteractive(false)
57-
}
5855
return runner.Run(&params)
5956
},
6057
)
@@ -63,7 +60,7 @@ func newUpdateLockCommand(prime *primer.Values, globals *globalOptions) *captain
6360
return cmd
6461
}
6562

66-
func newUpdateUnlockCommand(prime *primer.Values, globals *globalOptions) *captain.Command {
63+
func newUpdateUnlockCommand(prime *primer.Values) *captain.Command {
6764
runner := update.NewUnlock(prime)
6865
params := update.UnlockParams{}
6966

@@ -75,9 +72,6 @@ func newUpdateUnlockCommand(prime *primer.Values, globals *globalOptions) *capta
7572
[]*captain.Flag{},
7673
[]*captain.Argument{},
7774
func(cmd *captain.Command, args []string) error {
78-
if globals.NonInteractive {
79-
prime.Prompt().SetInteractive(false)
80-
}
8175
return runner.Run(&params)
8276
},
8377
)

cmd/state/internal/cmdtree/use.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func newUseCommand(prime *primer.Values) *captain.Command {
3333
return cmd
3434
}
3535

36-
func newUseResetCommand(prime *primer.Values, globals *globalOptions) *captain.Command {
36+
func newUseResetCommand(prime *primer.Values) *captain.Command {
3737
params := &use.ResetParams{}
3838

3939
return captain.NewCommand(
@@ -44,9 +44,6 @@ func newUseResetCommand(prime *primer.Values, globals *globalOptions) *captain.C
4444
[]*captain.Flag{},
4545
[]*captain.Argument{},
4646
func(_ *captain.Command, _ []string) error {
47-
if globals.NonInteractive {
48-
prime.Prompt().SetInteractive(false)
49-
}
5047
return use.NewReset(prime).Run(params)
5148
},
5249
)

internal/captain/command.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,9 @@ func (c *Command) flagByName(name string, persistOnly bool) *Flag {
521521
return flag
522522
}
523523
}
524+
if c.parent != nil {
525+
return c.parent.flagByName(name, persistOnly)
526+
}
524527
return nil
525528
}
526529

internal/prompt/prompt.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type Prompter interface {
2828
IsInteractive() bool
2929
SetInteractive(bool)
3030
SetForce(bool)
31+
IsForced() bool
3132
}
3233

3334
// ValidatorFunc is a function pass to the Prompter to perform validation
@@ -80,6 +81,8 @@ const (
8081
)
8182

8283
// Input prompts the user for input. The user can specify available validation flags to trigger validation of responses
84+
// If the prompt is non-interactive, it returns defaultResponse.
85+
// If the prompt is forced, it returns forcedResponse if not nil, or defaultResponse.
8386
func (p *Prompt) Input(title, message string, defaultResponse *string, forcedResponse *string, flags ...ValidatorFlag) (string, error) {
8487
return p.InputAndValidate(title, message, defaultResponse, forcedResponse, func(val interface{}) error {
8588
return nil
@@ -98,6 +101,8 @@ func interactiveInputError(message string) error {
98101
}
99102

100103
// InputAndValidate prompts an input field and allows you to specfiy a custom validation function as well as the built in flags
104+
// If the prompt is non-interactive, it returns defaultResponse.
105+
// If the prompt is forced, it returns forcedResponse if not nil, or defaultResponse.
101106
func (p *Prompt) InputAndValidate(title, message string, defaultResponse *string, forcedResponse *string, validator ValidatorFunc, flags ...ValidatorFlag) (string, error) {
102107
if p.isForced {
103108
response := forcedResponse
@@ -154,7 +159,9 @@ func (p *Prompt) InputAndValidate(title, message string, defaultResponse *string
154159
return response, nil
155160
}
156161

157-
// Select prompts the user to select one entry from multiple choices
162+
// Select prompts the user to select one entry from multiple choices.
163+
// If the prompt is non-interactive, it returns defaultChoice.
164+
// If the prompt is forced, it returns forcedChoice if not nil, or defaultChoice.
158165
func (p *Prompt) Select(title, message string, choices []string, defaultChoice *string, forcedChoice *string) (string, error) {
159166
if p.isForced {
160167
choice := forcedChoice
@@ -199,6 +206,8 @@ func (p *Prompt) Select(title, message string, choices []string, defaultChoice *
199206
}
200207

201208
// Confirm prompts user for yes or no response.
209+
// If the prompt is non-interactive, it returns defaultChoice.
210+
// If the prompt is forced, it returns forcedChoice if not nil, or defaultChoice.
202211
func (p *Prompt) Confirm(title, message string, defaultChoice *bool, forcedChoice *bool) (bool, error) {
203212
if p.isForced {
204213
choice := forcedChoice
@@ -259,7 +268,7 @@ func translateConfirm(confirm bool) string {
259268
// InputSecret prompts the user for input and obfuscates the text in stdout.
260269
// Will fail if empty.
261270
func (p *Prompt) InputSecret(title, message string, flags ...ValidatorFlag) (string, error) {
262-
if !p.isInteractive {
271+
if !p.isInteractive || p.isForced {
263272
return "", interactiveInputError(message)
264273
}
265274
var response string

internal/runbits/auth/login.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,12 @@ var OpenURI = osutils.OpenURI
2929

3030
// Authenticate will prompt the user for authentication
3131
func Authenticate(cfg keypairs.Configurable, out output.Outputer, prompt prompt.Prompter, auth *authentication.Auth) error {
32-
return AuthenticateWithInput("", "", "", false, cfg, out, prompt, auth)
32+
return AuthenticateWithInput("", "", "", cfg, out, prompt, auth)
3333
}
3434

3535
// AuthenticateWithInput will prompt the user for authentication if the input doesn't already provide it
3636
func AuthenticateWithInput(
3737
username, password, totp string,
38-
nonInteractive bool,
3938
cfg keypairs.Configurable,
4039
out output.Outputer,
4140
prompt prompt.Prompter,
@@ -44,7 +43,7 @@ func AuthenticateWithInput(
4443
logging.Debug("Authenticating with input")
4544

4645
credentials := &mono_models.Credentials{Username: username, Password: password, Totp: totp}
47-
if err := ensureCredentials(credentials, prompt, nonInteractive); err != nil {
46+
if err := ensureCredentials(credentials, prompt); err != nil {
4847
return locale.WrapInputError(err, "login_cancelled")
4948
}
5049

@@ -133,10 +132,10 @@ func RequireAuthentication(message string, cfg keypairs.Configurable, out output
133132
return nil
134133
}
135134

136-
func ensureCredentials(credentials *mono_models.Credentials, prompter prompt.Prompter, nonInteractive bool) error {
135+
func ensureCredentials(credentials *mono_models.Credentials, prompter prompt.Prompter) error {
137136
var err error
138137
if credentials.Username == "" {
139-
if nonInteractive {
138+
if !prompter.IsInteractive() || prompter.IsForced() {
140139
return locale.NewInputError("err_auth_needinput")
141140
}
142141
credentials.Username, err = prompter.Input("", locale.T("username_prompt"), ptr.To(""), nil, prompt.InputRequired)
@@ -146,7 +145,7 @@ func ensureCredentials(credentials *mono_models.Credentials, prompter prompt.Pro
146145
}
147146

148147
if credentials.Password == "" {
149-
if nonInteractive {
148+
if !prompter.IsInteractive() || prompter.IsForced() {
150149
return locale.NewInputError("err_auth_needinput")
151150
}
152151
credentials.Password, err = prompter.InputSecret("", locale.T("password_prompt"), prompt.InputRequired)

0 commit comments

Comments
 (0)