File Coverage

blib/lib/Test/Version.pm
Criterion Covered Total %
statement 139 143 97.2
branch 71 78 91.0
condition 20 26 76.9
subroutine 13 13 100.0
pod 2 2 100.0
total 245 262 93.5


line stmt bran cond sub pod time code
1             package Test::Version;
2 19     19   1289239 use 5.006;
  19         215  
3 19     19   97 use strict;
  19         34  
  19         402  
4 19     19   84 use warnings;
  19         27  
  19         425  
5 19     19   82 use Carp;
  19         31  
  19         1427  
6              
7             our $VERSION = '2.09'; # VERSION
8              
9 19     19   7955 use parent 'Exporter';
  19         5041  
  19         89  
10 19     19   979 use Test::Builder;
  19         35  
  19         461  
11 19     19   7533 use version 0.86 qw( is_lax is_strict );
  19         34049  
  19         122  
12 19     19   9738 use File::Find::Rule::Perl;
  19         310291  
  19         186  
13 19     19   2742 use Test::More;
  19         17055  
  19         136  
14 19     19   16474 use Module::Metadata 1.000020;
  19         105255  
  19         22060  
15              
16             our @EXPORT = qw( version_all_ok ); ## no critic (Modules::ProhibitAutomaticExportation)
17             our @EXPORT_OK = qw( version_ok );
18              
19             my $cfg;
20              
21             sub import { ## no critic qw( Subroutines::RequireArgUnpacking Subroutines::RequireFinalReturn )
22 23     23   21372 my @exports;
23 23         61 foreach my $param ( @_ ) {
24 59 100       151 unless ( ref( $param ) eq 'HASH' ) {
25 40         100 push @exports, $param;
26             } else {
27 19         47 $cfg = $param
28             }
29             }
30              
31             $cfg->{is_strict}
32             = defined $cfg->{is_strict} ? $cfg->{is_strict}
33 23 100       92 : 0
34             ;
35              
36             $cfg->{has_version}
37             = defined $cfg->{has_version} ? $cfg->{has_version}
38 23 100       70 : 1
39             ;
40              
41             $cfg->{consistent}
42             = defined $cfg->{consistent} ? $cfg->{consistent}
43 23 100       67 : 0
44             ;
45              
46             $cfg->{filename_match}
47             = defined $cfg->{filename_match} ? $cfg->{filename_match}
48 23 100       89 : []
49             ;
50              
51             $cfg->{multiple}
52             = defined $cfg->{multiple} ? $cfg->{multiple}
53 23 100       68 : 0
54             ;
55              
56 23 100       106 unless(ref($cfg->{filename_match}) eq 'ARRAY') {
57 3         10 $cfg->{filename_match} = [$cfg->{filename_match}];
58             }
59              
60 23         196 my $mmv = version->parse( $Module::Metadata::VERSION );
61 23         111 my $rec = version->parse( '1.000020' );
62 23 100 66     756 if ( $mmv >= $rec && ! defined $cfg->{ignore_unindexable} ) {
63 8         19 $cfg->{ignore_unindexable} = 1;
64             }
65              
66 23         22024 __PACKAGE__->export_to_level( 1, @exports );
67             }
68              
69             my $version_counter = 0;
70             my $version_number;
71             my $consistent = 1;
72             my %versions;
73              
74             my $test = Test::Builder->new;
75              
76             our $_IN_VERSION_ALL_OK = 0;
77             our %FILE_FIND_RULE_EXTRAS = (
78             untaint => 1,
79             #
80             # the untainting pattern for Windows used by File::Find seems to be wrong.
81             #
82             # - cwd returns an absolute directory will usually return a volume (e.g. 'C:')
83             # - windows file systems frequently include directorieswith parans and spaces in them
84             # I am a little dubious that accepting them is safe. The alternative is that
85             # this module would not be installable in a lot of environments, and I honestly
86             # don't believe that many people are using Test::Version in taint mode on Windows
87             # anyway, so I am weighing the risk as worth it.
88             # - windows has short names with tildes in them (e.g. "FOO~1"). Tilde is not a
89             # special character in windows shells anyway, so I think we should be safe there.
90             #
91             ($^O eq 'MSWin32' ? (untaint_pattern => qr|^(([a-zA-Z]:)?[-+@\w./\~\(\) ]+)$|x) : ()),
92             );
93              
94              
95             sub version_ok {
96 73     73 1 26238 my ( $file, $name ) = @_;
97 73   100     237 $file ||= '';
98 73   33     598 $name ||= "check version in '$file'";
99              
100 73 100       196 croak 'No file passed to version_ok().' unless $file;
101              
102 72 100       1388 croak "'$file' doesn't exist." unless -e $file;
103              
104 71         506 my $info = Module::Metadata->new_from_file( $file );
105 71 50 66     45082 if ( $cfg->{ignore_unindexable} && ! $info->is_indexable) {
106 0         0 $test->skip( "$file not indexable" );
107 0         0 return 0;
108             }
109              
110 71 100       393 if(@{ $cfg->{filename_match} } > 0) {
  71         196  
111 12         16 my $match = 0;
112 12         22 foreach my $pattern (@{ $cfg->{filename_match} }) {
  12         45  
113              
114 12 100       38 if(ref($pattern) eq 'Regexp') {
    100          
115 3 100       16 $match = 1 if $file =~ $pattern;
116             }
117              
118             elsif(ref($pattern) eq 'CODE') {
119 3 100       8 $match = 1 if $pattern->($file);
120             }
121              
122             else {
123 6 100       36 $match = 1 if $file eq $pattern;
124             }
125              
126 12 100       45 last if $match;
127             }
128 12 100       29 unless ($match) {
129 8         71 $test->skip( "$file does not match filename_match" );
130 8         1506 return 0;
131             }
132             }
133              
134 63         98 my $ok = 1;
135 63         96 my @diag;
136 63 100       260 my @packages = $cfg->{multiple} ? $info->packages_inside : ($info->name);
137              
138 63 100       303 unless($_IN_VERSION_ALL_OK) {
139 11         19 $consistent = 1;
140 11         18 $version_number = undef;
141             }
142              
143 63 100       132 unless($cfg->{has_version}) {
144 25         41 @packages = grep { $info->version($_) } @packages;
  25         55  
145 25 100       378 unless(@packages) {
146 6         76 $test->skip(qq{No versions were found in "$file" and has_version is false});
147 6         1112 $consistent = 0;
148 6         27 $versions{$file}->{$info->name} = undef;
149 6         46 return 1;
150             }
151             }
152              
153 57 50       113 unless(@packages) {
154 0         0 $ok = 0;
155 0         0 push @diag, "No packages found in '$file'";
156             }
157              
158 57         116 foreach my $package (@packages) {
159              
160 63         145 my $version = $info->version($package);
161              
162 63         673 $versions{$file}->{$package} = $version;
163              
164 63 100       134 if (not defined $version) {
165 10         17 $consistent = 0;
166             }
167              
168 63         82 $version_counter++;
169              
170 63 100       476 unless ( $version ) {
171 10         18 $ok = 0;
172 10         52 push @diag, "No version was found in '$file' ($package).";
173 10         28 next;
174             }
175              
176 53 100       191 unless (defined $version_number) {
177 21         39 $version_number = $version;
178             }
179 53 100       212 if ($version ne $version_number) {
180 27         43 $consistent = 0;
181             }
182              
183 53 100       187 unless ( is_lax( $version ) ) {
184 3         98 $ok = 0;
185 3         19 push @diag, "The version '$version' found in '$file' ($package) is invalid.";
186 3         11 next;
187             }
188              
189 50 100       1614 if ( $cfg->{is_strict} ) {
190 1 50       5 unless ( is_strict( $version ) ) {
191 1         36 $ok = 0;
192 1         8 push @diag, "The version '$version' found in '$file' ($package) is not strict.";
193 1         5 next;
194             }
195             }
196             }
197              
198 57 100       135 unless($_IN_VERSION_ALL_OK) {
199 11 100 100     73 if($ok && ! $consistent && $cfg->{consistent}) {
      100        
200 1         3 $ok = 0;
201 1         6 push @diag, "The versions found in '$file' are inconsistent.";
202             }
203             }
204              
205 57         394 $test->ok( $ok, $name );
206 57         22226 $test->diag($_) for @diag;
207 57         2396 return $ok;
208             }
209              
210             sub version_all_ok {
211 12     12 1 2868 my ( $dir, $name ) = @_;
212              
213 12         27 $version_counter = 0;
214 12         22 $version_number = undef;
215 12         23 $consistent = 1;
216 12         31 %versions = ();
217              
218 12 0       49 $dir
    50          
219             = defined $dir ? $dir
220             : -d 'blib' ? 'blib'
221             : 'lib'
222             ;
223              
224 12 50       276 croak $dir . ' does not exist, or is not a directory' unless -d $dir;
225              
226             # Report failure location correctly - GH #1
227 12         45 local $Test::Builder::Level = $Test::Builder::Level + 1; ## no critic (Variables::ProhibitPackageVars)
228              
229 12   33     97 $name ||= "all modules in $dir have valid versions";
230              
231 12         124 my @files = File::Find::Rule->perl_module->extras(\%FILE_FIND_RULE_EXTRAS)->in($dir);
232              
233             {
234 12         18821 local $_IN_VERSION_ALL_OK = 1;
  12         32  
235 12         31 foreach my $file ( @files ) {
236 60         131 version_ok( $file );
237             }
238             }
239              
240 12 100 100     70 if ($cfg->{consistent} and not $consistent) {
241 3         20 $test->ok( 0, $name );
242 3         1069 $test->diag('The version numbers in this distribution are not the same');
243 3         362 foreach my $file (sort keys %versions) {
244 8         655 foreach my $package (sort keys %{ $versions{$file} }) {
  8         32  
245 8         18 my $version = $versions{$file}->{$package};
246 8 100       78 $test->diag(sprintf "%10s %s (%s)", defined $version ? $version : 'undef', $file, $package);
247             }
248             }
249 3         381 return;
250             }
251              
252             # has at least 1 version in the dist
253 9 100 100     43 if ( not $cfg->{has_version} and $version_counter < 1 ) {
254 1         7 $test->ok( 0, $name );
255 1         416 $test->diag(
256             'Your dist has no valid versions defined. '
257             . 'Must have at least one version'
258             );
259             }
260             else {
261 8         48 $test->ok( 1, $name );
262             }
263              
264 9         3205 return;
265             }
266             1;
267              
268             # ABSTRACT: Check to see that version's in modules are sane
269              
270             __END__