X Tutup
Skip to content

Commit 1fa763f

Browse files
committed
Avoid having to first query for username in repo list
Dynamically construct the GraphQL query by using the `viewer` connection if the owner isn't set and the `repositoryOwner(login:"...")` connection if the owner was set.
1 parent 4da0261 commit 1fa763f

File tree

4 files changed

+42
-48
lines changed

4 files changed

+42
-48
lines changed

pkg/cmd/repo/list/fixtures/repoList.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"data": {
33
"repositoryOwner": {
4+
"login": "octocat",
45
"repositories": {
56
"totalCount": 3,
67
"nodes": [

pkg/cmd/repo/list/http.go

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package list
33
import (
44
"context"
55
"net/http"
6+
"reflect"
67
"strings"
78
"time"
89

@@ -39,31 +40,18 @@ func (r Repository) Info() string {
3940
}
4041

4142
type RepositoryList struct {
43+
Owner string
4244
Repositories []Repository
4345
TotalCount int
4446
}
4547

4648
func listRepos(client *http.Client, hostname string, limit int, owner string, filter FilterOptions) (*RepositoryList, error) {
47-
type query struct {
48-
RepositoryOwner struct {
49-
Repositories struct {
50-
Nodes []Repository
51-
TotalCount int
52-
PageInfo struct {
53-
HasNextPage bool
54-
EndCursor string
55-
}
56-
} `graphql:"repositories(first: $perPage, after: $endCursor, privacy: $privacy, isFork: $fork, ownerAffiliations: OWNER, orderBy: { field: PUSHED_AT, direction: DESC })"`
57-
} `graphql:"repositoryOwner(login: $owner)"`
58-
}
59-
6049
perPage := limit
6150
if perPage > 100 {
6251
perPage = 100
6352
}
6453

6554
variables := map[string]interface{}{
66-
"owner": githubv4.String(owner),
6755
"perPage": githubv4.Int(perPage),
6856
"endCursor": (*githubv4.String)(nil),
6957
}
@@ -82,28 +70,58 @@ func listRepos(client *http.Client, hostname string, limit int, owner string, fi
8270
variables["fork"] = (*githubv4.Boolean)(nil)
8371
}
8472

73+
var ownerConnection string
74+
if owner == "" {
75+
ownerConnection = `graphql:"repositoryOwner: viewer"`
76+
} else {
77+
ownerConnection = `graphql:"repositoryOwner(login: $owner)"`
78+
variables["owner"] = githubv4.String(owner)
79+
}
80+
81+
type repositoryOwner struct {
82+
Login string
83+
Repositories struct {
84+
Nodes []Repository
85+
TotalCount int
86+
PageInfo struct {
87+
HasNextPage bool
88+
EndCursor string
89+
}
90+
} `graphql:"repositories(first: $perPage, after: $endCursor, privacy: $privacy, isFork: $fork, ownerAffiliations: OWNER, orderBy: { field: PUSHED_AT, direction: DESC })"`
91+
}
92+
query := reflect.StructOf([]reflect.StructField{
93+
{
94+
Name: "RepositoryOwner",
95+
Type: reflect.TypeOf(repositoryOwner{}),
96+
Tag: reflect.StructTag(ownerConnection),
97+
},
98+
})
99+
85100
listResult := RepositoryList{}
86101
pagination:
87102
for {
88-
var result query
103+
result := reflect.New(query)
89104
gql := graphql.NewClient(ghinstance.GraphQLEndpoint(hostname), client)
90-
err := gql.QueryNamed(context.Background(), "RepositoryList", &result, variables)
105+
err := gql.QueryNamed(context.Background(), "RepositoryList", result.Interface(), variables)
91106
if err != nil {
92107
return nil, err
93108
}
94109

95-
listResult.TotalCount = result.RepositoryOwner.Repositories.TotalCount
96-
for _, repo := range result.RepositoryOwner.Repositories.Nodes {
110+
owner := result.Elem().FieldByName("RepositoryOwner").Interface().(repositoryOwner)
111+
listResult.TotalCount = owner.Repositories.TotalCount
112+
listResult.Owner = owner.Login
113+
114+
for _, repo := range owner.Repositories.Nodes {
97115
listResult.Repositories = append(listResult.Repositories, repo)
98116
if len(listResult.Repositories) >= limit {
99117
break pagination
100118
}
101119
}
102120

103-
if !result.RepositoryOwner.Repositories.PageInfo.HasNextPage {
121+
if !owner.Repositories.PageInfo.HasNextPage {
104122
break
105123
}
106-
variables["endCursor"] = githubv4.String(result.RepositoryOwner.Repositories.PageInfo.EndCursor)
124+
variables["endCursor"] = githubv4.String(owner.Repositories.PageInfo.EndCursor)
107125
}
108126

109127
return &listResult, nil

pkg/cmd/repo/list/list.go

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"net/http"
66
"time"
77

8-
"github.com/cli/cli/api"
98
"github.com/cli/cli/internal/ghinstance"
109
"github.com/cli/cli/pkg/cmdutil"
1110
"github.com/cli/cli/pkg/iostreams"
@@ -94,25 +93,13 @@ func listRun(opts *ListOptions) error {
9493
return err
9594
}
9695

97-
apiClient := api.NewClientFromHTTP(httpClient)
98-
99-
isTerminal := opts.IO.IsStdoutTTY()
100-
101-
owner := opts.Owner
102-
if owner == "" {
103-
owner, err = api.CurrentLoginName(apiClient, ghinstance.OverridableDefault())
104-
if err != nil {
105-
return err
106-
}
107-
}
108-
10996
filter := FilterOptions{
11097
Visibility: opts.Visibility,
11198
Fork: opts.Fork,
11299
Source: opts.Source,
113100
}
114101

115-
listResult, err := listRepos(httpClient, ghinstance.OverridableDefault(), opts.Limit, owner, filter)
102+
listResult, err := listRepos(httpClient, ghinstance.OverridableDefault(), opts.Limit, opts.Owner, filter)
116103
if err != nil {
117104
return err
118105
}
@@ -139,9 +126,9 @@ func listRun(opts *ListOptions) error {
139126
tp.EndRow()
140127
}
141128

142-
if isTerminal {
129+
if opts.IO.IsStdoutTTY() {
143130
hasFilters := filter.Visibility != "" || filter.Fork || filter.Source
144-
title := listHeader(owner, len(listResult.Repositories), listResult.TotalCount, hasFilters)
131+
title := listHeader(listResult.Owner, len(listResult.Repositories), listResult.TotalCount, hasFilters)
145132
fmt.Fprintf(opts.IO.Out, "\n%s\n\n", title)
146133
}
147134

pkg/cmd/repo/list/list_test.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ func TestRepoList_nontty(t *testing.T) {
5757
httpReg := &httpmock.Registry{}
5858
defer httpReg.Verify(t)
5959

60-
httpReg.Register(
61-
httpmock.GraphQL(`query UserCurrent\b`),
62-
httpmock.StringResponse(`{"data":{"viewer":{"login":"octocat"}}}`),
63-
)
6460
httpReg.Register(
6561
httpmock.GraphQL(`query RepositoryList\b`),
6662
httpmock.FileResponse("./fixtures/repoList.json"),
@@ -99,10 +95,6 @@ func TestRepoList_tty(t *testing.T) {
9995
httpReg := &httpmock.Registry{}
10096
defer httpReg.Verify(t)
10197

102-
httpReg.Register(
103-
httpmock.GraphQL(`query UserCurrent\b`),
104-
httpmock.StringResponse(`{"data":{"viewer":{"login":"octocat"}}}`),
105-
)
10698
httpReg.Register(
10799
httpmock.GraphQL(`query RepositoryList\b`),
108100
httpmock.FileResponse("./fixtures/repoList.json"),
@@ -139,10 +131,6 @@ func TestRepoList_filtering(t *testing.T) {
139131
http := &httpmock.Registry{}
140132
defer http.Verify(t)
141133

142-
http.Register(
143-
httpmock.GraphQL(`query UserCurrent\b`),
144-
httpmock.StringResponse(`{"data":{"viewer":{"login":"octocat"}}}`),
145-
)
146134
http.Register(
147135
httpmock.GraphQL(`query RepositoryList\b`),
148136
httpmock.GraphQLQuery(`{}`, func(_ string, params map[string]interface{}) {

0 commit comments

Comments
 (0)
X Tutup