1
2
3
4
5
6 package github
7
8 import (
9 "context"
10 "fmt"
11 "time"
12 )
13
14
15
16
17
18 type IssuesService service
19
20
21
22
23
24
25
26
27 type Issue struct {
28 ID *int64 `json:"id,omitempty"`
29 Number *int `json:"number,omitempty"`
30 State *string `json:"state,omitempty"`
31 Locked *bool `json:"locked,omitempty"`
32 Title *string `json:"title,omitempty"`
33 Body *string `json:"body,omitempty"`
34 AuthorAssociation *string `json:"author_association,omitempty"`
35 User *User `json:"user,omitempty"`
36 Labels []*Label `json:"labels,omitempty"`
37 Assignee *User `json:"assignee,omitempty"`
38 Comments *int `json:"comments,omitempty"`
39 ClosedAt *time.Time `json:"closed_at,omitempty"`
40 CreatedAt *time.Time `json:"created_at,omitempty"`
41 UpdatedAt *time.Time `json:"updated_at,omitempty"`
42 ClosedBy *User `json:"closed_by,omitempty"`
43 URL *string `json:"url,omitempty"`
44 HTMLURL *string `json:"html_url,omitempty"`
45 CommentsURL *string `json:"comments_url,omitempty"`
46 EventsURL *string `json:"events_url,omitempty"`
47 LabelsURL *string `json:"labels_url,omitempty"`
48 RepositoryURL *string `json:"repository_url,omitempty"`
49 Milestone *Milestone `json:"milestone,omitempty"`
50 PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"`
51 Repository *Repository `json:"repository,omitempty"`
52 Reactions *Reactions `json:"reactions,omitempty"`
53 Assignees []*User `json:"assignees,omitempty"`
54 NodeID *string `json:"node_id,omitempty"`
55
56
57
58 TextMatches []*TextMatch `json:"text_matches,omitempty"`
59
60
61
62 ActiveLockReason *string `json:"active_lock_reason,omitempty"`
63 }
64
65 func (i Issue) String() string {
66 return Stringify(i)
67 }
68
69
70
71
72 func (i Issue) IsPullRequest() bool {
73 return i.PullRequestLinks != nil
74 }
75
76
77
78
79 type IssueRequest struct {
80 Title *string `json:"title,omitempty"`
81 Body *string `json:"body,omitempty"`
82 Labels *[]string `json:"labels,omitempty"`
83 Assignee *string `json:"assignee,omitempty"`
84 State *string `json:"state,omitempty"`
85
86 StateReason *string `json:"state_reason,omitempty"`
87 Milestone *int `json:"milestone,omitempty"`
88 Assignees *[]string `json:"assignees,omitempty"`
89 }
90
91
92
93 type IssueListOptions struct {
94
95
96 Filter string `url:"filter,omitempty"`
97
98
99
100 State string `url:"state,omitempty"`
101
102
103 Labels []string `url:"labels,comma,omitempty"`
104
105
106
107 Sort string `url:"sort,omitempty"`
108
109
110
111 Direction string `url:"direction,omitempty"`
112
113
114 Since time.Time `url:"since,omitempty"`
115
116 ListOptions
117 }
118
119
120
121 type PullRequestLinks struct {
122 URL *string `json:"url,omitempty"`
123 HTMLURL *string `json:"html_url,omitempty"`
124 DiffURL *string `json:"diff_url,omitempty"`
125 PatchURL *string `json:"patch_url,omitempty"`
126 }
127
128
129
130
131
132
133
134
135 func (s *IssuesService) List(ctx context.Context, all bool, opts *IssueListOptions) ([]*Issue, *Response, error) {
136 var u string
137 if all {
138 u = "issues"
139 } else {
140 u = "user/issues"
141 }
142 return s.listIssues(ctx, u, opts)
143 }
144
145
146
147
148
149 func (s *IssuesService) ListByOrg(ctx context.Context, org string, opts *IssueListOptions) ([]*Issue, *Response, error) {
150 u := fmt.Sprintf("orgs/%v/issues", org)
151 return s.listIssues(ctx, u, opts)
152 }
153
154 func (s *IssuesService) listIssues(ctx context.Context, u string, opts *IssueListOptions) ([]*Issue, *Response, error) {
155 u, err := addOptions(u, opts)
156 if err != nil {
157 return nil, nil, err
158 }
159
160 req, err := s.client.NewRequest("GET", u, nil)
161 if err != nil {
162 return nil, nil, err
163 }
164
165
166 req.Header.Set("Accept", mediaTypeReactionsPreview)
167
168 var issues []*Issue
169 resp, err := s.client.Do(ctx, req, &issues)
170 if err != nil {
171 return nil, resp, err
172 }
173
174 return issues, resp, nil
175 }
176
177
178
179 type IssueListByRepoOptions struct {
180
181
182
183 Milestone string `url:"milestone,omitempty"`
184
185
186
187 State string `url:"state,omitempty"`
188
189
190
191
192 Assignee string `url:"assignee,omitempty"`
193
194
195 Creator string `url:"creator,omitempty"`
196
197
198 Mentioned string `url:"mentioned,omitempty"`
199
200
201 Labels []string `url:"labels,omitempty,comma"`
202
203
204
205 Sort string `url:"sort,omitempty"`
206
207
208
209 Direction string `url:"direction,omitempty"`
210
211
212 Since time.Time `url:"since,omitempty"`
213
214 ListOptions
215 }
216
217
218
219
220 func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo string, opts *IssueListByRepoOptions) ([]*Issue, *Response, error) {
221 u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
222 u, err := addOptions(u, opts)
223 if err != nil {
224 return nil, nil, err
225 }
226
227 req, err := s.client.NewRequest("GET", u, nil)
228 if err != nil {
229 return nil, nil, err
230 }
231
232
233 req.Header.Set("Accept", mediaTypeReactionsPreview)
234
235 var issues []*Issue
236 resp, err := s.client.Do(ctx, req, &issues)
237 if err != nil {
238 return nil, resp, err
239 }
240
241 return issues, resp, nil
242 }
243
244
245
246
247 func (s *IssuesService) Get(ctx context.Context, owner string, repo string, number int) (*Issue, *Response, error) {
248 u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
249 req, err := s.client.NewRequest("GET", u, nil)
250 if err != nil {
251 return nil, nil, err
252 }
253
254
255 req.Header.Set("Accept", mediaTypeReactionsPreview)
256
257 issue := new(Issue)
258 resp, err := s.client.Do(ctx, req, issue)
259 if err != nil {
260 return nil, resp, err
261 }
262
263 return issue, resp, nil
264 }
265
266
267
268
269 func (s *IssuesService) Create(ctx context.Context, owner string, repo string, issue *IssueRequest) (*Issue, *Response, error) {
270 u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
271 req, err := s.client.NewRequest("POST", u, issue)
272 if err != nil {
273 return nil, nil, err
274 }
275
276 i := new(Issue)
277 resp, err := s.client.Do(ctx, req, i)
278 if err != nil {
279 return nil, resp, err
280 }
281
282 return i, resp, nil
283 }
284
285
286
287
288 func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, number int, issue *IssueRequest) (*Issue, *Response, error) {
289 u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
290 req, err := s.client.NewRequest("PATCH", u, issue)
291 if err != nil {
292 return nil, nil, err
293 }
294
295 i := new(Issue)
296 resp, err := s.client.Do(ctx, req, i)
297 if err != nil {
298 return nil, resp, err
299 }
300
301 return i, resp, nil
302 }
303
304
305
306
307
308
309 func (s *IssuesService) RemoveMilestone(ctx context.Context, owner, repo string, issueNumber int) (*Issue, *Response, error) {
310 u := fmt.Sprintf("repos/%v/%v/issues/%v", owner, repo, issueNumber)
311 req, err := s.client.NewRequest("PATCH", u, &struct {
312 Milestone *Milestone `json:"milestone"`
313 }{})
314 if err != nil {
315 return nil, nil, err
316 }
317
318 i := new(Issue)
319 resp, err := s.client.Do(ctx, req, i)
320 if err != nil {
321 return nil, resp, err
322 }
323
324 return i, resp, nil
325 }
326
327
328
329 type LockIssueOptions struct {
330
331
332
333 LockReason string `json:"lock_reason,omitempty"`
334 }
335
336
337
338
339 func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, number int, opts *LockIssueOptions) (*Response, error) {
340 u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
341 req, err := s.client.NewRequest("PUT", u, opts)
342 if err != nil {
343 return nil, err
344 }
345
346 return s.client.Do(ctx, req, nil)
347 }
348
349
350
351
352 func (s *IssuesService) Unlock(ctx context.Context, owner string, repo string, number int) (*Response, error) {
353 u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
354 req, err := s.client.NewRequest("DELETE", u, nil)
355 if err != nil {
356 return nil, err
357 }
358
359 return s.client.Do(ctx, req, nil)
360 }
361
View as plain text