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 func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*PullRequestReview, *Response, error) {
106 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number)
107 u, err := addOptions(u, opts)
108 if err != nil {
109 return nil, nil, err
110 }
111
112 req, err := s.client.NewRequest("GET", u, nil)
113 if err != nil {
114 return nil, nil, err
115 }
116
117 var reviews []*PullRequestReview
118 resp, err := s.client.Do(ctx, req, &reviews)
119 if err != nil {
120 return nil, resp, err
121 }
122
123 return reviews, resp, nil
124 }
125
126
127
128
129 func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) {
130 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
131
132 req, err := s.client.NewRequest("GET", u, nil)
133 if err != nil {
134 return nil, nil, err
135 }
136
137 review := new(PullRequestReview)
138 resp, err := s.client.Do(ctx, req, review)
139 if err != nil {
140 return nil, resp, err
141 }
142
143 return review, resp, nil
144 }
145
146
147
148
149 func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error) {
150 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
151
152 req, err := s.client.NewRequest("DELETE", u, nil)
153 if err != nil {
154 return nil, nil, err
155 }
156
157 review := new(PullRequestReview)
158 resp, err := s.client.Do(ctx, req, review)
159 if err != nil {
160 return nil, resp, err
161 }
162
163 return review, resp, nil
164 }
165
166
167
168
169 func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opts *ListOptions) ([]*PullRequestComment, *Response, error) {
170 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/comments", owner, repo, number, reviewID)
171 u, err := addOptions(u, opts)
172 if err != nil {
173 return nil, nil, err
174 }
175
176 req, err := s.client.NewRequest("GET", u, nil)
177 if err != nil {
178 return nil, nil, err
179 }
180
181 var comments []*PullRequestComment
182 resp, err := s.client.Do(ctx, req, &comments)
183 if err != nil {
184 return nil, resp, err
185 }
186
187 return comments, resp, nil
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
227 func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo string, number int, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) {
228 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number)
229
230 req, err := s.client.NewRequest("POST", u, review)
231 if err != nil {
232 return nil, nil, err
233 }
234
235
236 if isCF, err := review.isComfortFadePreview(); err != nil {
237 return nil, nil, err
238 } else if isCF {
239
240
241 req.Header.Set("Accept", mediaTypeMultiLineCommentsPreview)
242 }
243
244 r := new(PullRequestReview)
245 resp, err := s.client.Do(ctx, req, r)
246 if err != nil {
247 return nil, resp, err
248 }
249
250 return r, resp, nil
251 }
252
253
254
255
256 func (s *PullRequestsService) UpdateReview(ctx context.Context, owner, repo string, number int, reviewID int64, body string) (*PullRequestReview, *Response, error) {
257 opts := &struct {
258 Body string `json:"body"`
259 }{Body: body}
260 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
261
262 req, err := s.client.NewRequest("PUT", u, opts)
263 if err != nil {
264 return nil, nil, err
265 }
266
267 review := &PullRequestReview{}
268 resp, err := s.client.Do(ctx, req, review)
269 if err != nil {
270 return nil, resp, err
271 }
272
273 return review, resp, nil
274 }
275
276
277
278
279 func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) {
280 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/events", owner, repo, number, reviewID)
281
282 req, err := s.client.NewRequest("POST", u, review)
283 if err != nil {
284 return nil, nil, err
285 }
286
287 r := new(PullRequestReview)
288 resp, err := s.client.Do(ctx, req, r)
289 if err != nil {
290 return nil, resp, err
291 }
292
293 return r, resp, nil
294 }
295
296
297
298
299 func (s *PullRequestsService) DismissReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewDismissalRequest) (*PullRequestReview, *Response, error) {
300 u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/dismissals", owner, repo, number, reviewID)
301
302 req, err := s.client.NewRequest("PUT", u, review)
303 if err != nil {
304 return nil, nil, err
305 }
306
307 r := new(PullRequestReview)
308 resp, err := s.client.Do(ctx, req, r)
309 if err != nil {
310 return nil, resp, err
311 }
312
313 return r, resp, nil
314 }
315
View as plain text