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