File Coverage

blib/lib/Parse/PMFile.pm
Criterion Covered Total %
statement 312 476 65.5
branch 134 240 55.8
condition 52 143 36.3
subroutine 32 41 78.0
pod 2 2 100.0
total 532 902 58.9


line stmt bran cond sub pod time code
1             package Parse::PMFile;
2              
3 80     80   11599 sub __clean_eval { eval $_[0] } # needs to be here (RT#101273)
4              
5 48     48   3316349 use strict;
  48         595  
  48         1553  
6 48     48   264 use warnings;
  48         97  
  48         1390  
7 48     48   26787 use Safe;
  48         1834427  
  48         2890  
8 48     48   35475 use JSON::PP ();
  48         722643  
  48         1489  
9 48     48   25893 use Dumpvalue;
  48         232835  
  48         2400  
10 48     48   21999 use version ();
  48         93711  
  48         1399  
11 48     48   408 use File::Spec ();
  48         112  
  48         55798  
12              
13             our $VERSION = '0.43';
14             our $VERBOSE = 0;
15             our $ALLOW_DEV_VERSION = 0;
16             our $FORK = 0;
17             our $UNSAFE = $] < 5.010000 ? 1 : 0;
18              
19             sub new {
20 128     128 1 381050 my ($class, $meta, $opts) = @_;
21 128 100       406 bless {%{ $opts || {} }, META_CONTENT => $meta}, $class;
  128         1550  
22             }
23              
24             # from PAUSE::pmfile::examine_fio
25             sub parse {
26 128     128 1 1006 my ($self, $pmfile) = @_;
27              
28 128         448 $pmfile =~ s|\\|/|g;
29              
30 128         2539 my($filemtime) = (stat $pmfile)[9];
31 128         788 $self->{MTIME} = $filemtime;
32 128         350 $self->{PMFILE} = $pmfile;
33              
34 128 100       492 unless ($self->_version_from_meta_ok) {
35 122         239 my $version;
36 122 50       241 unless (eval { $version = $self->_parse_version; 1 }) {
  122         411  
  97         488  
37 0         0 $self->_verbose(1, "error with version in $pmfile: $@");
38 0         0 return;
39             }
40              
41 97         592 $self->{VERSION} = $version;
42 97 50 66     1499 if ($self->{VERSION} =~ /^\{.*\}$/) {
    100 100        
43             # JSON error message
44             } elsif ($self->{VERSION} =~ /[_\s]/ && !$self->{ALLOW_DEV_VERSION} && !$ALLOW_DEV_VERSION){ # ignore developer releases and "You suck!"
45 5         68 return;
46             }
47             }
48              
49 98         1001 my($ppp) = $self->_packages_per_pmfile;
50 98         1361 my @keys_ppp = $self->_filter_ppps(sort keys %$ppp);
51 98         626 $self->_verbose(1,"Will check keys_ppp[@keys_ppp]\n");
52              
53             #
54             # Immediately after each package (pmfile) examined contact
55             # the database
56             #
57              
58 98         376 my ($package, %errors);
59 98         0 my %checked_in;
60 98         443 DBPACK: foreach $package (@keys_ppp) {
61             # this part is taken from PAUSE::package::examine_pkg
62             # and PAUSE::package::_pkg_name_insane
63 92 50 33     3790 if ($package !~ /^\w[\w\:\']*\w?\z/
      33        
      33        
      33        
      33        
64             || $package !~ /\w\z/
65             || $package =~ /:/ && $package !~ /::/
66             || $package =~ /\w:\w/
67             || $package =~ /:::/
68             ){
69 0         0 $self->_verbose(1,"Package[$package] did not pass the ultimate sanity check");
70 0         0 delete $ppp->{$package};
71 0         0 next;
72             }
73              
74 92 0 33     383 if ($self->{USERID} && $self->{PERMISSIONS} && !$self->_perm_check($package)) {
      0        
75 0         0 delete $ppp->{$package};
76 0         0 next;
77             }
78              
79             # Check that package name matches case of file name
80             {
81 92         189 my (undef, $module) = split m{/lib/}, $self->{PMFILE}, 2;
  92         528  
82 92 100       359 if ($module) {
83 6         43 $module =~ s{\.pm\z}{};
84 6         40 $module =~ s{/}{::}g;
85              
86 6 50 33     67 if (lc $module eq lc $package && $module ne $package) {
87             # warn "/// $self->{PMFILE} vs. $module vs. $package\n";
88             $errors{$package} = {
89             indexing_warning => "Capitalization of package ($package) does not match filename!",
90             infile => $self->{PMFILE},
91 0         0 };
92             }
93             }
94             }
95              
96 92         242 my $pp = $ppp->{$package};
97 92 50 66     836 if ($pp->{version} && $pp->{version} =~ /^\{.*\}$/) { # JSON parser error
98 0         0 my $err = JSON::PP::decode_json($pp->{version});
99 0 0       0 if ($err->{x_normalize}) {
    0          
100             $errors{$package} = {
101             normalize => $err->{version},
102             infile => $pp->{infile},
103 0         0 };
104 0         0 $pp->{version} = "undef";
105             } elsif ($err->{openerr}) {
106 0         0 $pp->{version} = "undef";
107 0         0 $self->_verbose(1,
108             qq{Parse::PMFile was not able to
109             read the file. It issued the following error: C< $err->{r} >},
110             );
111             $errors{$package} = {
112             open => $err->{r},
113             infile => $pp->{infile},
114 0         0 };
115             } else {
116 0         0 $pp->{version} = "undef";
117 0         0 $self->_verbose(1,
118             qq{Parse::PMFile was not able to
119             parse the following line in that file: C< $err->{line} >
120              
121             Note: the indexer is running in a Safe compartement and cannot
122             provide the full functionality of perl in the VERSION line. It
123             is trying hard, but sometime it fails. As a workaround, please
124             consider writing a META.yml that contains a 'provides'
125             attribute or contact the CPAN admins to investigate (yet
126             another) workaround against "Safe" limitations.)},
127              
128             );
129             $errors{$package} = {
130             parse_version => $err->{line},
131             infile => $err->{file},
132 0         0 };
133             }
134             }
135              
136             # Sanity checks
137              
138 92         329 for (
139             $package,
140             $pp->{version},
141             ) {
142 184 50 66     2557 if (!defined || /^\s*$/ || /\s/){ # for whatever reason I come here
      66        
143 4         10 delete $ppp->{$package};
144 4         8 next; # don't screw up 02packages
145             }
146             }
147 92 100       624 unless ($self->_version_ok($pp)) {
148             $errors{$package} = {
149             long_version => qq{Version string exceeds maximum allowed length of 16b: "$pp->{version}"},
150             infile => $pp->{infile},
151 3         39 };
152 3         11 next;
153             }
154 89         356 $checked_in{$package} = $ppp->{$package};
155             } # end foreach package
156              
157 98 100 66     1231 return (wantarray && %errors) ? (\%checked_in, \%errors) : \%checked_in;
158             }
159              
160             sub _version_ok {
161 92     92   335 my ($self, $pp) = @_;
162 92 100 100     493 return if length($pp->{version} || 0) > 16;
163 89         315 return 1
164             }
165              
166             sub _perm_check {
167 0     0   0 my ($self, $package) = @_;
168 0         0 my $userid = $self->{USERID};
169 0         0 my $module = $self->{PERMISSIONS}->module_permissions($package);
170 0 0       0 return 1 if !$module; # not listed yet
171 0 0 0     0 return 1 if defined $module->m && $module->m eq $userid;
172 0 0 0     0 return 1 if defined $module->f && $module->f eq $userid;
173 0 0 0     0 return 1 if defined $module->c && grep {$_ eq $userid} @{$module->c};
  0         0  
  0         0  
174 0         0 return;
175             }
176              
177             # from PAUSE::pmfile;
178             sub _parse_version {
179 122     122   269 my $self = shift;
180              
181 48     48   464 use strict;
  48         111  
  48         16568  
182              
183 122         291 my $pmfile = $self->{PMFILE};
184 122         6433 my $tmpfile = File::Spec->catfile(File::Spec->tmpdir, "ParsePMFile$$" . rand(1000));
185              
186 122         434 my $pmcp = $pmfile;
187 122         342 for ($pmcp) {
188 122         456 s/([^\\](\\\\)*)@/$1\\@/g; # thanks to Raphael Manfredi for the
189             # solution to escape @s and \
190             }
191 122         273 my($v);
192             {
193              
194 122         207 package main; # seems necessary
195              
196             # XXX: do we need to fork as PAUSE does?
197             # or, is alarm() just fine?
198 122         522 my $pid;
199 122 100 66     912 if ($self->{FORK} || $FORK) {
200 61         65022 $pid = fork();
201 61 50       6081 die "Can't fork: $!" unless defined $pid;
202             }
203 122 100       1450 if ($pid) {
204 36         15572145 waitpid($pid, 0);
205 36 50       8947 if (open my $fh, '<', $tmpfile) {
206 36         5967 $v = <$fh>;
207             }
208             } else {
209             # XXX Limit Resources too
210              
211 86         652 my $comp;
212 86         844 my $eval = qq{
213             local(\$^W) = 0;
214             Parse::PMFile::_parse_version_safely("$pmcp");
215             };
216 86 50 33     1425 unless ($self->{UNSAFE} || $UNSAFE) {
217 86         3684 $comp = Safe->new;
218 86         147238 $comp->permit("entereval"); # for MBARBON/Module-Info-0.30.tar.gz
219 86         1563 $comp->share("*Parse::PMFile::_parse_version_safely");
220 86         10059 $comp->share("*version::new");
221 86         5144 $comp->share("*version::numify");
222 86         5221 $comp->share_from('main', ['*version::',
223             '*charstar::',
224             '*Exporter::',
225             '*DynaLoader::']);
226 86         110976 $comp->share_from('version', ['&qv']);
227 86         4833 $comp->permit(":base_math"); # atan2 (Acme-Pi)
228             # $comp->permit("require"); # no strict!
229 86         1171 $comp->deny(qw/enteriter iter unstack goto/); # minimum protection against Acme::BadExample
230             }
231              
232 86 50 33     2616 version->import('qv') if $self->{UNSAFE} || $UNSAFE;
233             {
234 48     48   763 no strict;
  48         101  
  48         16001  
  86         566  
235 86 50       1276 $v = $comp ? $comp->reval($eval) : eval $eval;
236             }
237 86 100       91558 if ($@){ # still in the child process, out of Safe::reval
238 21         78 my $err = $@;
239             # warn ">>>>>>>err[$err]<<<<<<<<";
240 21 50       185 if (ref $err) {
241 21 50       377 if ($err->{line} =~ /([\$*])([\w\:\']*)\bVERSION\b.*?\=(.*)/) {
242 21         119 local($^W) = 0;
243 21         147 my ($sigil, $vstr) = ($1, $3);
244 21 50       532 $self->_restore_overloaded_stuff(1) if $err->{line} =~ /use\s+version\b|version\->|qv\(/;
245 21 50       130 $v = $comp ? $comp->reval($vstr) : eval $vstr;
246 21 50 33     22022 $v = $$v if $sigil eq '*' && ref $v;
247             }
248 21 50 33     299 if ($@ or !$v) {
249 0         0 $self->_verbose(1, sprintf("reval failed: err[%s] for eval[%s]",
250             JSON::PP::encode_json($err),
251             $eval,
252             ));
253 0         0 $v = JSON::PP::encode_json($err);
254             }
255             } else {
256 0         0 $v = JSON::PP::encode_json({ openerr => $err });
257             }
258             }
259 86 50       575 if (defined $v) {
260 48     48   402 no warnings;
  48         101  
  48         14920  
261 86 100       1139 $v = $v->numify if ref($v) =~ /^version(::vpp)?$/;
262             } else {
263 0         0 $v = "";
264             }
265 86 100 66     2324 if ($self->{FORK} || $FORK) {
266 25         4226 open my $fh, '>:utf8', $tmpfile;
267 25         455 print $fh $v;
268 25         1934 exit 0;
269             } else {
270 61         370 utf8::encode($v);
271             # undefine empty $v as if read from the tmpfile
272 61 50 33     503 $v = undef if defined $v && !length $v;
273 61 50       504 $comp->erase if ($comp);
274 61         64960 $self->_restore_overloaded_stuff;
275             }
276             }
277             }
278 97 100 66     11392 unlink $tmpfile if ($self->{FORK} || $FORK) && -e $tmpfile;
      66        
279              
280 97         1389 return $self->_normalize_version($v);
281             }
282              
283             sub _restore_overloaded_stuff {
284 82     82   378 my ($self, $used_version_in_safe) = @_;
285 82 50 33     895 return if $self->{UNSAFE} || $UNSAFE;
286              
287 48     48   444 no strict 'refs';
  48         136  
  48         1885  
288 48     48   335 no warnings 'redefine';
  48         805  
  48         52064  
289              
290             # version XS in CPAN
291 82         215 my $restored;
292 82 50       370 if ($INC{'version/vxs.pm'}) {
293 0         0 *{'version::(""'} = \&version::vxs::stringify;
  0         0  
294 0         0 *{'version::(0+'} = \&version::vxs::numify;
  0         0  
295 0         0 *{'version::(cmp'} = \&version::vxs::VCMP;
  0         0  
296 0         0 *{'version::(<=>'} = \&version::vxs::VCMP;
  0         0  
297 0         0 *{'version::(bool'} = \&version::vxs::boolean;
  0         0  
298 0         0 $restored = 1;
299             }
300             # version PP in CPAN
301 82 50       331 if ($INC{'version/vpp.pm'}) {
302             {
303 0         0 package # hide from PAUSE
304             charstar;
305 0         0 overload->import;
306             }
307 0 0       0 if (!$used_version_in_safe) {
308             package # hide from PAUSE
309             version::vpp;
310 0         0 overload->import;
311             }
312 0 0       0 unless ($restored) {
313 0         0 *{'version::(""'} = \&version::vpp::stringify;
  0         0  
314 0         0 *{'version::(0+'} = \&version::vpp::numify;
  0         0  
315 0         0 *{'version::(cmp'} = \&version::vpp::vcmp;
  0         0  
316 0         0 *{'version::(<=>'} = \&version::vpp::vcmp;
  0         0  
317 0         0 *{'version::(bool'} = \&version::vpp::vbool;
  0         0  
318             }
319 0         0 *{'version::vpp::(""'} = \&version::vpp::stringify;
  0         0  
320 0         0 *{'version::vpp::(0+'} = \&version::vpp::numify;
  0         0  
321 0         0 *{'version::vpp::(cmp'} = \&version::vpp::vcmp;
  0         0  
322 0         0 *{'version::vpp::(<=>'} = \&version::vpp::vcmp;
  0         0  
323 0         0 *{'version::vpp::(bool'} = \&version::vpp::vbool;
  0         0  
324 0         0 *{'charstar::(""'} = \&charstar::thischar;
  0         0  
325 0         0 *{'charstar::(0+'} = \&charstar::thischar;
  0         0  
326 0         0 *{'charstar::(++'} = \&charstar::increment;
  0         0  
327 0         0 *{'charstar::(--'} = \&charstar::decrement;
  0         0  
328 0         0 *{'charstar::(+'} = \&charstar::plus;
  0         0  
329 0         0 *{'charstar::(-'} = \&charstar::minus;
  0         0  
330 0         0 *{'charstar::(*'} = \&charstar::multiply;
  0         0  
331 0         0 *{'charstar::(cmp'} = \&charstar::cmp;
  0         0  
332 0         0 *{'charstar::(<=>'} = \&charstar::spaceship;
  0         0  
333 0         0 *{'charstar::(bool'} = \&charstar::thischar;
  0         0  
334 0         0 *{'charstar::(='} = \&charstar::clone;
  0         0  
335 0         0 $restored = 1;
336             }
337             # version in core
338 82 50       431 if (!$restored) {
339 82         208 *{'version::(""'} = \&version::stringify;
  82         386  
340 82         248 *{'version::(0+'} = \&version::numify;
  82         394  
341 82         262 *{'version::(cmp'} = \&version::vcmp;
  82         304  
342 82         251 *{'version::(<=>'} = \&version::vcmp;
  82         255  
343 82         189 *{'version::(bool'} = \&version::boolean;
  82         529  
344             }
345             }
346              
347             # from PAUSE::pmfile;
348             sub _packages_per_pmfile {
349 98     98   320 my $self = shift;
350              
351 98         296 my $ppp = {};
352 98         353 my $pmfile = $self->{PMFILE};
353 98         283 my $filemtime = $self->{MTIME};
354 98         354 my $version = $self->{VERSION};
355              
356 98 50       4706 open my $fh, "<", "$pmfile" or return $ppp;
357              
358 98         1239 local $/ = "\n";
359 98         301 my $inpod = 0;
360              
361 98         2422 PLINE: while (<$fh>) {
362 5266         7580 chomp;
363 5266         8191 my($pline) = $_;
364 5266 50       10875 $inpod = $pline =~ /^=(?!cut)/ ? 1 :
    50          
365             $pline =~ /^=cut/ ? 0 : $inpod;
366 5266 50       8484 next if $inpod;
367 5266 50       9404 next if substr($pline,0,4) eq "=cut";
368              
369 5266         8776 $pline =~ s/\#.*//;
370 5266 100       13626 next if $pline =~ /^\s*$/;
371 4160 100 66     8278 if ($pline =~ /^__(?:END|DATA)__\b/
372             and $pmfile !~ /\.PL$/ # PL files may well have code after __DATA__
373             ){
374 9         45 last PLINE;
375             }
376              
377 4151         5577 my $pkg;
378             my $strict_version;
379              
380 4151 100       19896 if (
381             $pline =~ m{
382             # (.*) # takes too much time if $pline is long
383             #(?
384             ^[\s\{;]*
385             \bpackage\s+
386             ([\w\:\']+)
387             \s*
388             (?: $ | [\}\;] | \{ | \s+($version::STRICT) )
389             }x) {
390 101         582 $pkg = $1;
391 101         311 $strict_version = $2;
392 101 50       369 if ($pkg eq "DB"){
393             # XXX if pumpkin and perl make him comaintainer! I
394             # think I always made the pumpkins comaint on DB
395             # without further ado (?)
396 0         0 next PLINE;
397             }
398             }
399              
400 4151 100       12487 if ($pkg) {
401             # Found something
402              
403             # from package
404 101         414 $pkg =~ s/\'/::/g;
405 101 50       648 next PLINE unless $pkg =~ /^[A-Za-z]/;
406 101 50       590 next PLINE unless $pkg =~ /\w$/;
407 101 100       371 next PLINE if $pkg eq "main";
408             # Perl::Critic::Policy::TestingAndDebugging::ProhibitShebangWarningsArg
409             # database for modid in mods, package in packages, package in perms
410             # alter table mods modify modid varchar(128) binary NOT NULL default '';
411             # alter table packages modify package varchar(128) binary NOT NULL default '';
412 95 50       338 next PLINE if length($pkg) > 128;
413             #restriction
414 95         686 $ppp->{$pkg}{parsed}++;
415 95         414 $ppp->{$pkg}{infile} = $pmfile;
416 95 50       615 if ($self->_simile($pmfile,$pkg)) {
417 95         354 $ppp->{$pkg}{simile} = $pmfile;
418 95 100       524 if ($self->_version_from_meta_ok) {
419 6         24 my $provides = $self->{META_CONTENT}{provides};
420 6 50       20 if (exists $provides->{$pkg}) {
421 6 50       21 if (defined $provides->{$pkg}{version}) {
422 6         19 my $v = $provides->{$pkg}{version};
423 6 100 33     95 if ($v =~ /[_\s]/ && !$self->{ALLOW_DEV_VERSION} && !$ALLOW_DEV_VERSION){ # ignore developer releases and "You suck!"
      66        
424 4         26 next PLINE;
425             }
426              
427 2 50       21 unless (eval { $version = $self->_normalize_version($v); 1 }) {
  2         18  
  2         18  
428 0         0 $self->_verbose(1, "error with version in $pmfile: $@");
429 0         0 next;
430              
431             }
432 2         14 $ppp->{$pkg}{version} = $version;
433             } else {
434 0         0 $ppp->{$pkg}{version} = "undef";
435             }
436             }
437             } else {
438 89 100       294 if (defined $strict_version){
439 3         15 $ppp->{$pkg}{version} = $strict_version ;
440             } else {
441 86 50       366 $ppp->{$pkg}{version} = defined $version ? $version : "";
442             }
443 48     48   409 no warnings;
  48         119  
  48         11454  
444 89 100       299 if ($version eq 'undef') {
445 3 50       12 $ppp->{$pkg}{version} = $version unless defined $ppp->{$pkg}{version};
446             } else {
447             $ppp->{$pkg}{version} =
448             $version
449             if $version
450             > $ppp->{$pkg}{version} ||
451             $version
452 86 50 33     963 gt $ppp->{$pkg}{version};
453             }
454             }
455             } else { # not simile
456             #### it comes later, it would be nonsense
457             #### to set to "undef". MM_Unix gives us
458             #### the best we can reasonably consider
459             $ppp->{$pkg}{version} =
460             $version
461             unless defined $ppp->{$pkg}{version} &&
462 0 0 0     0 length($ppp->{$pkg}{version});
463             }
464 91         616 $ppp->{$pkg}{filemtime} = $filemtime;
465             } else {
466             # $self->_verbose(2,"no pkg found");
467             }
468             }
469              
470 98         1197 close $fh;
471 98         1440 $ppp;
472             }
473              
474             # from PAUSE::pmfile;
475             {
476 48     48   372 no strict;
  48         112  
  48         22598  
477             sub _parse_version_safely {
478 86     86   43461 my($parsefile) = @_;
479 86         224 my $result;
480 86         339 local *FH;
481 86         984 local $/ = "\n";
482 86 50       6043 open(FH,$parsefile) or die "Could not open '$parsefile': $!";
483 86         730 my $inpod = 0;
484 86         3651 while () {
485 257 50       1869 $inpod = /^=(?!cut)/ ? 1 : /^=cut/ ? 0 : $inpod;
    50          
486 257 50 33     1804 next if $inpod || /^\s*#/;
487 257 100       854 last if /^__(?:END|DATA)__\b/; # fails on quoted __END__ but this is rare -> __END__ in the middle of a line is rarer
488 254         600 chop;
489              
490 254 100       1591 if (my ($ver) = /package \s+ \S+ \s+ (\S+) \s* [;{]/x) {
491             # XXX: should handle this better if version is bogus -- rjbs,
492             # 2014-03-16
493 6 100       91 return $ver if version::is_lax($ver);
494             }
495              
496             # next unless /\$(([\w\:\']*)\bVERSION)\b.*\=/;
497 251 100       2394 next unless /(?<=])\=(?![=>])/;
498 80         300 my $current_parsed_line = $_;
499 80         1180 my $eval = qq{
500             package #
501             ExtUtils::MakeMaker::_version;
502              
503             local $1$2;
504             \$$2=undef; do {
505             $_
506             }; \$$2
507             };
508 80         890 local $^W = 0;
509 80     0   1437 local $SIG{__WARN__} = sub {};
510 80         849 $result = __clean_eval($eval);
511             # warn "current_parsed_line[$current_parsed_line]\$\@[$@]";
512 80 100 66     907 if ($@ or !defined $result){
513 21         1128 die +{
514             eval => $eval,
515             line => $current_parsed_line,
516             file => $parsefile,
517             err => $@,
518             };
519             }
520 59         497 last;
521             } #;
522 62         934 close FH;
523              
524 62 100       308 $result = "undef" unless defined $result;
525 62 100       300 if ((ref $result) =~ /^version(?:::vpp)?\b/) {
526 48     48   394 no warnings;
  48         97  
  48         41094  
527 6         60 $result = $result->numify;
528             }
529 62         1903 return $result;
530             }
531             }
532              
533             # from PAUSE::pmfile;
534             sub _filter_ppps {
535 98     98   457 my($self,@ppps) = @_;
536 98         218 my @res;
537              
538             # very similar code is in PAUSE::dist::filter_pms
539 98         433 MANI: for my $ppp ( @ppps ) {
540 95 100       395 if ($self->{META_CONTENT}){
541             my $no_index = $self->{META_CONTENT}{no_index}
542 9   66     68 || $self->{META_CONTENT}{private}; # backward compat
543 9 100       37 if (ref($no_index) eq 'HASH') {
544 3         39 my %map = (
545             package => qr{\z},
546             namespace => qr{::},
547             );
548 3         12 for my $k (qw(package namespace)) {
549 3 50       20 next unless my $v = $no_index->{$k};
550 3         9 my $rest = $map{$k};
551 3 50       10 if (ref $v eq "ARRAY") {
552 3         9 for my $ve (@$v) {
553 3         13 $ve =~ s|::$||;
554 3 50       50 if ($ppp =~ /^$ve$rest/){
555 3         53 $self->_verbose(1,"Skipping ppp[$ppp] due to ve[$ve]");
556 3         24 next MANI;
557             } else {
558 0         0 $self->_verbose(1,"NOT skipping ppp[$ppp] due to ve[$ve]");
559             }
560             }
561             } else {
562 0         0 $v =~ s|::$||;
563 0 0       0 if ($ppp =~ /^$v$rest/){
564 0         0 $self->_verbose(1,"Skipping ppp[$ppp] due to v[$v]");
565 0         0 next MANI;
566             } else {
567 0         0 $self->_verbose(1,"NOT skipping ppp[$ppp] due to v[$v]");
568             }
569             }
570             }
571             } else {
572 6         20 $self->_verbose(1,"No keyword 'no_index' or 'private' in META_CONTENT");
573             }
574             } else {
575             # $self->_verbose(1,"no META_CONTENT"); # too noisy
576             }
577 92         457 push @res, $ppp;
578             }
579 98         815 $self->_verbose(1,"Result of filter_ppps: res[@res]");
580 98         323 @res;
581             }
582              
583             # from PAUSE::pmfile;
584             sub _simile {
585 95     95   402 my($self,$file,$package) = @_;
586             # MakeMaker gives them the chance to have the file Simple.pm in
587             # this directory but have the package HTML::Simple in it.
588             # Afaik, they wouldn't be able to do so with deeper nested packages
589 95         786 $file =~ s|.*/||;
590 95         952 $file =~ s|\.pm(?:\.PL)?||;
591 95         1225 my $ret = $package =~ m/\b\Q$file\E$/;
592 95   50     339 $ret ||= 0;
593 95 50       284 unless ($ret) {
594             # Apache::mod_perl_guide stuffs it into Version.pm
595 0 0       0 $ret = 1 if lc $file eq 'version';
596             }
597 95         672 $self->_verbose(1,"Result of simile(): file[$file] package[$package] ret[$ret]\n");
598 95         407 $ret;
599             }
600              
601             # from PAUSE::pmfile
602             sub _normalize_version {
603 99     99   684 my($self,$v) = @_;
604 99 50       471 $v = "undef" unless defined $v;
605 99         2168 my $dv = Dumpvalue->new;
606 99         8257 my $sdv = $dv->stringify($v,1); # second argument prevents ticks
607 99         5279 $self->_verbose(1,"Result of normalize_version: sdv[$sdv]\n");
608              
609 99 100       566 return $v if $v eq "undef";
610 96 50       1108 return $v if $v =~ /^\{.*\}$/; # JSON object
611 96         1146 $v =~ s/^\s+//;
612 96         451 $v =~ s/\s+\z//;
613 96 100       686 if ($v =~ /_/) {
614             # XXX should pass something like EDEVELOPERRELEASE up e.g.
615             # SIXTEASE/XML-Entities-0.0306.tar.gz had nothing but one
616             # such modules and the mesage was not helpful that "nothing
617             # was found".
618 10         174 return $v ;
619             }
620 86 50       964 if (!version::is_lax($v)) {
621 0         0 return JSON::PP::encode_json({ x_normalize => 'version::is_lax failed', version => $v });
622             }
623             # may warn "Integer overflow"
624 48     48   417 my $vv = eval { no warnings; version->new($v)->numify };
  48         109  
  48         5344  
  86         6016  
  86         2608  
625 86 50       619 if ($@) {
626             # warn "$v: $@";
627 0         0 return JSON::PP::encode_json({ x_normalize => $@, version => $v });
628             # return "undef";
629             }
630 86 100       513 if ($vv eq $v) {
631             # the boring 3.14
632             } else {
633 59         364 my $forced = $self->_force_numeric($v);
634 59 50       382 if ($forced eq $vv) {
    50          
635             } elsif ($forced =~ /^v(.+)/) {
636             # rare case where a v1.0.23 slipped in (JANL/w3mir-1.0.10.tar.gz)
637 48     48   329 no warnings;
  48         109  
  48         71988  
638 0         0 $vv = version->new($1)->numify;
639             } else {
640             # warn "Unequal forced[$forced] and vv[$vv]";
641 59 50       475 if ($forced == $vv) {
642             # the trailing zeroes would cause unnecessary havoc
643 59         150 $vv = $forced;
644             }
645             }
646             }
647 86         1606 return $vv;
648             }
649              
650             # from PAUSE::pmfile;
651             sub _force_numeric {
652 59     59   286 my($self,$v) = @_;
653 59         492 $v = $self->_readable($v);
654              
655 59 50 33     1332 if (
      33        
656             $v =~
657             /^(\+?)(\d*)(\.(\d*))?/ &&
658             # "$2$4" ne ''
659             (
660             defined $2 && length $2
661             ||
662             defined $4 && length $4
663             )
664             ) {
665 59 50       254 my $two = defined $2 ? $2 : "";
666 59 50       307 my $three = defined $3 ? $3 : "";
667 59         172 $v = "$two$three";
668             }
669             # no else branch! We simply say, everything else is a string.
670 59         195 $v;
671             }
672              
673             # from PAUSE::dist
674             sub _version_from_meta_ok {
675 223     223   642 my($self) = @_;
676 223 100       1021 return $self->{VERSION_FROM_META_OK} if exists $self->{VERSION_FROM_META_OK};
677 128         386 my $c = $self->{META_CONTENT};
678              
679             # If there's no provides hash, we can't get our module versions from the
680             # provides hash! -- rjbs, 2012-03-31
681 128 100       779 return($self->{VERSION_FROM_META_OK} = 0) unless $c->{provides};
682              
683             # Some versions of Module::Build geneated an empty provides hash. If we're
684             # *not* looking at a Module::Build-generated metafile, then it's okay.
685 6 50       41 my ($mb_v) = (defined $c->{generated_by} ? $c->{generated_by} : '') =~ /Module::Build version ([\d\.]+)/;
686 6 50       52 return($self->{VERSION_FROM_META_OK} = 1) unless $mb_v;
687              
688             # ??? I don't know why this is here.
689 0 0       0 return($self->{VERSION_FROM_META_OK} = 1) if $mb_v eq '0.250.0';
690              
691 0 0 0     0 if ($mb_v >= 0.19 && $mb_v < 0.26 && ! keys %{$c->{provides}}) {
  0   0     0  
692             # RSAVAGE/Javascript-SHA1-1.01.tgz had an empty provides hash. Ron
693             # did not find the reason why this happened, but let's not go
694             # overboard, 0.26 seems a good threshold from the statistics: there
695             # are not many empty provides hashes from 0.26 up.
696 0         0 return($self->{VERSION_FROM_META_OK} = 0);
697             }
698              
699             # We're not in the suspect range of M::B versions. It's good to go.
700 0         0 return($self->{VERSION_FROM_META_OK} = 1);
701             }
702              
703             sub _verbose {
704 399     399   1144 my($self,$level,@what) = @_;
705 399 50 33     4053 warn @what if $level <= ((ref $self && $self->{VERBOSE}) || $VERBOSE);
706             }
707              
708             # all of the following methods are stripped from CPAN::Version
709             # (as of version 5.5001, bundled in CPAN 2.03), and slightly
710             # modified (ie. made private, as well as CPAN->debug(...) are
711             # replaced with $self->_verbose(9, ...).)
712              
713             # CPAN::Version::vcmp courtesy Jost Krieger
714             sub _vcmp {
715 0     0   0 my($self,$l,$r) = @_;
716 0         0 local($^W) = 0;
717 0         0 $self->_verbose(9, "l[$l] r[$r]");
718              
719 0 0       0 return 0 if $l eq $r; # short circuit for quicker success
720              
721 0         0 for ($l,$r) {
722 0         0 s/_//g;
723             }
724 0         0 $self->_verbose(9, "l[$l] r[$r]");
725 0         0 for ($l,$r) {
726 0 0 0     0 next unless tr/.// > 1 || /^v/;
727 0         0 s/^v?/v/;
728 0         0 1 while s/\.0+(\d)/.$1/; # remove leading zeroes per group
729             }
730 0         0 $self->_verbose(9, "l[$l] r[$r]");
731 0 0       0 if ($l=~/^v/ <=> $r=~/^v/) {
732 0         0 for ($l,$r) {
733 0 0       0 next if /^v/;
734 0         0 $_ = $self->_float2vv($_);
735             }
736             }
737 0         0 $self->_verbose(9, "l[$l] r[$r]");
738 0         0 my $lvstring = "v0";
739 0         0 my $rvstring = "v0";
740 0 0 0     0 if ($] >= 5.006
      0        
741             && $l =~ /^v/
742             && $r =~ /^v/) {
743 0         0 $lvstring = $self->_vstring($l);
744 0         0 $rvstring = $self->_vstring($r);
745 0         0 $self->_verbose(9, sprintf "lv[%vd] rv[%vd]", $lvstring, $rvstring);
746             }
747              
748             return (
749 0   0     0 ($l ne "undef") <=> ($r ne "undef")
750             ||
751             $lvstring cmp $rvstring
752             ||
753             $l <=> $r
754             ||
755             $l cmp $r
756             );
757             }
758              
759             sub _vgt {
760 0     0   0 my($self,$l,$r) = @_;
761 0         0 $self->_vcmp($l,$r) > 0;
762             }
763              
764             sub _vlt {
765 0     0   0 my($self,$l,$r) = @_;
766 0         0 $self->_vcmp($l,$r) < 0;
767             }
768              
769             sub _vge {
770 0     0   0 my($self,$l,$r) = @_;
771 0         0 $self->_vcmp($l,$r) >= 0;
772             }
773              
774             sub _vle {
775 0     0   0 my($self,$l,$r) = @_;
776 0         0 $self->_vcmp($l,$r) <= 0;
777             }
778              
779             sub _vstring {
780 0     0   0 my($self,$n) = @_;
781 0 0       0 $n =~ s/^v// or die "Parse::PMFile::_vstring() called with invalid arg [$n]";
782 0         0 pack "U*", split /\./, $n;
783             }
784              
785             # vv => visible vstring
786             sub _float2vv {
787 0     0   0 my($self,$n) = @_;
788 0         0 my($rev) = int($n);
789 0   0     0 $rev ||= 0;
790 0         0 my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits to limit
791             # architecture influence
792 0   0     0 $mantissa ||= 0;
793 0         0 $mantissa .= "0" while length($mantissa)%3;
794 0         0 my $ret = "v" . $rev;
795 0         0 while ($mantissa) {
796 0 0       0 $mantissa =~ s/(\d{1,3})// or
797             die "Panic: length>0 but not a digit? mantissa[$mantissa]";
798 0         0 $ret .= ".".int($1);
799             }
800             # warn "n[$n]ret[$ret]";
801 0         0 $ret =~ s/(\.0)+/.0/; # v1.0.0 => v1.0
802 0         0 $ret;
803             }
804              
805             sub _readable {
806 59     59   253 my($self,$n) = @_;
807 59         547 $n =~ /^([\w\-\+\.]+)/;
808              
809 59 50 33     1061 return $1 if defined $1 && length($1)>0;
810             # if the first user reaches version v43, he will be treated as "+".
811             # We'll have to decide about a new rule here then, depending on what
812             # will be the prevailing versioning behavior then.
813              
814 0 0         if ($] < 5.006) { # or whenever v-strings were introduced
815             # we get them wrong anyway, whatever we do, because 5.005 will
816             # have already interpreted 0.2.4 to be "0.24". So even if he
817             # indexer sends us something like "v0.2.4" we compare wrongly.
818              
819             # And if they say v1.2, then the old perl takes it as "v12"
820              
821 0           $self->_verbose(9, "Suspicious version string seen [$n]\n");
822 0           return $n;
823             }
824 0           my $better = sprintf "v%vd", $n;
825 0           $self->_verbose(9, "n[$n] better[$better]");
826 0           return $better;
827             }
828              
829             1;
830              
831             __END__