File Coverage

blib/lib/CPAN/Distribution.pm
Criterion Covered Total %
statement 737 2500 29.4
branch 323 1606 20.1
condition 83 604 13.7
subroutine 65 117 55.5
pod 0 75 0.0
total 1208 4902 24.6


line stmt bran cond sub pod time code
1             # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
2             # vim: ts=4 sts=4 sw=4:
3             package CPAN::Distribution;
4 22     22   5156 use strict;
  22         72  
  22         879  
5 22     22   96 use Cwd qw(chdir);
  22         27  
  22         1074  
6 22     22   10655 use CPAN::Distroprefs;
  22         74  
  22         809  
7 22     22   564 use CPAN::InfoObj;
  22         31  
  22         438  
8 22     22   83 use File::Path ();
  22         32  
  22         379  
9 22     22   9704 use POSIX ":sys_wait_h";
  22         147325  
  22         129  
10             @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
11 22     22   32758 use vars qw($VERSION);
  22         41  
  22         1744  
12             $VERSION = "2.39";
13              
14             my $run_allow_installing_within_test = 1; # boolean; either in test or in install, there is no third option
15              
16             # no prepare, because prepare is not a command on the shell command line
17             # TODO: clear instance cache on reload
18             my %instance;
19             for my $method (qw(get make test install)) {
20 22     22   160 no strict 'refs';
  22         38  
  22         323236  
21             for my $prefix (qw(pre post)) {
22             my $hookname = sprintf "%s_%s", $prefix, $method;
23             *$hookname = sub {
24 52     52   264 my($self) = @_;
25 52         77 for my $plugin (@{$CPAN::Config->{plugin_list}}) {
  52         323  
26 0         0 my($plugin_proper,$args) = split /=/, $plugin, 2;
27 0 0       0 $args = "" unless defined $args;
28 0 0       0 if ($CPAN::META->has_inst($plugin_proper)){
29 0         0 my @args = split /,/, $args;
30 0   0     0 $instance{$plugin} ||= $plugin_proper->new(@args);
31 0 0       0 if ($instance{$plugin}->can($hookname)) {
32 0         0 $instance{$plugin}->$hookname($self);
33             }
34             } else {
35 0         0 $CPAN::Frontend->mydie("Plugin '$plugin_proper' not found for hook '$hookname'");
36             }
37             }
38             };
39             }
40             }
41              
42             # Accessors
43             sub cpan_comment {
44 7     7 0 19 my $self = shift;
45 7 50       103 my $ro = $self->ro or return;
46             $ro->{CPAN_COMMENT}
47 7         67 }
48              
49             #-> CPAN::Distribution::undelay
50             sub undelay {
51 5     5 0 20 my $self = shift;
52 5         29 for my $delayer (
53             "configure_requires_later",
54             "configure_requires_later_for",
55             "later",
56             "later_for",
57             ) {
58 20         56 delete $self->{$delayer};
59             }
60             }
61              
62             #-> CPAN::Distribution::is_dot_dist
63             sub is_dot_dist {
64 21     21 0 74 my($self) = @_;
65 21         241 return substr($self->id,-1,1) eq ".";
66             }
67              
68             # add the A/AN/ stuff
69             #-> CPAN::Distribution::normalize
70             sub normalize {
71 25     25 0 60 my($self,$s) = @_;
72 25 50       68 $s = $self->id unless defined $s;
73 25 50 33     391 if (substr($s,-1,1) eq ".") {
    50          
74             # using a global because we are sometimes called as static method
75 0 0 0     0 if (!$CPAN::META->{LOCK}
76             && !$CPAN::Have_warned->{"$s is unlocked"}++
77             ) {
78 0         0 $CPAN::Frontend->mywarn("You are visiting the local directory
79             '$s'
80             without lock, take care that concurrent processes do not do likewise.\n");
81 0         0 $CPAN::Frontend->mysleep(1);
82             }
83 0 0       0 if ($s eq ".") {
    0          
    0          
84 0         0 $s = "$CPAN::iCwd/.";
85             } elsif (File::Spec->file_name_is_absolute($s)) {
86             } elsif (File::Spec->can("rel2abs")) {
87 0         0 $s = File::Spec->rel2abs($s);
88             } else {
89 0         0 $CPAN::Frontend->mydie("Your File::Spec is too old, please upgrade File::Spec");
90             }
91 0 0       0 CPAN->debug("s[$s]") if $CPAN::DEBUG;
92 0 0       0 unless ($CPAN::META->exists("CPAN::Distribution", $s)) {
93 0         0 for ($CPAN::META->instance("CPAN::Distribution", $s)) {
94 0         0 $_->{build_dir} = $s;
95 0         0 $_->{archived} = "local_directory";
96 0         0 $_->{unwrapped} = CPAN::Distrostatus->new("YES -- local_directory");
97             }
98             }
99             } elsif (
100             $s =~ tr|/|| == 1
101             or
102             $s !~ m|[A-Z]/[A-Z-0-9]{2}/[A-Z-0-9]{2,}/|
103             ) {
104 0 0       0 return $s if $s =~ m:^N/A|^Contact Author: ;
105 0         0 $s =~ s|^(.)(.)([^/]*/)(.+)$|$1/$1$2/$1$2$3$4|;
106 0 0       0 CPAN->debug("s[$s]") if $CPAN::DEBUG;
107             }
108 25         78 $s;
109             }
110              
111             #-> sub CPAN::Distribution::author ;
112             sub author {
113 1     1 0 2 my($self) = @_;
114 1         3 my($authorid);
115 1 50       3 if (substr($self->id,-1,1) eq ".") {
116 0         0 $authorid = "LOCAL";
117             } else {
118 1         6 ($authorid) = $self->pretty_id =~ /^([\w\-]+)/;
119             }
120 1         3 CPAN::Shell->expand("Author",$authorid);
121             }
122              
123             # tries to get the yaml from CPAN instead of the distro itself:
124             # EXPERIMENTAL, UNDOCUMENTED AND UNTESTED, for Tels
125             sub fast_yaml {
126 0     0 0 0 my($self) = @_;
127 0         0 my $meta = $self->pretty_id;
128 0         0 $meta =~ s/\.(tar.gz|tgz|zip|tar.bz2)/.meta/;
129 0         0 my(@ls) = CPAN::Shell->globls($meta);
130 0         0 my $norm = $self->normalize($meta);
131              
132 0         0 my($local_file);
133             my($local_wanted) =
134             File::Spec->catfile(
135             $CPAN::Config->{keep_source_where},
136 0         0 "authors",
137             "id",
138             split(/\//,$norm)
139             );
140 0 0       0 $self->debug("Doing localize") if $CPAN::DEBUG;
141 0 0       0 unless ($local_file =
142             CPAN::FTP->localize("authors/id/$norm",
143             $local_wanted)) {
144 0         0 $CPAN::Frontend->mydie("Giving up on downloading yaml file '$local_wanted'\n");
145             }
146 0         0 my $yaml = CPAN->_yaml_loadfile($local_file)->[0];
147             }
148              
149             #-> sub CPAN::Distribution::cpan_userid
150             sub cpan_userid {
151 0     0 0 0 my $self = shift;
152 0 0       0 if ($self->{ID} =~ m{[A-Z]/[A-Z\-]{2}/([A-Z\-]+)/}) {
153 0         0 return $1;
154             }
155 0         0 return $self->SUPER::cpan_userid;
156             }
157              
158             #-> sub CPAN::Distribution::pretty_id
159             sub pretty_id {
160 25     25 0 103 my $self = shift;
161 25         387 my $id = $self->id;
162 25 50       367 return $id unless $id =~ m|^./../|;
163 25         2061 substr($id,5);
164             }
165              
166             #-> sub CPAN::Distribution::base_id
167             sub base_id {
168 0     0 0 0 my $self = shift;
169 0         0 my $id = $self->pretty_id();
170 0         0 my $base_id = File::Basename::basename($id);
171 0         0 $base_id =~ s{\.(?:tar\.(bz2|gz|Z)|t(?:gz|bz)|zip)$}{}i;
172 0         0 return $base_id;
173             }
174              
175             #-> sub CPAN::Distribution::tested_ok_but_not_installed
176             sub tested_ok_but_not_installed {
177 0     0 0 0 my $self = shift;
178             return (
179             $self->{make_test}
180             && $self->{build_dir}
181             && (UNIVERSAL::can($self->{make_test},"failed") ?
182             ! $self->{make_test}->failed :
183             $self->{make_test} =~ /^YES/
184             )
185             && (
186             !$self->{install}
187             ||
188             $self->{install}->failed
189             )
190 0   0     0 );
191             }
192              
193              
194             # mark as dirty/clean for the sake of recursion detection. $color=1
195             # means "in use", $color=0 means "not in use anymore". $color=2 means
196             # we have determined prereqs now and thus insist on passing this
197             # through (at least) once again.
198              
199             #-> sub CPAN::Distribution::color_cmd_tmps ;
200             sub color_cmd_tmps {
201 12     12 0 33 my($self) = shift;
202 12   50     46 my($depth) = shift || 0;
203 12   100     124 my($color) = shift || 0;
204 12   50     64 my($ancestors) = shift || [];
205             # a distribution needs to recurse into its prereq_pms
206 12 50       36 $self->debug("color_cmd_tmps[$depth,$color,@$ancestors]") if $CPAN::DEBUG;
207              
208             return if exists $self->{incommandcolor}
209             && $color==1
210 12 50 66     103 && $self->{incommandcolor}==$color;
      33        
211 12   50     166 $CPAN::MAX_RECURSION||=0; # silence 'once' warnings
212 12 50       38 if ($depth>=$CPAN::MAX_RECURSION) {
213 0         0 my $e = CPAN::Exception::RecursiveDependency->new($ancestors);
214 0 0       0 if ($e->is_resolvable) {
215 0         0 return $self->{incommandcolor}=2;
216             } else {
217 0         0 die $e;
218             }
219             }
220             # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
221 12         147 my $prereq_pm = $self->prereq_pm;
222 12 100       62 if (defined $prereq_pm) {
223             # XXX also optional_req & optional_breq? -- xdg, 2012-04-01
224             # A: no, optional deps may recurse -- ak, 2014-05-07
225 2         7 PREREQ: for my $pre (sort(
226 2 50       11 keys %{$prereq_pm->{requires}||{}},
227 2 50       25 keys %{$prereq_pm->{build_requires}||{}},
228             )) {
229 4 50       17 next PREREQ if $pre eq "perl";
230 4         14 my $premo;
231 4 50       30 unless ($premo = CPAN::Shell->expand("Module",$pre)) {
232 0         0 $CPAN::Frontend->mywarn("prerequisite module[$pre] not known\n");
233 0         0 $CPAN::Frontend->mysleep(0.2);
234 0         0 next PREREQ;
235             }
236 4         34 $premo->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
237             }
238             }
239 12 100       68 if ($color==0) {
240 5         33 delete $self->{sponsored_mods};
241              
242             # as we are at the end of a command, we'll give up this
243             # reminder of a broken test. Other commands may test this guy
244             # again. Maybe 'badtestcnt' should be renamed to
245             # 'make_test_failed_within_command'?
246 5         18 delete $self->{badtestcnt};
247             }
248 12         86 $self->{incommandcolor} = $color;
249             }
250              
251             #-> sub CPAN::Distribution::as_string ;
252             sub as_string {
253 0     0 0 0 my $self = shift;
254 0         0 $self->containsmods;
255 0         0 $self->upload_date;
256 0         0 $self->SUPER::as_string(@_);
257             }
258              
259             #-> sub CPAN::Distribution::containsmods ;
260             sub containsmods {
261 0     0 0 0 my $self = shift;
262 0 0       0 return sort keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
  0         0  
263 0         0 my $dist_id = $self->{ID};
264 0         0 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
265 0 0       0 my $mod_file = $mod->cpan_file or next;
266 0 0       0 my $mod_id = $mod->{ID} or next;
267             # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
268             # sleep 1;
269 0 0       0 if ($CPAN::Signal) {
270 0         0 delete $self->{CONTAINSMODS};
271 0         0 return;
272             }
273 0 0       0 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
274             }
275 0   0     0 sort keys %{$self->{CONTAINSMODS}||={}};
  0         0  
276             }
277              
278             #-> sub CPAN::Distribution::upload_date ;
279             sub upload_date {
280 0     0 0 0 my $self = shift;
281 0 0       0 return $self->{UPLOAD_DATE} if exists $self->{UPLOAD_DATE};
282 0         0 my(@local_wanted) = split(/\//,$self->id);
283 0         0 my $filename = pop @local_wanted;
284 0         0 push @local_wanted, "CHECKSUMS";
285 0         0 my $author = CPAN::Shell->expand("Author",$self->cpan_userid);
286 0 0       0 return unless $author;
287 0         0 my @dl = $author->dir_listing(\@local_wanted,0,$CPAN::Config->{show_upload_date});
288 0 0       0 return unless @dl;
289 0         0 my($dirent) = grep { $_->[2] eq $filename } @dl;
  0         0  
290             # warn sprintf "dirent[%s]id[%s]", $dirent, $self->id;
291 0 0       0 return unless $dirent->[1];
292 0         0 return $self->{UPLOAD_DATE} = $dirent->[1];
293             }
294              
295             #-> sub CPAN::Distribution::uptodate ;
296             sub uptodate {
297 0     0 0 0 my($self) = @_;
298 0         0 my $c;
299 0         0 foreach $c ($self->containsmods) {
300 0         0 my $obj = CPAN::Shell->expandany($c);
301 0 0       0 unless ($obj->uptodate) {
302 0         0 my $id = $self->pretty_id;
303 0 0       0 $self->debug("$id not uptodate due to $c") if $CPAN::DEBUG;
304 0         0 return 0;
305             }
306             }
307 0         0 return 1;
308             }
309              
310             #-> sub CPAN::Distribution::called_for ;
311             sub called_for {
312 7     7 0 25 my($self,$id) = @_;
313 7 50       30 $self->{CALLED_FOR} = $id if defined $id;
314 7         19 return $self->{CALLED_FOR};
315             }
316              
317             #-> sub CPAN::Distribution::shortcut_get ;
318             # return values: undef means don't shortcut; 0 means shortcut as fail;
319             # and 1 means shortcut as success
320             sub shortcut_get {
321 7     7 0 19 my ($self) = @_;
322              
323 7 50       24 if (exists $self->{cleanup_after_install_done}) {
324 0 0       0 if ($self->{force_update}) {
325 0         0 delete $self->{cleanup_after_install_done};
326             } else {
327 0   0     0 my $id = $self->{CALLED_FOR} || $self->pretty_id;
328 0         0 return $self->success(
329             "Has already been *installed and cleaned up in the staging area* within this session, will not work on it again; if you really want to start over, try something like `force get $id`"
330             );
331             }
332             }
333              
334 7 50       68 if (my $why = $self->check_disabled) {
335 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO $why");
336             # XXX why is this goodbye() instead of just print/warn?
337             # Alternatively, should other print/warns here be goodbye()?
338             # -- xdg, 2012-04-05
339 0         0 return $self->goodbye("[disabled] -- NA $why");
340             }
341              
342 7 50       21 $self->debug("checking already unwrapped[$self->{ID}]") if $CPAN::DEBUG;
343 7 50 33     46 if (exists $self->{build_dir} && -d $self->{build_dir}) {
344             # this deserves print, not warn:
345 0         0 return $self->success("Has already been unwrapped into directory ".
346             "$self->{build_dir}"
347             );
348             }
349              
350             # XXX I'm not sure this should be here because it's not really
351             # a test for whether get should continue or return; this is
352             # a side effect -- xdg, 2012-04-05
353 7 50       56 $self->debug("checking missing build_dir[$self->{ID}]") if $CPAN::DEBUG;
354 7 50 33     27 if (exists $self->{build_dir} && ! -d $self->{build_dir}){
355             # we have lost it.
356 0         0 $self->fforce(""); # no method to reset all phases but not set force (dodge)
357 0         0 return undef; # no shortcut
358             }
359              
360             # although we talk about 'force' we shall not test on
361             # force directly. New model of force tries to refrain from
362             # direct checking of force.
363 7 50       20 $self->debug("checking unwrapping error[$self->{ID}]") if $CPAN::DEBUG;
364 7 0 33     23 if ( exists $self->{unwrapped} and (
    0          
365             UNIVERSAL::can($self->{unwrapped},"failed") ?
366             $self->{unwrapped}->failed :
367             $self->{unwrapped} =~ /^NO/ )
368             ) {
369 0         0 return $self->goodbye("Unwrapping had some problem, won't try again without force");
370             }
371              
372 7         127 return undef; # no shortcut
373             }
374              
375             #-> sub CPAN::Distribution::get ;
376             sub get {
377 7     7 0 27 my($self) = @_;
378              
379 7         44 $self->pre_get();
380              
381 7 50       20 $self->debug("checking goto id[$self->{ID}]") if $CPAN::DEBUG;
382 7 50       24 if (my $goto = $self->prefs->{goto}) {
383 0         0 $self->post_get();
384 0         0 return $self->goto($goto);
385             }
386              
387 7 50       35 if ( defined( my $sc = $self->shortcut_get) ) {
388 0         0 $self->post_get();
389 0         0 return $sc;
390             }
391              
392             local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
393             ? $ENV{PERL5LIB}
394 7 50 0     84 : ($ENV{PERLLIB} || "");
395 7 50       44 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
396             # local $ENV{PERL_USE_UNSAFE_INC} = exists $ENV{PERL_USE_UNSAFE_INC} ? $ENV{PERL_USE_UNSAFE_INC} : 1; # get
397 7         131 $CPAN::META->set_perl5lib;
398 7         83 local $ENV{MAKEFLAGS}; # protect us from outer make calls
399              
400 7         42 my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
401              
402 7         137 my($local_file);
403             # XXX I don't think this check needs to be here, as it
404             # is already checked in shortcut_get() -- xdg, 2012-04-05
405 7 50 33     167 unless ($self->{build_dir} && -d $self->{build_dir}) {
406 7         187 $self->get_file_onto_local_disk;
407 7 50       37 if ($CPAN::Signal){
408 0         0 $self->post_get();
409 0         0 return;
410             }
411 7         77 $self->check_integrity;
412 7 50       144 if ($CPAN::Signal){
413 0         0 $self->post_get();
414 0         0 return;
415             }
416 7         63 (my $packagedir,$local_file) = $self->run_preps_on_packagedir;
417             # XXX why is this check here? -- xdg, 2012-04-08
418 7 0 33     86 if (exists $self->{writemakefile} && ref $self->{writemakefile}
      33        
      0        
419             && $self->{writemakefile}->can("failed") &&
420             $self->{writemakefile}->failed) {
421             #
422 0         0 $self->post_get();
423 0         0 return;
424             }
425 7   33     49 $packagedir ||= $self->{build_dir};
426 7         27 $self->{build_dir} = $packagedir;
427             }
428              
429             # XXX should this move up to after run_preps_on_packagedir?
430             # Otherwise, failing writemakefile can return without
431             # a $CPAN::Signal check -- xdg, 2012-04-05
432 7 50       53 if ($CPAN::Signal) {
433 0         0 $self->safe_chdir($sub_wd);
434 0         0 $self->post_get();
435 0         0 return;
436             }
437 7 50       84 unless ($self->patch){
438 0         0 $self->post_get();
439 0         0 return;
440             }
441 7         122 $self->store_persistent_state;
442              
443 7         113 $self->post_get();
444              
445 7         205 return 1; # success
446             }
447              
448             #-> CPAN::Distribution::get_file_onto_local_disk
449             sub get_file_onto_local_disk {
450 7     7 0 72 my($self) = @_;
451              
452 7 50       121 return if $self->is_dot_dist;
453 7         49 my($local_file);
454             my($local_wanted) =
455             File::Spec->catfile(
456             $CPAN::Config->{keep_source_where},
457 7         92 "authors",
458             "id",
459             split(/\//,$self->id)
460             );
461              
462 7 50       82 $self->debug("Doing localize") if $CPAN::DEBUG;
463 7 50       253 unless ($local_file =
464             CPAN::FTP->localize("authors/id/$self->{ID}",
465             $local_wanted)) {
466 0         0 my $note = "";
467 0 0       0 if ($CPAN::Index::DATE_OF_02) {
468 0         0 $note = "Note: Current database in memory was generated ".
469             "on $CPAN::Index::DATE_OF_02\n";
470             }
471 0         0 $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n$note");
472             }
473              
474 7 50       98 $self->debug("local_wanted[$local_wanted]local_file[$local_file]") if $CPAN::DEBUG;
475 7         102 $self->{localfile} = $local_file;
476             }
477              
478              
479             #-> CPAN::Distribution::check_integrity
480             sub check_integrity {
481 7     7 0 46 my($self) = @_;
482              
483 7 50       48 return if $self->is_dot_dist;
484 7 50       60 if ($CPAN::META->has_inst("Digest::SHA")) {
485 7         204 $self->debug("Digest::SHA is installed, verifying");
486 7         101 $self->verifyCHECKSUM;
487             } else {
488 0         0 $self->debug("Digest::SHA is NOT installed");
489             }
490             }
491              
492             #-> CPAN::Distribution::run_preps_on_packagedir
493             sub run_preps_on_packagedir {
494 7     7 0 22 my($self) = @_;
495 7 50       29 return if $self->is_dot_dist;
496              
497 7   33     239 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
498 7         276 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
499 7         86 $self->safe_chdir($builddir);
500 7 50       18 $self->debug("Removing tmp-$$") if $CPAN::DEBUG;
501 7         1506 File::Path::rmtree("tmp-$$");
502 7 50       954 unless (mkdir "tmp-$$", 0755) {
503 0         0 $CPAN::Frontend->unrecoverable_error(<
504             Couldn't mkdir '$builddir/tmp-$$': $!
505              
506             Cannot continue: Please find the reason why I cannot make the
507             directory
508             $builddir/tmp-$$
509             and fix the problem, then retry.
510              
511             EOF
512             }
513 7 50       43 if ($CPAN::Signal) {
514 0         0 return;
515             }
516 7         80 $self->safe_chdir("tmp-$$");
517              
518             #
519             # Unpack the goods
520             #
521 7         19 my $local_file = $self->{localfile};
522 7         17 my $ct = eval{CPAN::Tarzip->new($local_file)};
  7         54  
523 7 50       29 unless ($ct) {
524 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO");
525 0         0 delete $self->{build_dir};
526 0         0 return;
527             }
528 7 50       123 if ($local_file =~ /(\.tar\.(bz2|gz|Z)|\.tgz)(?!\n)\Z/i) {
    0          
529 7 50       15 $self->{was_uncompressed}++ unless eval{$ct->gtest()};
  7         27  
530 7         113 $self->untar_me($ct);
531             } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
532 0         0 $self->unzip_me($ct);
533             } else {
534 0 0       0 $self->{was_uncompressed}++ unless $ct->gtest();
535 0         0 $local_file = $self->handle_singlefile($local_file);
536             }
537              
538             # we are still in the tmp directory!
539             # Let's check if the package has its own directory.
540 7 50       417 my $dh = DirHandle->new(File::Spec->curdir)
541             or Carp::croak("Couldn't opendir .: $!");
542 7         1849 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
543 7 50       525 if (grep { $_ eq "pax_global_header" } @readdir) {
  7         94  
544 0         0 $CPAN::Frontend->mywarn("Your (un)tar seems to have extracted a file named 'pax_global_header'
545             from the tarball '$local_file'.
546             This is almost certainly an error. Please upgrade your tar.
547             I'll ignore this file for now.
548             See also http://rt.cpan.org/Ticket/Display.html?id=38932\n");
549 0         0 $CPAN::Frontend->mysleep(5);
550 0         0 @readdir = grep { $_ ne "pax_global_header" } @readdir;
  0         0  
551             }
552 7         85 $dh->close;
553 7         239 my $tdir_base;
554             my $from_dir;
555 7         0 my @dirents;
556 7 50 33     294 if (@readdir == 1 && -d $readdir[0]) {
557 7         34 $tdir_base = $readdir[0];
558 7         187 $from_dir = File::Spec->catdir(File::Spec->curdir,$readdir[0]);
559 7         121 my($mode) = (stat $from_dir)[2];
560 7         221 chmod $mode | 00755, $from_dir; # JONATHAN/Math-Calculus-TaylorSeries-0.1.tar.gz has 0644
561 7         34 my $dh2;
562 7 50       70 unless ($dh2 = DirHandle->new($from_dir)) {
563 0         0 my $why = sprintf
564             (
565             "Couldn't opendir '%s', mode '%o': %s",
566             $from_dir,
567             $mode,
568             $!,
569             );
570 0         0 $CPAN::Frontend->mywarn("$why\n");
571 0         0 $self->{writemakefile} = CPAN::Distrostatus->new("NO -- $why");
572 0         0 return;
573             }
574 7         683 @dirents = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh2->read; ### MAC??
575             } else {
576 0         0 my $userid = $self->cpan_userid;
577 0         0 CPAN->debug("userid[$userid]");
578 0 0 0     0 if (!$userid or $userid eq "N/A") {
579 0         0 $userid = "anon";
580             }
581 0         0 $tdir_base = $userid;
582 0         0 $from_dir = File::Spec->curdir;
583 0         0 @dirents = @readdir;
584             }
585 7         967 my $packagedir;
586 7 50 33     181 my $eexist = ($CPAN::META->has_usable("Errno") && defined &Errno::EEXIST)
587             ? &Errno::EEXIST : undef;
588 7         30 for(my $suffix = 0; ; $suffix++) {
589 7         124 $packagedir = File::Spec->catdir($builddir, "$tdir_base-$suffix");
590 7         41 my $parent = $builddir;
591 7 50       976 mkdir($packagedir, 0777) and last;
592 0 0 0     0 if((defined($eexist) && $! != $eexist) || $suffix == 999) {
      0        
593 0         0 $CPAN::Frontend->mydie("Cannot create directory $packagedir: $!\n");
594             }
595             }
596 7         47 my $f;
597 7         46 for $f (@dirents) { # is already without "." and ".."
598 38         4349 my $from = File::Spec->catfile($from_dir,$f);
599 38         565 my($mode) = (stat $from)[2];
600 38 100       459 chmod $mode | 00755, $from if -d $from; # OTTO/Pod-Trial-LinkImg-0.005.tgz
601 38         283 my $to = File::Spec->catfile($packagedir,$f);
602 38 50       227 unless (File::Copy::move($from,$to)) {
603 0         0 my $err = $!;
604 0         0 $from = File::Spec->rel2abs($from);
605 0 0       0 $CPAN::Frontend->mydie(
    0          
606             "Couldn't move $from to $to: $err; #82295? ".
607             "CPAN::VERSION=$CPAN::VERSION; ".
608             "File::Copy::VERSION=$File::Copy::VERSION; ".
609             "$from " . (-e $from ? "exists; " : "does not exist; ").
610             "$to " . (-e $to ? "exists; " : "does not exist; ").
611             "cwd=" . CPAN::anycwd() . ";"
612             );
613             }
614             }
615 7         900 $self->{build_dir} = $packagedir;
616 7         183 $self->safe_chdir($builddir);
617 7         4323 File::Path::rmtree("tmp-$$");
618              
619 7         67 $self->safe_chdir($packagedir);
620 7         73 $self->_signature_business();
621 7         33 $self->safe_chdir($builddir);
622              
623 7         55 return($packagedir,$local_file);
624             }
625              
626             #-> sub CPAN::Distribution::pick_meta_file ;
627             sub pick_meta_file {
628 54     54 0 9050 my($self, $filter) = @_;
629 54 100       165 $filter = '.' unless defined $filter;
630              
631 54         91 my $build_dir;
632 54 50       157 unless ($build_dir = $self->{build_dir}) {
633             # maybe permission on build_dir was missing
634 0         0 $CPAN::Frontend->mywarn("Warning: cannot determine META.yml without a build_dir.\n");
635 0         0 return;
636             }
637              
638 54         210 my $has_cm = $CPAN::META->has_usable("CPAN::Meta");
639 54         123 my $has_pcm = $CPAN::META->has_usable("Parse::CPAN::Meta");
640              
641 54         76 my @choices;
642 54 50       204 push @choices, 'MYMETA.json' if $has_cm;
643 54 50 33     141 push @choices, 'MYMETA.yml' if $has_cm || $has_pcm;
644 54 50       142 push @choices, 'META.json' if $has_cm;
645 54 50 33     112 push @choices, 'META.yml' if $has_cm || $has_pcm;
646              
647 54         105 for my $file ( grep { /$filter/ } @choices ) {
  216         920  
648 121         836 my $path = File::Spec->catfile( $build_dir, $file );
649 121 100       1899 return $path if -f $path
650             }
651              
652 10         111 return;
653             }
654              
655             #-> sub CPAN::Distribution::parse_meta_yml ;
656             sub parse_meta_yml {
657 11     11 0 33 my($self, $yaml) = @_;
658 11 50 0     37 $self->debug(sprintf("parse_meta_yml[%s]",$yaml||'undef')) if $CPAN::DEBUG;
659 11 50       46 my $build_dir = $self->{build_dir} or die "PANIC: cannot parse yaml without a build_dir";
660 11   33     203 $yaml ||= File::Spec->catfile($build_dir,"META.yml");
661 11 50       47 $self->debug("meta[$yaml]") if $CPAN::DEBUG;
662 11 50       466 return unless -f $yaml;
663 0         0 my $early_yaml;
664 0         0 eval {
665 0 0       0 $CPAN::META->has_inst("Parse::CPAN::Meta") or die;
666 0 0       0 die "Parse::CPAN::Meta yaml too old" unless $Parse::CPAN::Meta::VERSION >= "1.40";
667             # P::C::M returns last document in scalar context
668 0         0 $early_yaml = Parse::CPAN::Meta::LoadFile($yaml);
669             };
670 0 0       0 unless ($early_yaml) {
671 0         0 eval { $early_yaml = CPAN->_yaml_loadfile($yaml)->[0]; };
  0         0  
672             }
673 0 0 0     0 $self->debug(sprintf("yaml[%s]", $early_yaml || 'UNDEF')) if $CPAN::DEBUG;
674 0 0 0     0 $self->debug($early_yaml) if $CPAN::DEBUG && $early_yaml;
675 0 0 0     0 if (!ref $early_yaml or ref $early_yaml ne "HASH"){
676             # fix rt.cpan.org #95271
677 0         0 $CPAN::Frontend->mywarn("The content of '$yaml' is not a HASH reference. Cannot use it.\n");
678 0         0 return {};
679             }
680 0   0     0 return $early_yaml || undef;
681             }
682              
683             #-> sub CPAN::Distribution::satisfy_requires ;
684             # return values: 1 means requirements are satisfied;
685             # and 0 means not satisfied (and maybe queued)
686             sub satisfy_requires {
687 4     4 0 22 my ($self) = @_;
688 4 50       26 $self->debug("Entering satisfy_requires") if $CPAN::DEBUG;
689 4 50       42 if (my @prereq = $self->unsat_prereq("later")) {
690 0 0       0 if ($CPAN::DEBUG){
691 0         0 require Data::Dumper;
692 0         0 my $prereq = Data::Dumper->new(\@prereq)->Terse(1)->Indent(0)->Dump;
693 0         0 $self->debug("unsatisfied[$prereq]");
694             }
695 0 0       0 if ($prereq[0][0] eq "perl") {
696 0         0 my $need = "requires perl '$prereq[0][1]'";
697 0         0 my $id = $self->pretty_id;
698 0         0 $CPAN::Frontend->mywarn("$id $need; you have only $]; giving up\n");
699 0         0 $self->{make} = CPAN::Distrostatus->new("NO $need");
700 0         0 $self->store_persistent_state;
701 0         0 die "[prereq] -- NOT OK\n";
702             } else {
703 0         0 my $follow = eval { $self->follow_prereqs("later",@prereq); };
  0         0  
704 0 0 0     0 if (0) {
    0 0        
705 0         0 } elsif ($follow) {
706 0         0 return; # we need deps
707             } elsif ($@ && ref $@ && $@->isa("CPAN::Exception::RecursiveDependency")) {
708 0         0 $CPAN::Frontend->mywarn($@);
709 0         0 die "[depend] -- NOT OK\n";
710             }
711             }
712             }
713 4         16 return 1;
714             }
715              
716             #-> sub CPAN::Distribution::satisfy_configure_requires ;
717             # return values: 1 means configure_require is satisfied;
718             # and 0 means not satisfied (and maybe queued)
719             sub satisfy_configure_requires {
720 7     7 0 20 my($self) = @_;
721 7 50       24 $self->debug("Entering satisfy_configure_requires") if $CPAN::DEBUG;
722 7         18 my $enable_configure_requires = 1;
723 7 50       23 if (!$enable_configure_requires) {
724 0         0 return 1;
725             # if we return 1 here, everything is as before we introduced
726             # configure_requires that means, things with
727             # configure_requires simply fail, all others succeed
728             }
729 7         62 my @prereq = $self->unsat_prereq("configure_requires_later");
730 7 50       53 $self->debug(sprintf "configure_requires[%s]", join(",",map {join "/",@$_} @prereq)) if $CPAN::DEBUG;
  0         0  
731 7 50       36 return 1 unless @prereq;
732 0 0       0 $self->debug(\@prereq) if $CPAN::DEBUG;
733 0 0       0 if ($self->{configure_requires_later}) {
734 0 0       0 for my $k (sort keys %{$self->{configure_requires_later_for}||{}}) {
  0         0  
735 0 0       0 if ($self->{configure_requires_later_for}{$k}>1) {
736 0         0 my $type = "";
737 0         0 for my $p (@prereq) {
738 0 0       0 if ($p->[0] eq $k) {
739 0         0 $type = $p->[1];
740             }
741             }
742 0 0       0 $type = " $type" if $type;
743 0         0 $CPAN::Frontend->mywarn("Warning: unmanageable(?) prerequisite $k$type");
744 0         0 sleep 1;
745             }
746             }
747             }
748 0 0       0 if ($prereq[0][0] eq "perl") {
749 0         0 my $need = "requires perl '$prereq[0][1]'";
750 0         0 my $id = $self->pretty_id;
751 0         0 $CPAN::Frontend->mywarn("$id $need; you have only $]; giving up\n");
752 0         0 $self->{make} = CPAN::Distrostatus->new("NO $need");
753 0         0 $self->store_persistent_state;
754 0         0 return $self->goodbye("[prereq] -- NOT OK");
755             } else {
756 0         0 my $follow = eval {
757 0         0 $self->follow_prereqs("configure_requires_later", @prereq);
758             };
759 0 0 0     0 if (0) {
    0 0        
760 0         0 } elsif ($follow) {
761 0         0 return; # we need deps
762             } elsif ($@ && ref $@ && $@->isa("CPAN::Exception::RecursiveDependency")) {
763 0         0 $CPAN::Frontend->mywarn($@);
764 0         0 return $self->goodbye("[depend] -- NOT OK");
765             }
766             else {
767 0         0 return $self->goodbye("[configure_requires] -- NOT OK");
768             }
769             }
770 0         0 die "never reached";
771             }
772              
773             #-> sub CPAN::Distribution::choose_MM_or_MB ;
774             sub choose_MM_or_MB {
775 7     7 0 31 my($self) = @_;
776 7 50       84 $self->satisfy_configure_requires() or return;
777 7         29 my $local_file = $self->{localfile};
778 7         77 my($mpl) = File::Spec->catfile($self->{build_dir},"Makefile.PL");
779 7         191 my($mpl_exists) = -f $mpl;
780 7 50       31 unless ($mpl_exists) {
781             # NFS has been reported to have racing problems after the
782             # renaming of a directory in some environments.
783             # This trick helps.
784 0         0 $CPAN::Frontend->mysleep(1);
785             my $mpldh = DirHandle->new($self->{build_dir})
786 0 0       0 or Carp::croak("Couldn't opendir $self->{build_dir}: $!");
787 0         0 $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read;
788 0         0 $mpldh->close;
789             }
790 7         67 my $prefer_installer = "eumm"; # eumm|mb
791 7 50       98 if (-f File::Spec->catfile($self->{build_dir},"Build.PL")) {
792 0 0       0 if ($mpl_exists) { # they *can* choose
793 0 0       0 if ($CPAN::META->has_inst("Module::Build")) {
794 0         0 $prefer_installer = CPAN::HandleConfig->prefs_lookup(
795             $self, q{prefer_installer}
796             );
797             # M::B <= 0.35 left a DATA handle open that
798             # causes problems upgrading M::B on Windows
799 0 0       0 close *Module::Build::Version::DATA
800             if fileno *Module::Build::Version::DATA;
801             }
802             } else {
803 0         0 $prefer_installer = "mb";
804             }
805             }
806 7 50       36 if (lc($prefer_installer) eq "rand") {
807 0 0       0 $prefer_installer = rand()<.5 ? "eumm" : "mb";
808             }
809 7 50       62 if (lc($prefer_installer) eq "mb") {
    50          
    50          
810 0         0 $self->{modulebuild} = 1;
811             } elsif ($self->{archived} eq "patch") {
812             # not an edge case, nothing to install for sure
813 0         0 my $why = "A patch file cannot be installed";
814 0         0 $CPAN::Frontend->mywarn("Refusing to handle this file: $why\n");
815 0         0 $self->{writemakefile} = CPAN::Distrostatus->new("NO $why");
816             } elsif (! $mpl_exists) {
817 0         0 $self->_edge_cases($mpl,$local_file);
818             }
819 7 50 33     101 if ($self->{build_dir}
820             &&
821             $CPAN::Config->{build_dir_reuse}
822             ) {
823 0         0 $self->store_persistent_state;
824             }
825 7         32 return $self;
826             }
827              
828             # see also reanimate_build_dir
829             #-> CPAN::Distribution::store_persistent_state
830             sub store_persistent_state {
831 21     21 0 170 my($self) = @_;
832 21         125 my $dir = $self->{build_dir};
833 21 50 33     223 unless (defined $dir && length $dir) {
834 0         0 my $id = $self->id;
835 0         0 $CPAN::Frontend->mywarnonce("build_dir of $id is not known, ".
836             "will not store persistent state\n");
837 0         0 return;
838             }
839             # self-build-dir
840 21         2025 my $sbd = Cwd::realpath(
841             File::Spec->catdir($dir, File::Spec->updir ())
842             );
843             # config-build-dir
844             my $cbd = Cwd::realpath(
845             # the catdir is a workaround for bug https://rt.cpan.org/Ticket/Display.html?id=101283
846 21         1156 File::Spec->catdir($CPAN::Config->{build_dir}, File::Spec->curdir())
847             );
848 21 50       94 unless ($sbd eq $cbd) {
849 0         0 $CPAN::Frontend->mywarnonce("Directory '$dir' not below $CPAN::Config->{build_dir}, ".
850             "will not store persistent state\n");
851 0         0 return;
852             }
853 21         135 my $file = sprintf "%s.yml", $dir;
854 21         338 my $yaml_module = CPAN::_yaml_module();
855 21 50       102 if ($CPAN::META->has_inst($yaml_module)) {
856 0         0 CPAN->_yaml_dumpfile(
857             $file,
858             {
859             time => time,
860             perl => CPAN::_perl_fingerprint(),
861             distribution => $self,
862             }
863             );
864             } else {
865 21         462 $CPAN::Frontend->myprintonce("'$yaml_module' not installed, ".
866             "will not store persistent state\n");
867             }
868             }
869              
870             #-> CPAN::Distribution::try_download
871             sub try_download {
872 0     0 0 0 my($self,$patch) = @_;
873 0         0 my $norm = $self->normalize($patch);
874             my($local_wanted) =
875             File::Spec->catfile(
876             $CPAN::Config->{keep_source_where},
877 0         0 "authors",
878             "id",
879             split(/\//,$norm),
880             );
881 0 0       0 $self->debug("Doing localize") if $CPAN::DEBUG;
882 0         0 return CPAN::FTP->localize("authors/id/$norm",
883             $local_wanted);
884             }
885              
886             {
887             my $stdpatchargs = "";
888             #-> CPAN::Distribution::patch
889             sub patch {
890 7     7 0 23 my($self) = @_;
891 7 50       50 $self->debug("checking patches id[$self->{ID}]") if $CPAN::DEBUG;
892 7         34 my $patches = $self->prefs->{patches};
893 7   50     111 $patches ||= "";
894 7 50       54 $self->debug("patches[$patches]") if $CPAN::DEBUG;
895 7 50       60 if ($patches) {
896 0 0       0 return unless @$patches;
897 0         0 $self->safe_chdir($self->{build_dir});
898 0 0       0 CPAN->debug("patches[$patches]") if $CPAN::DEBUG;
899 0         0 my $patchbin = $CPAN::Config->{patch};
900 0 0 0     0 unless ($patchbin && length $patchbin) {
901 0         0 $CPAN::Frontend->mydie("No external patch command configured\n\n".
902             "Please run 'o conf init /patch/'\n\n");
903             }
904 0 0       0 unless (MM->maybe_command($patchbin)) {
905 0         0 $CPAN::Frontend->mydie("No external patch command available\n\n".
906             "Please run 'o conf init /patch/'\n\n");
907             }
908 0         0 $patchbin = CPAN::HandleConfig->safe_quote($patchbin);
909 0         0 local $ENV{PATCH_GET} = 0; # formerly known as -g0
910 0 0       0 unless ($stdpatchargs) {
911 0         0 my $system = "$patchbin --version |";
912 0         0 local *FH;
913 0 0       0 open FH, $system or die "Could not fork '$system': $!";
914 0         0 local $/ = "\n";
915 0         0 my $pversion;
916 0         0 PARSEVERSION: while () {
917 0 0       0 if (/^patch\s+([\d\.]+)/) {
918 0         0 $pversion = $1;
919 0         0 last PARSEVERSION;
920             }
921             }
922 0 0       0 if ($pversion) {
923 0         0 $stdpatchargs = "-N --fuzz=3";
924             } else {
925 0         0 $stdpatchargs = "-N";
926             }
927             }
928 0 0       0 my $countedpatches = @$patches == 1 ? "1 patch" : (scalar @$patches . " patches");
929 0         0 $CPAN::Frontend->myprint("Applying $countedpatches:\n");
930 0         0 my $patches_dir = $CPAN::Config->{patches_dir};
931 0         0 for my $patch (@$patches) {
932 0 0 0     0 if ($patches_dir && !File::Spec->file_name_is_absolute($patch)) {
933 0         0 my $f = File::Spec->catfile($patches_dir, $patch);
934 0 0       0 $patch = $f if -f $f;
935             }
936 0 0       0 unless (-f $patch) {
937 0 0       0 CPAN->debug("not on disk: patch[$patch]") if $CPAN::DEBUG;
938 0 0       0 if (my $trydl = $self->try_download($patch)) {
939 0         0 $patch = $trydl;
940             } else {
941 0         0 my $fail = "Could not find patch '$patch'";
942 0         0 $CPAN::Frontend->mywarn("$fail; cannot continue\n");
943 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
944 0         0 delete $self->{build_dir};
945 0         0 return;
946             }
947             }
948 0         0 $CPAN::Frontend->myprint(" $patch\n");
949 0         0 my $readfh = CPAN::Tarzip->TIEHANDLE($patch);
950              
951 0         0 my $pcommand;
952 0         0 my($ppp,$pfiles) = $self->_patch_p_parameter($readfh);
953 0 0       0 if ($ppp eq "applypatch") {
954 0         0 $pcommand = "$CPAN::Config->{applypatch} -verbose";
955             } else {
956 0         0 my $thispatchargs = join " ", $stdpatchargs, $ppp;
957 0         0 $pcommand = "$patchbin $thispatchargs";
958 0         0 require Config; # usually loaded from CPAN.pm
959 0 0       0 if ($Config::Config{osname} eq "solaris") {
960             # native solaris patch cannot patch readonly files
961 0 0       0 for my $file (@{$pfiles||[]}) {
  0         0  
962 0 0       0 my @stat = stat $file or next;
963 0         0 chmod $stat[2] | 0600, $file; # may fail
964             }
965             }
966             }
967              
968 0         0 $readfh = CPAN::Tarzip->TIEHANDLE($patch); # open again
969 0         0 my $writefh = FileHandle->new;
970 0         0 $CPAN::Frontend->myprint(" $pcommand\n");
971 0 0       0 unless (open $writefh, "|$pcommand") {
972 0         0 my $fail = "Could not fork '$pcommand'";
973 0         0 $CPAN::Frontend->mywarn("$fail; cannot continue\n");
974 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
975 0         0 delete $self->{build_dir};
976 0         0 return;
977             }
978 0         0 binmode($writefh);
979 0         0 while (my $x = $readfh->READLINE) {
980 0         0 print $writefh $x;
981             }
982 0 0       0 unless (close $writefh) {
983 0         0 my $fail = "Could not apply patch '$patch'";
984 0         0 $CPAN::Frontend->mywarn("$fail; cannot continue\n");
985 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
986 0         0 delete $self->{build_dir};
987 0         0 return;
988             }
989             }
990 0         0 $self->{patched}++;
991             }
992 7         29 return 1;
993             }
994             }
995              
996             # may return
997             # - "applypatch"
998             # - ("-p0"|"-p1", $files)
999             sub _patch_p_parameter {
1000 0     0   0 my($self,$fh) = @_;
1001 0         0 my $cnt_files = 0;
1002 0         0 my $cnt_p0files = 0;
1003 0         0 my @files;
1004 0         0 local($_);
1005 0         0 while ($_ = $fh->READLINE) {
1006 0 0 0     0 if (
1007             $CPAN::Config->{applypatch}
1008             &&
1009             /\#\#\#\# ApplyPatch data follows \#\#\#\#/
1010             ) {
1011 0         0 return "applypatch"
1012             }
1013 0 0       0 next unless /^[\*\+]{3}\s(\S+)/;
1014 0         0 my $file = $1;
1015 0         0 push @files, $file;
1016 0         0 $cnt_files++;
1017 0 0       0 $cnt_p0files++ if -f $file;
1018 0 0       0 CPAN->debug("file[$file]cnt_files[$cnt_files]cnt_p0files[$cnt_p0files]")
1019             if $CPAN::DEBUG;
1020             }
1021 0 0       0 return "-p1" unless $cnt_files;
1022 0 0       0 my $opt_p = $cnt_files==$cnt_p0files ? "-p0" : "-p1";
1023 0         0 return ($opt_p, \@files);
1024             }
1025              
1026             #-> sub CPAN::Distribution::_edge_cases
1027             # with "configure" or "Makefile" or single file scripts
1028             sub _edge_cases {
1029 0     0   0 my($self,$mpl,$local_file) = @_;
1030 0 0       0 $self->debug(sprintf("makefilepl[%s]anycwd[%s]",
1031             $mpl,
1032             CPAN::anycwd(),
1033             )) if $CPAN::DEBUG;
1034 0         0 my $build_dir = $self->{build_dir};
1035 0         0 my($configure) = File::Spec->catfile($build_dir,"Configure");
1036 0 0       0 if (-f $configure) {
    0          
1037             # do we have anything to do?
1038 0         0 $self->{configure} = $configure;
1039             } elsif (-f File::Spec->catfile($build_dir,"Makefile")) {
1040 0         0 $CPAN::Frontend->mywarn(qq{
1041             Package comes with a Makefile and without a Makefile.PL.
1042             We\'ll try to build it with that Makefile then.
1043             });
1044 0         0 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
1045 0         0 $CPAN::Frontend->mysleep(2);
1046             } else {
1047 0   0     0 my $cf = $self->called_for || "unknown";
1048 0 0       0 if ($cf =~ m|/|) {
1049 0         0 $cf =~ s|.*/||;
1050 0         0 $cf =~ s|\W.*||;
1051             }
1052 0         0 $cf =~ s|[/\\:]||g; # risk of filesystem damage
1053 0 0       0 $cf = "unknown" unless length($cf);
1054 0 0       0 if (my $crud = $self->_contains_crud($build_dir)) {
1055 0         0 my $why = qq{Package contains $crud; not recognized as a perl package, giving up};
1056 0         0 $CPAN::Frontend->mywarn("$why\n");
1057 0         0 $self->{writemakefile} = CPAN::Distrostatus->new(qq{NO -- $why});
1058 0         0 return;
1059             }
1060 0         0 $CPAN::Frontend->mywarn(qq{Package seems to come without Makefile.PL.
1061             (The test -f "$mpl" returned false.)
1062             Writing one on our own (setting NAME to $cf)\a\n});
1063 0         0 $self->{had_no_makefile_pl}++;
1064 0         0 $CPAN::Frontend->mysleep(3);
1065              
1066             # Writing our own Makefile.PL
1067              
1068 0         0 my $exefile_stanza = "";
1069 0 0       0 if ($self->{archived} eq "maybe_pl") {
1070 0         0 $exefile_stanza = $self->_exefile_stanza($build_dir,$local_file);
1071             }
1072              
1073 0         0 my $fh = FileHandle->new;
1074 0 0       0 $fh->open(">$mpl")
1075             or Carp::croak("Could not open >$mpl: $!");
1076 0         0 $fh->print(
1077             qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
1078             # because there was no Makefile.PL supplied.
1079             # Autogenerated on: }.scalar localtime().qq{
1080              
1081             use ExtUtils::MakeMaker;
1082             WriteMakefile(
1083             NAME => q[$cf],$exefile_stanza
1084             );
1085             });
1086 0         0 $fh->close;
1087             }
1088             }
1089              
1090             #-> CPAN;:Distribution::_contains_crud
1091             sub _contains_crud {
1092 0     0   0 my($self,$dir) = @_;
1093 0         0 my(@dirs, $dh, @files);
1094 0 0       0 opendir $dh, $dir or return;
1095 0         0 my $dirent;
1096 0         0 for $dirent (readdir $dh) {
1097 0 0       0 next if $dirent =~ /^\.\.?$/;
1098 0         0 my $path = File::Spec->catdir($dir,$dirent);
1099 0 0       0 if (-d $path) {
    0          
1100 0         0 push @dirs, $dirent;
1101             } elsif (-f $path) {
1102 0         0 push @files, $dirent;
1103             }
1104             }
1105 0 0 0     0 if (@dirs && @files) {
    0          
1106 0         0 return "both files[@files] and directories[@dirs]";
1107             } elsif (@files > 2) {
1108 0         0 return "several files[@files] but no Makefile.PL or Build.PL";
1109             }
1110 0         0 return;
1111             }
1112              
1113             #-> CPAN;:Distribution::_exefile_stanza
1114             sub _exefile_stanza {
1115 0     0   0 my($self,$build_dir,$local_file) = @_;
1116              
1117 0         0 my $fh = FileHandle->new;
1118 0         0 my $script_file = File::Spec->catfile($build_dir,$local_file);
1119 0 0       0 $fh->open($script_file)
1120             or Carp::croak("Could not open script '$script_file': $!");
1121 0         0 local $/ = "\n";
1122             # parse name and prereq
1123 0         0 my($state) = "poddir";
1124 0         0 my($name, $prereq) = ("", "");
1125 0         0 while (<$fh>) {
1126 0 0 0     0 if ($state eq "poddir" && /^=head\d\s+(\S+)/) {
    0          
    0          
1127 0 0       0 if ($1 eq 'NAME') {
    0          
1128 0         0 $state = "name";
1129             } elsif ($1 eq 'PREREQUISITES') {
1130 0         0 $state = "prereq";
1131             }
1132             } elsif ($state =~ m{^(name|prereq)$}) {
1133 0 0       0 if (/^=/) {
    0          
    0          
    0          
1134 0         0 $state = "poddir";
1135             } elsif (/^\s*$/) {
1136             # nop
1137             } elsif ($state eq "name") {
1138 0 0       0 if ($name eq "") {
1139 0         0 ($name) = /^(\S+)/;
1140 0         0 $state = "poddir";
1141             }
1142             } elsif ($state eq "prereq") {
1143 0         0 $prereq .= $_;
1144             }
1145             } elsif (/^=cut\b/) {
1146 0         0 last;
1147             }
1148             }
1149 0         0 $fh->close;
1150              
1151 0         0 for ($name) {
1152 0         0 s{.*<}{}; # strip X<...>
1153 0         0 s{>.*}{};
1154             }
1155 0         0 chomp $prereq;
1156 0         0 $prereq = join " ", split /\s+/, $prereq;
1157             my($PREREQ_PM) = join("\n", map {
1158 0         0 s{.*<}{}; # strip X<...>
  0         0  
1159 0         0 s{>.*}{};
1160 0 0       0 if (/[\s\'\"]/) { # prose?
1161             } else {
1162 0         0 s/[^\w:]$//; # period?
1163 0         0 " "x28 . "'$_' => 0,";
1164             }
1165             } split /\s*,\s*/, $prereq);
1166              
1167 0 0       0 if ($name) {
1168 0         0 my $to_file = File::Spec->catfile($build_dir, $name);
1169 0 0       0 rename $script_file, $to_file
1170             or die "Can't rename $script_file to $to_file: $!";
1171             }
1172              
1173 0         0 return "
1174             EXE_FILES => ['$name'],
1175             PREREQ_PM => {
1176             $PREREQ_PM
1177             },
1178             ";
1179             }
1180              
1181             #-> CPAN::Distribution::_signature_business
1182             sub _signature_business {
1183 7     7   29 my($self) = @_;
1184 7         212 my $check_sigs = CPAN::HandleConfig->prefs_lookup($self,
1185             q{check_sigs});
1186 7 50       50 if ($check_sigs) {
1187 0 0       0 if ($CPAN::META->has_inst("Module::Signature")) {
1188 0 0       0 if (-f "SIGNATURE") {
1189 0 0       0 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
1190 0         0 my $rv = Module::Signature::verify();
1191 0 0 0     0 if ($rv != Module::Signature::SIGNATURE_OK() and
1192             $rv != Module::Signature::SIGNATURE_MISSING()) {
1193 0         0 $CPAN::Frontend->mywarn(
1194             qq{\nSignature invalid for }.
1195             qq{distribution file. }.
1196             qq{Please investigate.\n\n}
1197             );
1198              
1199             my $wrap =
1200             sprintf(qq{I'd recommend removing %s. Some error occurred }.
1201             qq{while checking its signature, so it could }.
1202             qq{be invalid. Maybe you have configured }.
1203             qq{your 'urllist' with a bad URL. Please check this }.
1204             qq{array with 'o conf urllist' and retry. Or }.
1205             qq{examine the distribution in a subshell. Try
1206             look %s
1207             and run
1208             cpansign -v
1209             },
1210             $self->{localfile},
1211 0         0 $self->pretty_id,
1212             );
1213 0         0 $self->{signature_verify} = CPAN::Distrostatus->new("NO");
1214 0         0 $CPAN::Frontend->mywarn(Text::Wrap::wrap("","",$wrap));
1215 0 0       0 $CPAN::Frontend->mysleep(5) if $CPAN::Frontend->can("mysleep");
1216             } else {
1217 0         0 $self->{signature_verify} = CPAN::Distrostatus->new("YES");
1218 0 0       0 $self->debug("Module::Signature has verified") if $CPAN::DEBUG;
1219             }
1220             } else {
1221 0         0 $CPAN::Frontend->mywarn(qq{Package came without SIGNATURE\n\n});
1222             }
1223             } else {
1224 0 0       0 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
1225             }
1226             }
1227             }
1228              
1229             #-> CPAN::Distribution::untar_me ;
1230             sub untar_me {
1231 7     7 0 27 my($self,$ct) = @_;
1232 7         68 $self->{archived} = "tar";
1233 7         16 my $result = eval { $ct->untar() };
  7         51  
1234 7 50       145 if ($result) {
1235 7         325 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
1236             } else {
1237             # unfortunately we have no $@ here, Tarzip is using mydie which dies with "\n"
1238 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- untar failed");
1239             }
1240             }
1241              
1242             # CPAN::Distribution::unzip_me ;
1243             sub unzip_me {
1244 0     0 0 0 my($self,$ct) = @_;
1245 0         0 $self->{archived} = "zip";
1246 0 0       0 if (eval { $ct->unzip() }) {
  0         0  
1247 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
1248             } else {
1249 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- unzip failed during unzip");
1250             }
1251 0         0 return;
1252             }
1253              
1254             sub handle_singlefile {
1255 0     0 0 0 my($self,$local_file) = @_;
1256              
1257 0 0       0 if ( $local_file =~ /\.pm(\.(gz|Z))?(?!\n)\Z/ ) {
    0          
1258 0         0 $self->{archived} = "pm";
1259             } elsif ( $local_file =~ /\.patch(\.(gz|bz2))?(?!\n)\Z/ ) {
1260 0         0 $self->{archived} = "patch";
1261             } else {
1262 0         0 $self->{archived} = "maybe_pl";
1263             }
1264              
1265 0         0 my $to = File::Basename::basename($local_file);
1266 0 0       0 if ($to =~ s/\.(gz|Z)(?!\n)\Z//) {
1267 0 0       0 if (eval{CPAN::Tarzip->new($local_file)->gunzip($to)}) {
  0         0  
1268 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
1269             } else {
1270 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- uncompressing failed");
1271             }
1272             } else {
1273 0 0       0 if (File::Copy::cp($local_file,".")) {
1274 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
1275             } else {
1276 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- copying failed");
1277             }
1278             }
1279 0         0 return $to;
1280             }
1281              
1282             #-> sub CPAN::Distribution::new ;
1283             sub new {
1284 64     64 0 5220 my($class,%att) = @_;
1285              
1286             # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
1287              
1288 64         239 my $this = { %att };
1289 64         346 return bless $this, $class;
1290             }
1291              
1292             #-> sub CPAN::Distribution::look ;
1293             sub look {
1294 0     0 0 0 my($self) = @_;
1295              
1296 0 0       0 if ( $CPAN::Config->{'shell'} ) {
1297 0         0 $CPAN::Frontend->myprint(qq{
1298             Trying to open a subshell in the build directory...
1299             });
1300             } else {
1301 0         0 $CPAN::Frontend->myprint(qq{
1302             Your configuration does not define a value for subshells.
1303             Please define it with "o conf shell "
1304             });
1305 0         0 return;
1306             }
1307 0         0 my $dist = $self->id;
1308 0         0 my $dir;
1309 0 0       0 unless ($dir = $self->dir) {
1310 0         0 $self->get;
1311             }
1312 0 0 0     0 unless ($dir ||= $self->dir) {
1313 0         0 $CPAN::Frontend->mywarn(qq{
1314             Could not determine which directory to use for looking at $dist.
1315             });
1316 0         0 return;
1317             }
1318 0         0 my $pwd = CPAN::anycwd();
1319 0         0 $self->safe_chdir($dir);
1320 0         0 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
1321             {
1322 0   0     0 local $ENV{CPAN_SHELL_LEVEL} = $ENV{CPAN_SHELL_LEVEL}||0;
  0         0  
1323 0         0 $ENV{CPAN_SHELL_LEVEL} += 1;
1324 0         0 my $shell = CPAN::HandleConfig->safe_quote($CPAN::Config->{'shell'});
1325              
1326             local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
1327             ? $ENV{PERL5LIB}
1328 0 0 0     0 : ($ENV{PERLLIB} || "");
1329              
1330 0 0       0 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
1331             # local $ENV{PERL_USE_UNSAFE_INC} = exists $ENV{PERL_USE_UNSAFE_INC} ? $ENV{PERL_USE_UNSAFE_INC} : 1; # look
1332 0         0 $CPAN::META->set_perl5lib;
1333 0         0 local $ENV{MAKEFLAGS}; # protect us from outer make calls
1334              
1335 0 0       0 unless (system($shell) == 0) {
1336 0         0 my $code = $? >> 8;
1337 0         0 $CPAN::Frontend->mywarn("Subprocess shell exit code $code\n");
1338             }
1339             }
1340 0         0 $self->safe_chdir($pwd);
1341             }
1342              
1343             # CPAN::Distribution::cvs_import ;
1344             sub cvs_import {
1345 0     0 0 0 my($self) = @_;
1346 0         0 $self->get;
1347 0         0 my $dir = $self->dir;
1348              
1349 0         0 my $package = $self->called_for;
1350 0         0 my $module = $CPAN::META->instance('CPAN::Module', $package);
1351 0         0 my $version = $module->cpan_version;
1352              
1353 0         0 my $userid = $self->cpan_userid;
1354              
1355 0         0 my $cvs_dir = (split /\//, $dir)[-1];
1356 0         0 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
1357             my $cvs_root =
1358 0   0     0 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
1359             my $cvs_site_perl =
1360 0   0     0 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
1361 0 0       0 if ($cvs_site_perl) {
1362 0         0 $cvs_dir = "$cvs_site_perl/$cvs_dir";
1363             }
1364 0         0 my $cvs_log = qq{"imported $package $version sources"};
1365 0         0 $version =~ s/\./_/g;
1366             # XXX cvs: undocumented and unclear how it was meant to work
1367 0         0 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
1368             "$cvs_dir", $userid, "v$version");
1369              
1370 0         0 my $pwd = CPAN::anycwd();
1371 0 0       0 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
1372              
1373 0         0 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
1374              
1375 0         0 $CPAN::Frontend->myprint(qq{@cmd\n});
1376 0 0       0 system(@cmd) == 0 or
1377             # XXX cvs
1378             $CPAN::Frontend->mydie("cvs import failed");
1379 0 0       0 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
1380             }
1381              
1382             #-> sub CPAN::Distribution::readme ;
1383             sub readme {
1384 0     0 0 0 my($self) = @_;
1385 0         0 my($dist) = $self->id;
1386 0         0 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
1387 0 0       0 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
1388 0         0 my($local_file);
1389             my($local_wanted) =
1390             File::Spec->catfile(
1391             $CPAN::Config->{keep_source_where},
1392 0         0 "authors",
1393             "id",
1394             split(/\//,"$sans.readme"),
1395             );
1396 0         0 my $readme = "authors/id/$sans.readme";
1397 0 0       0 $self->debug("Doing localize for '$readme'") if $CPAN::DEBUG;
1398 0 0       0 $local_file = CPAN::FTP->localize($readme,
1399             $local_wanted)
1400             or $CPAN::Frontend->mydie(qq{No $sans.readme found});
1401              
1402 0         0 my $fh_pager = FileHandle->new;
1403 0         0 local($SIG{PIPE}) = "IGNORE";
1404 0   0     0 my $pager = $CPAN::Config->{'pager'} || "cat";
1405 0 0       0 $fh_pager->open("|$pager")
1406             or die "Could not open pager $pager\: $!";
1407 0         0 my $fh_readme = FileHandle->new;
1408 0 0       0 $fh_readme->open($local_file)
1409             or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
1410 0         0 $CPAN::Frontend->myprint(qq{
1411             Displaying file
1412             $local_file
1413             with pager "$pager"
1414             });
1415 0         0 $fh_pager->print(<$fh_readme>);
1416 0         0 $fh_pager->close;
1417             }
1418              
1419             #-> sub CPAN::Distribution::verifyCHECKSUM ;
1420             sub verifyCHECKSUM {
1421 7     7 0 42 my($self) = @_;
1422             EXCUSE: {
1423 7         15 my @e;
  7         19  
1424 7   50     126 $self->{CHECKSUM_STATUS} ||= "";
1425 7 50       67 $self->{CHECKSUM_STATUS} eq "OK" and push @e, "Checksum was ok";
1426 7 50 0     31 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
  0         0  
1427             }
1428 7         32 my($lc_want,$lc_file,@local,$basename);
1429 7         64 @local = split(/\//,$self->id);
1430 7         20 pop @local;
1431 7         41 push @local, "CHECKSUMS";
1432             $lc_want =
1433             File::Spec->catfile($CPAN::Config->{keep_source_where},
1434 7         156 "authors", "id", @local);
1435 7         40 local($") = "/";
1436 7 50       148 if (my $size = -s $lc_want) {
1437 0 0       0 $self->debug("lc_want[$lc_want]size[$size]") if $CPAN::DEBUG;
1438 0         0 my @stat = stat $lc_want;
1439 0         0 my $epoch_starting_support_of_cpan_path = 1637471530;
1440 0 0       0 if ($stat[9] >= $epoch_starting_support_of_cpan_path) {
1441 0 0       0 if ($self->CHECKSUM_check_file($lc_want, 1)) {
1442 0         0 return $self->{CHECKSUM_STATUS} = "OK";
1443             }
1444             } else {
1445 0         0 unlink $lc_want;
1446             }
1447             }
1448 7         96 $lc_file = CPAN::FTP->localize("authors/id/@local",
1449             $lc_want,1);
1450 7 50       46 unless ($lc_file) {
1451 0         0 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
1452 0         0 $local[-1] .= ".gz";
1453 0         0 $lc_file = CPAN::FTP->localize("authors/id/@local",
1454             "$lc_want.gz",1);
1455 0 0       0 if ($lc_file) {
1456 0         0 $lc_file =~ s/\.gz(?!\n)\Z//;
1457 0         0 eval{CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file)};
  0         0  
1458             } else {
1459 0         0 return;
1460             }
1461             }
1462 7 50       87 if ($self->CHECKSUM_check_file($lc_file)) {
1463 7         251 return $self->{CHECKSUM_STATUS} = "OK";
1464             }
1465             }
1466              
1467             #-> sub CPAN::Distribution::SIG_check_file ;
1468             sub SIG_check_file {
1469 0     0 0 0 my($self,$chk_file) = @_;
1470 0         0 my $rv = eval { Module::Signature::_verify($chk_file) };
  0         0  
1471              
1472 0 0       0 if ($rv eq Module::Signature::CANNOT_VERIFY()) {
1473 0         0 $CPAN::Frontend->myprint(qq{\nSignature for }.
1474             qq{file $chk_file could not be verified for an unknown reason. }.
1475             $self->as_string.
1476             qq{Module::Signature verification returned value $rv\n\n}
1477             );
1478              
1479 0         0 my $wrap = qq{The manual says for this case: Cannot verify the
1480             OpenPGP signature, maybe due to the lack of a network connection to
1481             the key server, or if neither gnupg nor Crypt::OpenPGP exists on the
1482             system. You probably want to analyse the situation and if you cannot
1483             fix it you will have to decide whether you want to stop this session
1484             or you want to turn off signature verification. The latter would be
1485             done with the command 'o conf init check_sigs'};
1486              
1487 0         0 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
1488 0 0       0 } if ($rv == Module::Signature::SIGNATURE_OK()) {
1489 0         0 $CPAN::Frontend->myprint("Signature for $chk_file ok\n");
1490 0         0 return $self->{SIG_STATUS} = "OK";
1491             } else {
1492 0         0 $CPAN::Frontend->mywarn(qq{\nSignature invalid for }.
1493             qq{file $chk_file. }.
1494             qq{Please investigate.\n\n}.
1495             $self->as_string.
1496             qq{Module::Signature verification returned value $rv\n\n}
1497             );
1498              
1499 0         0 my $wrap = qq{I\'d recommend removing $chk_file. Its signature
1500             is invalid. Maybe you have configured your 'urllist' with
1501             a bad URL. Please check this array with 'o conf urllist', and
1502             retry.};
1503              
1504 0         0 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
1505             }
1506             }
1507              
1508             #-> sub CPAN::Distribution::CHECKSUM_check_file ;
1509              
1510             # sloppy is 1 when we have an old checksums file that maybe is good
1511             # enough
1512              
1513             sub CHECKSUM_check_file {
1514 7     7 0 34 my($self,$chk_file,$sloppy) = @_;
1515 7         19 my($cksum,$file,$basename);
1516              
1517 7   50     213 $sloppy ||= 0;
1518 7 50       20 $self->debug("chk_file[$chk_file]sloppy[$sloppy]") if $CPAN::DEBUG;
1519 7         172 my $check_sigs = CPAN::HandleConfig->prefs_lookup($self,
1520             q{check_sigs});
1521 7 50       26 if ($check_sigs) {
1522 0 0       0 if ($CPAN::META->has_inst("Module::Signature")) {
1523 0 0       0 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
1524 0         0 $self->SIG_check_file($chk_file);
1525             } else {
1526 0 0       0 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
1527             }
1528             }
1529              
1530 7         31 $file = $self->{localfile};
1531 7         459 $basename = File::Basename::basename($file);
1532 7         24 my($signed_data);
1533 7         85 my $fh = FileHandle->new;
1534 7 50       379 if ($check_sigs) {
1535 0         0 my $tempdir;
1536 0 0       0 if ($CPAN::META->has_usable("File::Temp")) {
1537 0         0 $tempdir = File::Temp::tempdir("CHECKSUMS-XXXX", CLEANUP => 1, DIR => "/tmp" );
1538             } else {
1539 0         0 $tempdir = File::Spec->catdir(File::Spec->tmpdir, "CHECKSUMS-$$");
1540 0         0 File::Path::mkpath($tempdir);
1541             }
1542 0         0 my $tempfile = File::Spec->catfile($tempdir, "CHECKSUMS.$$");
1543 0         0 unlink $tempfile; # ignore missing file
1544 0         0 my $devnull = File::Spec->devnull;
1545             my $gpg = $CPAN::Config->{gpg} or
1546 0 0       0 $CPAN::Frontend->mydie("Your configuration suggests that you do not have 'gpg' installed. This is needed to verify checksums with the config variable 'check_sigs' on. Please configure it with 'o conf init gpg'");
1547 0         0 my $system = qq{"$gpg" --verify --batch --no-tty --output "$tempfile" "$chk_file" 2> "$devnull"};
1548 0 0       0 0 == system $system or $CPAN::Frontend->mydie("gpg run was failing, cannot continue: $system");
1549 0 0       0 open $fh, $tempfile or $CPAN::Frontend->mydie("Could not open $tempfile: $!");
1550 0         0 local $/;
1551 0         0 $signed_data = <$fh>;
1552 0         0 close $fh;
1553 0         0 File::Path::rmtree($tempdir);
1554             } else {
1555 7         39 my $fh = FileHandle->new;
1556 7 50       512 if (open $fh, $chk_file) {
1557 7         43 local($/);
1558 7         304 $signed_data = <$fh>;
1559             } else {
1560 0         0 $CPAN::Frontend->mydie("Could not open $chk_file for reading");
1561             }
1562 7         94 close $fh;
1563             }
1564 7         330 $signed_data =~ s/\015?\012/\n/g;
1565 7         143 my($compmt) = Safe->new();
1566 7         7393 $cksum = $compmt->reval($signed_data);
1567 7 50       6224 if ($@) {
1568 0         0 rename $chk_file, "$chk_file.bad";
1569 0 0       0 Carp::confess($@) if $@;
1570             }
1571              
1572 7 50 33     241 if (! ref $cksum or ref $cksum ne "HASH") {
    50 33        
    50 33        
    50          
1573 0         0 $CPAN::Frontend->mywarn(qq{
1574             Warning: checksum file '$chk_file' broken.
1575              
1576             When trying to read that file I expected to get a hash reference
1577             for further processing, but got garbage instead.
1578             });
1579 0         0 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed nonetheless?", "no");
1580 0 0       0 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
1581 0         0 $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS file broken";
1582 0         0 return;
1583             } elsif (exists $cksum->{$basename} && ! exists $cksum->{$basename}{cpan_path}) {
1584 0         0 $CPAN::Frontend->mywarn(qq{
1585             Warning: checksum file '$chk_file' not conforming.
1586              
1587             The cksum does not contain the key 'cpan_path' for '$basename'.
1588             });
1589 0         0 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed nonetheless?", "no");
1590 0 0       0 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
1591 0         0 $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS file without cpan_path";
1592 0         0 return;
1593             } elsif (exists $cksum->{$basename} && substr($self->{ID},0,length($cksum->{$basename}{cpan_path}))
1594             ne $cksum->{$basename}{cpan_path}) {
1595 0         0 $CPAN::Frontend->mywarn(qq{
1596             Warning: checksum file not matching path '$self->{ID}'.
1597              
1598             The cksum contain the key 'cpan_path=$cksum->{$basename}{cpan_path}'
1599             which does not match the ID of the distribution '$self->{ID}'.
1600             Something's suspicious might be going on here. Please investigate.
1601              
1602             });
1603 0         0 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed nonetheless?", "no");
1604 0 0       0 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
1605 0         0 $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS non-matching cpan_path vs. ID";
1606 0         0 return;
1607             } elsif (exists $cksum->{$basename}{sha256}) {
1608 7 50       25 $self->debug("Found checksum for $basename:" .
1609             "$cksum->{$basename}{sha256}\n") if $CPAN::DEBUG;
1610              
1611 7         323 open($fh, $file);
1612 7         27 binmode $fh;
1613 7         140 my $eq = $self->eq_CHECKSUM($fh,$cksum->{$basename}{sha256});
1614 7         80 $fh->close;
1615 7         249 $fh = CPAN::Tarzip->TIEHANDLE($file);
1616              
1617 7 50       45 unless ($eq) {
1618 0         0 my $dg = Digest::SHA->new(256);
1619 0         0 my($data,$ref);
1620 0         0 $ref = \$data;
1621 0         0 while ($fh->READ($ref, 4096) > 0) {
1622 0         0 $dg->add($data);
1623             }
1624 0         0 my $hexdigest = $dg->hexdigest;
1625 0         0 $eq += $hexdigest eq $cksum->{$basename}{'sha256-ungz'};
1626             }
1627              
1628 7 50       24 if ($eq) {
1629 7         85 $CPAN::Frontend->myprint("Checksum for $file ok\n");
1630 7         89 return $self->{CHECKSUM_STATUS} = "OK";
1631             } else {
1632 0         0 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
1633             qq{distribution file. }.
1634             qq{Please investigate.\n\n}.
1635             $self->as_string,
1636             $CPAN::META->instance(
1637             'CPAN::Author',
1638             $self->cpan_userid
1639             )->as_string);
1640              
1641 0         0 my $wrap = qq{I\'d recommend removing $file. Its
1642             checksum is incorrect. Maybe you have configured your 'urllist' with
1643             a bad URL. Please check this array with 'o conf urllist', and
1644             retry.};
1645              
1646 0         0 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
1647              
1648             # former versions just returned here but this seems a
1649             # serious threat that deserves a die
1650              
1651             # $CPAN::Frontend->myprint("\n\n");
1652             # sleep 3;
1653             # return;
1654             }
1655             # close $fh if fileno($fh);
1656             } else {
1657 0 0       0 return if $sloppy;
1658 0 0       0 unless ($self->{CHECKSUM_STATUS}) {
1659 0         0 $CPAN::Frontend->mywarn(qq{
1660             Warning: No checksum for $basename in $chk_file.
1661              
1662             The cause for this may be that the file is very new and the checksum
1663             has not yet been calculated, but it may also be that something is
1664             going awry right now.
1665             });
1666 0         0 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed?", "yes");
1667 0 0       0 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
1668             }
1669 0         0 $self->{CHECKSUM_STATUS} = "NIL -- distro not in CHECKSUMS file";
1670 0         0 return;
1671             }
1672             }
1673              
1674             #-> sub CPAN::Distribution::eq_CHECKSUM ;
1675             sub eq_CHECKSUM {
1676 7     7 0 36 my($self,$fh,$expect) = @_;
1677 7 50       47 if ($CPAN::META->has_inst("Digest::SHA")) {
1678 7         75 my $dg = Digest::SHA->new(256);
1679 7         108 my($data);
1680 7         390 while (read($fh, $data, 4096)) {
1681 7         123 $dg->add($data);
1682             }
1683 7         59 my $hexdigest = $dg->hexdigest;
1684             # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
1685 7         108 return $hexdigest eq $expect;
1686             }
1687 0         0 return 1;
1688             }
1689              
1690             #-> sub CPAN::Distribution::force ;
1691              
1692             # Both CPAN::Modules and CPAN::Distributions know if "force" is in
1693             # effect by autoinspection, not by inspecting a global variable. One
1694             # of the reason why this was chosen to work that way was the treatment
1695             # of dependencies. They should not automatically inherit the force
1696             # status. But this has the downside that ^C and die() will return to
1697             # the prompt but will not be able to reset the force_update
1698             # attributes. We try to correct for it currently in the read_metadata
1699             # routine, and immediately before we check for a Signal. I hope this
1700             # works out in one of v1.57_53ff
1701              
1702             # "Force get forgets previous error conditions"
1703              
1704             #-> sub CPAN::Distribution::fforce ;
1705             sub fforce {
1706 0     0 0 0 my($self, $method) = @_;
1707 0         0 $self->force($method,1);
1708             }
1709              
1710             #-> sub CPAN::Distribution::force ;
1711             sub force {
1712 0     0 0 0 my($self, $method,$fforce) = @_;
1713 0         0 my %phase_map = (
1714             get => [
1715             "unwrapped",
1716             "build_dir",
1717             "archived",
1718             "localfile",
1719             "CHECKSUM_STATUS",
1720             "signature_verify",
1721             "prefs",
1722             "prefs_file",
1723             "prefs_file_doc",
1724             "cleanup_after_install_done",
1725             ],
1726             make => [
1727             "writemakefile",
1728             "make",
1729             "modulebuild",
1730             "prereq_pm",
1731             "cleanup_after_install_done",
1732             ],
1733             test => [
1734             "badtestcnt",
1735             "make_test",
1736             "cleanup_after_install_done",
1737             ],
1738             install => [
1739             "install",
1740             "cleanup_after_install_done",
1741             ],
1742             unknown => [
1743             "reqtype",
1744             "yaml_content",
1745             "cleanup_after_install_done",
1746             ],
1747             );
1748 0         0 my $methodmatch = 0;
1749 0         0 my $ldebug = 0;
1750 0         0 PHASE: for my $phase (qw(unknown get make test install)) { # order matters
1751 0 0 0     0 $methodmatch = 1 if $fforce || ($method && $phase eq $method);
      0        
1752 0 0       0 next unless $methodmatch;
1753 0         0 ATTRIBUTE: for my $att (@{$phase_map{$phase}}) {
  0         0  
1754 0 0       0 if ($phase eq "get") {
    0          
1755 0 0 0     0 if (substr($self->id,-1,1) eq "."
1756             && $att =~ /(unwrapped|build_dir|archived)/ ) {
1757             # cannot be undone for local distros
1758 0         0 next ATTRIBUTE;
1759             }
1760 0 0 0     0 if ($att eq "build_dir"
      0        
1761             && $self->{build_dir}
1762             && $CPAN::META->{is_tested}
1763             ) {
1764 0         0 delete $CPAN::META->{is_tested}{$self->{build_dir}};
1765             }
1766             } elsif ($phase eq "test") {
1767 0 0 0     0 if ($att eq "make_test"
      0        
      0        
1768             && $self->{make_test}
1769             && $self->{make_test}{COMMANDID}
1770             && $self->{make_test}{COMMANDID} == $CPAN::CurrentCommandId
1771             ) {
1772             # endless loop too likely
1773 0         0 next ATTRIBUTE;
1774             }
1775             }
1776 0         0 delete $self->{$att};
1777 0 0 0     0 if ($ldebug || $CPAN::DEBUG) {
1778             # local $CPAN::DEBUG = 16; # Distribution
1779 0         0 CPAN->debug(sprintf "id[%s]phase[%s]att[%s]", $self->id, $phase, $att);
1780             }
1781             }
1782             }
1783 0 0 0     0 if ($method && $method =~ /make|test|install/) {
1784 0         0 $self->{force_update} = 1; # name should probably have been force_install
1785             }
1786             }
1787              
1788             #-> sub CPAN::Distribution::notest ;
1789             sub notest {
1790 0     0 0 0 my($self, $method) = @_;
1791             # $CPAN::Frontend->mywarn("XDEBUG: set notest for $self $method");
1792 0         0 $self->{"notest"}++; # name should probably have been force_install
1793             }
1794              
1795             #-> sub CPAN::Distribution::unnotest ;
1796             sub unnotest {
1797 0     0 0 0 my($self) = @_;
1798             # warn "XDEBUG: deleting notest";
1799 0         0 delete $self->{notest};
1800             }
1801              
1802             #-> sub CPAN::Distribution::unforce ;
1803             sub unforce {
1804 0     0 0 0 my($self) = @_;
1805 0         0 delete $self->{force_update};
1806             }
1807              
1808             #-> sub CPAN::Distribution::isa_perl ;
1809             sub isa_perl {
1810 7     7 0 46 my($self) = @_;
1811 7         66 my $file = File::Basename::basename($self->id);
1812 7 50 33     151 if ($file =~ m{ ^ perl
    50          
1813             (
1814             -(5\.\d+\.\d+)
1815             |
1816             (5)[._-](00[0-5](?:_[0-4][0-9])?)
1817             )
1818             \.tar[._-](?:gz|bz2)
1819             (?!\n)\Z
1820             }xs) {
1821 0         0 my $perl_version;
1822 0 0       0 if ($2) {
1823 0         0 $perl_version = $2;
1824             } else {
1825 0         0 $perl_version = "$3.$4";
1826             }
1827 0         0 return $perl_version;
1828             } elsif ($self->cpan_comment
1829             &&
1830             $self->cpan_comment =~ /isa_perl\(.+?\)/) {
1831 0         0 return $1;
1832             }
1833             }
1834              
1835              
1836             #-> sub CPAN::Distribution::perl ;
1837             sub perl {
1838 7     7 0 16 my ($self) = @_;
1839 7 50       33 if (! $self) {
1840 22     22   274 use Carp qw(carp);
  22         40  
  22         450114  
1841 0         0 carp __PACKAGE__ . "::perl was called without parameters.";
1842             }
1843 7         88 return CPAN::HandleConfig->safe_quote($CPAN::Perl);
1844             }
1845              
1846             #-> sub CPAN::Distribution::shortcut_prepare ;
1847             # return values: undef means don't shortcut; 0 means shortcut as fail;
1848             # and 1 means shortcut as success
1849              
1850             sub shortcut_prepare {
1851 7     7 0 89 my ($self) = @_;
1852              
1853 7 50       42 $self->debug("checking archive type[$self->{ID}]") if $CPAN::DEBUG;
1854 7 50 33     72 if (!$self->{archived} || $self->{archived} eq "NO") {
1855 0         0 return $self->goodbye("Is neither a tar nor a zip archive.");
1856             }
1857              
1858 7 50       35 $self->debug("checking unwrapping[$self->{ID}]") if $CPAN::DEBUG;
1859 7 50 33     282 if (!$self->{unwrapped}
    50          
1860             || (
1861             UNIVERSAL::can($self->{unwrapped},"failed") ?
1862             $self->{unwrapped}->failed :
1863             $self->{unwrapped} =~ /^NO/
1864             )) {
1865 0         0 return $self->goodbye("Had problems unarchiving. Please build manually");
1866             }
1867              
1868 7 50       38 $self->debug("checking signature[$self->{ID}]") if $CPAN::DEBUG;
1869 7 0 33     118 if ( ! $self->{force_update}
    0 33        
1870             && exists $self->{signature_verify}
1871             && (
1872             UNIVERSAL::can($self->{signature_verify},"failed") ?
1873             $self->{signature_verify}->failed :
1874             $self->{signature_verify} =~ /^NO/
1875             )
1876             ) {
1877 0         0 return $self->goodbye("Did not pass the signature test.");
1878             }
1879              
1880 7 50       29 $self->debug("checking writemakefile[$self->{ID}]") if $CPAN::DEBUG;
1881 7 50       30 if ($self->{writemakefile}) {
1882 0 0       0 if (
    0          
1883             UNIVERSAL::can($self->{writemakefile},"failed") ?
1884             $self->{writemakefile}->failed :
1885             $self->{writemakefile} =~ /^NO/
1886             ) {
1887             # XXX maybe a retry would be in order?
1888             my $err = UNIVERSAL::can($self->{writemakefile},"text") ?
1889             $self->{writemakefile}->text :
1890 0 0       0 $self->{writemakefile};
1891 0         0 $err =~ s/^NO\s*(--\s+)?//;
1892 0   0     0 $err ||= "Had some problem writing Makefile";
1893 0         0 $err .= ", not re-running";
1894 0         0 return $self->goodbye($err);
1895             } else {
1896 0         0 return $self->success("Has already been prepared");
1897             }
1898             }
1899              
1900 7 50       23 $self->debug("checking configure_requires_later[$self->{ID}]") if $CPAN::DEBUG;
1901 7 50       50 if( my $later = $self->{configure_requires_later} ) { # see also undelay
1902 0         0 return $self->goodbye($later);
1903             }
1904              
1905 7         38 return undef; # no shortcut
1906             }
1907              
1908             sub prepare {
1909 7     7 0 19 my ($self) = @_;
1910              
1911 7 50       53 $self->get
1912             or return;
1913              
1914 7 50       83 if ( defined( my $sc = $self->shortcut_prepare) ) {
1915 0         0 return $sc;
1916             }
1917              
1918             local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
1919             ? $ENV{PERL5LIB}
1920 7 50 0     86 : ($ENV{PERLLIB} || "");
1921 7 50       67 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
1922             local $ENV{PERL_USE_UNSAFE_INC} =
1923             exists $ENV{PERL_USE_UNSAFE_INC} && defined $ENV{PERL_USE_UNSAFE_INC}
1924 7 50 33     125 ? $ENV{PERL_USE_UNSAFE_INC} : 1; # prepare
1925 7         89 $CPAN::META->set_perl5lib;
1926 7         29 local $ENV{MAKEFLAGS}; # protect us from outer make calls
1927              
1928 7 50       43 if ($CPAN::Signal) {
1929 0         0 delete $self->{force_update};
1930 0         0 return;
1931             }
1932              
1933 7 50       76 my $builddir = $self->dir or
1934             $CPAN::Frontend->mydie("PANIC: Cannot determine build directory\n");
1935              
1936 7 50       188 unless (chdir $builddir) {
1937 0         0 $CPAN::Frontend->mywarn("Couldn't chdir to '$builddir': $!");
1938 0         0 return;
1939             }
1940              
1941 7 50       32 if ($CPAN::Signal) {
1942 0         0 delete $self->{force_update};
1943 0         0 return;
1944             }
1945              
1946 7 50       19 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
1947              
1948 7   50     219 local $ENV{PERL_AUTOINSTALL} = $ENV{PERL_AUTOINSTALL} || '';
1949 7   50     135 local $ENV{PERL_EXTUTILS_AUTOINSTALL} = $ENV{PERL_EXTUTILS_AUTOINSTALL} || '';
1950 7 50       52 $self->choose_MM_or_MB
1951             or return;
1952              
1953             my $configurator = $self->{configure} ? "Configure"
1954 7 50       44 : $self->{modulebuild} ? "Build.PL"
    50          
1955             : "Makefile.PL";
1956              
1957 7         80 $CPAN::Frontend->myprint("Configuring ".$self->id." with $configurator\n");
1958              
1959 7 50       44 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
1960 7   50     160 $ENV{PERL_AUTOINSTALL} ||= "--defaultdeps";
1961 7   50     136 $ENV{PERL_EXTUTILS_AUTOINSTALL} ||= "--defaultdeps";
1962             }
1963              
1964 7         21 my $system;
1965             my $pl_commandline;
1966 7 50       35 if ($self->prefs->{pl}) {
1967 0         0 $pl_commandline = $self->prefs->{pl}{commandline};
1968             }
1969 7 50       102 local $ENV{PERL} = defined $ENV{PERL}? $ENV{PERL} : $^X;
1970 7   50     114 local $ENV{PERL5_CPAN_IS_EXECUTING} = $ENV{PERL5_CPAN_IS_EXECUTING} || '';
1971 7 50       36 local $ENV{PERL_MM_USE_DEFAULT} = 1 if $CPAN::Config->{use_prompt_default};
1972 7 50       29 local $ENV{NONINTERACTIVE_TESTING} = 1 if $CPAN::Config->{use_prompt_default};
1973 7 50       50 if ($pl_commandline) {
    50          
    50          
1974 0         0 $system = $pl_commandline;
1975 0         0 $ENV{PERL} = $^X;
1976             } elsif ($self->{'configure'}) {
1977 0         0 $system = $self->{'configure'};
1978             } elsif ($self->{modulebuild}) {
1979 0 0       0 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
1980 0         0 my $mbuildpl_arg = $self->_make_phase_arg("pl");
1981 0 0       0 $system = sprintf("%s Build.PL%s",
1982             $perl,
1983             $mbuildpl_arg ? " $mbuildpl_arg" : "",
1984             );
1985             } else {
1986 7 50       46 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
1987 7         15 my $switch = "";
1988             # This needs a handler that can be turned on or off:
1989             # $switch = "-MExtUtils::MakeMaker ".
1990             # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
1991             # if $] > 5.00310;
1992 7         46 my $makepl_arg = $self->_make_phase_arg("pl");
1993             $ENV{PERL5_CPAN_IS_EXECUTING} = File::Spec->catfile($self->{build_dir},
1994 7         142 "Makefile.PL");
1995 7 50       85 $system = sprintf("%s%s Makefile.PL%s",
    50          
1996             $perl,
1997             $switch ? " $switch" : "",
1998             $makepl_arg ? " $makepl_arg" : "",
1999             );
2000             }
2001 7         19 my $pl_env;
2002 7 50       39 if ($self->prefs->{pl}) {
2003 0         0 $pl_env = $self->prefs->{pl}{env};
2004             }
2005 7 50       19 local @ENV{keys %$pl_env} = values %$pl_env if $pl_env;
2006 7 50       26 if (exists $self->{writemakefile}) {
2007             } else {
2008 7     0   212 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
  0         0  
2009 7         19 my($ret,$pid,$output);
2010 7         16 $@ = "";
2011 7         13 my $go_via_alarm;
2012 7 50       38 if ($CPAN::Config->{inactivity_timeout}) {
2013 0         0 require Config;
2014 0 0 0     0 if ($Config::Config{d_alarm}
2015             &&
2016             $Config::Config{d_alarm} eq "define"
2017             ) {
2018 0         0 $go_via_alarm++
2019             } else {
2020 0         0 $CPAN::Frontend->mywarn("Warning: you have configured the config ".
2021             "variable 'inactivity_timeout' to ".
2022             "'$CPAN::Config->{inactivity_timeout}'. But ".
2023             "on this machine the system call 'alarm' ".
2024             "isn't available. This means that we cannot ".
2025             "provide the feature of intercepting long ".
2026             "waiting code and will turn this feature off.\n"
2027             );
2028 0         0 $CPAN::Config->{inactivity_timeout} = 0;
2029             }
2030             }
2031 7 50       25 if ($go_via_alarm) {
2032 0 0       0 if ( $self->_should_report('pl') ) {
2033             ($output, $ret) = CPAN::Reporter::record_command(
2034             $system,
2035             $CPAN::Config->{inactivity_timeout},
2036 0         0 );
2037 0         0 CPAN::Reporter::grade_PL( $self, $system, $output, $ret );
2038             }
2039             else {
2040 0         0 eval {
2041 0         0 alarm $CPAN::Config->{inactivity_timeout};
2042 0         0 local $SIG{CHLD}; # = sub { wait };
2043 0 0       0 if (defined($pid = fork)) {
2044 0 0       0 if ($pid) { #parent
2045             # wait;
2046 0         0 waitpid $pid, 0;
2047             } else { #child
2048             # note, this exec isn't necessary if
2049             # inactivity_timeout is 0. On the Mac I'd
2050             # suggest, we set it always to 0.
2051 0         0 exec $system;
2052             }
2053             } else {
2054 0         0 $CPAN::Frontend->myprint("Cannot fork: $!");
2055 0         0 return;
2056             }
2057             };
2058 0         0 alarm 0;
2059 0 0       0 if ($@) {
2060 0         0 kill 9, $pid;
2061 0         0 waitpid $pid, 0;
2062 0         0 my $err = "$@";
2063 0         0 $CPAN::Frontend->myprint($err);
2064 0         0 $self->{writemakefile} = CPAN::Distrostatus->new("NO $err");
2065 0         0 $@ = "";
2066 0         0 $self->store_persistent_state;
2067 0         0 return $self->goodbye("$system -- TIMED OUT");
2068             }
2069             }
2070             } else {
2071 7 50       54 if (my $expect_model = $self->_prefs_with_expect("pl")) {
    50          
2072             # XXX probably want to check _should_report here and warn
2073             # about not being able to use CPAN::Reporter with expect
2074 0         0 $ret = $self->_run_via_expect($system,'writemakefile',$expect_model);
2075 0 0 0     0 if (! defined $ret
      0        
2076             && $self->{writemakefile}
2077             && $self->{writemakefile}->failed) {
2078             # timeout
2079 0         0 return;
2080             }
2081             }
2082             elsif ( $self->_should_report('pl') ) {
2083 0         0 ($output, $ret) = eval { CPAN::Reporter::record_command($system) };
  0         0  
2084 0 0 0     0 if (! defined $output or $@) {
2085 0   0     0 my $err = $@ || "Unknown error";
2086 0         0 $CPAN::Frontend->mywarn("Error while running PL phase: $err\n");
2087 0         0 $self->{writemakefile} = CPAN::Distrostatus
2088             ->new("NO '$system' returned status $ret and no output");
2089 0         0 return $self->goodbye("$system -- NOT OK");
2090             }
2091 0         0 CPAN::Reporter::grade_PL( $self, $system, $output, $ret );
2092             }
2093             else {
2094 7         4891066 $ret = system($system);
2095             }
2096 7 100       457 if ($ret != 0) {
2097 3         230 $self->{writemakefile} = CPAN::Distrostatus
2098             ->new("NO '$system' returned status $ret");
2099 3         119 $CPAN::Frontend->mywarn("Warning: No success on command[$system]\n");
2100 3         90 $self->store_persistent_state;
2101 3         74 return $self->goodbye("$system -- NOT OK");
2102             }
2103             }
2104 4 50 33     208 if (-f "Makefile" || -f "Build" || ($^O eq 'VMS' && (-f 'descrip.mms' || -f 'Build.com'))) {
      0        
      0        
      33        
2105 4         272 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
2106 4         40 delete $self->{make_clean}; # if cleaned before, enable next
2107 4         122 $self->store_persistent_state;
2108 4         106 return $self->success("$system -- OK");
2109             } else {
2110 0 0       0 my $makefile = $self->{modulebuild} ? "Build" : "Makefile";
2111 0         0 my $why = "No '$makefile' created";
2112 0         0 $CPAN::Frontend->mywarn($why);
2113 0         0 $self->{writemakefile} = CPAN::Distrostatus
2114             ->new(qq{NO -- $why\n});
2115 0         0 $self->store_persistent_state;
2116 0         0 return $self->goodbye("$system -- NOT OK");
2117             }
2118             }
2119 0         0 $self->store_persistent_state;
2120 0         0 return 1; # success
2121             }
2122              
2123             #-> sub CPAN::Distribution::shortcut_make ;
2124             # return values: undef means don't shortcut; 0 means shortcut as fail;
2125             # and 1 means shortcut as success
2126             sub shortcut_make {
2127 4     4 0 24 my ($self) = @_;
2128              
2129 4 50       22 $self->debug("checking make/build results[$self->{ID}]") if $CPAN::DEBUG;
2130 4 50       28 if (defined $self->{make}) {
2131 0 0       0 if (UNIVERSAL::can($self->{make},"failed") ?
    0          
2132             $self->{make}->failed :
2133             $self->{make} =~ /^NO/
2134             ) {
2135 0 0       0 if ($self->{force_update}) {
2136             # Trying an already failed 'make' (unless somebody else blocks)
2137 0         0 return undef; # no shortcut
2138             } else {
2139             # introduced for turning recursion detection into a distrostatus
2140             my $error = length $self->{make}>3
2141 0 0       0 ? substr($self->{make},3) : "Unknown error";
2142 0         0 $self->store_persistent_state;
2143 0         0 return $self->goodbye("Could not make: $error\n");
2144             }
2145             } else {
2146 0         0 return $self->success("Has already been made")
2147             }
2148             }
2149 4         26 return undef; # no shortcut
2150             }
2151              
2152             #-> sub CPAN::Distribution::make ;
2153             sub make {
2154 7     7 0 32 my($self) = @_;
2155              
2156 7         76 $self->pre_make();
2157              
2158 7 50       29 if (exists $self->{cleanup_after_install_done}) {
2159 0         0 $self->post_make();
2160 0         0 return $self->get;
2161             }
2162              
2163 7 50       55 $self->debug("checking goto id[$self->{ID}]") if $CPAN::DEBUG;
2164 7 50       26 if (my $goto = $self->prefs->{goto}) {
2165 0         0 $self->post_make();
2166 0         0 return $self->goto($goto);
2167             }
2168             # Emergency brake if they said install Pippi and get newest perl
2169              
2170             # XXX Would this make more sense in shortcut_prepare, since
2171             # that doesn't make sense on a perl dist either? Broader
2172             # question: what is the purpose of suggesting force install
2173             # on a perl distribution? That seems unlikely to result in
2174             # such a dependency being satisfied, even if the perl is
2175             # successfully installed. This situation is tantamount to
2176             # a prereq on a version of perl greater than the current one
2177             # so I think we should just abort. -- xdg, 2012-04-06
2178 7 50       58 if ($self->isa_perl) {
2179 0 0 0     0 if (
2180             $self->called_for ne $self->id &&
2181             ! $self->{force_update}
2182             ) {
2183             # if we die here, we break bundles
2184 0         0 $CPAN::Frontend
2185             ->mywarn(sprintf(
2186             qq{The most recent version "%s" of the module "%s"
2187             is part of the perl-%s distribution. To install that, you need to run
2188             force install %s --or--
2189             install %s
2190             },
2191             $CPAN::META->instance(
2192             'CPAN::Module',
2193             $self->called_for
2194             )->cpan_version,
2195             $self->called_for,
2196             $self->isa_perl,
2197             $self->called_for,
2198             $self->pretty_id,
2199             ));
2200 0         0 $self->{make} = CPAN::Distrostatus->new("NO isa perl");
2201 0         0 $CPAN::Frontend->mysleep(1);
2202 0         0 $self->post_make();
2203 0         0 return;
2204             }
2205             }
2206              
2207 7 100       64 unless ($self->prepare){
2208 3         70 $self->post_make();
2209 3         35 return;
2210             }
2211              
2212 4 50       52 if ( defined( my $sc = $self->shortcut_make) ) {
2213 0         0 $self->post_make();
2214 0         0 return $sc;
2215             }
2216              
2217 4 50       44 if ($CPAN::Signal) {
2218 0         0 delete $self->{force_update};
2219 0         0 $self->post_make();
2220 0         0 return;
2221             }
2222              
2223 4 50       58 my $builddir = $self->dir or
2224             $CPAN::Frontend->mydie("PANIC: Cannot determine build directory\n");
2225              
2226 4 50       250 unless (chdir $builddir) {
2227 0         0 $CPAN::Frontend->mywarn("Couldn't chdir to '$builddir': $!");
2228 0         0 $self->post_make();
2229 0         0 return;
2230             }
2231              
2232 4 50       36 my $make = $self->{modulebuild} ? "Build" : "make";
2233 4         40 $CPAN::Frontend->myprint(sprintf "Running %s for %s\n", $make, $self->id);
2234             local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
2235             ? $ENV{PERL5LIB}
2236 4 50 0     126 : ($ENV{PERLLIB} || "");
2237 4 50       48 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
2238             local $ENV{PERL_USE_UNSAFE_INC} =
2239             exists $ENV{PERL_USE_UNSAFE_INC} && defined $ENV{PERL_USE_UNSAFE_INC}
2240 4 50 33     92 ? $ENV{PERL_USE_UNSAFE_INC} : 1; # make
2241 4         54 $CPAN::META->set_perl5lib;
2242 4         12 local $ENV{MAKEFLAGS}; # protect us from outer make calls
2243              
2244 4 50       64 if ($CPAN::Signal) {
2245 0         0 delete $self->{force_update};
2246 0         0 $self->post_make();
2247 0         0 return;
2248             }
2249              
2250 4         14 my %env;
2251 4         34 while (my($k,$v) = each %ENV) {
2252 124 100       402 next if defined $v;
2253 4         46 $env{$k} = '';
2254             }
2255 4         34 local @ENV{keys %env} = values %env;
2256 4         20 my $satisfied = eval { $self->satisfy_requires };
  4         40  
2257 4 50       30 if ($@) {
2258 0         0 return $self->goodbye($@);
2259             }
2260 4 50       20 unless ($satisfied){
2261 0         0 $self->post_make();
2262 0         0 return;
2263             }
2264 4 50       20 if ($CPAN::Signal) {
2265 0         0 delete $self->{force_update};
2266 0         0 $self->post_make();
2267 0         0 return;
2268             }
2269              
2270             # need to chdir again, because $self->satisfy_requires might change the directory
2271 4 50       186 unless (chdir $builddir) {
2272 0         0 $CPAN::Frontend->mywarn("Couldn't chdir to '$builddir': $!");
2273 0         0 $self->post_make();
2274 0         0 return;
2275             }
2276              
2277 4         12 my $system;
2278             my $make_commandline;
2279 4 50       24 if ($self->prefs->{make}) {
2280 0         0 $make_commandline = $self->prefs->{make}{commandline};
2281             }
2282 4 50       104 local $ENV{PERL} = defined $ENV{PERL}? $ENV{PERL} : $^X;
2283 4 50       24 local $ENV{PERL_MM_USE_DEFAULT} = 1 if $CPAN::Config->{use_prompt_default};
2284 4 50       22 local $ENV{NONINTERACTIVE_TESTING} = 1 if $CPAN::Config->{use_prompt_default};
2285 4 50       18 if ($make_commandline) {
2286 0         0 $system = $make_commandline;
2287 0         0 $ENV{PERL} = CPAN::find_perl();
2288             } else {
2289 4 50       22 if ($self->{modulebuild}) {
2290 0 0 0     0 unless (-f "Build" || ($^O eq 'VMS' && -f 'Build.com')) {
      0        
2291 0         0 my $cwd = CPAN::anycwd();
2292 0         0 $CPAN::Frontend->mywarn("Alert: no Build file available for 'make $self->{id}'".
2293             " in cwd[$cwd]. Danger, Will Robinson!\n");
2294 0         0 $CPAN::Frontend->mysleep(5);
2295             }
2296 0         0 $system = join " ", $self->_build_command(), $CPAN::Config->{mbuild_arg};
2297             } else {
2298 4         40 $system = join " ", $self->_make_command(), $CPAN::Config->{make_arg};
2299             }
2300 4         46 $system =~ s/\s+$//;
2301 4         26 my $make_arg = $self->_make_phase_arg("make");
2302 4 50       34 $system = sprintf("%s%s",
2303             $system,
2304             $make_arg ? " $make_arg" : "",
2305             );
2306             }
2307 4         36 my $make_env;
2308 4 50       20 if ($self->prefs->{make}) {
2309 0         0 $make_env = $self->prefs->{make}{env};
2310             }
2311 4 50       14 local @ENV{keys %$make_env} = values %$make_env if $make_env;
2312 4         42 my $expect_model = $self->_prefs_with_expect("make");
2313 4         10 my $want_expect = 0;
2314 4 50 33     22 if ( $expect_model && @{$expect_model->{talk}} ) {
  0         0  
2315 0         0 my $can_expect = $CPAN::META->has_inst("Expect");
2316 0 0       0 if ($can_expect) {
2317 0         0 $want_expect = 1;
2318             } else {
2319 0         0 $CPAN::Frontend->mywarn("Expect not installed, falling back to ".
2320             "system()\n");
2321             }
2322             }
2323 4         10 my ($system_ok, $system_err);
2324 4 50       68 if ($want_expect) {
    50          
2325             # XXX probably want to check _should_report here and
2326             # warn about not being able to use CPAN::Reporter with expect
2327 0         0 $system_ok = $self->_run_via_expect($system,'make',$expect_model) == 0;
2328             }
2329             elsif ( $self->_should_report('make') ) {
2330 0         0 my ($output, $ret) = CPAN::Reporter::record_command($system);
2331 0         0 CPAN::Reporter::grade_make( $self, $system, $output, $ret );
2332 0         0 $system_ok = ! $ret;
2333             }
2334             else {
2335 4         17682804 my $rc = system($system);
2336 4         156 $system_ok = $rc == 0;
2337 4 50       118 $system_err = $! if $rc == -1;
2338             }
2339 4         192 $self->introduce_myself;
2340 4 50       66 if ( $system_ok ) {
2341 4         64 $CPAN::Frontend->myprint(" $system -- OK\n");
2342 4         306 $self->{make} = CPAN::Distrostatus->new("YES");
2343             } else {
2344 0   0     0 $self->{writemakefile} ||= CPAN::Distrostatus->new("YES");
2345 0         0 $self->{make} = CPAN::Distrostatus->new("NO");
2346 0         0 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
2347 0 0       0 $CPAN::Frontend->mywarn(" $system_err\n") if defined $system_err;
2348             }
2349 4         172 $self->store_persistent_state;
2350              
2351 4         96 $self->post_make();
2352              
2353 4         480 return !! $system_ok;
2354             }
2355              
2356             # CPAN::Distribution::goodbye ;
2357             sub goodbye {
2358 3     3 0 37 my($self,$goodbye) = @_;
2359 3         65 my $id = $self->pretty_id;
2360 3         55 $CPAN::Frontend->mywarn(" $id\n $goodbye\n");
2361 3         489 return 0; # must be explicit false, not undef
2362             }
2363              
2364             sub success {
2365 4     4 0 26 my($self,$why) = @_;
2366 4         84 my $id = $self->pretty_id;
2367 4         86 $CPAN::Frontend->myprint(" $id\n $why\n");
2368 4         454 return 1;
2369             }
2370              
2371             # CPAN::Distribution::_run_via_expect ;
2372             sub _run_via_expect {
2373 0     0   0 my($self,$system,$phase,$expect_model) = @_;
2374 0 0       0 CPAN->debug("system[$system]expect_model[$expect_model]") if $CPAN::DEBUG;
2375 0 0       0 if ($CPAN::META->has_inst("Expect")) {
2376 0         0 my $expo = Expect->new; # expo Expect object;
2377 0         0 $expo->spawn($system);
2378 0   0     0 $expect_model->{mode} ||= "deterministic";
2379 0 0       0 if ($expect_model->{mode} eq "deterministic") {
    0          
2380 0         0 return $self->_run_via_expect_deterministic($expo,$phase,$expect_model);
2381             } elsif ($expect_model->{mode} eq "anyorder") {
2382 0         0 return $self->_run_via_expect_anyorder($expo,$phase,$expect_model);
2383             } else {
2384 0         0 die "Panic: Illegal expect mode: $expect_model->{mode}";
2385             }
2386             } else {
2387 0         0 $CPAN::Frontend->mywarn("Expect not installed, falling back to system()\n");
2388 0         0 return system($system);
2389             }
2390             }
2391              
2392             sub _run_via_expect_anyorder {
2393 0     0   0 my($self,$expo,$phase,$expect_model) = @_;
2394 0   0     0 my $timeout = $expect_model->{timeout} || 5;
2395 0         0 my $reuse = $expect_model->{reuse};
2396 0         0 my @expectacopy = @{$expect_model->{talk}}; # we trash it!
  0         0  
2397 0         0 my $but = "";
2398 0         0 my $timeout_start = time;
2399 0         0 EXPECT: while () {
2400 0         0 my($eof,$ran_into_timeout);
2401             # XXX not up to the full power of expect. one could certainly
2402             # wrap all of the talk pairs into a single expect call and on
2403             # success tweak it and step ahead to the next question. The
2404             # current implementation unnecessarily limits itself to a
2405             # single match.
2406             my @match = $expo->expect(1,
2407             [ eof => sub {
2408 0     0   0 $eof++;
2409             } ],
2410             [ timeout => sub {
2411 0     0   0 $ran_into_timeout++;
2412 0         0 } ],
2413             -re => eval"qr{.}",
2414             );
2415 0 0       0 if ($match[2]) {
2416 0         0 $but .= $match[2];
2417             }
2418 0         0 $but .= $expo->clear_accum;
2419 0 0       0 if ($eof) {
    0          
2420 0         0 $expo->soft_close;
2421 0         0 return $expo->exitstatus();
2422             } elsif ($ran_into_timeout) {
2423             # warn "DEBUG: they are asking a question, but[$but]";
2424 0         0 for (my $i = 0; $i <= $#expectacopy; $i+=2) {
2425 0         0 my($next,$send) = @expectacopy[$i,$i+1];
2426 0         0 my $regex = eval "qr{$next}";
2427             # warn "DEBUG: will compare with regex[$regex].";
2428 0 0       0 if ($but =~ /$regex/) {
2429             # warn "DEBUG: will send send[$send]";
2430 0         0 $expo->send($send);
2431             # never allow reusing an QA pair unless they told us
2432 0 0       0 splice @expectacopy, $i, 2 unless $reuse;
2433 0         0 $but =~ s/(?s:^.*?)$regex//;
2434 0         0 $timeout_start = time;
2435 0         0 next EXPECT;
2436             }
2437             }
2438 0         0 my $have_waited = time - $timeout_start;
2439 0 0       0 if ($have_waited < $timeout) {
2440             # warn "DEBUG: have_waited[$have_waited]timeout[$timeout]";
2441 0         0 next EXPECT;
2442             }
2443 0         0 my $why = "could not answer a question during the dialog";
2444 0         0 $CPAN::Frontend->mywarn("Failing: $why\n");
2445 0         0 $self->{$phase} =
2446             CPAN::Distrostatus->new("NO $why");
2447 0         0 return 0;
2448             }
2449             }
2450             }
2451              
2452             sub _run_via_expect_deterministic {
2453 0     0   0 my($self,$expo,$phase,$expect_model) = @_;
2454 0         0 my $ran_into_timeout;
2455             my $ran_into_eof;
2456 0   0     0 my $timeout = $expect_model->{timeout} || 15; # currently unsettable
2457 0         0 my $expecta = $expect_model->{talk};
2458 0         0 EXPECT: for (my $i = 0; $i <= $#$expecta; $i+=2) {
2459 0         0 my($re,$send) = @$expecta[$i,$i+1];
2460 0 0       0 CPAN->debug("timeout[$timeout]re[$re]") if $CPAN::DEBUG;
2461 0         0 my $regex = eval "qr{$re}";
2462             $expo->expect($timeout,
2463             [ eof => sub {
2464 0     0   0 my $but = $expo->clear_accum;
2465 0         0 $CPAN::Frontend->mywarn("EOF (maybe harmless)
2466             expected[$regex]\nbut[$but]\n\n");
2467 0         0 $ran_into_eof++;
2468             } ],
2469             [ timeout => sub {
2470 0     0   0 my $but = $expo->clear_accum;
2471 0         0 $CPAN::Frontend->mywarn("TIMEOUT
2472             expected[$regex]\nbut[$but]\n\n");
2473 0         0 $ran_into_timeout++;
2474 0         0 } ],
2475             -re => $regex);
2476 0 0       0 if ($ran_into_timeout) {
    0          
2477             # note that the caller expects 0 for success
2478 0         0 $self->{$phase} =
2479             CPAN::Distrostatus->new("NO timeout during expect dialog");
2480 0         0 return 0;
2481             } elsif ($ran_into_eof) {
2482 0         0 last EXPECT;
2483             }
2484 0         0 $expo->send($send);
2485             }
2486 0         0 $expo->soft_close;
2487 0         0 return $expo->exitstatus();
2488             }
2489              
2490             #-> CPAN::Distribution::_validate_distropref
2491             sub _validate_distropref {
2492 0     0   0 my($self,@args) = @_;
2493 0 0 0     0 if (
2494             $CPAN::META->has_inst("CPAN::Kwalify")
2495             &&
2496             $CPAN::META->has_inst("Kwalify")
2497             ) {
2498 0         0 eval {CPAN::Kwalify::_validate("distroprefs",@args);};
  0         0  
2499 0 0       0 if ($@) {
2500 0         0 $CPAN::Frontend->mywarn($@);
2501             }
2502             } else {
2503 0 0       0 CPAN->debug("not validating '@args'") if $CPAN::DEBUG;
2504             }
2505             }
2506              
2507             #-> CPAN::Distribution::_find_prefs
2508             sub _find_prefs {
2509 0     0   0 my($self) = @_;
2510 0         0 my $distroid = $self->pretty_id;
2511             #CPAN->debug("distroid[$distroid]") if $CPAN::DEBUG;
2512 0         0 my $prefs_dir = $CPAN::Config->{prefs_dir};
2513 0 0       0 return if $prefs_dir =~ /^\s*$/;
2514 0         0 eval { File::Path::mkpath($prefs_dir); };
  0         0  
2515 0 0       0 if ($@) {
2516 0         0 $CPAN::Frontend->mydie("Cannot create directory $prefs_dir");
2517             }
2518             # shortcut if there are no distroprefs files
2519             {
2520 0 0       0 my $dh = DirHandle->new($prefs_dir) or $CPAN::Frontend->mydie("Couldn't open '$prefs_dir': $!");
  0         0  
2521 0         0 my @files = map { /\.(yml|dd|st)\z/i } $dh->read;
  0         0  
2522 0 0       0 return unless @files;
2523             }
2524 0         0 my $yaml_module = CPAN::_yaml_module();
2525 0         0 my $ext_map = {};
2526 0         0 my @extensions;
2527 0 0       0 if ($CPAN::META->has_inst($yaml_module)) {
2528 0         0 $ext_map->{yml} = 'CPAN';
2529             } else {
2530 0         0 my @fallbacks;
2531 0 0       0 if ($CPAN::META->has_inst("Data::Dumper")) {
2532 0         0 push @fallbacks, $ext_map->{dd} = 'Data::Dumper';
2533             }
2534 0 0       0 if ($CPAN::META->has_inst("Storable")) {
2535 0         0 push @fallbacks, $ext_map->{st} = 'Storable';
2536             }
2537 0 0       0 if (@fallbacks) {
2538 0         0 local $" = " and ";
2539 0 0       0 unless ($self->{have_complained_about_missing_yaml}++) {
2540 0         0 $CPAN::Frontend->mywarnonce("'$yaml_module' not installed, falling back ".
2541             "to @fallbacks to read prefs '$prefs_dir'\n");
2542             }
2543             } else {
2544 0 0       0 unless ($self->{have_complained_about_missing_yaml}++) {
2545 0         0 $CPAN::Frontend->mywarnonce("'$yaml_module' not installed, cannot ".
2546             "read prefs '$prefs_dir'\n");
2547             }
2548             }
2549             }
2550 0         0 my $finder = CPAN::Distroprefs->find($prefs_dir, $ext_map);
2551 0         0 DIRENT: while (my $result = $finder->next) {
2552 0 0       0 if ($result->is_warning) {
    0          
2553 0         0 $CPAN::Frontend->mywarn($result->as_string);
2554 0         0 $CPAN::Frontend->mysleep(1);
2555 0         0 next DIRENT;
2556             } elsif ($result->is_fatal) {
2557 0         0 $CPAN::Frontend->mydie($result->as_string);
2558             }
2559              
2560 0         0 my @prefs = @{ $result->prefs };
  0         0  
2561              
2562 0         0 ELEMENT: for my $y (0..$#prefs) {
2563 0         0 my $pref = $prefs[$y];
2564 0         0 $self->_validate_distropref($pref->data, $result->abs, $y);
2565              
2566             # I don't know why we silently skip when there's no match, but
2567             # complain if there's an empty match hashref, and there's no
2568             # comment explaining why -- hdp, 2008-03-18
2569 0 0       0 unless ($pref->has_any_match) {
2570 0         0 next ELEMENT;
2571             }
2572              
2573 0 0       0 unless ($pref->has_valid_subkeys) {
2574 0         0 $CPAN::Frontend->mydie(sprintf
2575             "Nonconforming .%s file '%s': " .
2576             "missing match/* subattribute. " .
2577             "Please remove, cannot continue.",
2578             $result->ext, $result->abs,
2579             );
2580             }
2581              
2582             my $arg = {
2583             env => \%ENV,
2584             distribution => $distroid,
2585             perl => \&CPAN::find_perl,
2586             perlconfig => \%Config::Config,
2587 0     0   0 module => sub { [ $self->containsmods ] },
2588 0         0 };
2589              
2590 0 0       0 if ($pref->matches($arg)) {
2591             return {
2592 0         0 prefs => $pref->data,
2593             prefs_file => $result->abs,
2594             prefs_file_doc => $y,
2595             };
2596             }
2597              
2598             }
2599             }
2600 0         0 return;
2601             }
2602              
2603             # CPAN::Distribution::prefs
2604             sub prefs {
2605 182     182 0 362 my($self) = @_;
2606 182 50 66     915 if (exists $self->{negative_prefs_cache}
2607             &&
2608             $self->{negative_prefs_cache} != $CPAN::CurrentCommandId
2609             ) {
2610 0         0 delete $self->{negative_prefs_cache};
2611 0         0 delete $self->{prefs};
2612             }
2613 182 100       349 if (exists $self->{prefs}) {
2614 175         1887 return $self->{prefs}; # XXX comment out during debugging
2615             }
2616 7 50       60 if ($CPAN::Config->{prefs_dir}) {
2617 0 0       0 CPAN->debug("prefs_dir[$CPAN::Config->{prefs_dir}]") if $CPAN::DEBUG;
2618 0         0 my $prefs = $self->_find_prefs();
2619 0   0     0 $prefs ||= ""; # avoid warning next line
2620 0 0       0 CPAN->debug("prefs[$prefs]") if $CPAN::DEBUG;
2621 0 0       0 if ($prefs) {
2622 0         0 for my $x (qw(prefs prefs_file prefs_file_doc)) {
2623 0         0 $self->{$x} = $prefs->{$x};
2624             }
2625             my $bs = sprintf(
2626             "%s[%s]",
2627             File::Basename::basename($self->{prefs_file}),
2628             $self->{prefs_file_doc},
2629 0         0 );
2630 0         0 my $filler1 = "_" x 22;
2631 0         0 my $filler2 = int(66 - length($bs))/2;
2632 0 0       0 $filler2 = 0 if $filler2 < 0;
2633 0         0 $filler2 = " " x $filler2;
2634 0         0 my $pretty = $self->pretty_id;
2635 0         0 my $filler3 = int(66 - length($pretty))/2;
2636 0         0 $filler3 = " " x $filler3;
2637 0         0 $CPAN::Frontend->myprint("
2638             $filler1 D i s t r o P r e f s $filler1
2639             $filler2 $bs $filler2
2640             $filler3 $pretty $filler3
2641             ");
2642 0         0 $CPAN::Frontend->mysleep(1);
2643 0         0 return $self->{prefs};
2644             }
2645             }
2646 7         41 $self->{negative_prefs_cache} = $CPAN::CurrentCommandId;
2647 7         46 return $self->{prefs} = +{};
2648             }
2649              
2650             # CPAN::Distribution::_make_phase_arg
2651             sub _make_phase_arg {
2652 15     15   62 my($self, $phase) = @_;
2653 15         36 my $_make_phase_arg;
2654 15         35 my $prefs = $self->prefs;
2655 15 0 33     192 if (
      33        
      0        
2656             $prefs
2657             && exists $prefs->{$phase}
2658             && exists $prefs->{$phase}{args}
2659             && $prefs->{$phase}{args}
2660             ) {
2661             $_make_phase_arg = join(" ",
2662 0         0 map {CPAN::HandleConfig
2663 0         0 ->safe_quote($_)} @{$prefs->{$phase}{args}},
  0         0  
2664             );
2665             }
2666              
2667             # cpan[2]> o conf make[TAB]
2668             # make make_install_make_command
2669             # make_arg makepl_arg
2670             # make_install_arg
2671             # cpan[2]> o conf mbuild[TAB]
2672             # mbuild_arg mbuild_install_build_command
2673             # mbuild_install_arg mbuildpl_arg
2674              
2675 15         22 my $mantra; # must switch make/mbuild here
2676 15 50       40 if ($self->{modulebuild}) {
2677 0         0 $mantra = "mbuild";
2678             } else {
2679 15         67 $mantra = "make";
2680             }
2681 15         283 my %map = (
2682             pl => "pl_arg",
2683             make => "_arg",
2684             test => "_test_arg", # does not really exist but maybe
2685             # will some day and now protects
2686             # us from unini warnings
2687             install => "_install_arg",
2688             );
2689 15         36 my $phase_underscore_meshup = $map{$phase};
2690 15         38 my $what = sprintf "%s%s", $mantra, $phase_underscore_meshup;
2691              
2692 15   66     145 $_make_phase_arg ||= $CPAN::Config->{$what};
2693 15         50 return $_make_phase_arg;
2694             }
2695              
2696             # CPAN::Distribution::_make_command
2697             sub _make_command {
2698 9     9   59 my ($self) = @_;
2699 9 50       28 if ($self) {
2700             return
2701             CPAN::HandleConfig
2702             ->safe_quote(
2703             CPAN::HandleConfig->prefs_lookup($self,
2704             q{make})
2705             || $Config::Config{make}
2706 9   50     106 || 'make'
2707             );
2708             } else {
2709             # Old style call, without object. Deprecated
2710 0         0 Carp::confess("CPAN::_make_command() used as function. Don't Do That.");
2711             return
2712             safe_quote(undef,
2713             CPAN::HandleConfig->prefs_lookup($self,q{make})
2714             || $CPAN::Config->{make}
2715             || $Config::Config{make}
2716 0   0     0 || 'make');
2717             }
2718             }
2719              
2720             sub _make_install_make_command {
2721 1     1   3 my ($self) = @_;
2722 1         20 my $mimc =
2723             CPAN::HandleConfig->prefs_lookup($self, q{make_install_make_command});
2724 1 50       7 return $self->_make_command() unless $mimc;
2725              
2726             # Quote the "make install" make command on Windows, where it is commonly
2727             # found in, e.g., C:\Program Files\... and therefore needs quoting. We can't
2728             # do this in general because the command maybe "sudo make..." (i.e. a
2729             # program with arguments), but that is unlikely to be the case on Windows.
2730 0 0       0 $mimc = CPAN::HandleConfig->safe_quote($mimc) if $^O eq 'MSWin32';
2731              
2732 0         0 return $mimc;
2733             }
2734              
2735             #-> sub CPAN::Distribution::is_locally_optional
2736             sub is_locally_optional {
2737 0     0 0 0 my($self, $prereq_pm, $prereq) = @_;
2738 0   0     0 $prereq_pm ||= $self->{prereq_pm};
2739 0         0 my($nmo,$opt);
2740 0         0 for my $rt (qw(requires build_requires)) {
2741 0 0       0 if (exists $prereq_pm->{$rt}{$prereq}) {
2742             # rt 121914
2743 0   0     0 $nmo ||= $CPAN::META->instance("CPAN::Module",$prereq);
2744 0         0 my $av = $nmo->available_version;
2745 0 0 0     0 return 0 if !$av || CPAN::Version->vlt($av,$prereq_pm->{$rt}{$prereq});
2746             }
2747 0 0       0 if (exists $prereq_pm->{"opt_$rt"}{$prereq}) {
2748 0         0 $opt = 1;
2749             }
2750             }
2751 0   0     0 return $opt||0;
2752             }
2753              
2754             #-> sub CPAN::Distribution::follow_prereqs ;
2755             sub follow_prereqs {
2756 0     0 0 0 my($self) = shift;
2757 0         0 my($slot) = shift;
2758 0         0 my(@prereq_tuples) = grep {$_->[0] ne "perl"} @_;
  0         0  
2759 0 0       0 return unless @prereq_tuples;
2760 0         0 my(@good_prereq_tuples);
2761 0         0 for my $p (@prereq_tuples) {
2762             # e.g. $p = ['Devel::PartialDump', 'r', 1]
2763             # promote if possible
2764 0 0       0 if ($p->[1] =~ /^(r|c)$/) {
    0          
2765 0         0 push @good_prereq_tuples, $p;
2766             } elsif ($p->[1] =~ /^(b)$/) {
2767 0         0 my $reqtype = CPAN::Queue->reqtype_of($p->[0]);
2768 0 0       0 if ($reqtype =~ /^(r|c)$/) {
2769 0         0 push @good_prereq_tuples, [$p->[0], $reqtype, $p->[2]];
2770             } else {
2771 0         0 push @good_prereq_tuples, $p;
2772             }
2773             } else {
2774 0         0 die "Panic: in follow_prereqs: reqtype[$p->[1]] seen, should never happen";
2775             }
2776             }
2777 0         0 my $pretty_id = $self->pretty_id;
2778 0         0 my %map = (
2779             b => "build_requires",
2780             r => "requires",
2781             c => "commandline",
2782             );
2783 0         0 my($filler1,$filler2,$filler3,$filler4);
2784 0         0 my $unsat = "Unsatisfied dependencies detected during";
2785 0 0       0 my $w = length($unsat) > length($pretty_id) ? length($unsat) : length($pretty_id);
2786             {
2787 0         0 my $r = int(($w - length($unsat))/2);
2788 0         0 my $l = $w - length($unsat) - $r;
2789 0         0 $filler1 = "-"x4 . " "x$l;
2790 0         0 $filler2 = " "x$r . "-"x4 . "\n";
2791             }
2792             {
2793 0         0 my $r = int(($w - length($pretty_id))/2);
  0         0  
  0         0  
2794 0         0 my $l = $w - length($pretty_id) - $r;
2795 0         0 $filler3 = "-"x4 . " "x$l;
2796 0         0 $filler4 = " "x$r . "-"x4 . "\n";
2797             }
2798             $CPAN::Frontend->
2799             myprint("$filler1 $unsat $filler2".
2800             "$filler3 $pretty_id $filler4".
2801 0 0       0 join("", map {sprintf " %s \[%s%s]\n", $_->[0], $map{$_->[1]}, $self->is_locally_optional(undef,$_->[0]) ? ",optional" : ""} @good_prereq_tuples),
  0         0  
2802             );
2803 0         0 my $follow = 0;
2804 0 0       0 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
    0          
2805 0         0 $follow = 1;
2806             } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
2807 0         0 my $answer = CPAN::Shell::colorable_makemaker_prompt(
2808             "Shall I follow them and prepend them to the queue
2809             of modules we are processing right now?", "yes");
2810 0         0 $follow = $answer =~ /^\s*y/i;
2811             } else {
2812 0         0 my @prereq = map { $_->[0] } @good_prereq_tuples;
  0         0  
2813 0         0 local($") = ", ";
2814 0         0 $CPAN::Frontend->
2815             myprint(" Ignoring dependencies on modules @prereq\n");
2816             }
2817 0 0       0 if ($follow) {
2818 0         0 my $id = $self->id;
2819 0         0 my(@to_queue_mand,@to_queue_opt);
2820 0         0 for my $gp (@good_prereq_tuples) {
2821 0         0 my($prereq,$reqtype,$optional) = @$gp;
2822 0         0 my $qthing = +{qmod=>$prereq,reqtype=>$reqtype,optional=>$optional};
2823 0 0 0     0 if ($optional &&
2824             $self->is_locally_optional(undef,$prereq)
2825             ){
2826             # Since we do not depend on this one, we do not need
2827             # this in a mandatory arrangement:
2828 0         0 push @to_queue_opt, $qthing;
2829             } else {
2830 0         0 my $any = CPAN::Shell->expandany($prereq);
2831 0         0 $self->{$slot . "_for"}{$any->id}++;
2832 0 0       0 if ($any) {
2833 0 0       0 unless ($optional) {
2834             # No recursion check in an optional area of the tree
2835 0         0 $any->color_cmd_tmps(0,2);
2836             }
2837             } else {
2838 0         0 $CPAN::Frontend->mywarn("Warning (maybe a bug): Cannot expand prereq '$prereq'\n");
2839 0         0 $CPAN::Frontend->mysleep(2);
2840             }
2841             # order everything that is not locally_optional just
2842             # like mandatory items: this keeps leaves before
2843             # branches
2844 0         0 unshift @to_queue_mand, $qthing;
2845             }
2846             }
2847 0 0       0 if (@to_queue_mand) {
    0          
2848 0         0 unshift @to_queue_mand, {qmod => $id, reqtype => $self->{reqtype}, optional=> !$self->{mandatory}};
2849 0         0 CPAN::Queue->jumpqueue(@to_queue_opt,@to_queue_mand);
2850 0         0 $self->{$slot} = "Delayed until after prerequisites";
2851 0         0 return 1; # signal we need dependencies
2852             } elsif (@to_queue_opt) {
2853 0         0 CPAN::Queue->jumpqueue(@to_queue_opt);
2854             }
2855             }
2856 0         0 return;
2857             }
2858              
2859             sub _feature_depends {
2860 11     11   50 my($self) = @_;
2861 11         52 my $meta_yml = $self->parse_meta_yml();
2862 11 50       188 my $optf = $meta_yml->{optional_features} or return;
2863 0 0 0     0 if (!ref $optf or ref $optf ne "HASH"){
2864 0         0 $CPAN::Frontend->mywarn("The content of optional_features is not a HASH reference. Cannot use it.\n");
2865 0         0 $optf = {};
2866             }
2867 0 0       0 my $wantf = $self->prefs->{features} or return;
2868 0 0 0     0 if (!ref $wantf or ref $wantf ne "ARRAY"){
2869 0         0 $CPAN::Frontend->mywarn("The content of 'features' is not an ARRAY reference. Cannot use it.\n");
2870 0         0 $wantf = [];
2871             }
2872 0         0 my $dep = +{};
2873 0         0 for my $wf (@$wantf) {
2874 0 0       0 if (my $f = $optf->{$wf}) {
2875             $CPAN::Frontend->myprint("Found the demanded feature '$wf' that ".
2876             "is accompanied by this description:\n".
2877             $f->{description}.
2878 0         0 "\n\n"
2879             );
2880             # configure_requires currently not in the spec, unlikely to be useful anyway
2881 0         0 for my $reqtype (qw(configure_requires build_requires requires)) {
2882 0 0       0 my $reqhash = $f->{$reqtype} or next;
2883 0         0 while (my($k,$v) = each %$reqhash) {
2884 0         0 $dep->{$reqtype}{$k} = $v;
2885             }
2886             }
2887             } else {
2888 0         0 $CPAN::Frontend->mywarn("The demanded feature '$wf' was not ".
2889             "found in the META.yml file".
2890             "\n\n"
2891             );
2892             }
2893             }
2894 0         0 $dep;
2895             }
2896              
2897             sub prereqs_for_slot {
2898 11     11 0 24 my($self,$slot) = @_;
2899 11         20 my($prereq_pm);
2900 11 50       63 unless ($CPAN::META->has_usable("CPAN::Meta::Requirements")) {
2901 0         0 my $whynot = "not available";
2902 0 0       0 if (defined $CPAN::Meta::Requirements::VERSION) {
2903 0         0 $whynot = "version $CPAN::Meta::Requirements::VERSION not sufficient";
2904             }
2905 0         0 $CPAN::Frontend->mywarn("CPAN::Meta::Requirements $whynot\n");
2906 0         0 my $before = "";
2907 0 0       0 if ($self->{CALLED_FOR}){
2908 0 0       0 if ($self->{CALLED_FOR} =~
2909             /^(
2910             CPAN::Meta::Requirements
2911             |CPAN::DistnameInfo
2912             |version
2913             |parent
2914             |ExtUtils::MakeMaker
2915             |Test::Harness
2916             )$/x) {
2917 0         0 $CPAN::Frontend->mywarn("Please install CPAN::Meta::Requirements ".
2918             "as soon as possible; it is needed for a reliable operation of ".
2919             "the cpan shell; setting requirements to nil for '$1' for now ".
2920             "to prevent deadlock during bootstrapping\n");
2921 0         0 return;
2922             }
2923 0         0 $before = " before $self->{CALLED_FOR}";
2924             }
2925 0         0 $CPAN::Frontend->mydie("Please install CPAN::Meta::Requirements manually$before");
2926             }
2927 11         209 my $merged = CPAN::Meta::Requirements->new;
2928 11   50     468 my $prefs_depends = $self->prefs->{depends}||{};
2929 11         55 my $feature_depends = $self->_feature_depends();
2930 11 100       52 if ($slot eq "configure_requires_later") {
    50          
2931 7         70 for my $hash ( $self->configure_requires,
2932             $prefs_depends->{configure_requires},
2933             $feature_depends->{configure_requires},
2934             ) {
2935 14         511 $merged->add_requirements(
2936             CPAN::Meta::Requirements->from_string_hash($hash)
2937             );
2938             }
2939 7 0 33     412 if (-f "Build.PL"
      33        
      0        
2940             && ! -f File::Spec->catfile($self->{build_dir},"Makefile.PL")
2941 0         0 && ! @{[ $merged->required_modules ]}
2942             && ! $CPAN::META->has_inst("Module::Build")
2943             ) {
2944 0         0 $CPAN::Frontend->mywarn(
2945             " Warning: CPAN.pm discovered Module::Build as undeclared prerequisite.\n".
2946             " Adding it now as such.\n"
2947             );
2948 0         0 $CPAN::Frontend->mysleep(5);
2949 0         0 $merged->add_minimum( "Module::Build" => 0 );
2950 0         0 delete $self->{writemakefile};
2951             }
2952 7         22 $prereq_pm = {}; # configure_requires defined as "b"
2953             } elsif ($slot eq "later") {
2954 4   50     56 my $prereq_pm_0 = $self->prereq_pm || {};
2955 4         16 for my $reqtype (qw(requires build_requires opt_requires opt_build_requires)) {
2956 16 50       20 $prereq_pm->{$reqtype} = {%{$prereq_pm_0->{$reqtype}||{}}}; # copy to not pollute it
  16         66  
2957 16         40 for my $dep ($prefs_depends,$feature_depends) {
2958 32 50       34 for my $k (keys %{$dep->{$reqtype}||{}}) {
  32         102  
2959 0         0 $prereq_pm->{$reqtype}{$k} = $dep->{$reqtype}{$k};
2960             }
2961             }
2962             }
2963             # XXX what about optional_req|breq? -- xdg, 2012-04-01
2964 4         14 for my $hash (
2965             $prereq_pm->{requires},
2966             $prereq_pm->{build_requires},
2967             $prereq_pm->{opt_requires},
2968             $prereq_pm->{opt_build_requires},
2969              
2970             ) {
2971 16         1408 $merged->add_requirements(
2972             CPAN::Meta::Requirements->from_string_hash($hash)
2973             );
2974             }
2975             } else {
2976 0         0 die "Panic: illegal slot '$slot'";
2977             }
2978 11         99 return ($merged->as_string_hash, $prereq_pm);
2979             }
2980              
2981             #-> sub CPAN::Distribution::unsat_prereq ;
2982             # return ([Foo,"r"],[Bar,"b"]) for normal modules
2983             # return ([perl=>5.008]) if we need a newer perl than we are running under
2984             # (sorry for the inconsistency, it was an accident)
2985             sub unsat_prereq {
2986 11     11 0 77 my($self,$slot) = @_;
2987 11         102 my($merged_hash,$prereq_pm) = $self->prereqs_for_slot($slot);
2988 11         381 my(@need);
2989 11 50       52 unless ($CPAN::META->has_usable("CPAN::Meta::Requirements")) {
2990 0         0 $CPAN::Frontend->mywarn("CPAN::Meta::Requirements not available, please install as soon as possible, trying to continue with severly limited capabilities\n");
2991 0         0 return;
2992             }
2993 11         45 my $merged = CPAN::Meta::Requirements->from_string_hash($merged_hash);
2994 11         692 my @merged = sort $merged->required_modules;
2995 11 50       103 CPAN->debug("all merged_prereqs[@merged]") if $CPAN::DEBUG;
2996 11         91 NEED: for my $need_module ( @merged ) {
2997 8         34 my $need_version = $merged->requirements_for_module($need_module);
2998 8         362 my($available_version,$inst_file,$available_file,$nmo);
2999 8 50       24 if ($need_module eq "perl") {
3000 0         0 $available_version = $];
3001 0         0 $available_file = CPAN::find_perl();
3002             } else {
3003 8 50       92 if (CPAN::_sqlite_running()) {
3004 0         0 CPAN::Index->reload;
3005 0         0 $CPAN::SQLite->search("CPAN::Module",$need_module);
3006             }
3007 8         62 $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
3008 8   50     70 $inst_file = $nmo->inst_file || '';
3009 8   50     60 $available_file = $nmo->available_file || '';
3010 8         70 $available_version = $nmo->available_version;
3011 8 50       56 if ($nmo->uptodate) {
3012 8         18 my $accepts = eval {
3013 8         56 $merged->accepts_module($need_module, $available_version);
3014             };
3015 8 50       326 unless ($accepts) {
3016 0         0 my $rq = $merged->requirements_for_module( $need_module );
3017 0         0 $CPAN::Frontend->mywarn(
3018             "Warning: Version '$available_version' of ".
3019             "'$need_module' is up to date but does not ".
3020             "fulfill requirements ($rq). I will continue, ".
3021             "but chances to succeed are low.\n");
3022             }
3023 8         34 next NEED;
3024             }
3025              
3026             # if they have not specified a version, we accept any
3027             # installed one; in that case inst_file is always
3028             # sufficient and available_file is sufficient on
3029             # both build_requires and configure_requires
3030             my $sufficient = $inst_file ||
3031 0   0     0 ( exists $prereq_pm->{requires}{$need_module} ? 0 : $available_file );
3032 0 0 0     0 if ( $sufficient
      0        
3033             and ( # a few quick short circuits
3034             not defined $need_version
3035             or $need_version eq '0' # "==" would trigger warning when not numeric
3036             or $need_version eq "undef"
3037             )) {
3038 0 0       0 unless ($nmo->inst_deprecated) {
3039 0         0 next NEED;
3040             }
3041             }
3042             }
3043              
3044             # We only want to install prereqs if either they're not installed
3045             # or if the installed version is too old. We cannot omit this
3046             # check, because if 'force' is in effect, nobody else will check.
3047             # But we don't want to accept a deprecated module installed as part
3048             # of the Perl core, so we continue if the available file is the installed
3049             # one and is deprecated
3050              
3051 0 0       0 if ( $available_file ) {
3052 0         0 my $fulfills_all_version_rqs = $self->_fulfills_all_version_rqs
3053             (
3054             $need_module,
3055             $available_file,
3056             $available_version,
3057             $need_version,
3058             );
3059 0 0 0     0 if ( $inst_file
    0 0        
      0        
      0        
      0        
      0        
      0        
3060             && $available_file eq $inst_file
3061             && $nmo->inst_deprecated
3062             ) {
3063             # continue installing as a prereq. we really want that
3064             # because the deprecated module may spit out warnings
3065             # and third party did not know until today. Only one
3066             # exception is OK, because CPANPLUS is special after
3067             # all:
3068 0 0 0     0 if ( $fulfills_all_version_rqs and
3069             $nmo->id =~ /^CPANPLUS(?:::Dist::Build)$/
3070             ) {
3071             # here we have an available version that is good
3072             # enough although deprecated (preventing circular
3073             # loop CPANPLUS => CPANPLUS::Dist::Build RT#83042)
3074 0         0 next NEED;
3075             }
3076             } elsif (
3077             $self->{reqtype} # e.g. maybe we came via goto?
3078             && $self->{reqtype} =~ /^(r|c)$/
3079             && ( exists $prereq_pm->{requires}{$need_module}
3080             || exists $prereq_pm->{opt_requires}{$need_module} )
3081             && $nmo
3082             && !$inst_file
3083             ) {
3084             # continue installing as a prereq; this may be a
3085             # distro we already used when it was a build_requires
3086             # so we did not install it. But suddenly somebody
3087             # wants it as a requires
3088 0         0 my $need_distro = $nmo->distribution;
3089 0 0 0     0 if ($need_distro->{install} && $need_distro->{install}->failed && $need_distro->{install}->text =~ /is only/) {
      0        
3090 0         0 my $id = $need_distro->pretty_id;
3091 0         0 $CPAN::Frontend->myprint("Promoting $id from build_requires to requires due $need_module\n");
3092 0         0 delete $need_distro->{install}; # promote to another installation attempt
3093 0         0 $need_distro->{reqtype} = "r";
3094 0         0 $need_distro->install;
3095 0         0 next NEED;
3096             }
3097             }
3098             else {
3099 0 0       0 next NEED if $fulfills_all_version_rqs;
3100             }
3101             }
3102              
3103 0 0       0 if ($need_module eq "perl") {
3104 0         0 return ["perl", $need_version];
3105             }
3106 0   0     0 $self->{sponsored_mods}{$need_module} ||= 0;
3107 0 0       0 CPAN->debug("need_module[$need_module]s/s/n[$self->{sponsored_mods}{$need_module}]") if $CPAN::DEBUG;
3108 0 0       0 if (my $sponsoring = $self->{sponsored_mods}{$need_module}++) {
3109             # We have already sponsored it and for some reason it's still
3110             # not available. So we do ... what??
3111              
3112             # if we push it again, we have a potential infinite loop
3113              
3114             # The following "next" was a very problematic construct.
3115             # It helped a lot but broke some day and had to be
3116             # replaced.
3117              
3118             # We must be able to deal with modules that come again and
3119             # again as a prereq and have themselves prereqs and the
3120             # queue becomes long but finally we would find the correct
3121             # order. The RecursiveDependency check should trigger a
3122             # die when it's becoming too weird. Unfortunately removing
3123             # this next breaks many other things.
3124              
3125             # The bug that brought this up is described in Todo under
3126             # "5.8.9 cannot install Compress::Zlib"
3127              
3128             # next; # this is the next that had to go away
3129              
3130             # The following "next NEED" are fine and the error message
3131             # explains well what is going on. For example when the DBI
3132             # fails and consequently DBD::SQLite fails and now we are
3133             # processing CPAN::SQLite. Then we must have a "next" for
3134             # DBD::SQLite. How can we get it and how can we identify
3135             # all other cases we must identify?
3136              
3137 0         0 my $do = $nmo->distribution;
3138 0 0       0 next NEED unless $do; # not on CPAN
3139 0 0       0 if (CPAN::Version->vcmp($need_version, $nmo->ro->{CPAN_VERSION}) > 0){
3140 0         0 $CPAN::Frontend->mywarn("Warning: Prerequisite ".
3141             "'$need_module => $need_version' ".
3142             "for '$self->{ID}' seems ".
3143             "not available according to the indices\n"
3144             );
3145 0         0 next NEED;
3146             }
3147 0         0 NOSAYER: for my $nosayer (
3148             "unwrapped",
3149             "writemakefile",
3150             "signature_verify",
3151             "make",
3152             "make_test",
3153             "install",
3154             "make_clean",
3155             ) {
3156 0 0       0 if ($do->{$nosayer}) {
3157 0         0 my $selfid = $self->pretty_id;
3158 0         0 my $did = $do->pretty_id;
3159 0 0       0 if (UNIVERSAL::can($do->{$nosayer},"failed") ?
    0          
3160             $do->{$nosayer}->failed :
3161             $do->{$nosayer} =~ /^NO/) {
3162 0 0 0     0 if ($nosayer eq "make_test"
3163             &&
3164             $do->{make_test}{COMMANDID} != $CPAN::CurrentCommandId
3165             ) {
3166 0         0 next NOSAYER;
3167             }
3168             ### XXX don't complain about missing optional deps -- xdg, 2012-04-01
3169 0 0       0 if ($self->is_locally_optional($prereq_pm, $need_module)) {
3170             # don't complain about failing optional prereqs
3171             }
3172             else {
3173 0         0 $CPAN::Frontend->mywarn("Warning: Prerequisite ".
3174             "'$need_module => $need_version' ".
3175             "for '$selfid' failed when ".
3176             "processing '$did' with ".
3177             "'$nosayer => $do->{$nosayer}'. Continuing, ".
3178             "but chances to succeed are limited.\n"
3179             );
3180 0         0 $CPAN::Frontend->mysleep($sponsoring/10);
3181             }
3182 0         0 next NEED;
3183             } else { # the other guy succeeded
3184 0 0       0 if ($nosayer =~ /^(install|make_test)$/) {
3185             # we had this with
3186             # DMAKI/DateTime-Calendar-Chinese-0.05.tar.gz
3187             # in 2007-03 for 'make install'
3188             # and 2008-04: #30464 (for 'make test')
3189             # $CPAN::Frontend->mywarn("Warning: Prerequisite ".
3190             # "'$need_module => $need_version' ".
3191             # "for '$selfid' already built ".
3192             # "but the result looks suspicious. ".
3193             # "Skipping another build attempt, ".
3194             # "to prevent looping endlessly.\n"
3195             # );
3196 0         0 next NEED;
3197             }
3198             }
3199             }
3200             }
3201             }
3202 0         0 my $needed_as;
3203 0 0       0 if (0) {
    0          
3204 0 0       0 } elsif (exists $prereq_pm->{requires}{$need_module}
3205             || exists $prereq_pm->{opt_requires}{$need_module}
3206             ) {
3207 0         0 $needed_as = "r";
3208             } elsif ($slot eq "configure_requires_later") {
3209             # in ae872487d5 we said: C< we have not yet run the
3210             # {Build,Makefile}.PL, we must presume "r" >; but the
3211             # meta.yml standard says C< These dependencies are not
3212             # required after the distribution is installed. >; so now
3213             # we change it back to "b" and care for the proper
3214             # promotion later.
3215 0         0 $needed_as = "b";
3216             } else {
3217 0         0 $needed_as = "b";
3218             }
3219             # here need to flag as optional for recommends/suggests
3220             # -- xdg, 2012-04-01
3221             $self->debug(sprintf "%s mandatory?[%s]",
3222             $self->pretty_id,
3223 0 0       0 defined($self->{mandatory}) ? $self->{mandatory} : "")
    0          
3224             if $CPAN::DEBUG;
3225             my $optional = !$self->{mandatory}
3226 0   0     0 || $self->is_locally_optional($prereq_pm, $need_module);
3227 0         0 push @need, [$need_module,$needed_as,$optional];
3228             }
3229 11         33 my @unfolded = map { "[".join(",",@$_)."]" } @need;
  0         0  
3230 11 50       46 CPAN->debug("returning from unsat_prereq[@unfolded]") if $CPAN::DEBUG;
3231 11         105 @need;
3232             }
3233              
3234             sub _fulfills_all_version_rqs {
3235 0     0   0 my($self,$need_module,$available_file,$available_version,$need_version) = @_;
3236 0         0 my(@all_requirements) = split /\s*,\s*/, $need_version;
3237 0         0 local($^W) = 0;
3238 0         0 my $ok = 0;
3239 0         0 RQ: for my $rq (@all_requirements) {
3240 0 0       0 if ($rq =~ s|>=\s*||) {
    0          
    0          
    0          
    0          
3241             } elsif ($rq =~ s|>\s*||) {
3242             # 2005-12: one user
3243 0 0       0 if (CPAN::Version->vgt($available_version,$rq)) {
3244 0         0 $ok++;
3245             }
3246 0         0 next RQ;
3247             } elsif ($rq =~ s|!=\s*||) {
3248             # 2005-12: no user
3249 0 0       0 if (CPAN::Version->vcmp($available_version,$rq)) {
3250 0         0 $ok++;
3251 0         0 next RQ;
3252             } else {
3253 0         0 $ok=0;
3254 0         0 last RQ;
3255             }
3256             } elsif ($rq =~ m|<=?\s*|) {
3257             # 2005-12: no user
3258 0         0 $CPAN::Frontend->mywarn("Downgrading not supported (rq[$rq])\n");
3259 0         0 $ok++;
3260 0         0 next RQ;
3261             } elsif ($rq =~ s|==\s*||) {
3262             # 2009-07: ELLIOTJS/Perl-Critic-1.099_002.tar.gz
3263 0 0       0 if (CPAN::Version->vcmp($available_version,$rq)) {
3264 0         0 $ok=0;
3265 0         0 last RQ;
3266             } else {
3267 0         0 $ok++;
3268 0         0 next RQ;
3269             }
3270             }
3271 0 0       0 if (! CPAN::Version->vgt($rq, $available_version)) {
3272 0         0 $ok++;
3273             }
3274 0 0       0 CPAN->debug(sprintf("need_module[%s]available_file[%s]".
3275             "available_version[%s]rq[%s]ok[%d]",
3276             $need_module,
3277             $available_file,
3278             $available_version,
3279             CPAN::Version->readable($rq),
3280             $ok,
3281             )) if $CPAN::DEBUG;
3282             }
3283 0         0 my $ret = $ok == @all_requirements;
3284 0 0       0 CPAN->debug(sprintf("need_module[%s]ok[%s]all_requirements[%d]",$need_module, $ok, scalar @all_requirements)) if $CPAN::DEBUG;
3285 0         0 return $ret;
3286             }
3287              
3288             #-> sub CPAN::Distribution::read_meta
3289             # read any sort of meta files, return CPAN::Meta object if no errors
3290             sub read_meta {
3291 36     36 0 168 my($self) = @_;
3292 36 100       124 my $meta_file = $self->pick_meta_file
3293             or return;
3294              
3295 34 50       126 return unless $CPAN::META->has_usable("CPAN::Meta");
3296 34 50       67 my $meta = eval { CPAN::Meta->load_file($meta_file)}
  34         230  
3297             or return;
3298              
3299             # Very old EU::MM could have wrong META
3300 34 50 33     199908 if ($meta_file eq 'META.yml'
3301             && $meta->generated_by =~ /ExtUtils::MakeMaker version ([\d\._]+)/
3302             ) {
3303 0         0 my $eummv = do { local $^W = 0; $1+0; };
  0         0  
  0         0  
3304 0 0       0 return if $eummv < 6.2501;
3305             }
3306              
3307 34         119 return $meta;
3308             }
3309              
3310             #-> sub CPAN::Distribution::read_yaml ;
3311             # XXX This should be DEPRECATED -- dagolden, 2011-02-05
3312             sub read_yaml {
3313 0     0 0 0 my($self) = @_;
3314 0         0 my $meta_file = $self->pick_meta_file('\.yml$');
3315 0 0       0 $self->debug("meta_file[$meta_file]") if $CPAN::DEBUG;
3316 0 0       0 return unless $meta_file;
3317 0         0 my $yaml;
3318 0         0 eval { $yaml = $self->parse_meta_yml($meta_file) };
  0         0  
3319 0 0 0     0 if ($@ or ! $yaml) {
3320 0         0 return undef; # if we die, then we cannot read YAML's own META.yml
3321             }
3322             # not "authoritative"
3323 0 0 0     0 if (defined $yaml && (! ref $yaml || ref $yaml ne "HASH")) {
      0        
3324 0         0 $CPAN::Frontend->mywarn("META.yml does not seem to be conforming, cannot use it.\n");
3325 0         0 $yaml = undef;
3326             }
3327 0 0 0     0 $self->debug(sprintf "yaml[%s]", $yaml || "UNDEF")
3328             if $CPAN::DEBUG;
3329 0 0 0     0 $self->debug($yaml) if $CPAN::DEBUG && $yaml;
3330             # MYMETA.yml is static and authoritative by definition
3331 0 0       0 if ( $meta_file =~ /MYMETA\.yml/ ) {
3332 0         0 return $yaml;
3333             }
3334             # META.yml is authoritative only if dynamic_config is defined and false
3335 0 0 0     0 if ( defined $yaml->{dynamic_config} && ! $yaml->{dynamic_config} ) {
3336 0         0 return $yaml;
3337             }
3338             # otherwise, we can't use what we found
3339 0         0 return undef;
3340             }
3341              
3342             #-> sub CPAN::Distribution::configure_requires ;
3343             sub configure_requires {
3344 7     7 0 18 my($self) = @_;
3345 7 50       36 return unless my $meta_file = $self->pick_meta_file('^META');
3346 0 0       0 if (my $meta_obj = $self->read_meta) {
3347 0         0 my $prereqs = $meta_obj->effective_prereqs;
3348 0         0 my $cr = $prereqs->requirements_for(qw/configure requires/);
3349 0 0       0 return $cr ? $cr->as_string_hash : undef;
3350             }
3351             else {
3352 0         0 my $yaml = eval { $self->parse_meta_yml($meta_file) };
  0         0  
3353 0         0 return $yaml->{configure_requires};
3354             }
3355             }
3356              
3357             #-> sub CPAN::Distribution::prereq_pm ;
3358             sub prereq_pm {
3359 24     24 0 112 my($self) = @_;
3360             return unless $self->{writemakefile} # no need to have succeeded
3361             # but we must have run it
3362 24 50 66     335 || $self->{modulebuild};
3363 17 50       102 unless ($self->{build_dir}) {
3364 0         0 return;
3365             }
3366 17 50       104 if ($self->{cleanup_after_install_done}) {
3367 0         0 return;
3368             }
3369             # no Makefile/Build means configuration aborted, so don't look for prereqs
3370 17 50       343 my $makefile = File::Spec->catfile($self->{build_dir}, $^O eq 'VMS' ? 'descrip.mms' : 'Makefile');
3371 17 50       321 my $buildfile = File::Spec->catfile($self->{build_dir}, $^O eq 'VMS' ? 'Build.com' : 'Build');
3372 17 100 66     734 return unless -f $makefile || -f $buildfile;
3373             CPAN->debug(sprintf "writemakefile[%s]modulebuild[%s]",
3374             $self->{writemakefile}||"",
3375 14 50 0     64 $self->{modulebuild}||"",
      0        
3376             ) if $CPAN::DEBUG;
3377 14         31 my($req,$breq, $opt_req, $opt_breq);
3378 14         62 my $meta_obj = $self->read_meta;
3379             # META/MYMETA is only authoritative if dynamic_config is false
3380 14 50 33     110 if ($meta_obj && ! $meta_obj->dynamic_config) {
    0          
3381 14         162 my $prereqs = $meta_obj->effective_prereqs;
3382 14         7413 my $requires = $prereqs->requirements_for(qw/runtime requires/);
3383 14         515 my $build_requires = $prereqs->requirements_for(qw/build requires/);
3384 14         366 my $test_requires = $prereqs->requirements_for(qw/test requires/);
3385             # XXX we don't yet distinguish build vs test, so merge them for now
3386 14         399 $build_requires->add_requirements($test_requires);
3387 14         513 $req = $requires->as_string_hash;
3388 14         932 $breq = $build_requires->as_string_hash;
3389              
3390             # XXX assemble optional_req && optional_breq from recommends/suggests
3391             # depending on corresponding policies -- xdg, 2012-04-01
3392 14         596 CPAN->use_inst("CPAN::Meta::Requirements");
3393 14         54 my $opt_runtime = CPAN::Meta::Requirements->new;
3394 14         153 my $opt_build = CPAN::Meta::Requirements->new;
3395 14 50       205 if ( $CPAN::Config->{recommends_policy} ) {
3396 0         0 $opt_runtime->add_requirements( $prereqs->requirements_for(qw/runtime recommends/));
3397 0         0 $opt_build->add_requirements( $prereqs->requirements_for(qw/build recommends/));
3398 0         0 $opt_build->add_requirements( $prereqs->requirements_for(qw/test recommends/));
3399              
3400             }
3401 14 50       48 if ( $CPAN::Config->{suggests_policy} ) {
3402 0         0 $opt_runtime->add_requirements( $prereqs->requirements_for(qw/runtime suggests/));
3403 0         0 $opt_build->add_requirements( $prereqs->requirements_for(qw/build suggests/));
3404 0         0 $opt_build->add_requirements( $prereqs->requirements_for(qw/test suggests/));
3405             }
3406 14         39 $opt_req = $opt_runtime->as_string_hash;
3407 14         156 $opt_breq = $opt_build->as_string_hash;
3408             }
3409             elsif (my $yaml = $self->read_yaml) { # often dynamic_config prevents a result here
3410 0   0     0 $req = $yaml->{requires} || {};
3411 0   0     0 $breq = $yaml->{build_requires} || {};
3412 0 0       0 if ( $CPAN::Config->{recommends_policy} ) {
3413 0   0     0 $opt_req = $yaml->{recommends} || {};
3414             }
3415 0 0 0     0 undef $req unless ref $req eq "HASH" && %$req;
3416 0 0       0 if ($req) {
3417 0 0 0     0 if ($yaml->{generated_by} &&
3418             $yaml->{generated_by} =~ /ExtUtils::MakeMaker version ([\d\._]+)/) {
3419 0         0 my $eummv = do { local $^W = 0; $1+0; };
  0         0  
  0         0  
3420 0 0       0 if ($eummv < 6.2501) {
3421             # thanks to Slaven for digging that out: MM before
3422             # that could be wrong because it could reflect a
3423             # previous release
3424 0         0 undef $req;
3425             }
3426             }
3427 0         0 my $areq;
3428             my $do_replace;
3429 0 0       0 foreach my $k (sort keys %{$req||{}}) {
  0         0  
3430 0         0 my $v = $req->{$k};
3431 0 0       0 next unless defined $v;
3432 0 0 0     0 if ($v =~ /\d/) {
    0 0        
3433 0         0 $areq->{$k} = $v;
3434             } elsif ($k =~ /[A-Za-z]/ &&
3435             $v =~ /[A-Za-z]/ &&
3436             $CPAN::META->exists("CPAN::Module",$v)
3437             ) {
3438 0         0 $CPAN::Frontend->mywarn("Suspicious key-value pair in META.yml's ".
3439             "requires hash: $k => $v; I'll take both ".
3440             "key and value as a module name\n");
3441 0         0 $CPAN::Frontend->mysleep(1);
3442 0         0 $areq->{$k} = 0;
3443 0         0 $areq->{$v} = 0;
3444 0         0 $do_replace++;
3445             }
3446             }
3447 0 0       0 $req = $areq if $do_replace;
3448             }
3449             }
3450             else {
3451 0         0 $CPAN::Frontend->mywarnonce("Could not read metadata file. Falling back to other ".
3452             "methods to determine prerequisites\n");
3453             }
3454              
3455 14 50 33     268 unless ($req || $breq) {
3456 0         0 my $build_dir;
3457 0 0       0 unless ( $build_dir = $self->{build_dir} ) {
3458 0         0 return;
3459             }
3460 0         0 my $makefile = File::Spec->catfile($build_dir,"Makefile");
3461 0         0 my $fh;
3462 0 0 0     0 if (-f $makefile
3463             and
3464             $fh = FileHandle->new("<$makefile\0")) {
3465 0 0       0 CPAN->debug("Getting prereq from Makefile") if $CPAN::DEBUG;
3466 0         0 local($/) = "\n";
3467 0         0 while (<$fh>) {
3468 0 0       0 last if /MakeMaker post_initialize section/;
3469 0         0 my($p) = m{^[\#]
3470             \s+PREREQ_PM\s+=>\s+(.+)
3471             }x;
3472 0 0       0 next unless $p;
3473             # warn "Found prereq expr[$p]";
3474              
3475             # Regexp modified by A.Speer to remember actual version of file
3476             # PREREQ_PM hash key wants, then add to
3477 0         0 while ( $p =~ m/(?:\s)([\w\:]+)=>(q\[.*?\]|undef),?/g ) {
3478 0         0 my($m,$n) = ($1,$2);
3479             # When a prereq is mentioned twice: let the bigger
3480             # win; usual culprit is that they declared
3481             # build_requires separately from requires; see
3482             # rt.cpan.org #47774
3483 0         0 my($prevn);
3484 0 0       0 if ( defined $req->{$m} ) {
3485 0         0 $prevn = $req->{$m};
3486             }
3487 0 0       0 if ($n =~ /^q\[(.*?)\]$/) {
3488 0         0 $n = $1;
3489             }
3490 0 0 0     0 if (!$prevn || CPAN::Version->vlt($prevn, $n)){
3491 0         0 $req->{$m} = $n;
3492             }
3493             }
3494 0         0 last;
3495             }
3496             }
3497             }
3498 14 50 33     55 unless ($req || $breq) {
3499 0 0       0 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
3500 0         0 my $buildfile = File::Spec->catfile($build_dir,"Build");
3501 0 0       0 if (-f $buildfile) {
3502 0 0       0 CPAN->debug("Found '$buildfile'") if $CPAN::DEBUG;
3503 0         0 my $build_prereqs = File::Spec->catfile($build_dir,"_build","prereqs");
3504 0 0       0 if (-f $build_prereqs) {
3505 0 0       0 CPAN->debug("Getting prerequisites from '$build_prereqs'") if $CPAN::DEBUG;
3506 0         0 my $content = do { local *FH;
  0         0  
3507 0 0       0 open FH, $build_prereqs
3508             or $CPAN::Frontend->mydie("Could not open ".
3509             "'$build_prereqs': $!");
3510 0         0 local $/;
3511 0         0 ;
3512             };
3513 0         0 my $bphash = eval $content;
3514 0 0       0 if ($@) {
3515             } else {
3516 0   0     0 $req = $bphash->{requires} || +{};
3517 0   0     0 $breq = $bphash->{build_requires} || +{};
3518             }
3519             }
3520             }
3521             }
3522             # XXX needs to be adapted for optional_req & optional_breq -- xdg, 2012-04-01
3523 14 50 33     78 if ($req || $breq || $opt_req || $opt_breq ) {
      33        
      0        
3524             return $self->{prereq_pm} = {
3525 14         307 requires => $req,
3526             build_requires => $breq,
3527             opt_requires => $opt_req,
3528             opt_build_requires => $opt_breq,
3529             };
3530             }
3531             }
3532              
3533             #-> sub CPAN::Distribution::shortcut_test ;
3534             # return values: undef means don't shortcut; 0 means shortcut as fail;
3535             # and 1 means shortcut as success
3536             sub shortcut_test {
3537 4     4 0 34 my ($self) = @_;
3538              
3539 4 50       36 $self->debug("checking badtestcnt[$self->{ID}]") if $CPAN::DEBUG;
3540 4   50     160 $self->{badtestcnt} ||= 0;
3541 4 50       54 if ($self->{badtestcnt} > 0) {
3542 0         0 require Data::Dumper;
3543 0 0       0 CPAN->debug(sprintf "NOREPEAT[%s]", Data::Dumper::Dumper($self)) if $CPAN::DEBUG;
3544 0         0 return $self->goodbye("Won't repeat unsuccessful test during this command");
3545             }
3546              
3547 4         20 for my $slot ( qw/later configure_requires_later/ ) {
3548 8 50       68 $self->debug("checking $slot slot[$self->{ID}]") if $CPAN::DEBUG;
3549             return $self->success($self->{$slot})
3550 8 50       54 if $self->{$slot};
3551             }
3552              
3553 4 50       116 $self->debug("checking if tests passed[$self->{ID}]") if $CPAN::DEBUG;
3554 4 50       36 if ( $self->{make_test} ) {
3555 0 0       0 if (
    0          
3556             UNIVERSAL::can($self->{make_test},"failed") ?
3557             $self->{make_test}->failed :
3558             $self->{make_test} =~ /^NO/
3559             ) {
3560 0 0 0     0 if (
3561             UNIVERSAL::can($self->{make_test},"commandid")
3562             &&
3563             $self->{make_test}->commandid == $CPAN::CurrentCommandId
3564             ) {
3565 0         0 return $self->goodbye("Has already been tested within this command");
3566             }
3567             } else {
3568             # if global "is_tested" has been cleared, we need to mark this to
3569             # be added to PERL5LIB if not already installed
3570 0 0       0 if ($self->tested_ok_but_not_installed) {
3571 0         0 $CPAN::META->is_tested($self->{build_dir},$self->{make_test}{TIME});
3572             }
3573 0         0 return $self->success("Has already been tested successfully");
3574             }
3575             }
3576              
3577 4 50       20 if ($self->{notest}) {
3578 0         0 $self->{make_test} = CPAN::Distrostatus->new("YES");
3579 0         0 return $self->success("Skipping test because of notest pragma");
3580             }
3581              
3582 4         66 return undef; # no shortcut
3583             }
3584              
3585             #-> sub CPAN::Distribution::_exe_files ;
3586             sub _exe_files {
3587 0     0   0 my($self) = @_;
3588             return unless $self->{writemakefile} # no need to have succeeded
3589             # but we must have run it
3590 0 0 0     0 || $self->{modulebuild};
3591 0 0       0 unless ($self->{build_dir}) {
3592 0         0 return;
3593             }
3594             CPAN->debug(sprintf "writemakefile[%s]modulebuild[%s]",
3595             $self->{writemakefile}||"",
3596 0 0 0     0 $self->{modulebuild}||"",
      0        
3597             ) if $CPAN::DEBUG;
3598 0         0 my $build_dir;
3599 0 0       0 unless ( $build_dir = $self->{build_dir} ) {
3600 0         0 return;
3601             }
3602 0         0 my $makefile = File::Spec->catfile($build_dir,"Makefile");
3603 0         0 my $fh;
3604             my @exe_files;
3605 0 0 0     0 if (-f $makefile
3606             and
3607             $fh = FileHandle->new("<$makefile\0")) {
3608 0 0       0 CPAN->debug("Getting exefiles from Makefile") if $CPAN::DEBUG;
3609 0         0 local($/) = "\n";
3610 0         0 while (<$fh>) {
3611 0 0       0 last if /MakeMaker post_initialize section/;
3612 0         0 my($p) = m{^[\#]
3613             \s+EXE_FILES\s+=>\s+\[(.+)\]
3614             }x;
3615 0 0       0 next unless $p;
3616             # warn "Found exefiles expr[$p]";
3617 0         0 my @p = split /,\s*/, $p;
3618 0         0 for my $p2 (@p) {
3619 0 0       0 if ($p2 =~ /^q\[(.+)\]/) {
3620 0         0 push @exe_files, $1;
3621             }
3622             }
3623             }
3624             }
3625 0 0       0 return \@exe_files if @exe_files;
3626 0         0 my $buildparams = File::Spec->catfile($build_dir,"_build","build_params");
3627 0 0       0 if (-f $buildparams) {
3628 0 0       0 CPAN->debug("Found '$buildparams'") if $CPAN::DEBUG;
3629 0         0 my $x = do $buildparams;
3630 0         0 for my $sf ($x->[2]{script_files}) {
3631 0 0       0 if (my $reftype = ref $sf) {
    0          
3632 0 0       0 if ($reftype eq "ARRAY") {
    0          
3633 0         0 push @exe_files, @$sf;
3634             }
3635             elsif ($reftype eq "HASH") {
3636 0         0 push @exe_files, keys %$sf;
3637             }
3638             else {
3639 0         0 $CPAN::Frontend->mywarn("Invalid reftype $reftype for Build.PL 'script_files'\n");
3640             }
3641             }
3642             elsif (defined $sf) {
3643 0         0 push @exe_files, $sf;
3644             }
3645             }
3646             }
3647 0         0 return \@exe_files;
3648             }
3649              
3650             #-> sub CPAN::Distribution::test ;
3651             sub test {
3652 7     7 0 19 my($self) = @_;
3653              
3654 7         53 $self->pre_test();
3655              
3656 7 50       28 if (exists $self->{cleanup_after_install_done}) {
3657 0         0 $self->post_test();
3658 0         0 return $self->make;
3659             }
3660              
3661 7 50       20 $self->debug("checking goto id[$self->{ID}]") if $CPAN::DEBUG;
3662 7 50       20 if (my $goto = $self->prefs->{goto}) {
3663 0         0 $self->post_test();
3664 0         0 return $self->goto($goto);
3665             }
3666              
3667 7 100       80 unless ($self->make){
3668 3         58 $self->post_test();
3669 3         51 return;
3670             }
3671              
3672 4 50       154 if ( defined( my $sc = $self->shortcut_test ) ) {
3673 0         0 $self->post_test();
3674 0         0 return $sc;
3675             }
3676              
3677 4 50       80 if ($CPAN::Signal) {
3678 0         0 delete $self->{force_update};
3679 0         0 $self->post_test();
3680 0         0 return;
3681             }
3682             # warn "XDEBUG: checking for notest: $self->{notest} $self";
3683 4 50       48 my $make = $self->{modulebuild} ? "Build" : "make";
3684              
3685             local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
3686             ? $ENV{PERL5LIB}
3687 4 50 0     82 : ($ENV{PERLLIB} || "");
3688              
3689 4 50       50 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
3690             local $ENV{PERL_USE_UNSAFE_INC} =
3691             exists $ENV{PERL_USE_UNSAFE_INC} && defined $ENV{PERL_USE_UNSAFE_INC}
3692 4 50 33     150 ? $ENV{PERL_USE_UNSAFE_INC} : 1; # test
3693 4         66 $CPAN::META->set_perl5lib;
3694 4         58 local $ENV{MAKEFLAGS}; # protect us from outer make calls
3695 4 50       60 local $ENV{PERL_MM_USE_DEFAULT} = 1 if $CPAN::Config->{use_prompt_default};
3696 4 50       34 local $ENV{NONINTERACTIVE_TESTING} = 1 if $CPAN::Config->{use_prompt_default};
3697              
3698 4 50       78 if ($run_allow_installing_within_test) {
3699 4         38 my($allow_installing, $why) = $self->_allow_installing;
3700 4 50       24 if (! $allow_installing) {
3701 0         0 $CPAN::Frontend->mywarn("Testing/Installation stopped: $why\n");
3702 0         0 $self->introduce_myself;
3703 0         0 $self->{make_test} = CPAN::Distrostatus->new("NO -- testing/installation stopped due $why");
3704 0         0 $CPAN::Frontend->mywarn(" [testing] -- NOT OK\n");
3705 0         0 delete $self->{force_update};
3706 0         0 $self->post_test();
3707 0         0 return;
3708             }
3709             }
3710 4         36 $CPAN::Frontend->myprint(sprintf "Running %s test for %s\n", $make, $self->pretty_id);
3711              
3712 4 50       76 my $builddir = $self->dir or
3713             $CPAN::Frontend->mydie("PANIC: Cannot determine build directory\n");
3714              
3715 4 50       288 unless (chdir $builddir) {
3716 0         0 $CPAN::Frontend->mywarn("Couldn't chdir to '$builddir': $!");
3717 0         0 $self->post_test();
3718 0         0 return;
3719             }
3720              
3721 4 50       42 $self->debug("Changed directory to $self->{build_dir}")
3722             if $CPAN::DEBUG;
3723              
3724 4 50       30 if ($self->{modulebuild}) {
3725 0         0 my $thm = CPAN::Shell->expand("Module","Test::Harness");
3726 0         0 my $v = $thm->inst_version;
3727 0 0       0 if (CPAN::Version->vlt($v,2.62)) {
3728             # XXX Eric Wilhelm reported this as a bug: klapperl:
3729             # Test::Harness 3.0 self-tests, so that should be 'unless
3730             # installing Test::Harness'
3731 0 0       0 unless ($self->id eq $thm->distribution->id) {
3732 0         0 $CPAN::Frontend->mywarn(qq{The version of your Test::Harness is only
3733             '$v', you need at least '2.62'. Please upgrade your Test::Harness.\n});
3734 0         0 $self->{make_test} = CPAN::Distrostatus->new("NO Test::Harness too old");
3735 0         0 $self->post_test();
3736 0         0 return;
3737             }
3738             }
3739             }
3740              
3741 4 50       20 if ( ! $self->{force_update} ) {
3742             # bypass actual tests if "trust_test_report_history" and have a report
3743 4         14 my $have_tested_fcn;
3744 4 0 33     22 if ( $CPAN::Config->{trust_test_report_history}
      33        
3745             && $CPAN::META->has_inst("CPAN::Reporter::History")
3746             && ( $have_tested_fcn = CPAN::Reporter::History->can("have_tested" ))) {
3747 0 0       0 if ( my @reports = $have_tested_fcn->( dist => $self->base_id ) ) {
3748             # Do nothing if grade was DISCARD
3749 0 0       0 if ( $reports[-1]->{grade} =~ /^(?:PASS|UNKNOWN)$/ ) {
    0          
3750 0         0 $self->{make_test} = CPAN::Distrostatus->new("YES");
3751             # if global "is_tested" has been cleared, we need to mark this to
3752             # be added to PERL5LIB if not already installed
3753 0 0       0 if ($self->tested_ok_but_not_installed) {
3754 0         0 $CPAN::META->is_tested($self->{build_dir},$self->{make_test}{TIME});
3755             }
3756 0         0 $CPAN::Frontend->myprint("Found prior test report -- OK\n");
3757 0         0 $self->post_test();
3758 0         0 return;
3759             }
3760             elsif ( $reports[-1]->{grade} =~ /^(?:FAIL|NA)$/ ) {
3761 0         0 $self->{make_test} = CPAN::Distrostatus->new("NO");
3762 0         0 $self->{badtestcnt}++;
3763 0         0 $CPAN::Frontend->mywarn("Found prior test report -- NOT OK\n");
3764 0         0 $self->post_test();
3765 0         0 return;
3766             }
3767             }
3768             }
3769             }
3770              
3771 4         16 my $system;
3772 4         46 my $prefs_test = $self->prefs->{test};
3773 4 50       58 if (my $commandline
    50          
    50          
3774             = exists $prefs_test->{commandline} ? $prefs_test->{commandline} : "") {
3775 0         0 $system = $commandline;
3776 0         0 $ENV{PERL} = CPAN::find_perl();
3777             } elsif ($self->{modulebuild}) {
3778 0         0 $system = sprintf "%s test", $self->_build_command();
3779 0 0 0     0 unless (-e "Build" || ($^O eq 'VMS' && -e "Build.com")) {
      0        
3780 0         0 my $id = $self->pretty_id;
3781 0         0 $CPAN::Frontend->mywarn("Alert: no 'Build' file found while trying to test '$id'");
3782             }
3783             } else {
3784 4         58 $system = join " ", $self->_make_command(), "test";
3785             }
3786 4         26 my $make_test_arg = $self->_make_phase_arg("test");
3787 4 50       18 $system = sprintf("%s%s",
3788             $system,
3789             $make_test_arg ? " $make_test_arg" : "",
3790             );
3791 4         12 my($tests_ok);
3792             my $test_env;
3793 4 50       12 if ($self->prefs->{test}) {
3794 0         0 $test_env = $self->prefs->{test}{env};
3795             }
3796 4 50       14 local @ENV{keys %$test_env} = values %$test_env if $test_env;
3797 4         28 my $expect_model = $self->_prefs_with_expect("test");
3798 4         8 my $want_expect = 0;
3799 4 50 33     54 if ( $expect_model && @{$expect_model->{talk}} ) {
  0         0  
3800 0         0 my $can_expect = $CPAN::META->has_inst("Expect");
3801 0 0       0 if ($can_expect) {
3802 0         0 $want_expect = 1;
3803             } else {
3804 0         0 $CPAN::Frontend->mywarn("Expect not installed, falling back to ".
3805             "testing without\n");
3806             }
3807             }
3808              
3809             FORK: {
3810 4         14 my $pid = fork;
  4         17069  
3811 4 50       683 if (! defined $pid) { # contention
    100          
3812 0         0 warn "Contention '$!', sleeping 2";
3813 0         0 sleep 2;
3814 0         0 redo FORK;
3815             } elsif ($pid) { # parent
3816 2 50       322 if ($^O eq "MSWin32") {
3817 0         0 wait;
3818             } else {
3819 2         97 SUPERVISE: while (waitpid($pid, WNOHANG) <= 0) {
3820 17 50       212 if ($CPAN::Signal) {
3821 0         0 kill 9, -$pid;
3822             }
3823 17         17003554 sleep 1;
3824             }
3825             }
3826 2         124 $tests_ok = !$?;
3827             } else { # child
3828 2 50       494 POSIX::setsid() unless $^O eq "MSWin32";
3829 2         19 my $c_ok;
3830 2         115 $|=1;
3831 2 50       316 if ($want_expect) {
    50          
3832 0 0       0 if ($self->_should_report('test')) {
3833 0         0 $CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is currently ".
3834             "not supported when distroprefs specify ".
3835             "an interactive test\n");
3836             }
3837 0         0 $c_ok = $self->_run_via_expect($system,'test',$expect_model) == 0;
3838             } elsif ( $self->_should_report('test') ) {
3839 0         0 $c_ok = CPAN::Reporter::test($self, $system);
3840             } else {
3841 2         3437882 $c_ok = system($system) == 0;
3842             }
3843 2         2818 exit !$c_ok;
3844             }
3845             } # FORK
3846              
3847 2         71 $self->introduce_myself;
3848 2         40 my $but = $self->_make_test_illuminate_prereqs();
3849 2 100       32 if ( $tests_ok ) {
3850 1 50       11 if ($but) {
3851 0         0 $CPAN::Frontend->mywarn("Tests succeeded but $but\n");
3852 0         0 $self->{make_test} = CPAN::Distrostatus->new("NO $but");
3853 0         0 $self->store_persistent_state;
3854 0         0 $self->post_test();
3855 0         0 return $self->goodbye("[dependencies] -- NA");
3856             }
3857 1         33 $CPAN::Frontend->myprint(" $system -- OK\n");
3858 1         51 $self->{make_test} = CPAN::Distrostatus->new("YES");
3859 1         29 $CPAN::META->is_tested($self->{build_dir},$self->{make_test}{TIME});
3860             # probably impossible to need the next line because badtestcnt
3861             # has a lifespan of one command
3862 1         4 delete $self->{badtestcnt};
3863             } else {
3864 1 50       24 if ($but) {
    50          
    50          
3865 0         0 $but .= "; additionally test harness failed";
3866 0         0 $CPAN::Frontend->mywarn("$but\n");
3867 0         0 $self->{make_test} = CPAN::Distrostatus->new("NO $but");
3868             } elsif ( $self->{force_update} ) {
3869 0         0 $self->{make_test} = CPAN::Distrostatus->new(
3870             "NO but failure ignored because 'force' in effect"
3871             );
3872             } elsif ($CPAN::Signal) {
3873 0         0 $self->{make_test} = CPAN::Distrostatus->new("NO -- Interrupted");
3874             } else {
3875 1         33 $self->{make_test} = CPAN::Distrostatus->new("NO");
3876             }
3877 1         3 $self->{badtestcnt}++;
3878 1         31 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
3879 1         8 CPAN::Shell->optprint
3880             ("hint",
3881             sprintf
3882             ("//hint// to see the cpan-testers results for installing this module, try:
3883             reports %s\n",
3884             $self->pretty_id));
3885             }
3886 2         54 $self->store_persistent_state;
3887              
3888 2         55 $self->post_test();
3889              
3890 2 50       185 return $self->{force_update} ? 1 : !! $tests_ok;
3891             }
3892              
3893             sub _make_test_illuminate_prereqs {
3894 2     2   16 my($self) = @_;
3895 2         8 my @prereq;
3896              
3897             # local $CPAN::DEBUG = 16; # Distribution
3898 2         15 for my $m (sort keys %{$self->{sponsored_mods}}) {
  2         97  
3899 0 0       0 next unless $self->{sponsored_mods}{$m} > 0;
3900 0 0       0 my $m_obj = CPAN::Shell->expand("Module",$m) or next;
3901             # XXX we need available_version which reflects
3902             # $ENV{PERL5LIB} so that already tested but not yet
3903             # installed modules are counted.
3904 0         0 my $available_version = $m_obj->available_version;
3905 0         0 my $available_file = $m_obj->available_file;
3906 0 0 0     0 if ($available_version &&
    0 0        
      0        
3907             !CPAN::Version->vlt($available_version,$self->{prereq_pm}{$m})
3908             ) {
3909 0 0       0 CPAN->debug("m[$m] good enough available_version[$available_version]")
3910             if $CPAN::DEBUG;
3911             } elsif ($available_file
3912             && (
3913             !$self->{prereq_pm}{$m}
3914             ||
3915             $self->{prereq_pm}{$m} == 0
3916             )
3917             ) {
3918             # lex Class::Accessor::Chained::Fast which has no $VERSION
3919 0 0       0 CPAN->debug("m[$m] have available_file[$available_file]")
3920             if $CPAN::DEBUG;
3921             } else {
3922 0 0       0 push @prereq, $m
3923             unless $self->is_locally_optional(undef, $m);
3924             }
3925             }
3926 2         28 my $but;
3927 2 50       103 if (@prereq) {
3928 0         0 my $cnt = @prereq;
3929 0         0 my $which = join ",", @prereq;
3930 0 0       0 $but = $cnt == 1 ? "one dependency not OK ($which)" :
3931             "$cnt dependencies missing ($which)";
3932             }
3933 2         18 $but;
3934             }
3935              
3936             sub _prefs_with_expect {
3937 15     15   81 my($self,$where) = @_;
3938 15 50       37 return unless my $prefs = $self->prefs;
3939 15 50       158 return unless my $where_prefs = $prefs->{$where};
3940 0 0       0 if ($where_prefs->{expect}) {
    0          
3941             return {
3942             mode => "deterministic",
3943             timeout => 15,
3944             talk => $where_prefs->{expect},
3945 0         0 };
3946             } elsif ($where_prefs->{"eexpect"}) {
3947 0         0 return $where_prefs->{"eexpect"};
3948             }
3949 0         0 return;
3950             }
3951              
3952             #-> sub CPAN::Distribution::clean ;
3953             sub clean {
3954 0     0 0 0 my($self) = @_;
3955 0 0       0 my $make = $self->{modulebuild} ? "Build" : "make";
3956 0         0 $CPAN::Frontend->myprint(sprintf "Running %s clean for %s\n", $make, $self->pretty_id);
3957 0 0       0 unless (exists $self->{archived}) {
3958 0         0 $CPAN::Frontend->mywarn("Distribution seems to have never been unzipped".
3959             "/untarred, nothing done\n");
3960 0         0 return 1;
3961             }
3962 0 0       0 unless (exists $self->{build_dir}) {
3963 0         0 $CPAN::Frontend->mywarn("Distribution has no own directory, nothing to do.\n");
3964 0         0 return 1;
3965             }
3966 0 0 0     0 if (exists $self->{writemakefile}
3967             and $self->{writemakefile}->failed
3968             ) {
3969 0         0 $CPAN::Frontend->mywarn("No Makefile, don't know how to 'make clean'\n");
3970 0         0 return 1;
3971             }
3972             EXCUSE: {
3973 0         0 my @e;
  0         0  
3974 0 0 0     0 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
3975             push @e, "make clean already called once";
3976 0 0 0     0 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
  0         0  
3977             }
3978 0 0       0 chdir "$self->{build_dir}" or
3979             Carp::confess("Couldn't chdir to $self->{build_dir}: $!");
3980 0 0       0 $self->debug("Changed directory to $self->{build_dir}") if $CPAN::DEBUG;
3981              
3982 0         0 my $system;
3983 0 0       0 if ($self->{modulebuild}) {
3984 0 0       0 unless (-f "Build") {
3985 0         0 my $cwd = CPAN::anycwd();
3986 0         0 $CPAN::Frontend->mywarn("Alert: no Build file available for 'clean $self->{id}".
3987             " in cwd[$cwd]. Danger, Will Robinson!");
3988 0         0 $CPAN::Frontend->mysleep(5);
3989             }
3990 0         0 $system = sprintf "%s clean", $self->_build_command();
3991             } else {
3992 0         0 $system = join " ", $self->_make_command(), "clean";
3993             }
3994 0         0 my $system_ok = system($system) == 0;
3995 0         0 $self->introduce_myself;
3996 0 0       0 if ( $system_ok ) {
3997 0         0 $CPAN::Frontend->myprint(" $system -- OK\n");
3998              
3999             # $self->force;
4000              
4001             # Jost Krieger pointed out that this "force" was wrong because
4002             # it has the effect that the next "install" on this distribution
4003             # will untar everything again. Instead we should bring the
4004             # object's state back to where it is after untarring.
4005              
4006 0         0 for my $k (qw(
4007             force_update
4008             install
4009             writemakefile
4010             make
4011             make_test
4012             )) {
4013 0         0 delete $self->{$k};
4014             }
4015 0         0 $self->{make_clean} = CPAN::Distrostatus->new("YES");
4016              
4017             } else {
4018             # Hmmm, what to do if make clean failed?
4019              
4020 0         0 $self->{make_clean} = CPAN::Distrostatus->new("NO");
4021 0         0 $CPAN::Frontend->mywarn(qq{ $system -- NOT OK\n});
4022              
4023             # 2006-02-27: seems silly to me to force a make now
4024             # $self->force("make"); # so that this directory won't be used again
4025              
4026             }
4027 0         0 $self->store_persistent_state;
4028             }
4029              
4030             #-> sub CPAN::Distribution::check_disabled ;
4031             sub check_disabled {
4032 7     7 0 18 my ($self) = @_;
4033 7 50       24 $self->debug("checking disabled id[$self->{ID}]") if $CPAN::DEBUG;
4034 7 50 33     29 if ($self->prefs->{disabled} && ! $self->{force_update}) {
4035             return sprintf(
4036             "Disabled via prefs file '%s' doc %d",
4037             $self->{prefs_file},
4038             $self->{prefs_file_doc},
4039 0         0 );
4040             }
4041 7         25 return;
4042             }
4043              
4044             #-> sub CPAN::Distribution::goto ;
4045             sub goto {
4046 0     0 0 0 my($self,$goto) = @_;
4047 0         0 $goto = $self->normalize($goto);
4048             my $why = sprintf(
4049             "Goto '$goto' via prefs file '%s' doc %d",
4050             $self->{prefs_file},
4051             $self->{prefs_file_doc},
4052 0         0 );
4053 0         0 $self->{unwrapped} = CPAN::Distrostatus->new("NO $why");
4054             # 2007-07-16 akoenig : Better than NA would be if we could inherit
4055             # the status of the $goto distro but given the exceptional nature
4056             # of 'goto' I feel reluctant to implement it
4057 0         0 my $goodbye_message = "[goto] -- NA $why";
4058 0         0 $self->goodbye($goodbye_message);
4059              
4060             # inject into the queue
4061              
4062 0         0 CPAN::Queue->delete($self->id);
4063 0         0 CPAN::Queue->jumpqueue({qmod => $goto, reqtype => $self->{reqtype}});
4064              
4065             # and run where we left off
4066              
4067 0         0 my($method) = (caller(1))[3];
4068 0         0 my $goto_do = CPAN->instance("CPAN::Distribution",$goto);
4069 0 0       0 $goto_do->called_for($self->called_for) unless $goto_do->called_for;
4070 0   0     0 $goto_do->{mandatory} ||= $self->{mandatory};
4071 0   0     0 $goto_do->{reqtype} ||= $self->{reqtype};
4072 0         0 $goto_do->{coming_from} = $self->pretty_id;
4073 0         0 $goto_do->$method();
4074 0         0 CPAN::Queue->delete_first($goto);
4075             # XXX delete_first returns undef; is that what this should return
4076             # up the call stack, eg. return $sefl->goto($goto) -- xdg, 2012-04-04
4077             }
4078              
4079             #-> sub CPAN::Distribution::shortcut_install ;
4080             # return values: undef means don't shortcut; 0 means shortcut as fail;
4081             # and 1 means shortcut as success
4082             sub shortcut_install {
4083 1     1 0 8 my ($self) = @_;
4084              
4085 1 50       11 $self->debug("checking previous install results[$self->{ID}]") if $CPAN::DEBUG;
4086 1 50       29 if (exists $self->{install}) {
4087             my $text = UNIVERSAL::can($self->{install},"text") ?
4088             $self->{install}->text :
4089 0 0       0 $self->{install};
4090 0 0       0 if ($text =~ /^YES/) {
    0          
4091 0         0 $CPAN::META->is_installed($self->{build_dir});
4092 0         0 return $self->success("Already done");
4093             } elsif ($text =~ /is only/) {
4094             # e.g. 'is only build_requires': may be overruled later
4095 0         0 return $self->goodbye($text);
4096             } else {
4097             # comment in Todo on 2006-02-11; maybe retry?
4098 0         0 return $self->goodbye("Already tried without success");
4099             }
4100             }
4101              
4102 1         8 for my $slot ( qw/later configure_requires_later/ ) {
4103             return $self->success($self->{$slot})
4104 2 50       9 if $self->{$slot};
4105             }
4106              
4107 1         15 return undef;
4108             }
4109              
4110             #-> sub CPAN::Distribution::is_being_sponsored ;
4111              
4112             # returns true if we find a distro object in the queue that has
4113             # sponsored this one
4114             sub is_being_sponsored {
4115 0     0 0 0 my($self) = @_;
4116 0         0 my $iterator = CPAN::Queue->iterator;
4117 0         0 QITEM: while (my $q = $iterator->()) {
4118 0         0 my $s = $q->as_string;
4119 0 0       0 my $obj = CPAN::Shell->expandany($s) or next QITEM;
4120 0         0 my $type = ref $obj;
4121 0 0       0 if ( $type eq 'CPAN::Distribution' ){
4122 0 0       0 for my $module (sort keys %{$obj->{sponsored_mods} || {}}) {
  0         0  
4123 0 0       0 return 1 if grep { $_ eq $module } $self->containsmods;
  0         0  
4124             }
4125             }
4126             }
4127 0         0 return 0;
4128             }
4129              
4130             #-> sub CPAN::Distribution::install ;
4131             sub install {
4132 7     7 0 21 my($self) = @_;
4133              
4134 7         98 $self->pre_install();
4135              
4136 7 50       30 if (exists $self->{cleanup_after_install_done}) {
4137 0         0 return $self->test;
4138             }
4139              
4140 7 50       20 $self->debug("checking goto id[$self->{ID}]") if $CPAN::DEBUG;
4141 7 50       78 if (my $goto = $self->prefs->{goto}) {
4142 0         0 $self->goto($goto);
4143 0         0 $self->post_install();
4144 0         0 return;
4145             }
4146              
4147 7 100       66 unless ($self->test) {
4148 4         61 $self->post_install();
4149 4         83 return;
4150             }
4151              
4152 1 50       24 if ( defined( my $sc = $self->shortcut_install ) ) {
4153 0         0 $self->post_install();
4154 0         0 return $sc;
4155             }
4156              
4157 1 50       8 if ($CPAN::Signal) {
4158 0         0 delete $self->{force_update};
4159 0         0 $self->post_install();
4160 0         0 return;
4161             }
4162              
4163 1 50       12 my $builddir = $self->dir or
4164             $CPAN::Frontend->mydie("PANIC: Cannot determine build directory\n");
4165              
4166 1 50       101 unless (chdir $builddir) {
4167 0         0 $CPAN::Frontend->mywarn("Couldn't chdir to '$builddir': $!");
4168 0         0 $self->post_install();
4169 0         0 return;
4170             }
4171              
4172 1 50       9 $self->debug("Changed directory to $self->{build_dir}")
4173             if $CPAN::DEBUG;
4174              
4175 1 50       11 my $make = $self->{modulebuild} ? "Build" : "make";
4176 1         4 $CPAN::Frontend->myprint(sprintf "Running %s install for %s\n", $make, $self->pretty_id);
4177              
4178 1         3 my $system;
4179 1 50       24 if (my $commandline = $self->prefs->{install}{commandline}) {
    50          
4180 0         0 $system = $commandline;
4181 0         0 $ENV{PERL} = CPAN::find_perl();
4182             } elsif ($self->{modulebuild}) {
4183             my($mbuild_install_build_command) =
4184             exists $CPAN::HandleConfig::keys{mbuild_install_build_command} &&
4185             $CPAN::Config->{mbuild_install_build_command} ?
4186             $CPAN::Config->{mbuild_install_build_command} :
4187 0 0 0     0 $self->_build_command();
4188 0 0       0 my $install_directive = $^O eq 'VMS' ? '"install"' : 'install';
4189             $system = sprintf("%s %s %s",
4190             $mbuild_install_build_command,
4191             $install_directive,
4192             $CPAN::Config->{mbuild_install_arg},
4193 0         0 );
4194             } else {
4195 1         17 my($make_install_make_command) = $self->_make_install_make_command();
4196             $system = sprintf("%s install %s",
4197             $make_install_make_command,
4198             $CPAN::Config->{make_install_arg},
4199 1         8 );
4200             }
4201              
4202 1 50 33     13 my($stderr) = $^O eq "MSWin32" || $^O eq 'VMS' ? "" : " 2>&1 ";
4203 1         7 my $brip = CPAN::HandleConfig->prefs_lookup($self,
4204             q{build_requires_install_policy});
4205 1   50     20 $brip ||="ask/yes";
4206 1         7 my $id = $self->id;
4207 1   50     15 my $reqtype = $self->{reqtype} ||= "c"; # in doubt it was a command
4208 1         6 my $want_install = "yes";
4209 1 50       7 if ($reqtype eq "b") {
4210 0 0       0 if ($brip eq "no") {
    0          
4211 0         0 $want_install = "no";
4212             } elsif ($brip =~ m|^ask/(.+)|) {
4213 0         0 my $default = $1;
4214 0 0       0 $default = "yes" unless $default =~ /^(y|n)/i;
4215 0         0 $want_install =
4216             CPAN::Shell::colorable_makemaker_prompt
4217             ("$id is just needed temporarily during building or testing. ".
4218             "Do you want to install it permanently?",
4219             $default);
4220             }
4221             }
4222 1 50       14 unless ($want_install =~ /^y/i) {
4223 0         0 my $is_only = "is only 'build_requires'";
4224 0         0 $self->{install} = CPAN::Distrostatus->new("NO -- $is_only");
4225 0         0 delete $self->{force_update};
4226 0         0 $self->goodbye("Not installing because $is_only");
4227 0         0 $self->post_install();
4228 0         0 return;
4229             }
4230             local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
4231             ? $ENV{PERL5LIB}
4232 1 50 0     20 : ($ENV{PERLLIB} || "");
4233              
4234 1 50       16 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
4235             local $ENV{PERL_USE_UNSAFE_INC} =
4236             exists $ENV{PERL_USE_UNSAFE_INC} && defined $ENV{PERL_USE_UNSAFE_INC}
4237 1 50 33     66 ? $ENV{PERL_USE_UNSAFE_INC} : 1; # install
4238 1         37 $CPAN::META->set_perl5lib;
4239 1 50       5 local $ENV{PERL_MM_USE_DEFAULT} = 1 if $CPAN::Config->{use_prompt_default};
4240 1 50       7 local $ENV{NONINTERACTIVE_TESTING} = 1 if $CPAN::Config->{use_prompt_default};
4241              
4242 1         2 my $install_env;
4243 1 50       7 if ($self->prefs->{install}) {
4244 1         13 $install_env = $self->prefs->{install}{env};
4245             }
4246 1 50       4 local @ENV{keys %$install_env} = values %$install_env if $install_env;
4247              
4248 1 50       3 if (! $run_allow_installing_within_test) {
4249 0         0 my($allow_installing, $why) = $self->_allow_installing;
4250 0 0       0 if (! $allow_installing) {
4251 0         0 $CPAN::Frontend->mywarn("Installation stopped: $why\n");
4252 0         0 $self->introduce_myself;
4253 0         0 $self->{install} = CPAN::Distrostatus->new("NO -- installation stopped due $why");
4254 0         0 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
4255 0         0 delete $self->{force_update};
4256 0         0 $self->post_install();
4257 0         0 return;
4258             }
4259             }
4260 1         27 my($pipe) = FileHandle->new("$system $stderr |");
4261 1 50       9976 unless ($pipe) {
4262 0         0 $CPAN::Frontend->mywarn("Can't execute $system: $!");
4263 0         0 $self->introduce_myself;
4264 0         0 $self->{install} = CPAN::Distrostatus->new("NO");
4265 0         0 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
4266 0         0 delete $self->{force_update};
4267 0         0 $self->post_install();
4268 0         0 return;
4269             }
4270 1         17 my($makeout) = "";
4271 1         5281 while (<$pipe>) {
4272 6         285 print $_; # intentionally NOT use Frontend->myprint because it
4273             # looks irritating when we markup in color what we
4274             # just pass through from an external program
4275 6         2137397 $makeout .= $_;
4276             }
4277 1         49 $pipe->close;
4278 1         79 my $close_ok = $? == 0;
4279 1         25 $self->introduce_myself;
4280 1 50       9 if ( $close_ok ) {
4281 1         17 $CPAN::Frontend->myprint(" $system -- OK\n");
4282 1         31 $CPAN::META->is_installed($self->{build_dir});
4283 1         32 $self->{install} = CPAN::Distrostatus->new("YES");
4284 1 0 33     15 if ($CPAN::Config->{'cleanup_after_install'}
      33        
4285             && ! $self->is_dot_dist
4286             && ! $self->is_being_sponsored) {
4287 0         0 my $parent = File::Spec->catdir( $self->{build_dir}, File::Spec->updir );
4288 0 0       0 chdir $parent or $CPAN::Frontend->mydie("Couldn't chdir to $parent: $!\n");
4289 0         0 File::Path::rmtree($self->{build_dir});
4290 0         0 my $yml = "$self->{build_dir}.yml";
4291 0 0       0 if (-e $yml) {
4292 0 0       0 unlink $yml or $CPAN::Frontend->mydie("Couldn't unlink $yml: $!\n");
4293             }
4294 0         0 $self->{cleanup_after_install_done}=1;
4295             }
4296             } else {
4297 0         0 $self->{install} = CPAN::Distrostatus->new("NO");
4298 0         0 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
4299 0         0 my $mimc =
4300             CPAN::HandleConfig->prefs_lookup($self,
4301             q{make_install_make_command});
4302 0 0 0     0 if (
      0        
      0        
4303             $makeout =~ /permission/s
4304             && $> > 0
4305             && (
4306             ! $mimc
4307             || $mimc eq (CPAN::HandleConfig->prefs_lookup($self,
4308             q{make}))
4309             )
4310             ) {
4311 0         0 $CPAN::Frontend->myprint(
4312             qq{----\n}.
4313             qq{ You may have to su }.
4314             qq{to root to install the package\n}.
4315             qq{ (Or you may want to run something like\n}.
4316             qq{ o conf make_install_make_command 'sudo make'\n}.
4317             qq{ to raise your permissions.}
4318             );
4319             }
4320             }
4321 1         3 delete $self->{force_update};
4322 1 50       12 unless ($CPAN::Config->{'cleanup_after_install'}) {
4323 1         20 $self->store_persistent_state;
4324             }
4325              
4326 1         16 $self->post_install();
4327              
4328 1         82 return !! $close_ok;
4329             }
4330              
4331             sub blib_pm_walk {
4332 0     0 0 0 my @queue = grep { -e $_ } File::Spec->catdir("blib","lib"), File::Spec->catdir("blib","arch");
  0         0  
4333             return sub {
4334             LOOP: {
4335 0 0   0   0 if (@queue) {
  0         0  
4336 0         0 my $file = shift @queue;
4337 0 0       0 if (-d $file) {
4338 0         0 my $dh;
4339 0 0       0 opendir $dh, $file or next;
4340             my @newfiles = map {
4341 0         0 my @ret;
4342 0         0 my $maybedir = File::Spec->catdir($file, $_);
4343 0 0       0 if (-d $maybedir) {
    0          
4344 0 0       0 unless (File::Spec->catdir("blib","arch","auto") eq $maybedir) {
4345             # prune the blib/arch/auto directory, no pm files there
4346 0         0 @ret = $maybedir;
4347             }
4348             } elsif (/\.pm$/) {
4349 0         0 my $mustbefile = File::Spec->catfile($file, $_);
4350 0 0       0 if (-f $mustbefile) {
4351 0         0 @ret = $mustbefile;
4352             }
4353             }
4354 0         0 @ret;
4355             } grep {
4356 0 0       0 $_ ne "."
  0         0  
4357             && $_ ne ".."
4358             } readdir $dh;
4359 0         0 push @queue, @newfiles;
4360 0         0 redo LOOP;
4361             } else {
4362 0         0 return $file;
4363             }
4364             } else {
4365 0         0 return;
4366             }
4367             }
4368 0         0 };
4369             }
4370              
4371             sub _allow_installing {
4372 4     4   18 my($self) = @_;
4373 4         22 my $id = my $pretty_id = $self->pretty_id;
4374 4 50       208 if ($self->{CALLED_FOR}) {
4375 4         28 $id .= " (called for $self->{CALLED_FOR})";
4376             }
4377 4         86 my $allow_down = CPAN::HandleConfig->prefs_lookup($self,q{allow_installing_module_downgrades});
4378 4   50     140 $allow_down ||= "ask/yes";
4379 4         28 my $allow_outdd = CPAN::HandleConfig->prefs_lookup($self,q{allow_installing_outdated_dists});
4380 4   50     44 $allow_outdd ||= "ask/yes";
4381 4 50 33     916 return 1 if
4382             $allow_down eq "yes"
4383             && $allow_outdd eq "yes";
4384 0 0 0     0 if (($allow_outdd ne "yes") && ! $CPAN::META->has_inst('CPAN::DistnameInfo')) {
4385 0 0       0 return 1 if grep { $_ eq 'CPAN::DistnameInfo'} $self->containsmods;
  0         0  
4386 0 0       0 if ($allow_outdd ne "yes") {
4387 0         0 $CPAN::Frontend->mywarn("The current configuration of allow_installing_outdated_dists is '$allow_outdd', but for this option we would need 'CPAN::DistnameInfo' installed. Please install 'CPAN::DistnameInfo' as soon as possible. As long as we are not equipped with 'CPAN::DistnameInfo' this option does not take effect\n");
4388 0         0 $allow_outdd = "yes";
4389             }
4390             }
4391 0 0 0     0 return 1 if
4392             $allow_down eq "yes"
4393             && $allow_outdd eq "yes";
4394 0         0 my($dist_version, $dist_dist);
4395 0 0       0 if ($allow_outdd ne "yes"){
4396 0         0 my $dni = CPAN::DistnameInfo->new($pretty_id);
4397 0         0 $dist_version = $dni->version;
4398 0         0 $dist_dist = $dni->dist;
4399             }
4400 0         0 my $iterator = blib_pm_walk();
4401 0         0 my(@down,@outdd);
4402 0         0 while (my $file = $iterator->()) {
4403 0         0 my $version = CPAN::Module->parse_version($file);
4404 0         0 my($volume, $directories, $pmfile) = File::Spec->splitpath( $file );
4405 0         0 my @dirs = File::Spec->splitdir( $directories );
4406 0         0 my(@blib_plus1) = splice @dirs, 0, 2;
4407 0         0 my($pmpath) = File::Spec->catfile(grep { length($_) } @dirs, $pmfile);
  0         0  
4408 0 0       0 unless ($allow_down eq "yes") {
4409 0 0       0 if (my $inst_file = $self->_file_in_path($pmpath, \@INC)) {
4410 0         0 my $inst_version = CPAN::Module->parse_version($inst_file);
4411 0         0 my $cmp = CPAN::Version->vcmp($version, $inst_version);
4412 0 0       0 if ($cmp) {
4413 0 0       0 if ($cmp < 0) {
4414 0         0 push @down, { pmpath => $pmpath, version => $version, inst_version => $inst_version };
4415             }
4416             }
4417 0 0       0 if (@down) {
4418 0         0 my $why = "allow_installing_module_downgrades: $id contains downgrading module(s) (e.g. '$down[0]{pmpath}' would downgrade installed '$down[0]{inst_version}' to '$down[0]{version}')";
4419 0 0       0 if (my($default) = $allow_down =~ m|^ask/(.+)|) {
4420 0 0       0 $default = "yes" unless $default =~ /^(y|n)/i;
4421 0         0 my $answer = CPAN::Shell::colorable_makemaker_prompt
4422             ("$why. Do you want to allow installing it?",
4423             $default, "colorize_warn");
4424 0 0       0 $allow_down = $answer =~ /^\s*y/i ? "yes" : "no";
4425             }
4426 0 0       0 if ($allow_down eq "no") {
4427 0         0 return (0, $why);
4428             }
4429             }
4430             }
4431             }
4432 0 0       0 unless ($allow_outdd eq "yes") {
4433 0         0 my @pmpath = (@dirs, $pmfile);
4434 0         0 $pmpath[-1] =~ s/\.pm$//;
4435 0         0 my $mo = CPAN::Shell->expand("Module",join "::", grep { length($_) } @pmpath);
  0         0  
4436 0 0       0 if ($mo) {
4437 0         0 my $cpan_version = $mo->cpan_version;
4438 0         0 my $is_lower = CPAN::Version->vlt($version, $cpan_version);
4439 0         0 my $other_dist;
4440 0 0       0 if (my $mo_dist = $mo->distribution) {
4441 0         0 $other_dist = $mo_dist->pretty_id;
4442 0         0 my $dni = CPAN::DistnameInfo->new($other_dist);
4443 0 0       0 if ($dni->dist eq $dist_dist){
4444 0 0       0 if (CPAN::Version->vgt($dni->version, $dist_version)) {
4445 0         0 push @outdd, {
4446             pmpath => $pmpath,
4447             cpan_path => $dni->pathname,
4448             dist_version => $dni->version,
4449             dist_dist => $dni->dist,
4450             };
4451             }
4452             }
4453             }
4454             }
4455 0 0 0     0 if (@outdd && $allow_outdd ne "yes") {
4456 0         0 my $why = "allow_installing_outdated_dists: $id contains module(s) that are indexed on the CPAN with a different distro: (e.g. '$outdd[0]{pmpath}' is indexed with '$outdd[0]{cpan_path}')";
4457 0 0       0 if ($outdd[0]{dist_dist} eq $dist_dist) {
4458 0         0 $why .= ", and this has a higher distribution-version, i.e. version '$outdd[0]{dist_version}' is higher than '$dist_version')";
4459             }
4460 0 0       0 if (my($default) = $allow_outdd =~ m|^ask/(.+)|) {
4461 0 0       0 $default = "yes" unless $default =~ /^(y|n)/i;
4462 0         0 my $answer = CPAN::Shell::colorable_makemaker_prompt
4463             ("$why. Do you want to allow installing it?",
4464             $default, "colorize_warn");
4465 0 0       0 $allow_outdd = $answer =~ /^\s*y/i ? "yes" : "no";
4466             }
4467 0 0       0 if ($allow_outdd eq "no") {
4468 0         0 return (0, $why);
4469             }
4470             }
4471             }
4472             }
4473 0         0 return 1;
4474             }
4475              
4476             sub _file_in_path { # similar to CPAN::Module::_file_in_path
4477 0     0   0 my($self,$pmpath,$incpath) = @_;
4478 0         0 my($dir,@packpath);
4479 0         0 foreach $dir (@$incpath) {
4480 0         0 my $pmfile = File::Spec->catfile($dir,$pmpath);
4481 0 0       0 if (-f $pmfile) {
4482 0         0 return $pmfile;
4483             }
4484             }
4485 0         0 return;
4486             }
4487             sub introduce_myself {
4488 7     7 0 70 my($self) = @_;
4489 7         248 $CPAN::Frontend->myprint(sprintf(" %s\n",$self->pretty_id));
4490             }
4491              
4492             #-> sub CPAN::Distribution::dir ;
4493             sub dir {
4494 16     16 0 130 shift->{build_dir};
4495             }
4496              
4497             #-> sub CPAN::Distribution::perldoc ;
4498             sub perldoc {
4499 0     0 0 0 my($self) = @_;
4500              
4501 0         0 my($dist) = $self->id;
4502 0         0 my $package = $self->called_for;
4503              
4504 0 0       0 if ($CPAN::META->has_inst("Pod::Perldocs")) {
4505 0 0       0 my($perl) = $self->perl
4506             or $CPAN::Frontend->mydie("Couldn't find executable perl\n");
4507 0         0 my @args = ($perl, q{-MPod::Perldocs}, q{-e},
4508             q{Pod::Perldocs->run()}, $package);
4509 0         0 my($wstatus);
4510 0 0       0 unless ( ($wstatus = system(@args)) == 0 ) {
4511 0         0 my $estatus = $wstatus >> 8;
4512 0         0 $CPAN::Frontend->myprint(qq{
4513             Function system("@args")
4514             returned status $estatus (wstat $wstatus)
4515             });
4516             }
4517             }
4518             else {
4519 0         0 $self->_display_url( $CPAN::Defaultdocs . $package );
4520             }
4521             }
4522              
4523             #-> sub CPAN::Distribution::_check_binary ;
4524             sub _check_binary {
4525 0     0   0 my ($dist,$shell,$binary) = @_;
4526 0         0 my ($pid,$out);
4527              
4528 0 0       0 $CPAN::Frontend->myprint(qq{ + _check_binary($binary)\n})
4529             if $CPAN::DEBUG;
4530              
4531 0 0       0 if ($CPAN::META->has_inst("File::Which")) {
4532 0         0 return File::Which::which($binary);
4533             } else {
4534 0         0 local *README;
4535 0 0       0 $pid = open README, "which $binary|"
4536             or $CPAN::Frontend->mywarn(qq{Could not fork 'which $binary': $!\n});
4537 0 0       0 return unless $pid;
4538 0         0 while () {
4539 0         0 $out .= $_;
4540             }
4541 0 0 0     0 close README
4542             or $CPAN::Frontend->mywarn("Could not run 'which $binary': $!\n")
4543             and return;
4544             }
4545              
4546 0 0 0     0 $CPAN::Frontend->myprint(qq{ + $out \n})
4547             if $CPAN::DEBUG && $out;
4548              
4549 0         0 return $out;
4550             }
4551              
4552             #-> sub CPAN::Distribution::_display_url ;
4553             sub _display_url {
4554 0     0   0 my($self,$url) = @_;
4555 0         0 my($res,$saved_file,$pid,$out);
4556              
4557 0 0       0 $CPAN::Frontend->myprint(qq{ + _display_url($url)\n})
4558             if $CPAN::DEBUG;
4559              
4560             # should we define it in the config instead?
4561 0         0 my $html_converter = "html2text.pl";
4562              
4563 0   0     0 my $web_browser = $CPAN::Config->{'lynx'} || undef;
4564 0 0       0 my $web_browser_out = $web_browser
4565             ? CPAN::Distribution->_check_binary($self,$web_browser)
4566             : undef;
4567              
4568 0 0       0 if ($web_browser_out) {
4569             # web browser found, run the action
4570 0         0 my $browser = CPAN::HandleConfig->safe_quote($CPAN::Config->{'lynx'});
4571 0 0       0 $CPAN::Frontend->myprint(qq{system[$browser $url]})
4572             if $CPAN::DEBUG;
4573 0         0 $CPAN::Frontend->myprint(qq{
4574             Displaying URL
4575             $url
4576             with browser $browser
4577             });
4578 0         0 $CPAN::Frontend->mysleep(1);
4579 0         0 system("$browser $url");
4580 0 0       0 if ($saved_file) { 1 while unlink($saved_file) }
  0         0  
4581             } else {
4582             # web browser not found, let's try text only
4583 0         0 my $html_converter_out =
4584             CPAN::Distribution->_check_binary($self,$html_converter);
4585 0         0 $html_converter_out = CPAN::HandleConfig->safe_quote($html_converter_out);
4586              
4587 0 0       0 if ($html_converter_out ) {
4588             # html2text found, run it
4589 0         0 $saved_file = CPAN::Distribution->_getsave_url( $self, $url );
4590 0 0       0 $CPAN::Frontend->mydie(qq{ERROR: problems while getting $url\n})
4591             unless defined($saved_file);
4592              
4593 0         0 local *README;
4594 0 0       0 $pid = open README, "$html_converter $saved_file |"
4595             or $CPAN::Frontend->mydie(qq{
4596             Could not fork '$html_converter $saved_file': $!});
4597 0         0 my($fh,$filename);
4598 0 0       0 if ($CPAN::META->has_usable("File::Temp")) {
4599 0         0 $fh = File::Temp->new(
4600             dir => File::Spec->tmpdir,
4601             template => 'cpan_htmlconvert_XXXX',
4602             suffix => '.txt',
4603             unlink => 0,
4604             );
4605 0         0 $filename = $fh->filename;
4606             } else {
4607 0         0 $filename = "cpan_htmlconvert_$$.txt";
4608 0         0 $fh = FileHandle->new();
4609 0 0       0 open $fh, ">$filename" or die;
4610             }
4611 0         0 while () {
4612 0         0 $fh->print($_);
4613             }
4614 0 0       0 close README or
4615             $CPAN::Frontend->mydie(qq{Could not run '$html_converter $saved_file': $!});
4616 0         0 my $tmpin = $fh->filename;
4617 0 0       0 $CPAN::Frontend->myprint(sprintf(qq{
4618             Run '%s %s' and
4619             saved output to %s\n},
4620             $html_converter,
4621             $saved_file,
4622             $tmpin,
4623             )) if $CPAN::DEBUG;
4624 0         0 close $fh;
4625 0         0 local *FH;
4626 0 0       0 open FH, $tmpin
4627             or $CPAN::Frontend->mydie(qq{Could not open "$tmpin": $!});
4628 0         0 my $fh_pager = FileHandle->new;
4629 0         0 local($SIG{PIPE}) = "IGNORE";
4630 0   0     0 my $pager = $CPAN::Config->{'pager'} || "cat";
4631 0 0       0 $fh_pager->open("|$pager")
4632             or $CPAN::Frontend->mydie(qq{
4633             Could not open pager '$pager': $!});
4634 0         0 $CPAN::Frontend->myprint(qq{
4635             Displaying URL
4636             $url
4637             with pager "$pager"
4638             });
4639 0         0 $CPAN::Frontend->mysleep(1);
4640 0         0 $fh_pager->print();
4641 0         0 $fh_pager->close;
4642             } else {
4643             # coldn't find the web browser or html converter
4644 0         0 $CPAN::Frontend->myprint(qq{
4645             You need to install lynx or $html_converter to use this feature.});
4646             }
4647             }
4648             }
4649              
4650             #-> sub CPAN::Distribution::_getsave_url ;
4651             sub _getsave_url {
4652 0     0   0 my($dist, $shell, $url) = @_;
4653              
4654 0 0       0 $CPAN::Frontend->myprint(qq{ + _getsave_url($url)\n})
4655             if $CPAN::DEBUG;
4656              
4657 0         0 my($fh,$filename);
4658 0 0       0 if ($CPAN::META->has_usable("File::Temp")) {
4659 0         0 $fh = File::Temp->new(
4660             dir => File::Spec->tmpdir,
4661             template => "cpan_getsave_url_XXXX",
4662             suffix => ".html",
4663             unlink => 0,
4664             );
4665 0         0 $filename = $fh->filename;
4666             } else {
4667 0         0 $fh = FileHandle->new;
4668 0         0 $filename = "cpan_getsave_url_$$.html";
4669             }
4670 0         0 my $tmpin = $filename;
4671 0 0       0 if ($CPAN::META->has_usable('LWP')) {
4672 0         0 $CPAN::Frontend->myprint("Fetching with LWP:
4673             $url
4674             ");
4675 0         0 my $Ua;
4676 0         0 CPAN::LWP::UserAgent->config;
4677 0         0 eval { $Ua = CPAN::LWP::UserAgent->new; };
  0         0  
4678 0 0       0 if ($@) {
4679 0         0 $CPAN::Frontend->mywarn("ERROR: CPAN::LWP::UserAgent->new dies with $@\n");
4680 0         0 return;
4681             } else {
4682 0         0 my($var);
4683             $Ua->proxy('http', $var)
4684 0 0 0     0 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
4685             $Ua->no_proxy($var)
4686 0 0 0     0 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
4687             }
4688              
4689 0         0 my $req = HTTP::Request->new(GET => $url);
4690 0         0 $req->header('Accept' => 'text/html');
4691 0         0 my $res = $Ua->request($req);
4692 0 0       0 if ($res->is_success) {
4693 0 0       0 $CPAN::Frontend->myprint(" + request successful.\n")
4694             if $CPAN::DEBUG;
4695 0         0 print $fh $res->content;
4696 0         0 close $fh;
4697 0 0       0 $CPAN::Frontend->myprint(qq{ + saved content to $tmpin \n})
4698             if $CPAN::DEBUG;
4699 0         0 return $tmpin;
4700             } else {
4701 0         0 $CPAN::Frontend->myprint(sprintf(
4702             "LWP failed with code[%s], message[%s]\n",
4703             $res->code,
4704             $res->message,
4705             ));
4706 0         0 return;
4707             }
4708             } else {
4709 0         0 $CPAN::Frontend->mywarn(" LWP not available\n");
4710 0         0 return;
4711             }
4712             }
4713              
4714             #-> sub CPAN::Distribution::_build_command
4715             sub _build_command {
4716 0     0   0 my($self) = @_;
4717 0 0       0 if ($^O eq "MSWin32") { # special code needed at least up to
    0          
4718             # Module::Build 0.2611 and 0.2706; a fix
4719             # in M:B has been promised 2006-01-30
4720 0 0       0 my($perl) = $self->perl or $CPAN::Frontend->mydie("Couldn't find executable perl\n");
4721 0         0 return "$perl ./Build";
4722             }
4723             elsif ($^O eq 'VMS') {
4724 0         0 return "$^X Build.com";
4725             }
4726 0         0 return "./Build";
4727             }
4728              
4729             #-> sub CPAN::Distribution::_should_report
4730             sub _should_report {
4731 13     13   121 my($self, $phase) = @_;
4732 13 50       51 die "_should_report() requires a 'phase' argument"
4733             if ! defined $phase;
4734              
4735 13 50       263 return unless $CPAN::META->has_usable("CPAN::Reporter");
4736              
4737             # configured
4738 0           my $test_report = CPAN::HandleConfig->prefs_lookup($self,
4739             q{test_report});
4740 0 0         return unless $test_report;
4741              
4742             # don't repeat if we cached a result
4743             return $self->{should_report}
4744 0 0         if exists $self->{should_report};
4745              
4746             # don't report if we generated a Makefile.PL
4747 0 0         if ( $self->{had_no_makefile_pl} ) {
4748 0           $CPAN::Frontend->mywarn(
4749             "Will not send CPAN Testers report with generated Makefile.PL.\n"
4750             );
4751 0           return $self->{should_report} = 0;
4752             }
4753              
4754             # available
4755 0 0         if ( ! $CPAN::META->has_inst("CPAN::Reporter")) {
4756 0           $CPAN::Frontend->mywarnonce(
4757             "CPAN::Reporter not installed. No reports will be sent.\n"
4758             );
4759 0           return $self->{should_report} = 0;
4760             }
4761              
4762             # capable
4763 0           my $crv = CPAN::Reporter->VERSION;
4764 0 0         if ( CPAN::Version->vlt( $crv, 0.99 ) ) {
4765             # don't cache $self->{should_report} -- need to check each phase
4766 0 0         if ( $phase eq 'test' ) {
4767 0           return 1;
4768             }
4769             else {
4770 0           $CPAN::Frontend->mywarn(
4771             "Reporting on the '$phase' phase requires CPAN::Reporter 0.99, but \n" .
4772             "you only have version $crv\. Only 'test' phase reports will be sent.\n"
4773             );
4774 0           return;
4775             }
4776             }
4777              
4778             # appropriate
4779 0 0         if ($self->is_dot_dist) {
4780 0           $CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is disabled ".
4781             "for local directories\n");
4782 0           return $self->{should_report} = 0;
4783             }
4784 0 0 0       if ($self->prefs->{patches}
      0        
4785             &&
4786 0           @{$self->prefs->{patches}}
4787             &&
4788             $self->{patched}
4789             ) {
4790 0           $CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is disabled ".
4791             "when the source has been patched\n");
4792 0           return $self->{should_report} = 0;
4793             }
4794              
4795             # proceed and cache success
4796 0           return $self->{should_report} = 1;
4797             }
4798              
4799             #-> sub CPAN::Distribution::reports
4800             sub reports {
4801 0     0 0   my($self) = @_;
4802 0           my $pathname = $self->id;
4803 0           $CPAN::Frontend->myprint("Distribution: $pathname\n");
4804              
4805 0 0         unless ($CPAN::META->has_inst("CPAN::DistnameInfo")) {
4806 0           $CPAN::Frontend->mydie("CPAN::DistnameInfo not installed; cannot continue");
4807             }
4808 0 0         unless ($CPAN::META->has_usable("LWP")) {
4809 0           $CPAN::Frontend->mydie("LWP not installed; cannot continue");
4810             }
4811 0 0         unless ($CPAN::META->has_usable("File::Temp")) {
4812 0           $CPAN::Frontend->mydie("File::Temp not installed; cannot continue");
4813             }
4814              
4815 0           my $format;
4816 0 0 0       if ($CPAN::META->has_inst("YAML::XS") || $CPAN::META->has_inst("YAML::Syck")){
    0 0        
4817 0           $format = 'yaml';
4818             }
4819             elsif (!$format && $CPAN::META->has_inst("JSON::PP") ) {
4820 0           $format = 'json';
4821             }
4822             else {
4823 0           $CPAN::Frontend->mydie("JSON::PP not installed, cannot continue");
4824             }
4825              
4826 0           my $d = CPAN::DistnameInfo->new($pathname);
4827              
4828 0           my $dist = $d->dist; # "CPAN-DistnameInfo"
4829 0           my $version = $d->version; # "0.02"
4830 0           my $maturity = $d->maturity; # "released"
4831 0           my $filename = $d->filename; # "CPAN-DistnameInfo-0.02.tar.gz"
4832 0           my $cpanid = $d->cpanid; # "GBARR"
4833 0           my $distvname = $d->distvname; # "CPAN-DistnameInfo-0.02"
4834              
4835 0           my $url = sprintf "http://www.cpantesters.org/show/%s.%s", $dist, $format;
4836              
4837 0           CPAN::LWP::UserAgent->config;
4838 0           my $Ua;
4839 0           eval { $Ua = CPAN::LWP::UserAgent->new; };
  0            
4840 0 0         if ($@) {
4841 0           $CPAN::Frontend->mydie("CPAN::LWP::UserAgent->new dies with $@\n");
4842             }
4843 0           $CPAN::Frontend->myprint("Fetching '$url'...");
4844 0           my $resp = $Ua->get($url);
4845 0 0         unless ($resp->is_success) {
4846 0           $CPAN::Frontend->mydie(sprintf "Could not download '%s': %s\n", $url, $resp->code);
4847             }
4848 0           $CPAN::Frontend->myprint("DONE\n\n");
4849 0           my $unserialized;
4850 0 0         if ( $format eq 'yaml' ) {
4851 0           my $yaml = $resp->content;
4852             # what a long way round!
4853 0           my $fh = File::Temp->new(
4854             dir => File::Spec->tmpdir,
4855             template => 'cpan_reports_XXXX',
4856             suffix => '.yaml',
4857             unlink => 0,
4858             );
4859 0           my $tfilename = $fh->filename;
4860 0           print $fh $yaml;
4861 0 0         close $fh or $CPAN::Frontend->mydie("Could not close '$tfilename': $!");
4862 0           $unserialized = CPAN->_yaml_loadfile($tfilename)->[0];
4863 0 0         unlink $tfilename or $CPAN::Frontend->mydie("Could not unlink '$tfilename': $!");
4864             } else {
4865 0           require JSON::PP;
4866 0           $unserialized = JSON::PP->new->utf8->decode($resp->content);
4867             }
4868 0           my %other_versions;
4869             my $this_version_seen;
4870 0           for my $rep (@$unserialized) {
4871 0           my $rversion = $rep->{version};
4872 0 0         if ($rversion eq $version) {
4873 0 0         unless ($this_version_seen++) {
4874 0           $CPAN::Frontend->myprint ("$rep->{version}:\n");
4875             }
4876 0   0       my $arch = $rep->{archname} || $rep->{platform} || '????';
4877 0   0       my $grade = $rep->{action} || $rep->{status} || '????';
4878 0   0       my $ostext = $rep->{ostext} || ucfirst($rep->{osname}) || '????';
4879             $CPAN::Frontend->myprint
4880             (sprintf("%1s%1s%-4s %s on %s %s (%s)\n",
4881             $arch eq $Config::Config{archname}?"*":"",
4882             $grade eq "PASS"?"+":$grade eq"FAIL"?"-":"",
4883             $grade,
4884             $rep->{perl},
4885             $ostext,
4886             $rep->{osvers},
4887 0 0         $arch,
    0          
    0          
4888             ));
4889             } else {
4890 0           $other_versions{$rep->{version}}++;
4891             }
4892             }
4893 0 0         unless ($this_version_seen) {
4894 0           $CPAN::Frontend->myprint("No reports found for version '$version'
4895             Reports for other versions:\n");
4896 0           for my $v (sort keys %other_versions) {
4897 0           $CPAN::Frontend->myprint(" $v\: $other_versions{$v}\n");
4898             }
4899             }
4900 0           $url = substr($url,0,-4) . 'html';
4901 0           $CPAN::Frontend->myprint("See $url for details\n");
4902             }
4903              
4904             1;