1
2
3
4
5
6 package github
7
8 import (
9 "bytes"
10 "context"
11 "fmt"
12 "time"
13 )
14
15
16
17
18
19 type PullRequestsService service
20
21
22 type PullRequest struct {
23 ID *int64 `json:"id,omitempty"`
24 Number *int `json:"number,omitempty"`
25 State *string `json:"state,omitempty"`
26 Locked *bool `json:"locked,omitempty"`
27 Title *string `json:"title,omitempty"`
28 Body *string `json:"body,omitempty"`
29 CreatedAt *time.Time `json:"created_at,omitempty"`
30 UpdatedAt *time.Time `json:"updated_at,omitempty"`
31 ClosedAt *time.Time `json:"closed_at,omitempty"`
32 MergedAt *time.Time `json:"merged_at,omitempty"`
33 Labels []*Label `json:"labels,omitempty"`
34 User *User `json:"user,omitempty"`
35 Draft *bool `json:"draft,omitempty"`
36 Merged *bool `json:"merged,omitempty"`
37 Mergeable *bool `json:"mergeable,omitempty"`
38 MergeableState *string `json:"mergeable_state,omitempty"`
39 MergedBy *User `json:"merged_by,omitempty"`
40 MergeCommitSHA *string `json:"merge_commit_sha,omitempty"`
41 Rebaseable *bool `json:"rebaseable,omitempty"`
42 Comments *int `json:"comments,omitempty"`
43 Commits *int `json:"commits,omitempty"`
44 Additions *int `json:"additions,omitempty"`
45 Deletions *int `json:"deletions,omitempty"`
46 ChangedFiles *int `json:"changed_files,omitempty"`
47 URL *string `json:"url,omitempty"`
48 HTMLURL *string `json:"html_url,omitempty"`
49 IssueURL *string `json:"issue_url,omitempty"`
50 StatusesURL *string `json:"statuses_url,omitempty"`
51 DiffURL *string `json:"diff_url,omitempty"`
52 PatchURL *string `json:"patch_url,omitempty"`
53 CommitsURL *string `json:"commits_url,omitempty"`
54 CommentsURL *string `json:"comments_url,omitempty"`
55 ReviewCommentsURL *string `json:"review_comments_url,omitempty"`
56 ReviewCommentURL *string `json:"review_comment_url,omitempty"`
57 ReviewComments *int `json:"review_comments,omitempty"`
58 Assignee *User `json:"assignee,omitempty"`
59 Assignees []*User `json:"assignees,omitempty"`
60 Milestone *Milestone `json:"milestone,omitempty"`
61 MaintainerCanModify *bool `json:"maintainer_can_modify,omitempty"`
62 AuthorAssociation *string `json:"author_association,omitempty"`
63 NodeID *string `json:"node_id,omitempty"`
64 RequestedReviewers []*User `json:"requested_reviewers,omitempty"`
65
66
67
68 RequestedTeams []*Team `json:"requested_teams,omitempty"`
69
70 Links *PRLinks `json:"_links,omitempty"`
71 Head *PullRequestBranch `json:"head,omitempty"`
72 Base *PullRequestBranch `json:"base,omitempty"`
73
74
75
76 ActiveLockReason *string `json:"active_lock_reason,omitempty"`
77 }
78
79 func (p PullRequest) String() string {
80 return Stringify(p)
81 }
82
83
84 type PRLink struct {
85 HRef *string `json:"href,omitempty"`
86 }
87
88
89 type PRLinks struct {
90 Self *PRLink `json:"self,omitempty"`
91 HTML *PRLink `json:"html,omitempty"`
92 Issue *PRLink `json:"issue,omitempty"`
93 Comments *PRLink `json:"comments,omitempty"`
94 ReviewComments *PRLink `json:"review_comments,omitempty"`
95 ReviewComment *PRLink `json:"review_comment,omitempty"`
96 Commits *PRLink `json:"commits,omitempty"`
97 Statuses *PRLink `json:"statuses,omitempty"`
98 }
99
100
101 type PullRequestBranch struct {
102 Label *string `json:"label,omitempty"`
103 Ref *string `json:"ref,omitempty"`
104 SHA *string `json:"sha,omitempty"`
105 Repo *Repository `json:"repo,omitempty"`
106 User *User `json:"user,omitempty"`
107 }
108
109
110
111 type PullRequestListOptions struct {
112
113
114 State string `url:"state,omitempty"`
115
116
117
118 Head string `url:"head,omitempty"`
119
120
121 Base string `url:"base,omitempty"`
122
123
124
125 Sort string `url:"sort,omitempty"`
126
127
128
129
130 Direction string `url:"direction,omitempty"`
131
132 ListOptions
133 }
134
135
136
137
138 func (s *PullRequestsService) List(ctx context.Context, owner string, repo string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error) {
139 u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
140 u, err := addOptions(u, opts)
141 if err != nil {
142 return nil, nil, err
143 }
144
145 req, err := s.client.NewRequest("GET", u, nil)
146 if err != nil {
147 return nil, nil, err
148 }
149
150 var pulls []*PullRequest
151 resp, err := s.client.Do(ctx, req, &pulls)
152 if err != nil {
153 return nil, resp, err
154 }
155
156 return pulls, resp, nil
157 }
158
159
160
161
162
163
164 func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error) {
165 u := fmt.Sprintf("repos/%v/%v/commits/%v/pulls", owner, repo, sha)
166 u, err := addOptions(u, opts)
167 if err != nil {
168 return nil, nil, err
169 }
170
171 req, err := s.client.NewRequest("GET", u, nil)
172 if err != nil {
173 return nil, nil, err
174 }
175
176
177 req.Header.Set("Accept", mediaTypeListPullsOrBranchesForCommitPreview)
178 var pulls []*PullRequest
179 resp, err := s.client.Do(ctx, req, &pulls)
180 if err != nil {
181 return nil, resp, err
182 }
183
184 return pulls, resp, nil
185 }
186
187
188
189
190 func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string, number int) (*PullRequest, *Response, error) {
191 u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
192 req, err := s.client.NewRequest("GET", u, nil)
193 if err != nil {
194 return nil, nil, err
195 }
196
197 pull := new(PullRequest)
198 resp, err := s.client.Do(ctx, req, pull)
199 if err != nil {
200 return nil, resp, err
201 }
202
203 return pull, resp, nil
204 }
205
206
207
208
209 func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opts RawOptions) (string, *Response, error) {
210 u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
211 req, err := s.client.NewRequest("GET", u, nil)
212 if err != nil {
213 return "", nil, err
214 }
215
216 switch opts.Type {
217 case Diff:
218 req.Header.Set("Accept", mediaTypeV3Diff)
219 case Patch:
220 req.Header.Set("Accept", mediaTypeV3Patch)
221 default:
222 return "", nil, fmt.Errorf("unsupported raw type %d", opts.Type)
223 }
224
225 var buf bytes.Buffer
226 resp, err := s.client.Do(ctx, req, &buf)
227 if err != nil {
228 return "", resp, err
229 }
230
231 return buf.String(), resp, nil
232 }
233
234
235 type NewPullRequest struct {
236 Title *string `json:"title,omitempty"`
237 Head *string `json:"head,omitempty"`
238 Base *string `json:"base,omitempty"`
239 Body *string `json:"body,omitempty"`
240 Issue *int `json:"issue,omitempty"`
241 MaintainerCanModify *bool `json:"maintainer_can_modify,omitempty"`
242 Draft *bool `json:"draft,omitempty"`
243 }
244
245
246
247
248 func (s *PullRequestsService) Create(ctx context.Context, owner string, repo string, pull *NewPullRequest) (*PullRequest, *Response, error) {
249 u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
250 req, err := s.client.NewRequest("POST", u, pull)
251 if err != nil {
252 return nil, nil, err
253 }
254
255 p := new(PullRequest)
256 resp, err := s.client.Do(ctx, req, p)
257 if err != nil {
258 return nil, resp, err
259 }
260
261 return p, resp, nil
262 }
263
264
265
266 type PullRequestBranchUpdateOptions struct {
267
268
269 ExpectedHeadSHA *string `json:"expected_head_sha,omitempty"`
270 }
271
272
273 type PullRequestBranchUpdateResponse struct {
274 Message *string `json:"message,omitempty"`
275 URL *string `json:"url,omitempty"`
276 }
277
278
279
280
281
282
283
284
285
286
287 func (s *PullRequestsService) UpdateBranch(ctx context.Context, owner, repo string, number int, opts *PullRequestBranchUpdateOptions) (*PullRequestBranchUpdateResponse, *Response, error) {
288 u := fmt.Sprintf("repos/%v/%v/pulls/%d/update-branch", owner, repo, number)
289
290 req, err := s.client.NewRequest("PUT", u, opts)
291 if err != nil {
292 return nil, nil, err
293 }
294
295
296 req.Header.Set("Accept", mediaTypeUpdatePullRequestBranchPreview)
297
298 p := new(PullRequestBranchUpdateResponse)
299 resp, err := s.client.Do(ctx, req, p)
300 if err != nil {
301 return nil, resp, err
302 }
303
304 return p, resp, nil
305 }
306
307 type pullRequestUpdate struct {
308 Title *string `json:"title,omitempty"`
309 Body *string `json:"body,omitempty"`
310 State *string `json:"state,omitempty"`
311 Base *string `json:"base,omitempty"`
312 MaintainerCanModify *bool `json:"maintainer_can_modify,omitempty"`
313 }
314
315
316
317
318
319
320
321
322 func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo string, number int, pull *PullRequest) (*PullRequest, *Response, error) {
323 if pull == nil {
324 return nil, nil, fmt.Errorf("pull must be provided")
325 }
326
327 u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
328
329 update := &pullRequestUpdate{
330 Title: pull.Title,
331 Body: pull.Body,
332 State: pull.State,
333 MaintainerCanModify: pull.MaintainerCanModify,
334 }
335
336
337
338 if pull.Base != nil && pull.GetState() != "closed" {
339 update.Base = pull.Base.Ref
340 }
341
342 req, err := s.client.NewRequest("PATCH", u, update)
343 if err != nil {
344 return nil, nil, err
345 }
346
347 p := new(PullRequest)
348 resp, err := s.client.Do(ctx, req, p)
349 if err != nil {
350 return nil, resp, err
351 }
352
353 return p, resp, nil
354 }
355
356
357
358
359 func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*RepositoryCommit, *Response, error) {
360 u := fmt.Sprintf("repos/%v/%v/pulls/%d/commits", owner, repo, number)
361 u, err := addOptions(u, opts)
362 if err != nil {
363 return nil, nil, err
364 }
365
366 req, err := s.client.NewRequest("GET", u, nil)
367 if err != nil {
368 return nil, nil, err
369 }
370
371 var commits []*RepositoryCommit
372 resp, err := s.client.Do(ctx, req, &commits)
373 if err != nil {
374 return nil, resp, err
375 }
376
377 return commits, resp, nil
378 }
379
380
381
382
383 func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo string, number int, opts *ListOptions) ([]*CommitFile, *Response, error) {
384 u := fmt.Sprintf("repos/%v/%v/pulls/%d/files", owner, repo, number)
385 u, err := addOptions(u, opts)
386 if err != nil {
387 return nil, nil, err
388 }
389
390 req, err := s.client.NewRequest("GET", u, nil)
391 if err != nil {
392 return nil, nil, err
393 }
394
395 var commitFiles []*CommitFile
396 resp, err := s.client.Do(ctx, req, &commitFiles)
397 if err != nil {
398 return nil, resp, err
399 }
400
401 return commitFiles, resp, nil
402 }
403
404
405
406
407 func (s *PullRequestsService) IsMerged(ctx context.Context, owner string, repo string, number int) (bool, *Response, error) {
408 u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
409 req, err := s.client.NewRequest("GET", u, nil)
410 if err != nil {
411 return false, nil, err
412 }
413
414 resp, err := s.client.Do(ctx, req, nil)
415 merged, err := parseBoolResponse(err)
416 return merged, resp, err
417 }
418
419
420 type PullRequestMergeResult struct {
421 SHA *string `json:"sha,omitempty"`
422 Merged *bool `json:"merged,omitempty"`
423 Message *string `json:"message,omitempty"`
424 }
425
426
427 type PullRequestOptions struct {
428 CommitTitle string
429 SHA string
430
431
432 MergeMethod string
433 }
434
435 type pullRequestMergeRequest struct {
436 CommitMessage string `json:"commit_message,omitempty"`
437 CommitTitle string `json:"commit_title,omitempty"`
438 MergeMethod string `json:"merge_method,omitempty"`
439 SHA string `json:"sha,omitempty"`
440 }
441
442
443
444
445
446 func (s *PullRequestsService) Merge(ctx context.Context, owner string, repo string, number int, commitMessage string, options *PullRequestOptions) (*PullRequestMergeResult, *Response, error) {
447 u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
448
449 pullRequestBody := &pullRequestMergeRequest{CommitMessage: commitMessage}
450 if options != nil {
451 pullRequestBody.CommitTitle = options.CommitTitle
452 pullRequestBody.MergeMethod = options.MergeMethod
453 pullRequestBody.SHA = options.SHA
454 }
455 req, err := s.client.NewRequest("PUT", u, pullRequestBody)
456 if err != nil {
457 return nil, nil, err
458 }
459
460 mergeResult := new(PullRequestMergeResult)
461 resp, err := s.client.Do(ctx, req, mergeResult)
462 if err != nil {
463 return nil, resp, err
464 }
465
466 return mergeResult, resp, nil
467 }
468
View as plain text