diff --git a/context/context.go b/context/context.go index 60a732a56..dc6407a67 100644 --- a/context/context.go +++ b/context/context.go @@ -62,6 +62,10 @@ func (r *ResolvedRemotes) BaseRepo(io *iostreams.IOStreams) (ghrepo.Interface, e return r.baseOverride, nil } + if len(r.remotes) == 0 { + return nil, errors.New("no git remotes") + } + // if any of the remotes already has a resolution, respect that for _, r := range r.remotes { if r.Resolved == "base" { @@ -87,6 +91,8 @@ func (r *ResolvedRemotes) BaseRepo(io *iostreams.IOStreams) (ghrepo.Interface, e if len(repos) == 0 { return r.remotes[0], nil + } else if len(repos) == 1 { + return repos[0], nil } cs := io.ColorScheme() diff --git a/pkg/cmd/factory/default_test.go b/pkg/cmd/factory/default_test.go index 2ba35b427..f9b316bce 100644 --- a/pkg/cmd/factory/default_test.go +++ b/pkg/cmd/factory/default_test.go @@ -10,6 +10,7 @@ import ( "github.com/cli/cli/v2/git" "github.com/cli/cli/v2/internal/config" "github.com/cli/cli/v2/pkg/cmdutil" + "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -115,6 +116,8 @@ func Test_SmartBaseRepo(t *testing.T) { wantsName string wantsOwner string wantsHost string + tty bool + httpStubs func(*httpmock.Registry) }{ { name: "override with matching remote", @@ -160,6 +163,43 @@ func Test_SmartBaseRepo(t *testing.T) { override: "test.com", wantsErr: true, }, + + { + name: "only one remote", + remotes: git.RemoteSet{ + git.NewRemote("origin", "https://github.com/owner/repo.git"), + }, + wantsName: "repo", + wantsOwner: "owner", + wantsHost: "github.com", + tty: true, + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL("RepositoryNetwork"), + httpmock.StringResponse(` + { + "data": { + "viewer": { + "login": "someone" + }, + "repo_000": { + "id": "MDEwOlJlcG9zaXRvcnkxMDM3MjM2Mjc=", + "name": "repo", + "owner": { + "login": "owner" + }, + "viewerPermission": "READ", + "defaultBranchRef": { + "name": "master" + }, + "isPrivate": false, + "parent": null + } + } + } + `)) + }, + }, } for _, tt := range tests { @@ -171,6 +211,9 @@ func Test_SmartBaseRepo(t *testing.T) { }, getConfig: func() (config.Config, error) { cfg := &config.ConfigMock{} + cfg.AuthTokenFunc = func(_ string) (string, string) { + return "", "" + } cfg.HostsFunc = func() []string { hosts := []string{"nonsense.com"} if tt.override != "" { @@ -187,7 +230,16 @@ func Test_SmartBaseRepo(t *testing.T) { return cfg, nil }, } - f.HttpClient = func() (*http.Client, error) { return nil, nil } + reg := &httpmock.Registry{} + defer reg.Verify(t) + ios, _, _, _ := iostreams.Test() + ios.SetStdinTTY(tt.tty) + ios.SetStdoutTTY(tt.tty) + if tt.httpStubs != nil { + tt.httpStubs(reg) + } + f.IOStreams = ios + f.HttpClient = func() (*http.Client, error) { return &http.Client{Transport: reg}, nil } f.Remotes = rr.Resolver() f.BaseRepo = SmartBaseRepoFunc(f) repo, err := f.BaseRepo()