File Coverage

blib/lib/CPAN/Distribution.pm
Criterion Covered Total %
statement 91 2263 4.0
branch 29 1474 1.9
condition 11 555 1.9
subroutine 15 111 13.5
pod 0 73 0.0
total 146 4476 3.2


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