/
item.go
129 lines (115 loc) · 3.12 KB
/
item.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package gh
import (
"github.com/google/go-github/github"
"github.com/pkg/errors"
)
// Item is a union type that can encapsulate either a github.Issue or a
// github.PullRequest. This allows to have a single Operation interface and let
// the implementation handle according to its capabilities.
type Item struct {
Issue *github.Issue
PullRequest *github.PullRequest
}
// MakeIssueItem create an Item wrapper around a GitHub issue.
func MakeIssueItem(issue *github.Issue) Item {
return Item{
Issue: issue,
}
}
// MakePullRequestItem create an Item wrapper around a GitHub pull request.
func MakePullRequestItem(pullRequest *github.PullRequest) Item {
return Item{
PullRequest: pullRequest,
}
}
// IsNil returns true when the item is not initialized.
func (i Item) IsNil() bool {
return i.Issue == nil && i.PullRequest == nil
}
// IsIssue returns whether the item is strictly a GitHub issue (i.e., not the
// issue object of a corresponding pull request).
func (i Item) IsIssue() bool {
// The `Issue` field can be non-nil even in the case of a pull request, as
// we may have fetched the related issue object (for example to retrieve
// labels).
return i.PullRequest == nil
}
// IsPullRequest returns whether the item is a GitHub pull request.
func (i Item) IsPullRequest() bool {
return i.PullRequest != nil
}
// Body returns the text body of the item.
func (i Item) Body() string {
switch {
case i.Issue != nil:
return *i.Issue.Body
case i.PullRequest != nil:
return *i.PullRequest.Body
default:
panic("uninitialized item")
}
}
// Number returns the number of the item.
func (i *Item) Number() int {
switch {
case i.Issue != nil:
return *i.Issue.Number
case i.PullRequest != nil:
return *i.PullRequest.Number
default:
panic("uninitialized item")
}
}
// Repository returns the repository full name of the item. In the case of a
// pull request, this is the destination repository.
func (i *Item) Repository() string {
switch {
case i.Issue != nil:
return *i.Issue.Repository.FullName
case i.PullRequest != nil:
return *i.PullRequest.Base.Repo.FullName
default:
panic("uninitialized item")
}
}
// Title returns the title of the item.
func (i *Item) Title() string {
switch {
case i.Issue != nil:
return *i.Issue.Title
case i.PullRequest != nil:
return *i.PullRequest.Title
default:
panic("uninitialized item")
}
}
// Type returns a string representation of the GitHub item type.
func (i *Item) Type() string {
switch {
case i.Issue != nil:
return "issue"
case i.PullRequest != nil:
return "pull_request"
default:
return "<none>"
}
}
// GetRelatedIssue retrieves and return the GitHub issue related to a pull
// request. This function will fail when called on a GitHub issue.
func (i *Item) GetRelatedIssue(client Client) (*github.Issue, error) {
if i.Issue != nil {
return i.Issue, nil
} else if i.IsIssue() {
return nil, errors.Errorf("GetRelatedIssue called on an issue")
}
issue, _, err := client.Issues().Get(
*i.PullRequest.Base.Repo.Owner.Login,
*i.PullRequest.Base.Repo.Name,
*i.PullRequest.Number,
)
if err != nil {
return nil, err
}
i.Issue = issue
return i.Issue, nil
}