1
2
3
4
5
6 package github
7
8 import (
9 "context"
10 "errors"
11 "fmt"
12 "time"
13 )
14
15 var ErrMixedCommentStyles = errors.New("cannot use both position and side/line form comments")
16
17
18 type PullRequestReview struct {
19 ID *int64 `json:"id,omitempty"`
20 NodeID *string `json:"node_id,omitempty"`
21 User *User `json:"user,omitempty"`
22 Body *string `json:"body,omitempty"`
23 SubmittedAt *time.Time `json:"submitted_at,omitempty"`
24 CommitID *string `json:"commit_id,omitempty"`
25 HTMLURL *string `json:"html_url,omitempty"`
26 PullRequestURL *string `json:"pull_request_url,omitempty"`
27 State *string `json:"state,omitempty"`
28
29
30 AuthorAssociation *string `json:"author_association,omitempty"`
31 }
32
33 func (p PullRequestReview) String() string {
34 return Stringify(p)
35 }
36
37
38 type DraftReviewComment struct {
39 Path *string `json:"path,omitempty"`
40 Position *int `json:"position,omitempty"`
41 Body *string `json:"body,omitempty"`
42
43
44 StartSide *string `json:"start_side,omitempty"`
45 Side *string `json:"side,omitempty"`
46 StartLine *int `json:"start_line,omitempty"`
47 Line *int `json:"line,omitempty"`
48 }
49
50 func (c DraftReviewComment) String() string {
51 return Stringify(c)
52 }
53
54
55 type PullRequestReviewRequest struct {
56 NodeID *string `json:"node_id,omitempty"`
57 CommitID *string `json:"commit_id,omitempty"`
58 Body *string `json:"body,omitempty"`
59 Event *string `json:"event,omitempty"`
60 Comments []*DraftReviewComment `json:"comments,omitempty"`
61 }
62
63 func (r PullRequestReviewRequest) String() string {
64 return Stringify(r)
65 }
66
67 func (r *PullRequestReviewRequest) isComfortFadePreview() (bool, error) {
68 var isCF *bool
69 for _, comment := range r.Comments {
70 if comment == nil {
71 continue
72 }
73 hasPos := comment.Position != nil
74 hasComfortFade := (comment.StartSide != nil) || (comment.Side != nil) ||
75 (comment.StartLine != nil) || (comment.Line != nil)
76
77 switch {
78 case hasPos && hasComfortFade:
79 return false, ErrMixedCommentStyles
80 case hasPos && isCF != nil && *isCF:
81 return false, ErrMixedCommentStyles
82 case hasComfortFade && isCF != nil && !*isCF:
83 return false, ErrMixedCommentStyles
84 }
85 isCF = &hasComfortFade
86 }
87 if isCF != nil {
88 return *isCF, nil
89 }
90 return false, nil
91 }
92
93
94 type PullRequestReviewDismissalRequest struct {
95 Message *string `json:"message,omitempty"`
96 }
97
98 func (r PullRequestReviewDismissalRequest) String() string {
99 return Stringify(r)
100 }
101
102
103
104
105
106
107
108
109 func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*PullRequestReview, *Response, error) {
110 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number)
111 u, err := addOptions(u, opts)
112 if err != nil {
113 return nil, nil, err
114 }
115
116 req, err := s.client.NewRequest("GET", u, nil)
117 if err != nil {
118 return nil, nil, err
119 }
120
121 var reviews []*PullRequestReview
122 resp, err := s.client.Do(ctx, req, &reviews)
123 if err != nil {
124 return nil, resp, err
125 }
126
127 return reviews, resp, nil
128 }
129
130
131
132
133
134
135
136
137 func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) {
138 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
139
140 req, err := s.client.NewRequest("GET", u, nil)
141 if err != nil {
142 return nil, nil, err
143 }
144
145 review := new(PullRequestReview)
146 resp, err := s.client.Do(ctx, req, review)
147 if err != nil {
148 return nil, resp, err
149 }
150
151 return review, resp, nil
152 }
153
154
155
156
157
158
159
160
161 func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) {
162 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
163
164 req, err := s.client.NewRequest("DELETE", u, nil)
165 if err != nil {
166 return nil, nil, err
167 }
168
169 review := new(PullRequestReview)
170 resp, err := s.client.Do(ctx, req, review)
171 if err != nil {
172 return nil, resp, err
173 }
174
175 return review, resp, nil
176 }
177
178
179
180
181
182
183
184
185 func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opts *ListOptions) ([]*PullRequestComment, *Response, error) {
186 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/comments", owner, repo, number, reviewID)
187 u, err := addOptions(u, opts)
188 if err != nil {
189 return nil, nil, err
190 }
191
192 req, err := s.client.NewRequest("GET", u, nil)
193 if err != nil {
194 return nil, nil, err
195 }
196
197 var comments []*PullRequestComment
198 resp, err := s.client.Do(ctx, req, &comments)
199 if err != nil {
200 return nil, resp, err
201 }
202
203 return comments, resp, nil
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245 func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo string, number int, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) {
246 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number)
247
248 req, err := s.client.NewRequest("POST", u, review)
249 if err != nil {
250 return nil, nil, err
251 }
252
253
254 if isCF, err := review.isComfortFadePreview(); err != nil {
255 return nil, nil, err
256 } else if isCF {
257
258
259 req.Header.Set("Accept", mediaTypeMultiLineCommentsPreview)
260 }
261
262 r := new(PullRequestReview)
263 resp, err := s.client.Do(ctx, req, r)
264 if err != nil {
265 return nil, resp, err
266 }
267
268 return r, resp, nil
269 }
270
271
272
273
274 func (s *PullRequestsService) UpdateReview(ctx context.Context, owner, repo string, number int, reviewID int64, body string) (*PullRequestReview, *Response, error) {
275 opts := &struct {
276 Body string `json:"body"`
277 }{Body: body}
278 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
279
280 req, err := s.client.NewRequest("PUT", u, opts)
281 if err != nil {
282 return nil, nil, err
283 }
284
285 review := &PullRequestReview{}
286 resp, err := s.client.Do(ctx, req, review)
287 if err != nil {
288 return nil, resp, err
289 }
290
291 return review, resp, nil
292 }
293
294
295
296
297
298
299
300
301 func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) {
302 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/events", owner, repo, number, reviewID)
303
304 req, err := s.client.NewRequest("POST", u, review)
305 if err != nil {
306 return nil, nil, err
307 }
308
309 r := new(PullRequestReview)
310 resp, err := s.client.Do(ctx, req, r)
311 if err != nil {
312 return nil, resp, err
313 }
314
315 return r, resp, nil
316 }
317
318
319
320
321
322
323
324
325 func (s *PullRequestsService) DismissReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewDismissalRequest) (*PullRequestReview, *Response, error) {
326 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/dismissals", owner, repo, number, reviewID)
327
328 req, err := s.client.NewRequest("PUT", u, review)
329 if err != nil {
330 return nil, nil, err
331 }
332
333 r := new(PullRequestReview)
334 resp, err := s.client.Do(ctx, req, r)
335 if err != nil {
336 return nil, resp, err
337 }
338
339 return r, resp, nil
340 }
341
View as plain text