File Coverage

blib/lib/Dist/Zilla/Plugin/TravisCI/StatusBadge.pm
Criterion Covered Total %
statement 78 78 100.0
branch 33 38 86.8
condition 14 18 77.7
subroutine 10 10 100.0
pod 0 1 0.0
total 135 145 93.1


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::TravisCI::StatusBadge;
2              
3             # ABSTRACT: Get Travis CI status badge for your markdown README
4              
5 3     3   6661670 use strict;
  3         11  
  3         104  
6 3     3   18 use warnings;
  3         7  
  3         116  
7 3     3   843 use Path::Tiny 0.004;
  3         11535  
  3         213  
8 3     3   594 use Encode qw(encode);
  3         14770  
  3         173  
9 3     3   1545 use Moose;
  3         492275  
  3         21  
10 3     3   23692 use namespace::autoclean;
  3         9206  
  3         27  
11 3     3   777 use Dist::Zilla::File::OnDisk;
  3         502039  
  3         4184  
12              
13             our $VERSION = '0.009'; # VERSION
14             our $AUTHORITY = 'cpan:CHIM'; # AUTHORITY
15              
16             with qw(
17             Dist::Zilla::Role::AfterBuild
18             );
19              
20             has readme => (
21             is => 'rw',
22             isa => 'Str',
23             predicate => 'has_readme',
24             clearer => 'clear_readme',
25             );
26              
27             has user => (
28             is => 'rw',
29             isa => 'Str',
30             predicate => 'has_user',
31             );
32              
33             has repo => (
34             is => 'rw',
35             isa => 'Str',
36             predicate => 'has_repo',
37             );
38              
39             has branch => (
40             is => 'rw',
41             isa => 'Str',
42             default => sub { 'master' },
43             );
44              
45             has vector => (
46             is => 'rw',
47             isa => 'Bool',
48             default => sub { 0 },
49             );
50              
51             has format => (
52             is => 'rw',
53             isa => Moose::Util::TypeConstraints::enum(['markdown', 'pod', '']),
54             default => sub { '' }
55             );
56              
57             has ext => (
58             is => 'rw',
59             isa => 'ArrayRef',
60             default => sub { [qw( md mkdn markdown pod )] },
61             );
62              
63             has names => (
64             is => 'rw',
65             isa => 'ArrayRef',
66             default => sub { [qw( README Readme )] },
67             );
68              
69             has matrix => (
70             is => 'rw',
71             isa => 'ArrayRef',
72             lazy => 1,
73             default => sub {
74             my ( $self ) = @_;
75              
76             my @combies;
77              
78             for my $ext ( @{ $self->ext } ) {
79             push @combies, map { $_ . '.' . $ext } @{ $self->names };
80             }
81              
82             [ @combies ];
83             },
84             );
85              
86              
87             sub after_build {
88 27     27 0 1095136 my ( $self ) = @_;
89              
90             # fill user/repo using distmeta
91 27 100 100     1393 $self->_try_distmeta() unless $self->has_user && $self->has_repo;
92              
93 27 100 100     1088 unless ( $self->has_user && $self->has_repo ) {
94 5         40 $self->log( "Missing option: user or repo." );
95 5         1824 return;
96             }
97              
98 22         159 my $file = $self->_try_any_readme();
99              
100 22 100       919 unless ( $self->has_readme ) {
101 3         22 $self->log( "No README found in root directory." );
102 3         1235 return;
103             }
104              
105 19         702 $self->log( "Override " . $self->readme . " in root directory." );
106              
107 19         7368 my $readme = Dist::Zilla::File::OnDisk->new( name => "$file" );
108              
109 19         7432 my $edited;
110              
111 19 100 66     758 if ($self->format eq 'pod' || ($self->readme =~ /\.pod$/ && $self->format eq '')) {
      100        
112 2         13 foreach my $line ( split /\n/, $readme->content ) {
113 42 100       2003 if ( $line =~ /^=head1 VERSION/ ) {
114 2         14 $self->log( "Inject build status badge" );
115 2 50       836 $line = join '' =>
116             sprintf(
117             qq(=for html <a href="https://travis-ci.org/%s/%s"><img alt="Build Status" src="https://travis-ci.org/%s/%s.%s?branch=%s" /></a>\n\n) =>
118             $self->user, $self->repo,
119             $self->user, $self->repo, ( $self->vector ? 'svg' : 'png' ), $self->branch,
120             ),
121             $line;
122             }
123 42         103 $edited .= $line . "\n";
124             }
125             } else {
126 17         110 foreach my $line ( split /\n/, $readme->content ) {
127 306 100       17090 if ( $line =~ /^# VERSION/ ) {
128 17         111 $self->log( "Inject build status badge" );
129 17 100       6701 $line = join '' =>
130             sprintf(
131             "[![Build Status](https://travis-ci.org/%s/%s.%s?branch=%s)](https://travis-ci.org/%s/%s)\n\n" =>
132             $self->user, $self->repo, ( $self->vector ? 'svg' : 'png' ), $self->branch,
133             $self->user, $self->repo
134             ),
135             $line;
136             }
137 306         727 $edited .= $line . "\n";
138             }
139             }
140              
141 19 50       707 my $encoding =
142             $readme->can( 'encoding' )
143             ? $readme->encoding
144             : 'raw' # Dist::Zilla pre-5.0
145             ;
146              
147 19 50       333 $file->spew_raw(
148             $encoding eq 'raw'
149             ? $edited
150             : encode( $encoding, $edited )
151             );
152              
153 19         10398 return;
154             }
155              
156              
157             # attempt to fill user/repo using distmeta resources
158             sub _try_distmeta {
159 20     20   95 my ( $self ) = @_;
160              
161 20         645 my $meta = $self->zilla->distmeta;
162              
163 20 100       1247 return unless exists $meta->{resources};
164              
165             # possible list of sources for user/repo:
166             # resources.repository.web
167             # resources.repository.url
168             # resources.homepage
169             my @sources = (
170             (
171             exists $meta->{resources}{repository}
172 10         48 ? grep { defined $_ } @{ $meta->{resources}{repository} }{qw( web url )}
  5         31  
173             : ()
174             ),
175             (
176             exists $meta->{resources}{homepage}
177             ? $meta->{resources}{homepage}
178             : ()
179 17 100       129 ),
    100          
180             );
181              
182             # remove duplicates
183 17         42 @sources = do {
184 17         61 my %seen = map { $_ => 1 } @sources;
  19         116  
185 17         104 sort keys %seen;
186             };
187              
188 17         63 for my $source ( @sources ) {
189             # dont overwrite
190 17 50 33     873 last if $self->has_user && $self->has_repo;
191              
192 17 100       106 next unless $source =~ m/github\.com/i;
193              
194             # taken from Dist/Zilla/Plugin/GithubMeta.pm
195             # thanks to BINGOS!
196 16         204 my ( $user, $repo ) = $source =~ m{
197             github\.com # the domain
198             [:/] ([^/]+) # the username (: for ssh, / for http)
199             / ([^/]+?) (?:\.git)? # the repo name
200             $
201             }ix;
202              
203 16 100 66     138 next unless defined $user && defined $repo;
204              
205 15         628 $self->user( $user );
206 15         588 $self->repo( $repo );
207              
208 15         49 last;
209             }
210             }
211              
212              
213             # guess readme filename
214             sub _try_any_readme {
215 22     22   63 my ( $self ) = @_;
216              
217 22         48 my $zillafile;
218              
219             my @variations = (
220             ( $self->has_readme ? $self->readme : () ),
221 22 100       1001 @{ $self->matrix },
  22         894  
222             );
223              
224 22         75 for my $name ( @variations ) {
225 65 50       1348 next unless $name;
226              
227 65         2952 $self->clear_readme;
228              
229 65         1820 my $file = $self->zilla->root->child( $name );
230              
231 65 100       4542 if ( $file->exists ) {
232 19         1379 $self->readme( $name );
233 19         49 $zillafile = $file;
234 19         61 last;
235             }
236             }
237              
238 22         146 return $zillafile;
239             }
240              
241             __PACKAGE__->meta->make_immutable;
242              
243             1;
244              
245             __END__
246              
247             =pod
248              
249             =encoding UTF-8
250              
251             =head1 NAME
252              
253             Dist::Zilla::Plugin::TravisCI::StatusBadge - Get Travis CI status badge for your markdown README
254              
255             =head1 VERSION
256              
257             version 0.009
258              
259             =head1 SYNOPSIS
260              
261             ; in dist.ini
262             [TravisCI::StatusBadge]
263             user = johndoe
264             repo = p5-John-Doe-Stuff
265             branch = foo ;; "master" by default
266             vector = 1 ;; SVG image
267              
268             ; or just
269             [TravisCI::StatusBadge]
270             ;; shortcut for "png image; master branch; user/repo from meta resources"
271              
272             =head1 DESCRIPTION
273              
274             Injects the Travis CI C<Build status> badge before the B<VERSION> header into any form of C<README.[md|pod]> file.
275              
276             Traget readme might be pointed via option L</readme> or guessed by module.
277              
278             Use L<Dist::Zilla::Plugin::ReadmeAnyFromPod> in markdown mode or any other plugin to generate target file
279              
280             [ReadmeAnyFromPod / ReadmeMdInRoot]
281             type = markdown
282             filename = README.md
283             location = root
284              
285             =for Pod::Coverage after_build
286              
287             =for Pod::Coverage _try_distmeta
288              
289             =for Pod::Coverage _try_distmeta
290              
291             =head1 OPTIONS
292              
293             =head2 readme
294              
295             The name of file to inject build status badge. No default value but there is some logic to guess target
296             filename. File can be named as C<README> or C<Readme> and has the one of following extensions: C<md>,
297             C<mkdn>, C<markdown> or C<pod>.
298              
299             In case of some name passed via this option, it will be used only if the target file exists otherwise
300             will be checked default variations and used first found.
301              
302             =head2 format
303              
304             Either C<pod> or C<markdown>. Optional. When unspecified, format is C<pod> if readme has a C<.pod> file extension and C<markdown> otherwise.
305              
306             =head2 user
307              
308             Github username. Might be obtained automatically (if not given) from META resources (C<resources.homepage>,
309             C<resources.repository.web>, C<resources.repository.url>).
310              
311             =head2 repo
312              
313             Github repository name. Might be obtained automatically (if not given) from META resources
314             (C<resources.homepage>, C<resources.repository.web>, C<resources.repository.url>).
315              
316             =head2 branch
317              
318             Branch name which build status should be shown. Optional. Default value is B<master>.
319              
320             =head2 vector
321              
322             Use vector representation (SVG) of build status image. Optional. Default value is B<false> which means
323             using of the raster representation (PNG).
324              
325             =head1 SEE ALSO
326              
327             Please see those modules/websites for more information related to this module.
328              
329             =over 4
330              
331             =item *
332              
333             L<https://travis-ci.org>
334              
335             =item *
336              
337             L<Dist::Zilla::Plugin::ReadmeAnyFromPod>
338              
339             =item *
340              
341             L<Dist::Zilla::Plugin::GithubMeta>
342              
343             =item *
344              
345             L<Dist::Zilla::Role::AfterBuild>
346              
347             =item *
348              
349             L<Dist::Zilla>
350              
351             =back
352              
353             =head1 BUGS
354              
355             Please report any bugs or feature requests on the bugtracker website
356             L<https://github.com/Wu-Wu/Dist-Zilla-Plugin-TravisCI-StatusBadge/issues>
357              
358             When submitting a bug or request, please include a test-file or a
359             patch to an existing test-file that illustrates the bug or desired
360             feature.
361              
362             =head1 AUTHOR
363              
364             Anton Gerasimov <chim@cpan.org>
365              
366             =head1 COPYRIGHT AND LICENSE
367              
368             This software is copyright (c) 2013 by Anton Gerasimov.
369              
370             This is free software; you can redistribute it and/or modify it under
371             the same terms as the Perl 5 programming language system itself.
372              
373             =cut