From f5d19b831e7537a67411ff37311d618846cd815c Mon Sep 17 00:00:00 2001 From: vilmibm Date: Thu, 15 Dec 2022 11:44:37 -0800 Subject: [PATCH] error instead of prompt when no base repo + fixes --- context/context.go | 45 +++++----------------- pkg/cmd/factory/default.go | 2 +- pkg/cmd/issue/shared/lookup.go | 2 +- pkg/cmd/pr/create/create.go | 4 +- pkg/cmd/pr/shared/finder.go | 2 +- pkg/cmd/repo/setdefault/setdefault.go | 39 +++++++++++++++---- pkg/cmd/repo/setdefault/setdefault_test.go | 37 +++++++++++++++++- pkg/cmd/secret/delete/delete.go | 2 +- pkg/cmd/secret/list/list.go | 2 +- pkg/cmd/secret/set/set.go | 2 +- pkg/cmd/workflow/disable/disable.go | 2 +- pkg/cmd/workflow/enable/enable.go | 2 +- pkg/cmd/workflow/list/list.go | 2 +- pkg/cmd/workflow/run/run.go | 2 +- pkg/cmd/workflow/view/view.go | 2 +- 15 files changed, 89 insertions(+), 58 deletions(-) diff --git a/context/context.go b/context/context.go index b5ed6dcbb..60a732a56 100644 --- a/context/context.go +++ b/context/context.go @@ -2,13 +2,11 @@ package context import ( - "context" "errors" + "fmt" "sort" - "strings" "github.com/cli/cli/v2/api" - "github.com/cli/cli/v2/git" "github.com/cli/cli/v2/internal/ghrepo" "github.com/cli/cli/v2/pkg/iostreams" ) @@ -59,11 +57,7 @@ type ResolvedRemotes struct { apiClient *api.Client } -type iprompter interface { - Select(string, string, []string) (int, error) -} - -func (r *ResolvedRemotes) BaseRepo(io *iostreams.IOStreams, p iprompter) (ghrepo.Interface, error) { +func (r *ResolvedRemotes) BaseRepo(io *iostreams.IOStreams) (ghrepo.Interface, error) { if r.baseOverride != nil { return r.baseOverride, nil } @@ -95,37 +89,16 @@ func (r *ResolvedRemotes) BaseRepo(io *iostreams.IOStreams, p iprompter) (ghrepo return r.remotes[0], nil } - var repoNames []string - for _, r := range repos { - repoNames = append(repoNames, ghrepo.FullName(r)) - } + cs := io.ColorScheme() - baseName := repoNames[0] - if len(repoNames) > 1 { - // hide the spinner in case a command started the progress indicator before base repo was fully - // resolved, e.g. in `gh issue view` - io.StopProgressIndicator() - selected, err := p.Select("Which should be the base repository (used for e.g. querying issues) for this directory?", "", repoNames) - if err != nil { - return nil, err - } - baseName = repoNames[selected] - } + fmt.Fprintf(io.ErrOut, + "%s No default remote repository has been set for this directory.\n", + cs.FailureIcon()) - // determine corresponding git remote - owner, repo, _ := strings.Cut(baseName, "/") - selectedRepo := ghrepo.New(owner, repo) - resolution := "base" - remote, _ := r.RemoteForRepo(selectedRepo) - if remote == nil { - remote = r.remotes[0] - resolution = ghrepo.FullName(selectedRepo) - } + fmt.Fprintln(io.Out) - // cache the result to git config - c := &git.Client{} - err = c.SetRemoteResolution(context.Background(), remote.Name, resolution) - return selectedRepo, err + return nil, errors.New( + "please run `gh repo set-default` to select a default remote repository.") } func (r *ResolvedRemotes) HeadRepos() ([]*api.Repository, error) { diff --git a/pkg/cmd/factory/default.go b/pkg/cmd/factory/default.go index 0113b0aad..c74815907 100644 --- a/pkg/cmd/factory/default.go +++ b/pkg/cmd/factory/default.go @@ -69,7 +69,7 @@ func SmartBaseRepoFunc(f *cmdutil.Factory) func() (ghrepo.Interface, error) { if err != nil { return nil, err } - baseRepo, err := repoContext.BaseRepo(f.IOStreams, f.Prompter) + baseRepo, err := repoContext.BaseRepo(f.IOStreams) if err != nil { return nil, err } diff --git a/pkg/cmd/issue/shared/lookup.go b/pkg/cmd/issue/shared/lookup.go index 3c38a3027..0b766292b 100644 --- a/pkg/cmd/issue/shared/lookup.go +++ b/pkg/cmd/issue/shared/lookup.go @@ -33,7 +33,7 @@ func IssueFromArgWithFields(httpClient *http.Client, baseRepoFn func() (ghrepo.I var err error baseRepo, err = baseRepoFn() if err != nil { - return nil, nil, fmt.Errorf("could not determine base repo: %w", err) + return nil, nil, err } } diff --git a/pkg/cmd/pr/create/create.go b/pkg/cmd/pr/create/create.go index 3c020d4a1..3248e485d 100644 --- a/pkg/cmd/pr/create/create.go +++ b/pkg/cmd/pr/create/create.go @@ -485,7 +485,7 @@ func NewCreateContext(opts *CreateOptions) (*CreateContext, error) { } var baseRepo *api.Repository - if br, err := repoContext.BaseRepo(opts.IO, opts.Prompter); err == nil { + if br, err := repoContext.BaseRepo(opts.IO); err == nil { if r, ok := br.(*api.Repository); ok { baseRepo = r } else { @@ -497,7 +497,7 @@ func NewCreateContext(opts *CreateOptions) (*CreateContext, error) { } } } else { - return nil, fmt.Errorf("could not determine base repository: %w", err) + return nil, err } isPushEnabled := false diff --git a/pkg/cmd/pr/shared/finder.go b/pkg/cmd/pr/shared/finder.go index ed04c4295..368134871 100644 --- a/pkg/cmd/pr/shared/finder.go +++ b/pkg/cmd/pr/shared/finder.go @@ -98,7 +98,7 @@ func (f *finder) Find(opts FindOptions) (*api.PullRequest, ghrepo.Interface, err if f.repo == nil { repo, err := f.baseRepoFn() if err != nil { - return nil, nil, fmt.Errorf("could not determine base repo: %w", err) + return nil, nil, err } f.repo = repo } diff --git a/pkg/cmd/repo/setdefault/setdefault.go b/pkg/cmd/repo/setdefault/setdefault.go index a86ca8960..0e25a2c25 100644 --- a/pkg/cmd/repo/setdefault/setdefault.go +++ b/pkg/cmd/repo/setdefault/setdefault.go @@ -44,8 +44,9 @@ type SetDefaultOptions struct { Prompter iprompter GitClient *git.Client - Repo ghrepo.Interface - ViewMode bool + Repo ghrepo.Interface + ViewMode bool + UnsetMode bool } func NewCmdSetDefault(f *cmdutil.Factory, runF func(*SetDefaultOptions) error) *cobra.Command { @@ -63,17 +64,17 @@ func NewCmdSetDefault(f *cmdutil.Factory, runF func(*SetDefaultOptions) error) * Long: explainer(), Example: heredoc.Doc(` Interactively select a default repository: - $ gh repo default + $ gh repo set-default Set a repository explicitly: - $ gh repo default owner/repo + $ gh repo set-default owner/repo View the current default repository: - $ gh repo default --view + $ gh repo set-default --view Show more repository options in the interactive picker: $ git remote add newrepo https://github.com/owner/repo - $ gh repo default + $ gh repo set-default `), Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -104,6 +105,7 @@ func NewCmdSetDefault(f *cmdutil.Factory, runF func(*SetDefaultOptions) error) * } cmd.Flags().BoolVarP(&opts.ViewMode, "view", "v", false, "view the current default repository") + cmd.Flags().BoolVarP(&opts.UnsetMode, "unset", "u", false, "unset the current default repository") return cmd } @@ -118,13 +120,35 @@ func setDefaultRun(opts *SetDefaultOptions) error { if opts.ViewMode { if currentDefaultRepo == nil { - fmt.Fprintln(opts.IO.Out, "no default repo has been set; use `gh repo default` to select one") + fmt.Fprintln(opts.IO.Out, "no default repository has been set; use `gh repo set-default` to select one") } else { fmt.Fprintln(opts.IO.Out, displayRemoteRepoName(currentDefaultRepo)) } return nil } + cs := opts.IO.ColorScheme() + + if opts.UnsetMode { + var msg string + if currentDefaultRepo != nil { + if err := opts.GitClient.UnsetRemoteResolution( + ctx.Background(), currentDefaultRepo.Name); err != nil { + return err + } + msg = fmt.Sprintf("%s Unset %s as default repository", + cs.SuccessIcon(), ghrepo.FullName(currentDefaultRepo)) + } else { + msg = "no default repository has been set" + } + + if opts.IO.IsStdoutTTY() { + fmt.Fprintln(opts.IO.Out, msg) + } + + return nil + } + httpClient, err := opts.HttpClient() if err != nil { return err @@ -157,7 +181,6 @@ func setDefaultRun(opts *SetDefaultOptions) error { return fmt.Errorf("%s does not correspond to any git remotes", ghrepo.FullName(opts.Repo)) } } - cs := opts.IO.ColorScheme() if selectedRepo == nil { if len(knownRepos) == 1 { diff --git a/pkg/cmd/repo/setdefault/setdefault_test.go b/pkg/cmd/repo/setdefault/setdefault_test.go index 707edf5b6..c90238548 100644 --- a/pkg/cmd/repo/setdefault/setdefault_test.go +++ b/pkg/cmd/repo/setdefault/setdefault_test.go @@ -57,6 +57,14 @@ func TestNewCmdSetDefault(t *testing.T) { input: "--view", output: SetDefaultOptions{ViewMode: true}, }, + { + name: "unset flag", + gitStubs: func(cs *run.CommandStubber) { + cs.Register(`git rev-parse --is-inside-work-tree`, 0, "true") + }, + input: "--unset", + output: SetDefaultOptions{UnsetMode: true}, + }, { name: "run from non-git directory", gitStubs: func(cs *run.CommandStubber) { @@ -126,6 +134,33 @@ func TestDefaultRun(t *testing.T) { wantErr bool errMsg string }{ + { + name: "unset mode with base resolved current default", + tty: true, + opts: SetDefaultOptions{UnsetMode: true}, + remotes: []*context.Remote{ + { + Remote: &git.Remote{Name: "origin", Resolved: "base"}, + Repo: repo1, + }, + }, + gitStubs: func(cs *run.CommandStubber) { + cs.Register(`git config --unset remote.origin.gh-resolved`, 0, "") + }, + wantStdout: "✓ Unset OWNER/REPO as default repository\n", + }, + { + name: "unset mode no current default", + tty: true, + opts: SetDefaultOptions{UnsetMode: true}, + remotes: []*context.Remote{ + { + Remote: &git.Remote{Name: "origin"}, + Repo: repo1, + }, + }, + wantStdout: "no default repository has been set\n", + }, { name: "view mode no current default", opts: SetDefaultOptions{ViewMode: true}, @@ -135,7 +170,7 @@ func TestDefaultRun(t *testing.T) { Repo: repo1, }, }, - wantStdout: "no default repo has been set; use `gh repo default` to select one\n", + wantStdout: "no default repository has been set; use `gh repo set-default` to select one\n", }, { name: "view mode with base resolved current default", diff --git a/pkg/cmd/secret/delete/delete.go b/pkg/cmd/secret/delete/delete.go index 4759dd1a2..fc75a490d 100644 --- a/pkg/cmd/secret/delete/delete.go +++ b/pkg/cmd/secret/delete/delete.go @@ -101,7 +101,7 @@ func removeRun(opts *DeleteOptions) error { if secretEntity == shared.Repository || secretEntity == shared.Environment { baseRepo, err = opts.BaseRepo() if err != nil { - return fmt.Errorf("could not determine base repo: %w", err) + return err } } diff --git a/pkg/cmd/secret/list/list.go b/pkg/cmd/secret/list/list.go index 4c1a1d01d..4844e8cc7 100644 --- a/pkg/cmd/secret/list/list.go +++ b/pkg/cmd/secret/list/list.go @@ -88,7 +88,7 @@ func listRun(opts *ListOptions) error { if orgName == "" && !opts.UserSecrets { baseRepo, err = opts.BaseRepo() if err != nil { - return fmt.Errorf("could not determine base repo: %w", err) + return err } } diff --git a/pkg/cmd/secret/set/set.go b/pkg/cmd/secret/set/set.go index d56b3d074..793d14cef 100644 --- a/pkg/cmd/secret/set/set.go +++ b/pkg/cmd/secret/set/set.go @@ -178,7 +178,7 @@ func setRun(opts *SetOptions) error { if orgName == "" && !opts.UserSecrets { baseRepo, err = opts.BaseRepo() if err != nil { - return fmt.Errorf("could not determine base repo: %w", err) + return err } host = baseRepo.RepoHost() } else { diff --git a/pkg/cmd/workflow/disable/disable.go b/pkg/cmd/workflow/disable/disable.go index 909ab6a39..ed3155fbd 100644 --- a/pkg/cmd/workflow/disable/disable.go +++ b/pkg/cmd/workflow/disable/disable.go @@ -64,7 +64,7 @@ func runDisable(opts *DisableOptions) error { repo, err := opts.BaseRepo() if err != nil { - return fmt.Errorf("could not determine base repo: %w", err) + return err } states := []shared.WorkflowState{shared.Active} diff --git a/pkg/cmd/workflow/enable/enable.go b/pkg/cmd/workflow/enable/enable.go index fe683209d..06922a46f 100644 --- a/pkg/cmd/workflow/enable/enable.go +++ b/pkg/cmd/workflow/enable/enable.go @@ -64,7 +64,7 @@ func runEnable(opts *EnableOptions) error { repo, err := opts.BaseRepo() if err != nil { - return fmt.Errorf("could not determine base repo: %w", err) + return err } states := []shared.WorkflowState{shared.DisabledManually, shared.DisabledInactivity} diff --git a/pkg/cmd/workflow/list/list.go b/pkg/cmd/workflow/list/list.go index a18ebd065..a080c4cf9 100644 --- a/pkg/cmd/workflow/list/list.go +++ b/pkg/cmd/workflow/list/list.go @@ -66,7 +66,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman func listRun(opts *ListOptions) error { repo, err := opts.BaseRepo() if err != nil { - return fmt.Errorf("could not determine base repo: %w", err) + return err } httpClient, err := opts.HttpClient() diff --git a/pkg/cmd/workflow/run/run.go b/pkg/cmd/workflow/run/run.go index 847683148..ca703027a 100644 --- a/pkg/cmd/workflow/run/run.go +++ b/pkg/cmd/workflow/run/run.go @@ -248,7 +248,7 @@ func runRun(opts *RunOptions) error { repo, err := opts.BaseRepo() if err != nil { - return fmt.Errorf("could not determine base repo: %w", err) + return err } ref := opts.Ref diff --git a/pkg/cmd/workflow/view/view.go b/pkg/cmd/workflow/view/view.go index 4dc4e7658..52a364be8 100644 --- a/pkg/cmd/workflow/view/view.go +++ b/pkg/cmd/workflow/view/view.go @@ -97,7 +97,7 @@ func runView(opts *ViewOptions) error { repo, err := opts.BaseRepo() if err != nil { - return fmt.Errorf("could not determine base repo: %w", err) + return err } var workflow *shared.Workflow