File Coverage

blib/lib/Test/Apocalypse/OutdatedPrereqs.pm
Criterion Covered Total %
statement 29 97 29.9
branch 0 26 0.0
condition 0 6 0.0
subroutine 11 15 73.3
pod 0 1 0.0
total 40 145 27.5


line stmt bran cond sub pod time code
1             #
2             # This file is part of Test-Apocalypse
3             #
4             # This software is copyright (c) 2014 by Apocalypse.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9 39     39   3938630 use strict; use warnings;
  39     39   49  
  39         1370  
  39         205  
  39         42  
  39         1804  
10             package Test::Apocalypse::OutdatedPrereqs;
11             $Test::Apocalypse::OutdatedPrereqs::VERSION = '1.003';
12             BEGIN {
13 39     39   508 $Test::Apocalypse::OutdatedPrereqs::AUTHORITY = 'cpan:APOCAL';
14             }
15              
16             # ABSTRACT: Plugin to detect outdated prereqs
17              
18 39     39   199 use Test::More;
  39         222  
  39         337  
19 39     39   11375 use YAML 0.70;
  39         971  
  39         2199  
20 39     39   17062 use CPANPLUS 0.90;
  39         6656687  
  39         2526  
21 39     39   388 use CPANPLUS::Configure; # TODO no version here, so we added CPANPLUS 0.90, ( should we use CPANPLUS::Internals instead? )
  39         40  
  39         233  
22 39     39   701 use CPANPLUS::Backend;
  39         78  
  39         155  
23 39     39   931 use version 0.77;
  39         813  
  39         386  
24 39     39   89139 use Module::CoreList 2.23;
  39         1204246  
  39         388  
25              
26 38     38   304 sub _do_automated { 0 }
27              
28             sub do_test {
29             # does META.yml exist?
30 0 0 0 0 0   if ( -e 'META.yml' and -f _ ) {
31 0           _load_yml( 'META.yml' );
32             } else {
33             # maybe one directory up?
34 0 0 0       if ( -e '../META.yml' and -f _ ) {
35 0           _load_yml( '../META.yml' );
36             } else {
37 0           plan tests => 1;
38 0           fail( 'META.yml is missing, unable to process it!' );
39             }
40             }
41              
42 0           return;
43             }
44              
45             sub _load_yml {
46             # we'll load a file
47 0     0     my $file = shift;
48              
49             # okay, proceed to load it!
50 0           my $data;
51 0           eval {
52 0           $data = YAML::LoadFile( $file );
53             };
54 0 0         if ( $@ ) {
55 0           plan tests => 1;
56 0           fail( "Unable to load $file => $@" );
57 0           return;
58             }
59              
60             # massage the data
61 0           $data = $data->{'requires'};
62 0 0         delete $data->{'perl'} if exists $data->{'perl'};
63              
64             # init the backend ( and set some options )
65 0           my $cpanconfig = CPANPLUS::Configure->new;
66 0           $cpanconfig->set_conf( 'verbose' => 0 );
67 0           $cpanconfig->set_conf( 'no_update' => 1 );
68              
69             # ARGH, CPANIDX doesn't work well with this kind of search...
70 0 0         if ( $cpanconfig->get_conf( 'source_engine' ) =~ /CPANIDX/ ) {
71 0           diag( "Disabling CPANIDX for CPANPLUS" );
72 0           $cpanconfig->set_conf( 'source_engine' => 'CPANPLUS::Internals::Source::Memory' );
73             }
74              
75 0           my $cpanplus = CPANPLUS::Backend->new( $cpanconfig );
76              
77             # silence CPANPLUS!
78 0           eval "no warnings; sub Log::Message::store { return }";
79              
80             # Okay, how many prereqs do we have?
81 0 0         if ( scalar keys %$data == 0 ) {
82 0           plan skip_all => "No prereqs found in META.yml";
83 0           return;
84             }
85              
86             # Argh, check for CPANPLUS sanity!
87             # Failed test 'no warnings'
88             # at /usr/local/share/perl/5.10.0/Test/NoWarnings.pm line 45.
89             # There were 1 warning(s)
90             # Previous test 189 'no breakpoint test of blib/lib/POE/Component/SSLify/ClientHandle.pm'
91             # Key 'archive' (/home/apoc/.cpanplus/01mailrc.txt.gz) is of invalid type for 'Archive::Extract::new' provided by CPANPLUS::Internals::Source::__create_author_tree at /usr/share/perl/5.10/CPANPLUS/Internals/Source.pm line 539
92             # at /usr/share/perl/5.10/Params/Check.pm line 565
93             # Params::Check::_store_error('Key \'archive\' (/home/apoc/.cpanplus/01mailrc.txt.gz) is of ...', 1) called at /usr/share/perl/5.10/Params/Check.pm line 345
94             # Params::Check::check('HASH(0x3ce9f50)', 'HASH(0x3cf7b08)') called at /usr/share/perl/5.10/Archive/Extract.pm line 227
95             {
96 0           my $warn_seen = 0;
  0            
97 0     0     local $SIG{'__WARN__'} = sub { $warn_seen = 1; return; };
  0            
  0            
98 0           my $module = $cpanplus->parse_module( 'module' => 'Test::More' );
99 0 0         if ( $warn_seen ) {
100 0           plan skip_all => "Unable to sanely use CPANPLUS, aborting!";
101 0           return;
102             }
103             }
104              
105             # analyze every one of them!
106 0           plan tests => scalar keys %$data;
107 0           foreach my $prereq ( keys %$data ) {
108 0           _check_cpan( $cpanplus, $prereq, $data->{ $prereq } );
109             }
110              
111 0           return;
112             }
113              
114             # checks a prereq against CPAN
115             sub _check_cpan {
116 0     0     my $backend = shift;
117 0           my $prereq = shift;
118 0           my $version = shift;
119              
120             # check CPANPLUS
121 0           my $module = $backend->parse_module( 'module' => $prereq );
122 0 0         if ( defined $module ) {
123             # okay, for starters we check to see if it's version 0 then we skip it
124 0 0         if ( $version eq '0' ) {
125 0           pass( "Skipping '$prereq' because it is specified as version 0" );
126 0           return;
127             }
128              
129             # Does the prereq have funky characters that we're unable to process now?
130 0 0         if ( $version =~ /[<>=,!]+/ ) {
131             # simple style of parsing, may blow up in the future!
132 0           my @versions = split( ',', $version );
133              
134             # sort them by version, descending
135 0           s/[\s<>=!]+// for @versions;
136 0           @versions = reverse sort { $a <=> $b }
  0            
137 0           map { version->new( $_ ) } @versions;
138              
139             # pick the highest version to use as comparison
140 0           $version = $versions[0];
141             }
142              
143             # convert both objects to version objects so we can compare
144 0 0         $version = version->new( $version ) if ! ref $version;
145 0           my $cpanversion = version->new( $module->version );
146              
147             # Make sure that the prereq version exists on CPAN
148 0 0         if ( $cpanversion < $version ) {
149 0           fail( "Warning: '$prereq' version $version is not found on CPAN!" );
150             } else {
151             # The version we specified should be the latest CPAN version
152 0           TODO: {
153 0           local $TODO = "OutdatedPrereqs";
154 0           cmp_ok( $cpanversion, '==', $version, "Comparing '$prereq' to CPAN version" );
155             }
156             }
157             } else {
158 0           my $release = Module::CoreList->first_release( $prereq );
159 0 0         if ( defined $release ) {
160 0           pass( "Skipping '$prereq' because it is a CORE module" );
161             } else {
162 0           fail( "Warning: '$prereq' is not found on CPAN!" );
163             }
164             }
165              
166 0           return;
167             }
168              
169             1;
170              
171             __END__
172              
173             =pod
174              
175             =encoding UTF-8
176              
177             =for :stopwords Apocalypse Niebur Ryan CPAN prereq prereqs backend
178              
179             =for Pod::Coverage do_test
180              
181             =head1 NAME
182              
183             Test::Apocalypse::OutdatedPrereqs - Plugin to detect outdated prereqs
184              
185             =head1 VERSION
186              
187             This document describes v1.003 of Test::Apocalypse::OutdatedPrereqs - released October 24, 2014 as part of Test-Apocalypse.
188              
189             =head1 DESCRIPTION
190              
191             This plugin detects outdated prereqs in F<META.yml> specified relative to CPAN. It uses L<CPANPLUS> as the backend.
192              
193             =head1 SEE ALSO
194              
195             Please see those modules/websites for more information related to this module.
196              
197             =over 4
198              
199             =item *
200              
201             L<Test::Apocalypse|Test::Apocalypse>
202              
203             =back
204              
205             =head1 AUTHOR
206              
207             Apocalypse <APOCAL@cpan.org>
208              
209             =head1 COPYRIGHT AND LICENSE
210              
211             This software is copyright (c) 2014 by Apocalypse.
212              
213             This is free software; you can redistribute it and/or modify it under
214             the same terms as the Perl 5 programming language system itself.
215              
216             The full text of the license can be found in the
217             F<LICENSE> file included with this distribution.
218              
219             =head1 DISCLAIMER OF WARRANTY
220              
221             THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
222             APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
223             HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
224             OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
225             THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
226             PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
227             IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
228             ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
229              
230             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
231             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
232             THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
233             GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
234             USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
235             DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
236             PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
237             EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
238             SUCH DAMAGES.
239              
240             =cut