X Tutup
Skip to content

Commit 1f90579

Browse files
committed
Extract common interface for a GitHub Repository
Also define a handful of utility methods: - `New(owner, repo)` - `FullName`: the name slash owner pair - `FromFullName`: parse the name slash owner pair - `FromURL`: parse a GitHub.com URL - `IsSame(r1, r2)`: compare two repositories
1 parent 6799e7f commit 1f90579

File tree

13 files changed

+187
-193
lines changed

13 files changed

+187
-193
lines changed

api/queries_issue.go

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package api
22

33
import (
44
"fmt"
5+
6+
"github.com/github/gh-cli/internal/ghrepo"
57
)
68

79
type IssuesPayload struct {
@@ -88,7 +90,7 @@ func IssueCreate(client *Client, repo *Repository, params map[string]interface{}
8890
return &result.CreateIssue.Issue, nil
8991
}
9092

91-
func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPayload, error) {
93+
func IssueStatus(client *Client, repo ghrepo.Interface, currentUsername string) (*IssuesPayload, error) {
9294
type response struct {
9395
Repository struct {
9496
Assigned struct {
@@ -132,11 +134,9 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
132134
}
133135
}`
134136

135-
owner := ghRepo.RepoOwner()
136-
repo := ghRepo.RepoName()
137137
variables := map[string]interface{}{
138-
"owner": owner,
139-
"repo": repo,
138+
"owner": repo.RepoOwner(),
139+
"repo": repo.RepoName(),
140140
"viewer": currentUsername,
141141
}
142142

@@ -147,7 +147,7 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
147147
}
148148

149149
if !resp.Repository.HasIssuesEnabled {
150-
return nil, fmt.Errorf("the '%s/%s' repository has disabled issues", owner, repo)
150+
return nil, fmt.Errorf("the '%s' repository has disabled issues", ghrepo.FullName(repo))
151151
}
152152

153153
payload := IssuesPayload{
@@ -168,7 +168,7 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
168168
return &payload, nil
169169
}
170170

171-
func IssueList(client *Client, ghRepo Repo, state string, labels []string, assigneeString string, limit int) ([]Issue, error) {
171+
func IssueList(client *Client, repo ghrepo.Interface, state string, labels []string, assigneeString string, limit int) ([]Issue, error) {
172172
var states []string
173173
switch state {
174174
case "open", "":
@@ -194,12 +194,10 @@ func IssueList(client *Client, ghRepo Repo, state string, labels []string, assig
194194
}
195195
`
196196

197-
owner := ghRepo.RepoOwner()
198-
repo := ghRepo.RepoName()
199197
variables := map[string]interface{}{
200198
"limit": limit,
201-
"owner": owner,
202-
"repo": repo,
199+
"owner": repo.RepoOwner(),
200+
"repo": repo.RepoName(),
203201
"states": states,
204202
}
205203
if len(labels) > 0 {
@@ -224,13 +222,13 @@ func IssueList(client *Client, ghRepo Repo, state string, labels []string, assig
224222
}
225223

226224
if !resp.Repository.HasIssuesEnabled {
227-
return nil, fmt.Errorf("the '%s/%s' repository has disabled issues", owner, repo)
225+
return nil, fmt.Errorf("the '%s' repository has disabled issues", ghrepo.FullName(repo))
228226
}
229227

230228
return resp.Repository.Issues.Nodes, nil
231229
}
232230

233-
func IssueByNumber(client *Client, ghRepo Repo, number int) (*Issue, error) {
231+
func IssueByNumber(client *Client, repo ghrepo.Interface, number int) (*Issue, error) {
234232
type response struct {
235233
Repository struct {
236234
Issue Issue
@@ -261,8 +259,8 @@ func IssueByNumber(client *Client, ghRepo Repo, number int) (*Issue, error) {
261259
}`
262260

263261
variables := map[string]interface{}{
264-
"owner": ghRepo.RepoOwner(),
265-
"repo": ghRepo.RepoName(),
262+
"owner": repo.RepoOwner(),
263+
"repo": repo.RepoName(),
266264
"issue_number": number,
267265
}
268266

api/queries_pr.go

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package api
33
import (
44
"fmt"
55
"strings"
6+
7+
"github.com/github/gh-cli/internal/ghrepo"
68
)
79

810
type PullRequestsPayload struct {
@@ -127,12 +129,7 @@ func (pr *PullRequest) ChecksStatus() (summary PullRequestChecksStatus) {
127129
return
128130
}
129131

130-
type Repo interface {
131-
RepoName() string
132-
RepoOwner() string
133-
}
134-
135-
func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHeadRef, currentUsername string) (*PullRequestsPayload, error) {
132+
func PullRequests(client *Client, repo ghrepo.Interface, currentPRNumber int, currentPRHeadRef, currentUsername string) (*PullRequestsPayload, error) {
136133
type edges struct {
137134
TotalCount int
138135
Edges []struct {
@@ -229,11 +226,8 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea
229226
}
230227
`
231228

232-
owner := ghRepo.RepoOwner()
233-
repo := ghRepo.RepoName()
234-
235-
viewerQuery := fmt.Sprintf("repo:%s/%s state:open is:pr author:%s", owner, repo, currentUsername)
236-
reviewerQuery := fmt.Sprintf("repo:%s/%s state:open review-requested:%s", owner, repo, currentUsername)
229+
viewerQuery := fmt.Sprintf("repo:%s state:open is:pr author:%s", ghrepo.FullName(repo), currentUsername)
230+
reviewerQuery := fmt.Sprintf("repo:%s state:open review-requested:%s", ghrepo.FullName(repo), currentUsername)
237231

238232
branchWithoutOwner := currentPRHeadRef
239233
if idx := strings.Index(currentPRHeadRef, ":"); idx >= 0 {
@@ -243,8 +237,8 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea
243237
variables := map[string]interface{}{
244238
"viewerQuery": viewerQuery,
245239
"reviewerQuery": reviewerQuery,
246-
"owner": owner,
247-
"repo": repo,
240+
"owner": repo.RepoOwner(),
241+
"repo": repo.RepoName(),
248242
"headRefName": branchWithoutOwner,
249243
"number": currentPRNumber,
250244
}
@@ -289,7 +283,7 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea
289283
return &payload, nil
290284
}
291285

292-
func PullRequestByNumber(client *Client, ghRepo Repo, number int) (*PullRequest, error) {
286+
func PullRequestByNumber(client *Client, repo ghrepo.Interface, number int) (*PullRequest, error) {
293287
type response struct {
294288
Repository struct {
295289
PullRequest PullRequest
@@ -328,8 +322,8 @@ func PullRequestByNumber(client *Client, ghRepo Repo, number int) (*PullRequest,
328322
}`
329323

330324
variables := map[string]interface{}{
331-
"owner": ghRepo.RepoOwner(),
332-
"repo": ghRepo.RepoName(),
325+
"owner": repo.RepoOwner(),
326+
"repo": repo.RepoName(),
333327
"pr_number": number,
334328
}
335329

@@ -342,7 +336,7 @@ func PullRequestByNumber(client *Client, ghRepo Repo, number int) (*PullRequest,
342336
return &resp.Repository.PullRequest, nil
343337
}
344338

345-
func PullRequestForBranch(client *Client, ghRepo Repo, branch string) (*PullRequest, error) {
339+
func PullRequestForBranch(client *Client, repo ghrepo.Interface, branch string) (*PullRequest, error) {
346340
type response struct {
347341
Repository struct {
348342
PullRequests struct {
@@ -383,8 +377,8 @@ func PullRequestForBranch(client *Client, ghRepo Repo, branch string) (*PullRequ
383377
}
384378

385379
variables := map[string]interface{}{
386-
"owner": ghRepo.RepoOwner(),
387-
"repo": ghRepo.RepoName(),
380+
"owner": repo.RepoOwner(),
381+
"repo": repo.RepoName(),
388382
"headRefName": branchWithoutOwner,
389383
}
390384

api/queries_repo.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"sort"
88
"strings"
99

10+
"github.com/github/gh-cli/internal/ghrepo"
1011
"github.com/pkg/errors"
1112
)
1213

@@ -60,10 +61,7 @@ func (r Repository) ViewerCanPush() bool {
6061
}
6162

6263
// GitHubRepo looks up the node ID of a named repository
63-
func GitHubRepo(client *Client, ghRepo Repo) (*Repository, error) {
64-
owner := ghRepo.RepoOwner()
65-
repo := ghRepo.RepoName()
66-
64+
func GitHubRepo(client *Client, repo ghrepo.Interface) (*Repository, error) {
6765
query := `
6866
query($owner: String!, $name: String!) {
6967
repository(owner: $owner, name: $name) {
@@ -72,8 +70,8 @@ func GitHubRepo(client *Client, ghRepo Repo) (*Repository, error) {
7270
}
7371
}`
7472
variables := map[string]interface{}{
75-
"owner": owner,
76-
"name": repo,
73+
"owner": repo.RepoOwner(),
74+
"name": repo.RepoName(),
7775
}
7876

7977
result := struct {
@@ -82,7 +80,7 @@ func GitHubRepo(client *Client, ghRepo Repo) (*Repository, error) {
8280
err := client.GraphQL(query, variables, &result)
8381

8482
if err != nil || result.Repository.ID == "" {
85-
newErr := fmt.Errorf("failed to determine repository ID for '%s/%s'", owner, repo)
83+
newErr := fmt.Errorf("failed to determine repository ID for '%s'", ghrepo.FullName(repo))
8684
if err != nil {
8785
newErr = errors.Wrap(err, newErr.Error())
8886
}
@@ -99,7 +97,7 @@ type RepoNetworkResult struct {
9997
}
10098

10199
// RepoNetwork inspects the relationship between multiple GitHub repositories
102-
func RepoNetwork(client *Client, repos []Repo) (RepoNetworkResult, error) {
100+
func RepoNetwork(client *Client, repos []ghrepo.Interface) (RepoNetworkResult, error) {
103101
queries := []string{}
104102
for i, repo := range repos {
105103
queries = append(queries, fmt.Sprintf(`
@@ -201,8 +199,8 @@ type repositoryV3 struct {
201199
}
202200

203201
// ForkRepo forks the repository on GitHub and returns the new repository
204-
func ForkRepo(client *Client, repo Repo) (*Repository, error) {
205-
path := fmt.Sprintf("repos/%s/%s/forks", repo.RepoOwner(), repo.RepoName())
202+
func ForkRepo(client *Client, repo ghrepo.Interface) (*Repository, error) {
203+
path := fmt.Sprintf("repos/%s/forks", ghrepo.FullName(repo))
206204
body := bytes.NewBufferString(`{}`)
207205
result := repositoryV3{}
208206
err := client.REST("POST", path, body, &result)

command/issue.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99
"strings"
1010

1111
"github.com/github/gh-cli/api"
12-
"github.com/github/gh-cli/context"
1312
"github.com/github/gh-cli/git"
13+
"github.com/github/gh-cli/internal/ghrepo"
1414
"github.com/github/gh-cli/pkg/githubtemplate"
1515
"github.com/github/gh-cli/utils"
1616
"github.com/pkg/errors"
@@ -107,7 +107,7 @@ func issueList(cmd *cobra.Command, args []string) error {
107107
return err
108108
}
109109

110-
fmt.Fprintf(colorableErr(cmd), "\nIssues for %s/%s\n\n", baseRepo.RepoOwner(), baseRepo.RepoName())
110+
fmt.Fprintf(colorableErr(cmd), "\nIssues for %s\n\n", ghrepo.FullName(baseRepo))
111111

112112
issues, err := api.IssueList(apiClient, baseRepo, state, labels, assignee, limit)
113113
if err != nil {
@@ -257,7 +257,7 @@ func printIssuePreview(out io.Writer, issue *api.Issue) {
257257

258258
var issueURLRE = regexp.MustCompile(`^https://github\.com/([^/]+)/([^/]+)/issues/(\d+)`)
259259

260-
func issueFromArg(apiClient *api.Client, baseRepo context.GitHubRepository, arg string) (*api.Issue, error) {
260+
func issueFromArg(apiClient *api.Client, baseRepo ghrepo.Interface, arg string) (*api.Issue, error) {
261261
if issueNumber, err := strconv.Atoi(arg); err == nil {
262262
return api.IssueByNumber(apiClient, baseRepo, issueNumber)
263263
}
@@ -278,7 +278,7 @@ func issueCreate(cmd *cobra.Command, args []string) error {
278278
return err
279279
}
280280

281-
fmt.Fprintf(colorableErr(cmd), "\nCreating issue in %s/%s\n\n", baseRepo.RepoOwner(), baseRepo.RepoName())
281+
fmt.Fprintf(colorableErr(cmd), "\nCreating issue in %s\n\n", ghrepo.FullName(baseRepo))
282282

283283
var templateFiles []string
284284
if rootDir, err := git.ToplevelDir(); err == nil {
@@ -288,7 +288,7 @@ func issueCreate(cmd *cobra.Command, args []string) error {
288288

289289
if isWeb, err := cmd.Flags().GetBool("web"); err == nil && isWeb {
290290
// TODO: move URL generation into GitHubRepository
291-
openURL := fmt.Sprintf("https://github.com/%s/%s/issues/new", baseRepo.RepoOwner(), baseRepo.RepoName())
291+
openURL := fmt.Sprintf("https://github.com/%s/issues/new", ghrepo.FullName(baseRepo))
292292
if len(templateFiles) > 1 {
293293
openURL += "/choose"
294294
}
@@ -306,7 +306,7 @@ func issueCreate(cmd *cobra.Command, args []string) error {
306306
return err
307307
}
308308
if !repo.HasIssuesEnabled {
309-
return fmt.Errorf("the '%s/%s' repository has disabled issues", baseRepo.RepoOwner(), baseRepo.RepoName())
309+
return fmt.Errorf("the '%s' repository has disabled issues", ghrepo.FullName(baseRepo))
310310
}
311311

312312
action := SubmitAction
@@ -346,9 +346,8 @@ func issueCreate(cmd *cobra.Command, args []string) error {
346346

347347
if action == PreviewAction {
348348
openURL := fmt.Sprintf(
349-
"https://github.com/%s/%s/issues/new/?title=%s&body=%s",
350-
baseRepo.RepoOwner(),
351-
baseRepo.RepoName(),
349+
"https://github.com/%s/issues/new/?title=%s&body=%s",
350+
ghrepo.FullName(baseRepo),
352351
url.QueryEscape(title),
353352
url.QueryEscape(body),
354353
)

command/pr.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/github/gh-cli/api"
1414
"github.com/github/gh-cli/context"
1515
"github.com/github/gh-cli/git"
16+
"github.com/github/gh-cli/internal/ghrepo"
1617
"github.com/github/gh-cli/utils"
1718
"github.com/spf13/cobra"
1819
"github.com/spf13/pflag"
@@ -139,7 +140,7 @@ func prList(cmd *cobra.Command, args []string) error {
139140
return err
140141
}
141142

142-
fmt.Fprintf(colorableErr(cmd), "\nPull requests for %s/%s\n\n", baseRepo.RepoOwner(), baseRepo.RepoName())
143+
fmt.Fprintf(colorableErr(cmd), "\nPull requests for %s\n\n", ghrepo.FullName(baseRepo))
143144

144145
limit, err := cmd.Flags().GetInt("limit")
145146
if err != nil {
@@ -275,7 +276,7 @@ func prView(cmd *cobra.Command, args []string) error {
275276
}
276277

277278
if prNumber > 0 {
278-
openURL = fmt.Sprintf("https://github.com/%s/%s/pull/%d", baseRepo.RepoOwner(), baseRepo.RepoName(), prNumber)
279+
openURL = fmt.Sprintf("https://github.com/%s/pull/%d", ghrepo.FullName(baseRepo), prNumber)
279280
if preview {
280281
pr, err = api.PullRequestByNumber(apiClient, baseRepo, prNumber)
281282
if err != nil {
@@ -323,7 +324,7 @@ func printPrPreview(out io.Writer, pr *api.PullRequest) {
323324

324325
var prURLRE = regexp.MustCompile(`^https://github\.com/([^/]+)/([^/]+)/pull/(\d+)`)
325326

326-
func prFromArg(apiClient *api.Client, baseRepo context.GitHubRepository, arg string) (*api.PullRequest, error) {
327+
func prFromArg(apiClient *api.Client, baseRepo ghrepo.Interface, arg string) (*api.PullRequest, error) {
327328
if prNumber, err := strconv.Atoi(arg); err == nil {
328329
return api.PullRequestByNumber(apiClient, baseRepo, prNumber)
329330
}
@@ -357,7 +358,7 @@ func prSelectorForCurrentBranch(ctx context.Context) (prNumber int, prHeadRef st
357358
var branchOwner string
358359
if branchConfig.RemoteURL != nil {
359360
// the branch merges from a remote specified by URL
360-
if r, err := context.RepoFromURL(branchConfig.RemoteURL); err == nil {
361+
if r, err := ghrepo.FromURL(branchConfig.RemoteURL); err == nil {
361362
branchOwner = r.RepoOwner()
362363
}
363364
} else if branchConfig.RemoteName != "" {

0 commit comments

Comments
 (0)
X Tutup