File Coverage

blib/lib/Dist/Zilla/Plugin/TravisCI/StatusBadge.pm
Criterion Covered Total %
statement 72 72 100.0
branch 28 32 87.5
condition 9 12 75.0
subroutine 10 10 100.0
pod 0 1 0.0
total 119 127 93.7


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   6383748 use strict;
  3         8  
  3         112  
6 3     3   18 use warnings;
  3         8  
  3         103  
7 3     3   874 use Path::Tiny 0.004;
  3         10680  
  3         170  
8 3     3   580 use Encode qw(encode);
  3         7387  
  3         132  
9 3     3   424 use Moose;
  3         454708  
  3         21  
10 3     3   21461 use namespace::autoclean;
  3         6732  
  3         22  
11 3     3   682 use Dist::Zilla::File::OnDisk;
  3         579057  
  3         2796  
12              
13             our $VERSION = '0.007'; # 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 ext => (
52             is => 'rw',
53             isa => 'ArrayRef',
54             default => sub { [qw( md mkdn markdown )] },
55             );
56              
57             has names => (
58             is => 'rw',
59             isa => 'ArrayRef',
60             default => sub { [qw( README Readme )] },
61             );
62              
63             has matrix => (
64             is => 'rw',
65             isa => 'ArrayRef',
66             lazy => 1,
67             default => sub {
68             my ( $self ) = @_;
69              
70             my @combies;
71              
72             for my $ext ( @{ $self->ext } ) {
73             push @combies, map { $_ . '.' . $ext } @{ $self->names };
74             }
75              
76             [ @combies ];
77             },
78             );
79              
80              
81             sub after_build {
82 22     22 0 986673 my ( $self ) = @_;
83              
84             # fill user/repo using distmeta
85 22 100 100     1059 $self->_try_distmeta() unless $self->has_user && $self->has_repo;
86              
87 22 100 100     805 unless ( $self->has_user && $self->has_repo ) {
88 5         40 $self->log( "Missing option: user or repo." );
89 5         2887 return;
90             }
91              
92 17         89 my $file = $self->_try_any_readme();
93              
94 17 100       667 unless ( $self->has_readme ) {
95 2         17 $self->log( "No README found in root directory." );
96 2         1052 return;
97             }
98              
99 15         479 $self->log( "Override " . $self->readme . " in root directory." );
100              
101 15         8052 my $readme = Dist::Zilla::File::OnDisk->new( name => "$file" );
102              
103 15         5826 my $edited;
104              
105 15         94 foreach my $line ( split /\n/, $readme->content ) {
106 270 100       14927 if ( $line =~ /^# VERSION/ ) {
107 15         86 $self->log( "Inject build status badge" );
108 15 100       7163 $line = join '' =>
109             sprintf(
110             "[![Build Status](https://travis-ci.org/%s/%s.%s?branch=%s)](https://travis-ci.org/%s/%s)\n\n" =>
111             $self->user, $self->repo,
112             ( $self->vector ? 'svg' : 'png' ),
113             $self->branch, $self->user, $self->repo
114             ),
115             $line;
116             }
117 270         634 $edited .= $line . "\n";
118             }
119              
120 15 50       524 my $encoding =
121             $readme->can( 'encoding' )
122             ? $readme->encoding
123             : 'raw' # Dist::Zilla pre-5.0
124             ;
125              
126 15 50       228 $file->spew_raw(
127             $encoding eq 'raw'
128             ? $edited
129             : encode( $encoding, $edited )
130             );
131              
132 15         8603 return;
133             }
134              
135              
136             # attempt to fill user/repo using distmeta resources
137             sub _try_distmeta {
138 18     18   57 my ( $self ) = @_;
139              
140 18         494 my $meta = $self->zilla->distmeta;
141              
142 18 100       1046 return unless exists $meta->{resources};
143              
144             # possible list of sources for user/repo:
145             # resources.repository.web
146             # resources.repository.url
147             # resources.homepage
148             my @sources = (
149             (
150             exists $meta->{resources}{repository}
151 10         37 ? grep { defined $_ } @{ $meta->{resources}{repository} }{qw( web url )}
  5         24  
152             : ()
153             ),
154             (
155             exists $meta->{resources}{homepage}
156             ? $meta->{resources}{homepage}
157             : ()
158 15 100       95 ),
    100          
159             );
160              
161             # remove duplicates
162 15         37 @sources = do {
163 15         46 my %seen = map { $_ => 1 } @sources;
  17         86  
164 15         84 sort keys %seen;
165             };
166              
167 15         55 for my $source ( @sources ) {
168             # dont overwrite
169 15 50 33     643 last if $self->has_user && $self->has_repo;
170              
171 15 100       86 next unless $source =~ m/github\.com/i;
172              
173             # taken from Dist/Zilla/Plugin/GithubMeta.pm
174             # thanks to BINGOS!
175 14         121 my ( $user, $repo ) = $source =~ m{
176             github\.com # the domain
177             [:/] ([^/]+) # the username (: for ssh, / for http)
178             / ([^/]+?) (?:\.git)? # the repo name
179             $
180             }ix;
181              
182 14 100 66     108 next unless defined $user && defined $repo;
183              
184 13         492 $self->user( $user );
185 13         499 $self->repo( $repo );
186              
187 13         47 last;
188             }
189             }
190              
191              
192             # guess readme filename
193             sub _try_any_readme {
194 17     17   52 my ( $self ) = @_;
195              
196 17         37 my $zillafile;
197              
198             my @variations = (
199             ( $self->has_readme ? $self->readme : () ),
200 17 100       629 @{ $self->matrix },
  17         588  
201             );
202              
203 17         57 for my $name ( @variations ) {
204 43 50       843 next unless $name;
205              
206 43         1772 $self->clear_readme;
207              
208 43         1208 my $file = $self->zilla->root->child( $name );
209              
210 43 100       3026 if ( $file->exists ) {
211 15         1101 $self->readme( $name );
212 15         35 $zillafile = $file;
213 15         45 last;
214             }
215             }
216              
217 17         96 return $zillafile;
218             }
219              
220             __PACKAGE__->meta->make_immutable;
221              
222             1;
223              
224             __END__
225              
226             =pod
227              
228             =encoding UTF-8
229              
230             =head1 NAME
231              
232             Dist::Zilla::Plugin::TravisCI::StatusBadge - Get Travis CI status badge for your markdown README
233              
234             =head1 VERSION
235              
236             version 0.007
237              
238             =head1 SYNOPSIS
239              
240             ; in dist.ini
241             [TravisCI::StatusBadge]
242             user = johndoe
243             repo = p5-John-Doe-Stuff
244             branch = foo ;; "master" by default
245             vector = 1 ;; SVG image
246              
247             ; or just
248             [TravisCI::StatusBadge]
249             ;; shortcut for "png image; master branch; user/repo from meta resources"
250              
251             =head1 DESCRIPTION
252              
253             Injects the Travis CI C<Build status> badge before the B<VERSION> header into any form of C<README.md>
254             file.
255              
256             Traget readme might be pointed via option L</readme> or guessed by module.
257              
258             Use L<Dist::Zilla::Plugin::ReadmeAnyFromPod> in markdown mode or any other plugin to generate target file
259              
260             [ReadmeAnyFromPod / ReadmeMdInRoot]
261             type = markdown
262             filename = README.md
263             location = root
264              
265             =for Pod::Coverage after_build
266              
267             =for Pod::Coverage _try_distmeta
268              
269             =for Pod::Coverage _try_distmeta
270              
271             =head1 OPTIONS
272              
273             =head2 readme
274              
275             The name of file to inject build status badge. No default value but there is some logic to guess target
276             filename. File can be named as C<README> or C<Readme> and has the one of following extensions: C<md>,
277             C<mkdn> or C<markdown>.
278              
279             In case of some name passed via this option, it will be used only if the target file exists otherwise
280             will be checked default variations and used first found.
281              
282             =head2 user
283              
284             Github username. Might be obtained automatically (if not given) from META resources (C<resources.homepage>,
285             C<resources.repository.web>, C<resources.repository.url>).
286              
287             =head2 repo
288              
289             Github repository name. Might be obtained automatically (if not given) from META resources
290             (C<resources.homepage>, C<resources.repository.web>, C<resources.repository.url>).
291              
292             =head2 branch
293              
294             Branch name which build status should be shown. Optional. Default value is B<master>.
295              
296             =head2 vector
297              
298             Use vector representation (SVG) of build status image. Optional. Default value is B<false> which means
299             using of the raster representation (PNG).
300              
301             =head1 SEE ALSO
302              
303             L<https://travis-ci.org>
304              
305             L<Dist::Zilla::Plugin::ReadmeAnyFromPod>
306              
307             L<Dist::Zilla::Plugin::GithubMeta>
308              
309             L<Dist::Zilla::Role::AfterBuild>
310              
311             L<Dist::Zilla>
312              
313             =head1 AUTHOR
314              
315             Anton Gerasimov <chim@cpan.org>
316              
317             =head1 COPYRIGHT AND LICENSE
318              
319             This software is copyright (c) 2013 by Anton Gerasimov.
320              
321             This is free software; you can redistribute it and/or modify it under
322             the same terms as the Perl 5 programming language system itself.
323              
324             =cut