diff --git a/internal/iostreams/prompts.go b/internal/iostreams/prompts.go index 31922327..bfa93068 100644 --- a/internal/iostreams/prompts.go +++ b/internal/iostreams/prompts.go @@ -271,6 +271,8 @@ func errInteractivityFlags(cfg PromptConfig, message string, options []string) e } } remediation = fmt.Sprintf("Re-run with one of the `--%s` values shown above", flagName) + case len(flags) == 1 && isPasswordPrompt(cfg): + remediation = fmt.Sprintf("Run this command in an interactive terminal to enter the value with hidden input\nThe `--%s` flag also works, but can leave the value in shell history", flags[0].Name) case len(flags) == 1: remediation = fmt.Sprintf("Try running the command with the `--%s` flag included\nLearn more about this flag with `--help`", flags[0].Name) case len(flags) > 1: @@ -290,6 +292,13 @@ func errInteractivityFlags(cfg PromptConfig, message string, options []string) e WithRemediation("%s", remediation) } +// isPasswordPrompt reports whether the prompt collects a secret, such as a +// token or a password, that is safer typed than passed as a flag. +func isPasswordPrompt(cfg PromptConfig) bool { + _, ok := cfg.(PasswordPromptConfig) + return ok +} + // ConfirmPrompt prompts the user for a "yes" or "no" (true or false) value for // the message func (io *IOStreams) ConfirmPrompt(ctx context.Context, message string, cfg ConfirmPromptConfig) (bool, error) { diff --git a/internal/iostreams/prompts_test.go b/internal/iostreams/prompts_test.go index b7d1e282..07472933 100644 --- a/internal/iostreams/prompts_test.go +++ b/internal/iostreams/prompts_test.go @@ -194,10 +194,20 @@ func TestErrInteractivityFlags(t *testing.T) { contains: []string{"not a TTY"}, }, "one flag suggests the flag name": { + cfg: SelectPromptConfig{ + Flag: &pflag.Flag{Name: "team"}, + }, + contains: []string{"Try running the command with the `--team` flag included"}, + }, + "password flag suggests an interactive terminal first": { cfg: PasswordPromptConfig{ Flag: &pflag.Flag{Name: "token"}, }, - contains: []string{"--token"}, + contains: []string{ + "Run this command in an interactive terminal to enter the value with hidden input", + "The `--token` flag also works, but can leave the value in shell history", + }, + excludes: []string{"Try running the command with"}, }, "multiple flags lists all flag names": { cfg: SelectPromptConfig{Flags: []*pflag.Flag{