File Coverage

blib/lib/CPAN/Distribution.pm
Criterion Covered Total %
statement 91 2251 4.0
branch 29 1478 1.9
condition 11 552 1.9
subroutine 15 111 13.5
pod 0 73 0.0
total 146 4465 3.2


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