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