File Coverage

blib/lib/Dist/Zilla/Plugin/GitHub/Update.pm
Criterion Covered Total %
statement 40 55 72.7
branch 4 18 22.2
condition 4 20 20.0
subroutine 7 7 100.0
pod 0 1 0.0
total 55 101 54.4


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::GitHub::Update;
2             # ABSTRACT: Update a GitHub repo's info on release
3 1     1   2328098 use strict;
  1         3  
  1         27  
4 1     1   4 use warnings;
  1         2  
  1         37  
5              
6             our $VERSION = '0.49';
7              
8 1     1   6 use JSON::MaybeXS;
  1         2  
  1         60  
9 1     1   5 use Moose;
  1         2  
  1         14  
10 1     1   5346 use List::Util 'first';
  1         2  
  1         658  
11              
12             extends 'Dist::Zilla::Plugin::GitHub';
13              
14             with 'Dist::Zilla::Role::AfterRelease';
15              
16             # deprecated and no longer documented. Use 'metacpan' instead!
17             has cpan => (
18             is => 'ro',
19             isa => 'Bool',
20             default => 0
21             );
22              
23             has p3rl => (
24             is => 'ro',
25             isa => 'Bool',
26             default => 0
27             );
28              
29             has metacpan => (
30             is => 'ro',
31             isa => 'Bool',
32             default => 1
33             );
34              
35             has meta_home => (
36             is => 'ro',
37             isa => 'Bool',
38             default => 0
39             );
40              
41             #pod =head1 SYNOPSIS
42             #pod
43             #pod Configure git with your GitHub credentials:
44             #pod
45             #pod $ git config --global github.user LoginName
46             #pod $ git config --global github.password GitHubPassword
47             #pod
48             #pod Alternatively you can install L<Config::Identity> and write your credentials
49             #pod in the (optionally GPG-encrypted) C<~/.github> file as follows:
50             #pod
51             #pod login LoginName
52             #pod password GitHubpassword
53             #pod
54             #pod (if only the login name is set, the password will be asked interactively).
55             #pod
56             #pod You can also generate an access token for "full control over repositories" by following
57             #pod L<these instructions|https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/>,
58             #pod
59             #pod then, in your F<dist.ini>:
60             #pod
61             #pod # default config
62             #pod [GitHub::Meta]
63             #pod
64             #pod # to override the repo name
65             #pod [GitHub::Meta]
66             #pod repo = SomeRepo
67             #pod
68             #pod See L</ATTRIBUTES> for more options.
69             #pod
70             #pod =head1 DESCRIPTION
71             #pod
72             #pod This Dist::Zilla plugin updates the information of the GitHub repository
73             #pod when C<dzil release> is run.
74             #pod
75             #pod =cut
76              
77             around dump_config => sub
78             {
79             my ($orig, $self) = @_;
80             my $config = $self->$orig;
81              
82             my $option = first { $self->$_ } qw(meta_home metacpan p3rl cpan);
83             if ($option eq 'cpan') {
84             $self->log->warn('the \'cpan\' option has been removed: please use \'metacpan\' instead');
85             $option = 'metacpan';
86             }
87              
88             $config->{+__PACKAGE__} = {
89             $option => ($self->$option ? 1 : 0),
90             };
91              
92             return $config;
93             };
94              
95             sub after_release {
96 1     1 0 118785 my $self = shift;
97 1         7 my ($opts) = @_;
98 1         176 my $dist_name = $self->zilla->name;
99              
100 1 50       105 return if (!$self->_has_credentials);
101              
102 1         32 my $repo_name = $self->_get_repo_name($self->_credentials->{login});
103 1 50       15 if (not $repo_name) {
104 0         0 $self->log('cannot update GitHub repository info');
105 0         0 return;
106             }
107              
108 1         42 my $params = {
109             name => ($repo_name =~ /\/(.*)$/)[0],
110             description => $self->zilla->abstract,
111             };
112              
113 1         56 my $with;
114 1 50 33     35 if ($self->meta_home && (my $meta_home = $self->zilla->distmeta->{resources}{homepage})) {
    0          
    0          
115 1         70 $with = ' using distmeta URL';
116 1         9 $params->{homepage} = $meta_home;
117             } elsif ($self->metacpan) {
118 0         0 $with = ' using MetaCPAN URL';
119 0         0 $params->{homepage} = "https://metacpan.org/release/$dist_name/";
120             } elsif ($self->p3rl) {
121 0         0 $with = ' using P3rl URL';
122 0         0 my $guess_name = $dist_name;
123 0         0 $guess_name =~ s/\-/\:\:/g;
124 0         0 $params->{homepage} = "https://p3rl.org/$guess_name";
125             }
126              
127 1   50     32 $self->log('Updating GitHub repository info'.($with // ''));
128              
129 1         331 my $url = $self->api."/repos/$repo_name";
130              
131 1         25 my $current = $self->_current_params($url);
132 1 0 0     9 if ($current &&
      33        
      0        
      33        
      0        
      0        
133             ($current->{name} || '') eq $params->{name} &&
134             ($current->{description} || '') eq $params->{description} &&
135             ($current->{homepage} || '') eq $params->{homepage}) {
136              
137 0         0 $self->log("GitHub repo info is up to date");
138 0         0 return;
139             }
140              
141 1         9 $self->log_debug("Sending PATCH $url");
142 1         228 my $response = HTTP::Tiny->new->request('PATCH', $url, {
143             content => encode_json($params),
144             headers => $self->_auth_headers,
145             });
146              
147 1         23 my $repo = $self->_check_response($response);
148              
149 1 50       17 return if not $repo;
150              
151 0 0       0 if ($repo eq 'redo') {
152 0         0 $self->log("Retrying with two-factor authentication");
153 0         0 $self->prompt_2fa(1);
154 0         0 $repo = $self->after_release($opts);
155 0 0       0 return if not $repo;
156             }
157             }
158              
159             sub _current_params {
160 1     1   5 my $self = shift;
161 1         6 my ($url) = @_;
162              
163 1         27 my $http = HTTP::Tiny->new;
164              
165 1         198 $self->log_debug("Sending GET $url");
166 1         295 my $response = $http->request('GET', $url);
167              
168 1         33 return $self->_check_response($response);
169             }
170              
171             __PACKAGE__->meta->make_immutable;
172             1; # End of Dist::Zilla::Plugin::GitHub::Update
173              
174             __END__
175              
176             =pod
177              
178             =encoding UTF-8
179              
180             =head1 NAME
181              
182             Dist::Zilla::Plugin::GitHub::Update - Update a GitHub repo's info on release
183              
184             =head1 VERSION
185              
186             version 0.49
187              
188             =head1 SYNOPSIS
189              
190             Configure git with your GitHub credentials:
191              
192             $ git config --global github.user LoginName
193             $ git config --global github.password GitHubPassword
194              
195             Alternatively you can install L<Config::Identity> and write your credentials
196             in the (optionally GPG-encrypted) C<~/.github> file as follows:
197              
198             login LoginName
199             password GitHubpassword
200              
201             (if only the login name is set, the password will be asked interactively).
202              
203             You can also generate an access token for "full control over repositories" by following
204             L<these instructions|https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/>,
205              
206             then, in your F<dist.ini>:
207              
208             # default config
209             [GitHub::Meta]
210              
211             # to override the repo name
212             [GitHub::Meta]
213             repo = SomeRepo
214              
215             See L</ATTRIBUTES> for more options.
216              
217             =head1 DESCRIPTION
218              
219             This Dist::Zilla plugin updates the information of the GitHub repository
220             when C<dzil release> is run.
221              
222             =head1 ATTRIBUTES
223              
224             =over
225              
226             =item C<repo>
227              
228             The name of the GitHub repository. By default the name will be extracted from
229             the URL of the remote specified in the C<remote> option, and if that fails the
230             dist name (from dist.ini) is used. It can also be in the form C<user/repo>
231             when it belongs to another GitHub user/organization.
232              
233             =item C<remote>
234              
235             The name of the Git remote pointing to the GitHub repository (C<"origin"> by
236             default). This is used when trying to guess the repository name.
237              
238             =item C<p3rl>
239              
240             The GitHub homepage field will be set to the p3rl.org shortened URL
241             (e.g. C<https://p3rl.org/Dist::Zilla::Plugin::GitHub>) if this option is set to true (default is
242             false).
243              
244             =item C<metacpan>
245              
246             The GitHub homepage field will be set to the metacpan.org distribution URL
247             (e.g. C<https://metacpan.org/release/Dist-Zilla-Plugin-GitHub>) if this option is set to true
248             (default).
249              
250             This takes precedence over the C<p3rl> options (if both are
251             true, metacpan will be used).
252              
253             =item C<meta_home>
254              
255             The GitHub homepage field will be set to the value present in the dist meta
256             (e.g. the one set by other plugins) if this option is set to true (default is
257             false). If no value is present in the dist meta, this option is ignored.
258              
259             This takes precedence over the C<metacpan> and C<p3rl> options (if all
260             three are true, meta_home will be used).
261              
262             =item C<prompt_2fa>
263              
264             Prompt for GitHub two-factor authentication code if this option is set to true
265             (default is false). If this option is set to false but GitHub requires 2fa for
266             the login, it'll be automatically enabled.
267              
268             =back
269              
270             =head1 SUPPORT
271              
272             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Zilla-Plugin-GitHub>
273             (or L<bug-Dist-Zilla-Plugin-GitHub@rt.cpan.org|mailto:bug-Dist-Zilla-Plugin-GitHub@rt.cpan.org>).
274              
275             There is also a mailing list available for users of this distribution, at
276             L<http://dzil.org/#mailing-list>.
277              
278             There is also an irc channel available for users of this distribution, at
279             L<C<#distzilla> on C<irc.perl.org>|irc://irc.perl.org/#distzilla>.
280              
281             =head1 AUTHOR
282              
283             Alessandro Ghedini <alexbio@cpan.org>
284              
285             =head1 COPYRIGHT AND LICENSE
286              
287             This software is copyright (c) 2011 by Alessandro Ghedini.
288              
289             This is free software; you can redistribute it and/or modify it under
290             the same terms as the Perl 5 programming language system itself.
291              
292             =cut