1package Net::GitHub::V3::PullRequests;
2
3use Moo;
4
5our $VERSION = '1.02';
6our $AUTHORITY = 'cpan:FAYLAND';
7
8use URI;
9use URI::Escape;
10
11with 'Net::GitHub::V3::Query';
12
13sub pulls {
14    my $self = shift;
15
16    return $self->query($self->_pulls_arg2url(@_));
17}
18
19sub next_pull {
20    my $self = shift;
21
22    return $self->next($self->_pulls_arg2url(@_));
23}
24
25sub close_pull {
26    my $self = shift;
27
28    return $self->close($self->_pulls_arg2url(@_));
29}
30
31sub _pulls_arg2url {
32    my $self = shift @_;
33    my $args = pop @_;
34
35    my ($user, $repos) = ($self->u, $self->repo);
36    if (scalar(@_) >= 2) {
37        ($user, $repos) = @_;
38    }
39
40    my $uri = URI->new('/repos/' . uri_escape($user) . '/' . uri_escape($repos) . '/pulls');
41    $uri->query_form($args);
42    return $uri->as_string;
43}
44
45## build methods on fly
46my %__methods = (
47
48    pull => { url => "/repos/%s/%s/pulls/%s" },
49
50    create_pull => { url => "/repos/%s/%s/pulls", method => "POST", args => 1 },
51    update_pull => { url => "/repos/%s/%s/pulls/%s", method => "PATCH", args => 1 },
52
53    commits => { url => "/repos/%s/%s/pulls/%s/commits", paginate => 1 },
54    files => { url => "/repos/%s/%s/pulls/%s/files", paginate => 1 },
55    is_merged => { url => "/repos/%s/%s/pulls/%s/merge", check_status => 204 },
56    merge => { url => "/repos/%s/%s/pulls/%s/merge", method => "PUT" },
57
58    # http://developer.github.com/v3/pulls/comments/
59    comments => { url => "/repos/%s/%s/pulls/%s/comments", paginate => 1 },
60    comment  => { url => "/repos/%s/%s/pulls/comments/%s" },
61    create_comment => { url => "/repos/%s/%s/pulls/%s/comments", method => 'POST',  args => 1 },
62    update_comment => { url => "/repos/%s/%s/pulls/comments/%s", method => 'PATCH', args => 1 },
63    delete_comment => { url => "/repos/%s/%s/pulls/comments/%s", method => 'DELETE', check_status => 204 },
64
65    # http://developer.github.com/v3/pulls/reviews/
66    reviews => { url => "/repos/%s/%s/pulls/%s/reviews", paginate => 1 },
67    review  => { url => "/repos/%s/%s/pulls/%s/reviews/%s" },
68    create_review => { url => "/repos/%s/%s/pulls/%s/reviews", method => 'POST',  args => 1 },
69    delete_review => { url => "/repos/%s/%s/pulls/%s/reviews/%s", method => 'DELETE' },
70    update_review => { url => "/repos/%s/%s/pulls/%s/reviews/%s", method => 'PUT', args => 1 },
71
72    # https://developer.github.com/v3/pulls/review_requests/
73    reviewers => { url => "/repos/%s/%s/pulls/%s/requested_reviewers", paginate => 1 },
74    add_reviewers => { url => "/repos/%s/%s/pulls/%s/requested_reviewers", method => 'POST', args => 1 },
75    delete_reviewers => { url => "/repos/%s/%s/pulls/%s/requested_reviewers", method => 'DELETE', check_status => 204, args => 1 },
76);
77__build_methods(__PACKAGE__, %__methods);
78
79no Moo;
80
811;
82__END__
83
84=head1 NAME
85
86Net::GitHub::V3::PullRequests - GitHub Pull Requests API
87
88=head1 SYNOPSIS
89
90    use Net::GitHub::V3;
91
92    my $gh = Net::GitHub::V3->new; # read L<Net::GitHub::V3> to set right authentication info
93    my $pull_request = $gh->pull_request;
94
95=head1 DESCRIPTION
96
97B<To ease the keyboard, we provied two ways to call any method which starts with :user/:repo>
98
991. SET user/repos before call methods below
100
101    $gh->set_default_user_repo('fayland', 'perl-net-github'); # take effects for all $gh->
102    $pull_request->set_default_user_repo('fayland', 'perl-net-github'); # only take effect to $gh->pull_request
103    my @pulls = $pull_request->pulls();
104
1052. If it is just for once, we can pass :user, :repo before any arguments
106
107    my @pulls = $pull_request->pulls($user, $repo);
108
109=head2 METHODS
110
111=head3 Pull Requets
112
113L<http://developer.github.com/v3/pulls/>
114
115=over 4
116
117=item pulls
118
119    my @pulls = $pull_request->pulls();
120    my @pulls = $pull_request->pulls( { state => 'open' } );
121    while (my $pr = $pull_request->next_pull( { state => 'open' } )) { ...; }
122
123=item pull
124
125    my $pull  = $pull_request->pull($pull_number);
126
127=item create_pull
128
129=item update_pull
130
131    my $pull = $pull_request->create_pull( {
132        "title" => "Amazing new feature",
133        "body" => "Please pull this in!",
134        "head" => "octocat:new-feature",
135        "base" => "master"
136    } );
137    my $pull = $pull_request->update_pull( $pull_number, $new_pull_data );
138
139=item commits
140
141=item files
142
143    my @commits = $pull_request->commits($pull_number);
144    my @files   = $pull_request->files($pull_number);
145    while (my $commit = $pull_request->next_commit($pull_number)) { ...; }
146    while (my $file = $pull_request->next_file($pull_number)) { ...; }
147
148
149=item is_merged
150
151=item merge
152
153    my $is_merged = $pull_request->is_merged($pull_number);
154    my $result    = $pull_request->merge($pull_number);
155
156=back
157
158=head3 Pull Request Comments API
159
160L<http://developer.github.com/v3/pulls/comments/>
161
162=over 4
163
164=item comments
165
166=item comment
167
168=item create_comment
169
170=item update_comment
171
172=item delete_comment
173
174    my @comments = $pull_request->comments($pull_number);
175    while (my $comment = $pull_request->next_comment($pull_number)) { ...; }
176    my $comment  = $pull_request->comment($comment_id);
177    my $comment  = $pull_request->create_comment($pull_number, {
178        "body" => "a new comment",
179        commit_id => '586fe4be94c32248043b344e99fa15c72b40d1c2',
180        path => 'test',
181        position => 1,
182    });
183    my $comment = $pull_request->update_comment($comment_id, {
184        "body" => "Nice change"
185    });
186    my $st = $pull_request->delete_comment($comment_id);
187
188=back
189
190=head3 Pull Request Reviews API
191
192L<http://developer.github.com/v3/pulls/reviews/>
193
194=over 4
195
196=item reviews
197
198=item review
199
200=item create_review
201
202=item update_review
203
204=item delete_review
205
206    my @reviews = $pull_request->reviews($pull_number);
207    while (my $review = $pull_request->next_review($pull_number)) { ...; }
208    my $review  = $pull_request->review($review_id);
209    my $review  = $pull_request->create_review($pull_number, {
210        "body" => "a new review",
211        commit_id => '586fe4be94c32248043b344e99fa15c72b40d1c2',
212        event => 'APPROVE',
213    });
214    my $review = $pull_request->update_review($review_id, {
215        "body" => "Nice change"
216    });
217    my $st = $pull_request->delete_review($review_id);
218
219=back
220
221=head3 Pull Request Review API
222
223L<https://developer.github.com/v3/pulls/review_requests/>
224
225=over 4
226
227=item reviewers
228
229=item add_reviewers
230
231=item delete_reviewers
232
233    my @reviewers = $pull_request->reviewers($pull_number);
234    my $result = $pull_request->add_reviewers($pull_number, {
235        reviewers => [$user1, $user2],
236        team_reviewers => [$team1],
237    );
238    my $result = $pull_request->delete_reviewers($pull_number, {
239        reviewers => [$user1, $user2],
240        team_reviewers => [$team1],
241    );
242
243=back
244
245=head1 AUTHOR & COPYRIGHT & LICENSE
246
247Refer L<Net::GitHub>
248