File Coverage

blib/lib/Test/Apocalypse/Dependencies.pm
Criterion Covered Total %
statement 32 95 33.6
branch 0 32 0.0
condition 0 12 0.0
subroutine 12 13 92.3
pod 0 1 0.0
total 44 153 28.7


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 38     38   2020870 use strict; use warnings;
  38     38   87  
  38         1486  
  38         157  
  38         43  
  38         1718  
10             package Test::Apocalypse::Dependencies;
11             $Test::Apocalypse::Dependencies::VERSION = '1.004';
12             BEGIN {
13 38     38   660 $Test::Apocalypse::Dependencies::AUTHORITY = 'cpan:APOCAL';
14             }
15              
16             # ABSTRACT: Plugin to check for metadata dependencies
17              
18 38     38   155 use Test::More;
  38         38  
  38         230  
19 38     38   27357 use File::Slurp 9999.13;
  38         312456  
  38         2450  
20 38     38   15165 use YAML::Any 0.72;
  38         32603  
  38         190  
21 38     38   116625 use JSON::Any 1.25;
  38         623303  
  38         192  
22 38     38   82563 use File::Find::Rule 0.32;
  38         7758  
  38         228  
23 38     38   17247 use Perl::PrereqScanner 1.000;
  38         17138070  
  38         418  
24 38     38   28292 use Test::Deep 0.108;
  38         233538  
  38         6335  
25 38     38   229 use CPAN::Meta::Requirements 2.113640;
  38         611  
  38         227  
26              
27 37     37   148 sub _do_automated { 0 }
28              
29             sub do_test {
30             # load the metadata
31 0     0 0   my $runtime_req;
32             my $test_req;
33 0           my $provides;
34 0 0         if ( -e 'META.json' ) {
    0          
35 0           my $file = read_file( 'META.json' );
36 0           my $metadata = JSON::Any->new->Load( $file );
37 0           $runtime_req = $metadata->{'prereqs'}{'runtime'}{'requires'};
38 0           $test_req = $metadata->{'prereqs'}{'test'}{'requires'};
39 0 0         $provides = $metadata->{'provides'} if exists $metadata->{'provides'};
40             } elsif ( -e 'META.yml' ) {
41 0           my $file = read_file( 'META.yml' );
42 0           my $metadata = Load( $file );
43 0           $runtime_req = $metadata->{'requires'};
44 0 0         $provides = $metadata->{'provides'} if exists $metadata->{'provides'};
45             } else {
46 0           die 'No META.(json|yml) found!';
47             }
48              
49             # Okay, scan the files
50 0           my $found_runtime = CPAN::Meta::Requirements->new;
51 0           my $found_test = CPAN::Meta::Requirements->new;
52 0           foreach my $file ( File::Find::Rule->file()->name( qr/\.pm$/ )->in( 'lib' ) ) {
53 0           $found_runtime->add_requirements( Perl::PrereqScanner->new->scan_file( $file ) );
54             }
55              
56             # scan the test dir only if we have test metadata
57 0 0         if ( defined $test_req ) {
58 0           foreach my $file ( File::Find::Rule->file()->name( qr/\.(pm|t|pl)$/ )->in( 't' ) ) {
59 0           $found_test->add_requirements( Perl::PrereqScanner->new->scan_file( $file ) );
60             }
61             }
62              
63             # Okay, the spec says that anything already in the runtime req shouldn't be listed in test req
64             # That means we need to "fake" the prereq and make sure the comparison is OK
65 0 0         if ( defined $test_req ) {
66 0           my %temp = %{ $found_test->as_string_hash };
  0            
67 0           foreach my $mod ( keys %temp ) {
68 0 0 0       if ( ! exists $test_req->{ $mod } and exists $runtime_req->{ $mod } ) {
69             # don't copy runtime_req's version because it might be different and cmp_deeply will complain!
70 0           $test_req->{ $mod } = $temp{ $mod };
71             }
72             }
73             }
74              
75             # We remove any prereqs that we provided in the package
76 0 0         if ( defined $provides ) {
77 0           foreach my $p ( keys %$provides ) {
78 0           $found_runtime->clear_requirement( $p );
79 0           $found_test->clear_requirement( $p );
80             }
81             }
82              
83             # Thanks to PoCo::SmokeBox::Uploads::Rsync's use of PoCo::Generic, we have to do this
84             # Mangle the found version to the required one if it was 0
85             {
86 0           my %temp = %{ $found_runtime->as_string_hash };
  0            
  0            
87 0           foreach my $p ( keys %temp ) {
88 0 0 0       if ( $runtime_req->{ $p } ne '0' and $temp{ $p } eq '0' ) {
89 0           $found_runtime->clear_requirement( $p );
90 0           $found_runtime->add_minimum( $p => $runtime_req->{ $p } );
91             }
92             }
93             }
94              
95             # Do the same for the test stuff
96 0 0         if ( defined $test_req ) {
97 0           my %temp = %{ $found_test->as_string_hash };
  0            
98 0           foreach my $p ( keys %temp ) {
99 0 0 0       if ( $test_req->{ $p } ne '0' and $temp{ $p } eq '0' ) {
100 0           $found_test->clear_requirement( $p );
101 0           $found_test->add_minimum( $p => $runtime_req->{ $p } );
102             }
103             }
104             }
105              
106             # remove 'perl' dep - we check it in MinimumVersion anyway
107 0 0         delete $runtime_req->{'perl'} if exists $runtime_req->{'perl'};
108 0 0 0       delete $test_req->{'perl'} if defined $test_req and exists $test_req->{'perl'};
109 0           $found_runtime->clear_requirement( 'perl' );
110 0           $found_test->clear_requirement( 'perl' );
111              
112             # Convert version objects to regular or we'll get something like this:
113             # Compared $data->{"Test\:\:NoPlan"}
114             # got : 'v0.0.6'
115             # expect : '0.0.6'
116 0           $found_runtime = $found_runtime->as_string_hash;
117 0           $found_runtime->{ $_ } =~ s/^v// for keys %$found_runtime;
118 0           $runtime_req->{ $_ } =~ s/^v// for keys %$runtime_req;
119              
120             # Do the actual comparison!
121 0 0         if ( defined $test_req ) {
122 0           plan tests => 2;
123              
124 0           $found_test = $found_test->as_string_hash;
125 0           $found_test->{ $_ } =~ s/^v// for keys %$found_test;
126 0           $test_req->{ $_ } =~ s/^v// for keys %$test_req;
127              
128             # TODO interesting, somewhere deep in the build chain it auto-upgraded Test::More version...
129             # I had 0.88 set but somehow 0.96 was in the META.yml argh!
130 0 0         if ( $found_test->{'Test::More'} ne $test_req->{'Test::More'} ) {
131 0           diag( 'Found weird Test::More version mismatch, ignoring it! (' . $found_test->{'Test::More'} . ' vs ' . $test_req->{'Test::More'} . ')' );
132 0           $found_test->{'Test::More'} = $test_req->{'Test::More'};
133             }
134             } else {
135 0           plan tests => 1;
136             }
137              
138 0           cmp_deeply( $found_runtime, $runtime_req, "Runtime requires" );
139 0 0         cmp_deeply( $found_test, $test_req, "Test requires" ) if defined $test_req;
140              
141 0           return;
142             }
143              
144             1;
145              
146             __END__
147              
148             =pod
149              
150             =encoding UTF-8
151              
152             =for :stopwords Apocalypse Niebur Ryan metadata
153              
154             =for Pod::Coverage do_test
155              
156             =head1 NAME
157              
158             Test::Apocalypse::Dependencies - Plugin to check for metadata dependencies
159              
160             =head1 VERSION
161              
162             This document describes v1.004 of Test::Apocalypse::Dependencies - released October 24, 2014 as part of Test-Apocalypse.
163              
164             =head1 DESCRIPTION
165              
166             Loads the metadata and uses L<Perl::PrereqScanner> to look for dependencies and compares the lists.
167              
168             =head1 SEE ALSO
169              
170             Please see those modules/websites for more information related to this module.
171              
172             =over 4
173              
174             =item *
175              
176             L<Test::Apocalypse|Test::Apocalypse>
177              
178             =back
179              
180             =head1 AUTHOR
181              
182             Apocalypse <APOCAL@cpan.org>
183              
184             =head1 COPYRIGHT AND LICENSE
185              
186             This software is copyright (c) 2014 by Apocalypse.
187              
188             This is free software; you can redistribute it and/or modify it under
189             the same terms as the Perl 5 programming language system itself.
190              
191             The full text of the license can be found in the
192             F<LICENSE> file included with this distribution.
193              
194             =head1 DISCLAIMER OF WARRANTY
195              
196             THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
197             APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
198             HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
199             OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
200             THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
201             PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
202             IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
203             ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
204              
205             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
206             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
207             THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
208             GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
209             USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
210             DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
211             PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
212             EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
213             SUCH DAMAGES.
214              
215             =cut