Print informative message before prompting for secret repo

This commit is contained in:
William Martin 2025-01-15 14:22:43 +01:00
parent a47327aee6
commit b382b24728
5 changed files with 24 additions and 9 deletions

View file

@ -56,7 +56,7 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
// But if we are able to prompt, then we will wrap that up in a BaseRepoFunc that can prompt the user to
// resolve the ambiguity.
if opts.IO.CanPrompt() {
opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.Prompter)
opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.IOStreams, f.Prompter)
}
}

View file

@ -77,7 +77,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
// But if we are able to prompt, then we will wrap that up in a BaseRepoFunc that can prompt the user to
// resolve the ambiguity.
if opts.IO.CanPrompt() {
opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.Prompter)
opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.IOStreams, f.Prompter)
}
}

View file

@ -114,7 +114,7 @@ func NewCmdSet(f *cmdutil.Factory, runF func(*SetOptions) error) *cobra.Command
// But if we are able to prompt, then we will wrap that up in a BaseRepoFunc that can prompt the user to
// resolve the ambiguity.
if opts.IO.CanPrompt() {
opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.Prompter)
opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.IOStreams, f.Prompter)
}
}

View file

@ -2,10 +2,12 @@ package shared
import (
"errors"
"fmt"
ghContext "github.com/cli/cli/v2/context"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/internal/prompter"
"github.com/cli/cli/v2/pkg/iostreams"
)
type AmbiguousBaseRepoError struct {
@ -19,7 +21,7 @@ func (e AmbiguousBaseRepoError) Error() string {
type baseRepoFn func() (ghrepo.Interface, error)
type remotesFn func() (ghContext.Remotes, error)
func PromptWhenAmbiguousBaseRepoFunc(baseRepoFn baseRepoFn, prompter prompter.Prompter) baseRepoFn {
func PromptWhenAmbiguousBaseRepoFunc(baseRepoFn baseRepoFn, ios *iostreams.IOStreams, prompter prompter.Prompter) baseRepoFn {
return func() (ghrepo.Interface, error) {
baseRepo, err := baseRepoFn()
if err != nil {
@ -33,6 +35,7 @@ func PromptWhenAmbiguousBaseRepoFunc(baseRepoFn baseRepoFn, prompter prompter.Pr
baseRepoOptions[i] = ghrepo.FullName(remote)
}
fmt.Fprintf(ios.Out, "%s Multiple remotes detected. Due to the sensitive nature of secrets, requiring disambiguation.\n", ios.ColorScheme().WarningIcon())
selectedBaseRepo, err := prompter.Select("Select a base repo", baseRepoOptions[0], baseRepoOptions)
if err != nil {
return nil, err

View file

@ -6,6 +6,7 @@ import (
ghContext "github.com/cli/cli/v2/context"
"github.com/cli/cli/v2/pkg/cmd/secret/shared"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/stretchr/testify/require"
"github.com/cli/cli/v2/git"
@ -91,8 +92,10 @@ func TestPromptWhenMultipleRemotesBaseRepoFunc(t *testing.T) {
t.Run("when there is no error from wrapped base repo func, then it succeeds without prompting", func(t *testing.T) {
t.Parallel()
ios, _, _, _ := iostreams.Test()
// Given the base repo function succeeds
baseRepoFn := shared.PromptWhenAmbiguousBaseRepoFunc(baseRepoStubFn, nil)
baseRepoFn := shared.PromptWhenAmbiguousBaseRepoFunc(baseRepoStubFn, ios, nil)
// When fetching the base repo
baseRepo, err := baseRepoFn()
@ -105,6 +108,8 @@ func TestPromptWhenMultipleRemotesBaseRepoFunc(t *testing.T) {
t.Run("when the wrapped base repo func returns a specific error, then the prompter is used for disambiguation, with the remote ordering remaining unchanged", func(t *testing.T) {
t.Parallel()
ios, _, stdout, _ := iostreams.Test()
pm := prompter.NewMockPrompter(t)
pm.RegisterSelect(
"Select a base repo",
@ -116,12 +121,15 @@ func TestPromptWhenMultipleRemotesBaseRepoFunc(t *testing.T) {
)
// Given the wrapped base repo func returns a specific error
baseRepoFn := shared.PromptWhenAmbiguousBaseRepoFunc(errMultipleRemotesStubFn, pm)
baseRepoFn := shared.PromptWhenAmbiguousBaseRepoFunc(errMultipleRemotesStubFn, ios, pm)
// When fetching the base repo
baseRepo, err := baseRepoFn()
// It uses the prompter for disambiguation
// It prints an informative message
require.Equal(t, "! Multiple remotes detected. Due to the sensitive nature of secrets, requiring disambiguation.\n", stdout.String())
// And it uses the prompter for disambiguation
require.NoError(t, err)
require.True(t, ghrepo.IsSame(ghrepo.New("owner", "repo"), baseRepo))
})
@ -129,6 +137,8 @@ func TestPromptWhenMultipleRemotesBaseRepoFunc(t *testing.T) {
t.Run("when the prompter returns an error, then it is returned", func(t *testing.T) {
t.Parallel()
ios, _, _, _ := iostreams.Test()
// Given the prompter returns an error
pm := prompter.NewMockPrompter(t)
pm.RegisterSelect(
@ -140,7 +150,7 @@ func TestPromptWhenMultipleRemotesBaseRepoFunc(t *testing.T) {
)
// Given the wrapped base repo func returns a specific error
baseRepoFn := shared.PromptWhenAmbiguousBaseRepoFunc(errMultipleRemotesStubFn, pm)
baseRepoFn := shared.PromptWhenAmbiguousBaseRepoFunc(errMultipleRemotesStubFn, ios, pm)
// When fetching the base repo
_, err := baseRepoFn()
@ -152,8 +162,10 @@ func TestPromptWhenMultipleRemotesBaseRepoFunc(t *testing.T) {
t.Run("when the wrapped base repo func returns a non-specific error, then it is returned", func(t *testing.T) {
t.Parallel()
ios, _, _, _ := iostreams.Test()
// Given the wrapped base repo func returns a non-specific error
baseRepoFn := shared.PromptWhenAmbiguousBaseRepoFunc(errBaseRepoStubFn, nil)
baseRepoFn := shared.PromptWhenAmbiguousBaseRepoFunc(errBaseRepoStubFn, ios, nil)
// When fetching the base repo
_, err := baseRepoFn()