File Coverage

blib/lib/CPAN/Distribution.pm
Criterion Covered Total %
statement 91 2233 4.0
branch 29 1462 1.9
condition 11 540 2.0
subroutine 15 111 13.5
pod 0 73 0.0
total 146 4419 3.3


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