X Tutup
Skip to content

Commit abe452b

Browse files
committed
Add --json export flag for issues and pull requests
The `--json` flag accepts a list of GraphQL fields to query for and output in JSON format. To get the list of available flags, run the command with a blank value for `--json`. Additional `--jq` and `--template` flags are available just like in `gh api`.
1 parent 19ea49b commit abe452b

File tree

16 files changed

+521
-118
lines changed

16 files changed

+521
-118
lines changed

api/export_pr.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package api
2+
3+
import (
4+
"reflect"
5+
"strings"
6+
)
7+
8+
func (issue *Issue) ExportData(fields []string) *map[string]interface{} {
9+
v := reflect.ValueOf(issue).Elem()
10+
data := map[string]interface{}{}
11+
12+
for _, f := range fields {
13+
switch f {
14+
case "milestone":
15+
if issue.Milestone.Title != "" {
16+
data[f] = &issue.Milestone
17+
} else {
18+
data[f] = nil
19+
}
20+
case "comments":
21+
data[f] = issue.Comments.Nodes
22+
case "assignees":
23+
data[f] = issue.Assignees.Nodes
24+
case "labels":
25+
data[f] = issue.Labels.Nodes
26+
case "projectCards":
27+
data[f] = issue.ProjectCards.Nodes
28+
default:
29+
sf := fieldByName(v, f)
30+
data[f] = sf.Interface()
31+
}
32+
}
33+
34+
return &data
35+
}
36+
37+
func (pr *PullRequest) ExportData(fields []string) *map[string]interface{} {
38+
v := reflect.ValueOf(pr).Elem()
39+
data := map[string]interface{}{}
40+
41+
for _, f := range fields {
42+
switch f {
43+
case "headRepository":
44+
data[f] = map[string]string{"name": pr.HeadRepository.Name}
45+
case "milestone":
46+
if pr.Milestone.Title != "" {
47+
data[f] = &pr.Milestone
48+
} else {
49+
data[f] = nil
50+
}
51+
case "statusCheckRollup":
52+
if n := pr.Commits.Nodes; len(n) > 0 {
53+
data[f] = n[0].Commit.StatusCheckRollup.Contexts.Nodes
54+
} else {
55+
data[f] = nil
56+
}
57+
case "comments":
58+
data[f] = pr.Comments.Nodes
59+
case "assignees":
60+
data[f] = pr.Assignees.Nodes
61+
case "labels":
62+
data[f] = pr.Labels.Nodes
63+
case "projectCards":
64+
data[f] = pr.ProjectCards.Nodes
65+
case "reviews":
66+
data[f] = pr.Reviews.Nodes
67+
case "reviewRequests":
68+
requests := make([]interface{}, 0, len(pr.ReviewRequests.Nodes))
69+
for _, req := range pr.ReviewRequests.Nodes {
70+
if req.RequestedReviewer.TypeName == "" {
71+
continue
72+
}
73+
requests = append(requests, req.RequestedReviewer)
74+
}
75+
data[f] = &requests
76+
default:
77+
sf := fieldByName(v, f)
78+
data[f] = sf.Interface()
79+
}
80+
}
81+
82+
return &data
83+
}
84+
85+
func fieldByName(v reflect.Value, field string) reflect.Value {
86+
return v.FieldByNameFunc(func(s string) bool {
87+
return strings.EqualFold(field, s)
88+
})
89+
}

api/queries_comments.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ type Comments struct {
1616
}
1717

1818
type Comment struct {
19-
Author Author
20-
AuthorAssociation string
21-
Body string
22-
CreatedAt time.Time
23-
IncludesCreatedEdit bool
24-
IsMinimized bool
25-
MinimizedReason string
26-
ReactionGroups ReactionGroups
19+
Author Author `json:"author"`
20+
AuthorAssociation string `json:"authorAssociation"`
21+
Body string `json:"body"`
22+
CreatedAt time.Time `json:"createdAt"`
23+
IncludesCreatedEdit bool `json:"includesCreatedEdit"`
24+
IsMinimized bool `json:"isMinimized"`
25+
MinimizedReason string `json:"minimizedReason"`
26+
ReactionGroups ReactionGroups `json:"reactionGroups"`
2727
}
2828

2929
type PageInfo struct {

api/queries_issue.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type Issue struct {
3030
Body string
3131
CreatedAt time.Time
3232
UpdatedAt time.Time
33+
ClosedAt *time.Time
3334
Comments Comments
3435
Author Author
3536
Assignees Assignees
@@ -41,7 +42,7 @@ type Issue struct {
4142

4243
type Assignees struct {
4344
Nodes []struct {
44-
Login string
45+
Login string `json:"login"`
4546
}
4647
TotalCount int
4748
}
@@ -56,7 +57,7 @@ func (a Assignees) Logins() []string {
5657

5758
type Labels struct {
5859
Nodes []struct {
59-
Name string
60+
Name string `json:"name"`
6061
}
6162
TotalCount int
6263
}
@@ -72,11 +73,11 @@ func (l Labels) Names() []string {
7273
type ProjectCards struct {
7374
Nodes []struct {
7475
Project struct {
75-
Name string
76-
}
76+
Name string `json:"name"`
77+
} `json:"project"`
7778
Column struct {
78-
Name string
79-
}
79+
Name string `json:"name"`
80+
} `json:"column"`
8081
}
8182
TotalCount int
8283
}
@@ -90,15 +91,15 @@ func (p ProjectCards) ProjectNames() []string {
9091
}
9192

9293
type Milestone struct {
93-
Title string
94+
Title string `json:"title"`
9495
}
9596

9697
type IssuesDisabledError struct {
9798
error
9899
}
99100

100101
type Author struct {
101-
Login string
102+
Login string `json:"login"`
102103
}
103104

104105
const fragments = `

api/queries_pr.go

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ type PullRequest struct {
4242
Additions int
4343
Deletions int
4444
MergeStateStatus string
45+
CreatedAt time.Time
46+
UpdatedAt time.Time
47+
ClosedAt *time.Time
48+
MergedAt *time.Time
4549

46-
Author struct {
47-
Login string
48-
}
50+
Author Author
4951
HeadRepositoryOwner struct {
50-
Login string
52+
Login string `json:"login"`
5153
}
5254
HeadRepository struct {
5355
Name string
@@ -75,15 +77,16 @@ type PullRequest struct {
7577
StatusCheckRollup struct {
7678
Contexts struct {
7779
Nodes []struct {
78-
Name string
79-
Context string
80-
State string
81-
Status string
82-
Conclusion string
83-
StartedAt time.Time
84-
CompletedAt time.Time
85-
DetailsURL string
86-
TargetURL string
80+
TypeName string `json:"__typename"`
81+
Name string `json:"name"`
82+
Context string `json:"context,omitempty"`
83+
State string `json:"state,omitempty"`
84+
Status string `json:"status"`
85+
Conclusion string `json:"conclusion"`
86+
StartedAt time.Time `json:"startedAt"`
87+
CompletedAt time.Time `json:"completedAt"`
88+
DetailsURL string `json:"detailsUrl"`
89+
TargetURL string `json:"targetUrl,omitempty"`
8790
}
8891
}
8992
}
@@ -104,8 +107,8 @@ type ReviewRequests struct {
104107
Nodes []struct {
105108
RequestedReviewer struct {
106109
TypeName string `json:"__typename"`
107-
Login string
108-
Name string
110+
Login string `json:"login"`
111+
Name string `json:"name"`
109112
}
110113
}
111114
TotalCount int
@@ -972,10 +975,3 @@ func BranchDeleteRemote(client *Client, repo ghrepo.Interface, branch string) er
972975
path := fmt.Sprintf("repos/%s/%s/git/refs/heads/%s", repo.RepoOwner(), repo.RepoName(), branch)
973976
return client.REST(repo.RepoHost(), "DELETE", path, nil, nil)
974977
}
975-
976-
func min(a, b int) int {
977-
if a < b {
978-
return a
979-
}
980-
return b
981-
}

api/queries_pr_review.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ type PullRequestReviews struct {
2828
}
2929

3030
type PullRequestReview struct {
31-
Author Author
32-
AuthorAssociation string
33-
Body string
34-
CreatedAt time.Time
35-
IncludesCreatedEdit bool
36-
ReactionGroups ReactionGroups
37-
State string
38-
URL string
31+
Author Author `json:"author"`
32+
AuthorAssociation string `json:"authorAssociation"`
33+
Body string `json:"body"`
34+
CreatedAt time.Time `json:"createdAt"`
35+
IncludesCreatedEdit bool `json:"includesCreatedEdit"`
36+
ReactionGroups ReactionGroups `json:"reactionGroups"`
37+
State string `json:"state"`
38+
URL string `json:"url"`
3939
}
4040

4141
func AddReview(client *Client, repo ghrepo.Interface, pr *PullRequest, input *PullRequestReviewInput) error {

0 commit comments

Comments
 (0)
X Tutup