Merge pull request #6738 from cli/default-repo-error

error instead of prompt for unset base repo
This commit is contained in:
Mislav Marohnić 2022-12-19 15:53:32 +01:00 committed by GitHub
commit 6d93849476
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 89 additions and 58 deletions

View file

@ -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) {

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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

View file

@ -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
}

View file

@ -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 {

View file

@ -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",

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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}

View file

@ -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}

View file

@ -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()

View file

@ -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

View file

@ -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