File Coverage

blib/lib/CPAN/Distribution.pm
Criterion Covered Total %
statement 91 2192 4.1
branch 30 1432 2.0
condition 11 530 2.0
subroutine 15 111 13.5
pod 0 73 0.0
total 147 4338 3.3


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