File Coverage

blib/lib/CPAN/Distribution.pm
Criterion Covered Total %
statement 94 2510 3.7
branch 29 1612 1.8
condition 11 604 1.8
subroutine 16 117 13.6
pod 0 75 0.0
total 150 4918 3.0


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