1 package CPAN::Distribution;
6 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
13 my $ro = $self->ro or return;
17 #-> CPAN::Distribution::undelay
21 "configure_requires_later",
22 "configure_requires_later_for",
26 delete $self->{$delayer};
30 #-> CPAN::Distribution::is_dot_dist
33 return substr($self->id,-1,1) eq ".";
37 #-> CPAN::Distribution::normalize
40 $s = $self->id unless defined $s;
41 if (substr($s,-1,1) eq ".") {
42 # using a global because we are sometimes called as static method
43 if (!$CPAN::META->{LOCK}
44 && !$CPAN::Have_warned->{"$s is unlocked"}++
46 $CPAN::Frontend->mywarn("You are visiting the local directory
48 without lock, take care that concurrent processes do not do likewise.\n");
49 $CPAN::Frontend->mysleep(1);
53 } elsif (File::Spec->file_name_is_absolute($s)) {
54 } elsif (File::Spec->can("rel2abs")) {
55 $s = File::Spec->rel2abs($s);
57 $CPAN::Frontend->mydie("Your File::Spec is too old, please upgrade File::Spec");
59 CPAN->debug("s[$s]") if $CPAN::DEBUG;
60 unless ($CPAN::META->exists("CPAN::Distribution", $s)) {
61 for ($CPAN::META->instance("CPAN::Distribution", $s)) {
63 $_->{archived} = "local_directory";
64 $_->{unwrapped} = CPAN::Distrostatus->new("YES -- local_directory");
70 $s !~ m|[A-Z]/[A-Z-]{2}/[A-Z-]{2,}/|
72 return $s if $s =~ m:^N/A|^Contact Author: ;
73 $s =~ s|^(.)(.)([^/]*/)(.+)$|$1/$1$2/$1$2$3$4|;
74 CPAN->debug("s[$s]") if $CPAN::DEBUG;
79 #-> sub CPAN::Distribution::author ;
83 if (substr($self->id,-1,1) eq ".") {
86 ($authorid) = $self->pretty_id =~ /^([\w\-]+)/;
88 CPAN::Shell->expand("Author",$authorid);
91 # tries to get the yaml from CPAN instead of the distro itself:
92 # EXPERIMENTAL, UNDOCUMENTED AND UNTESTED, for Tels
95 my $meta = $self->pretty_id;
96 $meta =~ s/\.(tar.gz|tgz|zip|tar.bz2)/.meta/;
97 my(@ls) = CPAN::Shell->globls($meta);
98 my $norm = $self->normalize($meta);
103 $CPAN::Config->{keep_source_where},
108 $self->debug("Doing localize") if $CPAN::DEBUG;
109 unless ($local_file =
110 CPAN::FTP->localize("authors/id/$norm",
112 $CPAN::Frontend->mydie("Giving up on downloading yaml file '$local_wanted'\n");
114 my $yaml = CPAN->_yaml_loadfile($local_file)->[0];
117 #-> sub CPAN::Distribution::cpan_userid
120 if ($self->{ID} =~ m{[A-Z]/[A-Z\-]{2}/([A-Z\-]+)/}) {
123 return $self->SUPER::cpan_userid;
126 #-> sub CPAN::Distribution::pretty_id
130 return $id unless $id =~ m|^./../|;
134 #-> sub CPAN::Distribution::base_id
137 my $id = $self->pretty_id();
138 my $base_id = File::Basename::basename($id);
139 $base_id =~ s{\.(?:tar\.(bz2|gz|Z)|t(?:gz|bz)|zip)$}{}i;
143 #-> sub CPAN::Distribution::tested_ok_but_not_installed
144 sub tested_ok_but_not_installed {
148 && $self->{build_dir}
149 && (UNIVERSAL::can($self->{make_test},"failed") ?
150 ! $self->{make_test}->failed :
151 $self->{make_test} =~ /^YES/
156 $self->{install}->failed
162 # mark as dirty/clean for the sake of recursion detection. $color=1
163 # means "in use", $color=0 means "not in use anymore". $color=2 means
164 # we have determined prereqs now and thus insist on passing this
165 # through (at least) once again.
167 #-> sub CPAN::Distribution::color_cmd_tmps ;
170 my($depth) = shift || 0;
171 my($color) = shift || 0;
172 my($ancestors) = shift || [];
173 # a distribution needs to recurse into its prereq_pms
175 return if exists $self->{incommandcolor}
177 && $self->{incommandcolor}==$color;
178 if ($depth>=$CPAN::MAX_RECURSION) {
179 die(CPAN::Exception::RecursiveDependency->new($ancestors));
181 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
182 my $prereq_pm = $self->prereq_pm;
183 if (defined $prereq_pm) {
184 PREREQ: for my $pre (keys %{$prereq_pm->{requires}||{}},
185 keys %{$prereq_pm->{build_requires}||{}}) {
186 next PREREQ if $pre eq "perl";
188 unless ($premo = CPAN::Shell->expand("Module",$pre)) {
189 $CPAN::Frontend->mywarn("prerequisite module[$pre] not known\n");
190 $CPAN::Frontend->mysleep(2);
193 $premo->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
197 delete $self->{sponsored_mods};
199 # as we are at the end of a command, we'll give up this
200 # reminder of a broken test. Other commands may test this guy
201 # again. Maybe 'badtestcnt' should be renamed to
202 # 'make_test_failed_within_command'?
203 delete $self->{badtestcnt};
205 $self->{incommandcolor} = $color;
208 #-> sub CPAN::Distribution::as_string ;
213 $self->SUPER::as_string(@_);
216 #-> sub CPAN::Distribution::containsmods ;
219 return keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
220 my $dist_id = $self->{ID};
221 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
222 my $mod_file = $mod->cpan_file or next;
223 my $mod_id = $mod->{ID} or next;
224 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
227 delete $self->{CONTAINSMODS};
230 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
232 keys %{$self->{CONTAINSMODS}||={}};
235 #-> sub CPAN::Distribution::upload_date ;
238 return $self->{UPLOAD_DATE} if exists $self->{UPLOAD_DATE};
239 my(@local_wanted) = split(/\//,$self->id);
240 my $filename = pop @local_wanted;
241 push @local_wanted, "CHECKSUMS";
242 my $author = CPAN::Shell->expand("Author",$self->cpan_userid);
243 return unless $author;
244 my @dl = $author->dir_listing(\@local_wanted,0,$CPAN::Config->{show_upload_date});
246 my($dirent) = grep { $_->[2] eq $filename } @dl;
247 # warn sprintf "dirent[%s]id[%s]", $dirent, $self->id;
248 return unless $dirent->[1];
249 return $self->{UPLOAD_DATE} = $dirent->[1];
252 #-> sub CPAN::Distribution::uptodate ;
256 foreach $c ($self->containsmods) {
257 my $obj = CPAN::Shell->expandany($c);
258 unless ($obj->uptodate) {
259 my $id = $self->pretty_id;
260 $self->debug("$id not uptodate due to $c") if $CPAN::DEBUG;
267 #-> sub CPAN::Distribution::called_for ;
270 $self->{CALLED_FOR} = $id if defined $id;
271 return $self->{CALLED_FOR};
274 #-> sub CPAN::Distribution::get ;
277 $self->debug("checking goto id[$self->{ID}]") if $CPAN::DEBUG;
278 if (my $goto = $self->prefs->{goto}) {
279 $CPAN::Frontend->mywarn
281 "delegating to '%s' as specified in prefs file '%s' doc %d\n",
284 $self->{prefs_file_doc},
286 return $self->goto($goto);
288 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
290 : ($ENV{PERLLIB} || "");
291 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
292 $CPAN::META->set_perl5lib;
293 local $ENV{MAKEFLAGS}; # protect us from outer make calls
298 $self->debug("checking disabled id[$self->{ID}]") if $CPAN::DEBUG;
299 if ($self->prefs->{disabled} && ! $self->{force_update}) {
301 "Disabled via prefs file '%s' doc %d",
303 $self->{prefs_file_doc},
306 $self->{unwrapped} = CPAN::Distrostatus->new("NO $why");
307 $goodbye_message = "[disabled] -- NA $why";
308 # note: not intended to be persistent but at least visible
309 # during this session
311 if (exists $self->{build_dir} && -d $self->{build_dir}
312 && ($self->{modulebuild}||$self->{writemakefile})
314 # this deserves print, not warn:
315 $CPAN::Frontend->myprint(" Has already been unwrapped into directory ".
316 "$self->{build_dir}\n"
321 # although we talk about 'force' we shall not test on
322 # force directly. New model of force tries to refrain from
323 # direct checking of force.
324 exists $self->{unwrapped} and (
325 UNIVERSAL::can($self->{unwrapped},"failed") ?
326 $self->{unwrapped}->failed :
327 $self->{unwrapped} =~ /^NO/
329 and push @e, "Unwrapping had some problem, won't try again without force";
332 $CPAN::Frontend->mywarn(join "", map {"$_\n"} @e);
333 if ($goodbye_message) {
334 $self->goodbye($goodbye_message);
339 my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
342 unless ($self->{build_dir} && -d $self->{build_dir}) {
343 $self->get_file_onto_local_disk;
344 return if $CPAN::Signal;
345 $self->check_integrity;
346 return if $CPAN::Signal;
347 (my $packagedir,$local_file) = $self->run_preps_on_packagedir;
348 if (exists $self->{writemakefile} && ref $self->{writemakefile}
349 && $self->{writemakefile}->can("failed") &&
350 $self->{writemakefile}->failed) {
353 $packagedir ||= $self->{build_dir};
354 $self->{build_dir} = $packagedir;
358 $self->safe_chdir($sub_wd);
361 return $self->choose_MM_or_MB($local_file);
364 #-> CPAN::Distribution::get_file_onto_local_disk
365 sub get_file_onto_local_disk {
368 return if $self->is_dot_dist;
372 $CPAN::Config->{keep_source_where},
375 split(/\//,$self->id)
378 $self->debug("Doing localize") if $CPAN::DEBUG;
379 unless ($local_file =
380 CPAN::FTP->localize("authors/id/$self->{ID}",
383 if ($CPAN::Index::DATE_OF_02) {
384 $note = "Note: Current database in memory was generated ".
385 "on $CPAN::Index::DATE_OF_02\n";
387 $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n$note");
390 $self->debug("local_wanted[$local_wanted]local_file[$local_file]") if $CPAN::DEBUG;
391 $self->{localfile} = $local_file;
395 #-> CPAN::Distribution::check_integrity
396 sub check_integrity {
399 return if $self->is_dot_dist;
400 if ($CPAN::META->has_inst("Digest::SHA")) {
401 $self->debug("Digest::SHA is installed, verifying");
402 $self->verifyCHECKSUM;
404 $self->debug("Digest::SHA is NOT installed");
408 #-> CPAN::Distribution::run_preps_on_packagedir
409 sub run_preps_on_packagedir {
411 return if $self->is_dot_dist;
413 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
414 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
415 $self->safe_chdir($builddir);
416 $self->debug("Removing tmp-$$") if $CPAN::DEBUG;
417 File::Path::rmtree("tmp-$$");
418 unless (mkdir "tmp-$$", 0755) {
419 $CPAN::Frontend->unrecoverable_error(<<EOF);
420 Couldn't mkdir '$builddir/tmp-$$': $!
422 Cannot continue: Please find the reason why I cannot make the
425 and fix the problem, then retry.
432 $self->safe_chdir("tmp-$$");
437 my $local_file = $self->{localfile};
438 my $ct = eval{CPAN::Tarzip->new($local_file)};
440 $self->{unwrapped} = CPAN::Distrostatus->new("NO");
441 delete $self->{build_dir};
444 if ($local_file =~ /(\.tar\.(bz2|gz|Z)|\.tgz)(?!\n)\Z/i) {
445 $self->{was_uncompressed}++ unless eval{$ct->gtest()};
446 $self->untar_me($ct);
447 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
448 $self->unzip_me($ct);
450 $self->{was_uncompressed}++ unless $ct->gtest();
451 $local_file = $self->handle_singlefile($local_file);
454 # we are still in the tmp directory!
455 # Let's check if the package has its own directory.
456 my $dh = DirHandle->new(File::Spec->curdir)
457 or Carp::croak("Couldn't opendir .: $!");
458 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
459 if (grep { $_ eq "pax_global_header" } @readdir) {
460 $CPAN::Frontend->mywarn("Your (un)tar seems to have extracted a file named 'pax_global_header'
461 from the tarball '$local_file'.
462 This is almost certainly an error. Please upgrade your tar.
463 I'll ignore this file for now.
464 See also http://rt.cpan.org/Ticket/Display.html?id=38932\n");
465 $CPAN::Frontend->mysleep(5);
466 @readdir = grep { $_ ne "pax_global_header" } @readdir;
470 # XXX here we want in each branch File::Temp to protect all build_dir directories
471 if (CPAN->has_usable("File::Temp")) {
475 if (@readdir == 1 && -d $readdir[0]) {
476 $tdir_base = $readdir[0];
477 $from_dir = File::Spec->catdir(File::Spec->curdir,$readdir[0]);
479 unless ($dh2 = DirHandle->new($from_dir)) {
480 my($mode) = (stat $from_dir)[2];
483 "Couldn't opendir '%s', mode '%o': %s",
488 $CPAN::Frontend->mywarn("$why\n");
489 $self->{writemakefile} = CPAN::Distrostatus->new("NO -- $why");
492 @dirents = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh2->read; ### MAC??
494 my $userid = $self->cpan_userid;
495 CPAN->debug("userid[$userid]");
496 if (!$userid or $userid eq "N/A") {
499 $tdir_base = $userid;
500 $from_dir = File::Spec->curdir;
503 $packagedir = File::Temp::tempdir(
508 chmod 0777 &~ umask, $packagedir; # may fail
510 for $f (@dirents) { # is already without "." and ".."
511 my $from = File::Spec->catdir($from_dir,$f);
512 my $to = File::Spec->catdir($packagedir,$f);
513 unless (File::Copy::move($from,$to)) {
515 $from = File::Spec->rel2abs($from);
516 Carp::confess("Couldn't move $from to $to: $err");
519 } else { # older code below, still better than nothing when there is no File::Temp
521 if (@readdir == 1 && -d $readdir[0]) {
522 $distdir = $readdir[0];
523 $packagedir = File::Spec->catdir($builddir,$distdir);
524 $self->debug("packagedir[$packagedir]builddir[$builddir]distdir[$distdir]")
526 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
528 File::Path::rmtree($packagedir);
529 unless (File::Copy::move($distdir,$packagedir)) {
530 $CPAN::Frontend->unrecoverable_error(<<EOF);
531 Couldn't move '$distdir' to '$packagedir': $!
533 Cannot continue: Please find the reason why I cannot move
534 $builddir/tmp-$$/$distdir
537 and fix the problem, then retry
541 $self->debug(sprintf("moved distdir[%s] to packagedir[%s] -e[%s]-d[%s]",
548 my $userid = $self->cpan_userid;
549 CPAN->debug("userid[$userid]") if $CPAN::DEBUG;
550 if (!$userid or $userid eq "N/A") {
553 my $pragmatic_dir = $userid . '000';
554 $pragmatic_dir =~ s/\W_//g;
555 $pragmatic_dir++ while -d "../$pragmatic_dir";
556 $packagedir = File::Spec->catdir($builddir,$pragmatic_dir);
557 $self->debug("packagedir[$packagedir]") if $CPAN::DEBUG;
558 File::Path::mkpath($packagedir);
560 for $f (@readdir) { # is already without "." and ".."
561 my $to = File::Spec->catdir($packagedir,$f);
562 File::Copy::move($f,$to) or Carp::confess("Couldn't move $f to $to: $!");
566 $self->{build_dir} = $packagedir;
567 $self->safe_chdir($builddir);
568 File::Path::rmtree("tmp-$$");
570 $self->safe_chdir($packagedir);
571 $self->_signature_business();
572 $self->safe_chdir($builddir);
574 return($packagedir,$local_file);
577 #-> sub CPAN::Distribution::parse_meta_yml ;
580 my $build_dir = $self->{build_dir} or die "PANIC: cannot parse yaml without a build_dir";
581 my $yaml = File::Spec->catfile($build_dir,"META.yml");
582 $self->debug("yaml[$yaml]") if $CPAN::DEBUG;
583 return unless -f $yaml;
586 require Parse::CPAN::Meta;
587 $early_yaml = Parse::CPAN::Meta::LoadFile($yaml)->[0];
589 unless ($early_yaml) {
590 eval { $early_yaml = CPAN->_yaml_loadfile($yaml)->[0]; };
592 unless ($early_yaml) {
598 #-> sub CPAN::Distribution::satisfy_requires ;
599 sub satisfy_requires {
601 if (my @prereq = $self->unsat_prereq("later")) {
602 if ($prereq[0][0] eq "perl") {
603 my $need = "requires perl '$prereq[0][1]'";
604 my $id = $self->pretty_id;
605 $CPAN::Frontend->mywarn("$id $need; you have only $]; giving up\n");
606 $self->{make} = CPAN::Distrostatus->new("NO $need");
607 $self->store_persistent_state;
608 die "[prereq] -- NOT OK\n";
610 my $follow = eval { $self->follow_prereqs("later",@prereq); };
613 # signal success to the queuerunner
615 } elsif ($@ && ref $@ && $@->isa("CPAN::Exception::RecursiveDependency")) {
616 $CPAN::Frontend->mywarn($@);
617 die "[depend] -- NOT OK\n";
623 #-> sub CPAN::Distribution::satisfy_configure_requires ;
624 sub satisfy_configure_requires {
626 my $enable_configure_requires = 1;
627 if (!$enable_configure_requires) {
629 # if we return 1 here, everything is as before we introduced
630 # configure_requires that means, things with
631 # configure_requires simply fail, all others succeed
633 my @prereq = $self->unsat_prereq("configure_requires_later") or return 1;
634 if ($self->{configure_requires_later}) {
635 for my $k (keys %{$self->{configure_requires_later_for}||{}}) {
636 if ($self->{configure_requires_later_for}{$k}>1) {
637 # we must not come here a second time
638 $CPAN::Frontend->mywarn("Panic: Some prerequisites is not available, please investigate...");
640 $CPAN::Frontend->mydie
643 ({self=>$self, prereq=>\@prereq})
648 if ($prereq[0][0] eq "perl") {
649 my $need = "requires perl '$prereq[0][1]'";
650 my $id = $self->pretty_id;
651 $CPAN::Frontend->mywarn("$id $need; you have only $]; giving up\n");
652 $self->{make} = CPAN::Distrostatus->new("NO $need");
653 $self->store_persistent_state;
654 return $self->goodbye("[prereq] -- NOT OK");
657 $self->follow_prereqs("configure_requires_later", @prereq);
662 } elsif ($@ && ref $@ && $@->isa("CPAN::Exception::RecursiveDependency")) {
663 $CPAN::Frontend->mywarn($@);
664 return $self->goodbye("[depend] -- NOT OK");
670 #-> sub CPAN::Distribution::choose_MM_or_MB ;
671 sub choose_MM_or_MB {
672 my($self,$local_file) = @_;
673 $self->satisfy_configure_requires() or return;
674 my($mpl) = File::Spec->catfile($self->{build_dir},"Makefile.PL");
675 my($mpl_exists) = -f $mpl;
676 unless ($mpl_exists) {
677 # NFS has been reported to have racing problems after the
678 # renaming of a directory in some environments.
680 $CPAN::Frontend->mysleep(1);
681 my $mpldh = DirHandle->new($self->{build_dir})
682 or Carp::croak("Couldn't opendir $self->{build_dir}: $!");
683 $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read;
686 my $prefer_installer = "eumm"; # eumm|mb
687 if (-f File::Spec->catfile($self->{build_dir},"Build.PL")) {
688 if ($mpl_exists) { # they *can* choose
689 if ($CPAN::META->has_inst("Module::Build")) {
690 $prefer_installer = CPAN::HandleConfig->prefs_lookup($self,
691 q{prefer_installer});
694 $prefer_installer = "mb";
697 return unless $self->patch;
698 if (lc($prefer_installer) eq "rand") {
699 $prefer_installer = rand()<.5 ? "eumm" : "mb";
701 if (lc($prefer_installer) eq "mb") {
702 $self->{modulebuild} = 1;
703 } elsif ($self->{archived} eq "patch") {
704 # not an edge case, nothing to install for sure
705 my $why = "A patch file cannot be installed";
706 $CPAN::Frontend->mywarn("Refusing to handle this file: $why\n");
707 $self->{writemakefile} = CPAN::Distrostatus->new("NO $why");
708 } elsif (! $mpl_exists) {
709 $self->_edge_cases($mpl,$local_file);
711 if ($self->{build_dir}
713 $CPAN::Config->{build_dir_reuse}
715 $self->store_persistent_state;
720 #-> CPAN::Distribution::store_persistent_state
721 sub store_persistent_state {
723 my $dir = $self->{build_dir};
724 unless (File::Spec->canonpath(File::Basename::dirname($dir))
725 eq File::Spec->canonpath($CPAN::Config->{build_dir})) {
726 $CPAN::Frontend->mywarn("Directory '$dir' not below $CPAN::Config->{build_dir}, ".
727 "will not store persistent state\n");
730 my $file = sprintf "%s.yml", $dir;
731 my $yaml_module = CPAN::_yaml_module();
732 if ($CPAN::META->has_inst($yaml_module)) {
733 CPAN->_yaml_dumpfile(
737 perl => CPAN::_perl_fingerprint(),
738 distribution => $self,
742 $CPAN::Frontend->myprint("Warning (usually harmless): '$yaml_module' not installed, ".
743 "will not store persistent state\n");
747 #-> CPAN::Distribution::try_download
749 my($self,$patch) = @_;
750 my $norm = $self->normalize($patch);
753 $CPAN::Config->{keep_source_where},
758 $self->debug("Doing localize") if $CPAN::DEBUG;
759 return CPAN::FTP->localize("authors/id/$norm",
764 my $stdpatchargs = "";
765 #-> CPAN::Distribution::patch
768 $self->debug("checking patches id[$self->{ID}]") if $CPAN::DEBUG;
769 my $patches = $self->prefs->{patches};
771 $self->debug("patches[$patches]") if $CPAN::DEBUG;
773 return unless @$patches;
774 $self->safe_chdir($self->{build_dir});
775 CPAN->debug("patches[$patches]") if $CPAN::DEBUG;
776 my $patchbin = $CPAN::Config->{patch};
777 unless ($patchbin && length $patchbin) {
778 $CPAN::Frontend->mydie("No external patch command configured\n\n".
779 "Please run 'o conf init /patch/'\n\n");
781 unless (MM->maybe_command($patchbin)) {
782 $CPAN::Frontend->mydie("No external patch command available\n\n".
783 "Please run 'o conf init /patch/'\n\n");
785 $patchbin = CPAN::HandleConfig->safe_quote($patchbin);
786 local $ENV{PATCH_GET} = 0; # formerly known as -g0
787 unless ($stdpatchargs) {
788 my $system = "$patchbin --version |";
790 open FH, $system or die "Could not fork '$system': $!";
793 PARSEVERSION: while (<FH>) {
794 if (/^patch\s+([\d\.]+)/) {
800 $stdpatchargs = "-N --fuzz=3";
802 $stdpatchargs = "-N";
805 my $countedpatches = @$patches == 1 ? "1 patch" : (scalar @$patches . " patches");
806 $CPAN::Frontend->myprint("Going to apply $countedpatches:\n");
807 my $patches_dir = $CPAN::Config->{patches_dir};
808 for my $patch (@$patches) {
809 if ($patches_dir && !File::Spec->file_name_is_absolute($patch)) {
810 my $f = File::Spec->catfile($patches_dir, $patch);
811 $patch = $f if -f $f;
814 if (my $trydl = $self->try_download($patch)) {
817 my $fail = "Could not find patch '$patch'";
818 $CPAN::Frontend->mywarn("$fail; cannot continue\n");
819 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
820 delete $self->{build_dir};
824 $CPAN::Frontend->myprint(" $patch\n");
825 my $readfh = CPAN::Tarzip->TIEHANDLE($patch);
828 my $ppp = $self->_patch_p_parameter($readfh);
829 if ($ppp eq "applypatch") {
830 $pcommand = "$CPAN::Config->{applypatch} -verbose";
832 my $thispatchargs = join " ", $stdpatchargs, $ppp;
833 $pcommand = "$patchbin $thispatchargs";
836 $readfh = CPAN::Tarzip->TIEHANDLE($patch); # open again
837 my $writefh = FileHandle->new;
838 $CPAN::Frontend->myprint(" $pcommand\n");
839 unless (open $writefh, "|$pcommand") {
840 my $fail = "Could not fork '$pcommand'";
841 $CPAN::Frontend->mywarn("$fail; cannot continue\n");
842 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
843 delete $self->{build_dir};
846 while (my $x = $readfh->READLINE) {
849 unless (close $writefh) {
850 my $fail = "Could not apply patch '$patch'";
851 $CPAN::Frontend->mywarn("$fail; cannot continue\n");
852 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
853 delete $self->{build_dir};
863 sub _patch_p_parameter {
868 while ($_ = $fh->READLINE) {
870 $CPAN::Config->{applypatch}
872 /\#\#\#\# ApplyPatch data follows \#\#\#\#/
876 next unless /^[\*\+]{3}\s(\S+)/;
879 $cnt_p0files++ if -f $file;
880 CPAN->debug("file[$file]cnt_files[$cnt_files]cnt_p0files[$cnt_p0files]")
883 return "-p1" unless $cnt_files;
884 return $cnt_files==$cnt_p0files ? "-p0" : "-p1";
887 #-> sub CPAN::Distribution::_edge_cases
888 # with "configure" or "Makefile" or single file scripts
890 my($self,$mpl,$local_file) = @_;
891 $self->debug(sprintf("makefilepl[%s]anycwd[%s]",
895 my $build_dir = $self->{build_dir};
896 my($configure) = File::Spec->catfile($build_dir,"Configure");
898 # do we have anything to do?
899 $self->{configure} = $configure;
900 } elsif (-f File::Spec->catfile($build_dir,"Makefile")) {
901 $CPAN::Frontend->mywarn(qq{
902 Package comes with a Makefile and without a Makefile.PL.
903 We\'ll try to build it with that Makefile then.
905 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
906 $CPAN::Frontend->mysleep(2);
908 my $cf = $self->called_for || "unknown";
913 $cf =~ s|[/\\:]||g; # risk of filesystem damage
914 $cf = "unknown" unless length($cf);
915 if (my $crud = $self->_contains_crud($build_dir)) {
916 my $why = qq{Package contains $crud; not recognized as a perl package, giving up};
917 $CPAN::Frontend->mywarn("$why\n");
918 $self->{writemakefile} = CPAN::Distrostatus->new(qq{NO -- $why});
921 $CPAN::Frontend->mywarn(qq{Package seems to come without Makefile.PL.
922 (The test -f "$mpl" returned false.)
923 Writing one on our own (setting NAME to $cf)\a\n});
924 $self->{had_no_makefile_pl}++;
925 $CPAN::Frontend->mysleep(3);
927 # Writing our own Makefile.PL
929 my $exefile_stanza = "";
930 if ($self->{archived} eq "maybe_pl") {
931 $exefile_stanza = $self->_exefile_stanza($build_dir,$local_file);
934 my $fh = FileHandle->new;
936 or Carp::croak("Could not open >$mpl: $!");
938 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
939 # because there was no Makefile.PL supplied.
940 # Autogenerated on: }.scalar localtime().qq{
942 use ExtUtils::MakeMaker;
944 NAME => q[$cf],$exefile_stanza
951 #-> CPAN;:Distribution::_contains_crud
954 my(@dirs, $dh, @files);
955 opendir $dh, $dir or return;
957 for $dirent (readdir $dh) {
958 next if $dirent =~ /^\.\.?$/;
959 my $path = File::Spec->catdir($dir,$dirent);
963 push @files, $dirent;
966 if (@dirs && @files) {
967 return "both files[@files] and directories[@dirs]";
968 } elsif (@files > 2) {
969 return "several files[@files] but no Makefile.PL or Build.PL";
974 #-> CPAN;:Distribution::_exefile_stanza
975 sub _exefile_stanza {
976 my($self,$build_dir,$local_file) = @_;
978 my $fh = FileHandle->new;
979 my $script_file = File::Spec->catfile($build_dir,$local_file);
980 $fh->open($script_file)
981 or Carp::croak("Could not open script '$script_file': $!");
983 # name parsen und prereq
984 my($state) = "poddir";
985 my($name, $prereq) = ("", "");
987 if ($state eq "poddir" && /^=head\d\s+(\S+)/) {
990 } elsif ($1 eq 'PREREQUISITES') {
993 } elsif ($state =~ m{^(name|prereq)$}) {
998 } elsif ($state eq "name") {
1003 } elsif ($state eq "prereq") {
1006 } elsif (/^=cut\b/) {
1013 s{.*<}{}; # strip X<...>
1017 $prereq = join " ", split /\s+/, $prereq;
1018 my($PREREQ_PM) = join("\n", map {
1019 s{.*<}{}; # strip X<...>
1021 if (/[\s\'\"]/) { # prose?
1023 s/[^\w:]$//; # period?
1024 " "x28 . "'$_' => 0,";
1026 } split /\s*,\s*/, $prereq);
1029 my $to_file = File::Spec->catfile($build_dir, $name);
1030 rename $script_file, $to_file
1031 or die "Can't rename $script_file to $to_file: $!";
1035 EXE_FILES => ['$name'],
1042 #-> CPAN::Distribution::_signature_business
1043 sub _signature_business {
1045 my $check_sigs = CPAN::HandleConfig->prefs_lookup($self,
1048 if ($CPAN::META->has_inst("Module::Signature")) {
1049 if (-f "SIGNATURE") {
1050 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
1051 my $rv = Module::Signature::verify();
1052 if ($rv != Module::Signature::SIGNATURE_OK() and
1053 $rv != Module::Signature::SIGNATURE_MISSING()) {
1054 $CPAN::Frontend->mywarn(
1055 qq{\nSignature invalid for }.
1056 qq{distribution file. }.
1057 qq{Please investigate.\n\n}
1061 sprintf(qq{I'd recommend removing %s. Some error occurred }.
1062 qq{while checking its signature, so it could }.
1063 qq{be invalid. Maybe you have configured }.
1064 qq{your 'urllist' with a bad URL. Please check this }.
1065 qq{array with 'o conf urllist' and retry. Or }.
1066 qq{examine the distribution in a subshell. Try
1074 $self->{signature_verify} = CPAN::Distrostatus->new("NO");
1075 $CPAN::Frontend->mywarn(Text::Wrap::wrap("","",$wrap));
1076 $CPAN::Frontend->mysleep(5) if $CPAN::Frontend->can("mysleep");
1078 $self->{signature_verify} = CPAN::Distrostatus->new("YES");
1079 $self->debug("Module::Signature has verified") if $CPAN::DEBUG;
1082 $CPAN::Frontend->mywarn(qq{Package came without SIGNATURE\n\n});
1085 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
1090 #-> CPAN::Distribution::untar_me ;
1093 $self->{archived} = "tar";
1094 my $result = eval { $ct->untar() };
1096 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
1098 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- untar failed");
1102 # CPAN::Distribution::unzip_me ;
1105 $self->{archived} = "zip";
1107 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
1109 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- unzip failed");
1114 sub handle_singlefile {
1115 my($self,$local_file) = @_;
1117 if ( $local_file =~ /\.pm(\.(gz|Z))?(?!\n)\Z/ ) {
1118 $self->{archived} = "pm";
1119 } elsif ( $local_file =~ /\.patch(\.(gz|bz2))?(?!\n)\Z/ ) {
1120 $self->{archived} = "patch";
1122 $self->{archived} = "maybe_pl";
1125 my $to = File::Basename::basename($local_file);
1126 if ($to =~ s/\.(gz|Z)(?!\n)\Z//) {
1127 if (eval{CPAN::Tarzip->new($local_file)->gunzip($to)}) {
1128 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
1130 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- uncompressing failed");
1133 if (File::Copy::cp($local_file,".")) {
1134 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
1136 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- copying failed");
1142 #-> sub CPAN::Distribution::new ;
1144 my($class,%att) = @_;
1146 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
1148 my $this = { %att };
1149 return bless $this, $class;
1152 #-> sub CPAN::Distribution::look ;
1156 if ($^O eq 'MacOS') {
1157 $self->Mac::BuildTools::look;
1161 if ( $CPAN::Config->{'shell'} ) {
1162 $CPAN::Frontend->myprint(qq{
1163 Trying to open a subshell in the build directory...
1166 $CPAN::Frontend->myprint(qq{
1167 Your configuration does not define a value for subshells.
1168 Please define it with "o conf shell <your shell>"
1172 my $dist = $self->id;
1174 unless ($dir = $self->dir) {
1177 unless ($dir ||= $self->dir) {
1178 $CPAN::Frontend->mywarn(qq{
1179 Could not determine which directory to use for looking at $dist.
1183 my $pwd = CPAN::anycwd();
1184 $self->safe_chdir($dir);
1185 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
1187 local $ENV{CPAN_SHELL_LEVEL} = $ENV{CPAN_SHELL_LEVEL}||0;
1188 $ENV{CPAN_SHELL_LEVEL} += 1;
1189 my $shell = CPAN::HandleConfig->safe_quote($CPAN::Config->{'shell'});
1191 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
1193 : ($ENV{PERLLIB} || "");
1195 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
1196 $CPAN::META->set_perl5lib;
1197 local $ENV{MAKEFLAGS}; # protect us from outer make calls
1199 unless (system($shell) == 0) {
1201 $CPAN::Frontend->mywarn("Subprocess shell exit code $code\n");
1204 $self->safe_chdir($pwd);
1207 # CPAN::Distribution::cvs_import ;
1211 my $dir = $self->dir;
1213 my $package = $self->called_for;
1214 my $module = $CPAN::META->instance('CPAN::Module', $package);
1215 my $version = $module->cpan_version;
1217 my $userid = $self->cpan_userid;
1219 my $cvs_dir = (split /\//, $dir)[-1];
1220 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
1222 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
1224 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
1225 if ($cvs_site_perl) {
1226 $cvs_dir = "$cvs_site_perl/$cvs_dir";
1228 my $cvs_log = qq{"imported $package $version sources"};
1229 $version =~ s/\./_/g;
1230 # XXX cvs: undocumented and unclear how it was meant to work
1231 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
1232 "$cvs_dir", $userid, "v$version");
1234 my $pwd = CPAN::anycwd();
1235 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
1237 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
1239 $CPAN::Frontend->myprint(qq{@cmd\n});
1240 system(@cmd) == 0 or
1242 $CPAN::Frontend->mydie("cvs import failed");
1243 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
1246 #-> sub CPAN::Distribution::readme ;
1249 my($dist) = $self->id;
1250 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
1251 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
1254 File::Spec->catfile(
1255 $CPAN::Config->{keep_source_where},
1258 split(/\//,"$sans.readme"),
1260 $self->debug("Doing localize") if $CPAN::DEBUG;
1261 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
1263 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
1265 if ($^O eq 'MacOS') {
1266 Mac::BuildTools::launch_file($local_file);
1270 my $fh_pager = FileHandle->new;
1271 local($SIG{PIPE}) = "IGNORE";
1272 my $pager = $CPAN::Config->{'pager'} || "cat";
1273 $fh_pager->open("|$pager")
1274 or die "Could not open pager $pager\: $!";
1275 my $fh_readme = FileHandle->new;
1276 $fh_readme->open($local_file)
1277 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
1278 $CPAN::Frontend->myprint(qq{
1283 $fh_pager->print(<$fh_readme>);
1287 #-> sub CPAN::Distribution::verifyCHECKSUM ;
1288 sub verifyCHECKSUM {
1292 $self->{CHECKSUM_STATUS} ||= "";
1293 $self->{CHECKSUM_STATUS} eq "OK" and push @e, "Checksum was ok";
1294 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
1296 my($lc_want,$lc_file,@local,$basename);
1297 @local = split(/\//,$self->id);
1299 push @local, "CHECKSUMS";
1301 File::Spec->catfile($CPAN::Config->{keep_source_where},
1302 "authors", "id", @local);
1304 if (my $size = -s $lc_want) {
1305 $self->debug("lc_want[$lc_want]size[$size]") if $CPAN::DEBUG;
1306 if ($self->CHECKSUM_check_file($lc_want,1)) {
1307 return $self->{CHECKSUM_STATUS} = "OK";
1310 $lc_file = CPAN::FTP->localize("authors/id/@local",
1313 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
1314 $local[-1] .= ".gz";
1315 $lc_file = CPAN::FTP->localize("authors/id/@local",
1318 $lc_file =~ s/\.gz(?!\n)\Z//;
1319 eval{CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file)};
1324 if ($self->CHECKSUM_check_file($lc_file)) {
1325 return $self->{CHECKSUM_STATUS} = "OK";
1329 #-> sub CPAN::Distribution::SIG_check_file ;
1330 sub SIG_check_file {
1331 my($self,$chk_file) = @_;
1332 my $rv = eval { Module::Signature::_verify($chk_file) };
1334 if ($rv == Module::Signature::SIGNATURE_OK()) {
1335 $CPAN::Frontend->myprint("Signature for $chk_file ok\n");
1336 return $self->{SIG_STATUS} = "OK";
1338 $CPAN::Frontend->myprint(qq{\nSignature invalid for }.
1339 qq{distribution file. }.
1340 qq{Please investigate.\n\n}.
1342 $CPAN::META->instance(
1347 my $wrap = qq{I\'d recommend removing $chk_file. Its signature
1348 is invalid. Maybe you have configured your 'urllist' with
1349 a bad URL. Please check this array with 'o conf urllist', and
1352 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
1356 #-> sub CPAN::Distribution::CHECKSUM_check_file ;
1358 # sloppy is 1 when we have an old checksums file that maybe is good
1361 sub CHECKSUM_check_file {
1362 my($self,$chk_file,$sloppy) = @_;
1363 my($cksum,$file,$basename);
1366 $self->debug("chk_file[$chk_file]sloppy[$sloppy]") if $CPAN::DEBUG;
1367 my $check_sigs = CPAN::HandleConfig->prefs_lookup($self,
1370 if ($CPAN::META->has_inst("Module::Signature")) {
1371 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
1372 $self->SIG_check_file($chk_file);
1374 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
1378 $file = $self->{localfile};
1379 $basename = File::Basename::basename($file);
1380 my $fh = FileHandle->new;
1381 if (open $fh, $chk_file) {
1384 $eval =~ s/\015?\012/\n/g;
1386 my($compmt) = Safe->new();
1387 $cksum = $compmt->reval($eval);
1389 rename $chk_file, "$chk_file.bad";
1390 Carp::confess($@) if $@;
1393 Carp::carp "Could not open $chk_file for reading";
1396 if (! ref $cksum or ref $cksum ne "HASH") {
1397 $CPAN::Frontend->mywarn(qq{
1398 Warning: checksum file '$chk_file' broken.
1400 When trying to read that file I expected to get a hash reference
1401 for further processing, but got garbage instead.
1403 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed nonetheless?", "no");
1404 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
1405 $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS file broken";
1407 } elsif (exists $cksum->{$basename}{sha256}) {
1408 $self->debug("Found checksum for $basename:" .
1409 "$cksum->{$basename}{sha256}\n") if $CPAN::DEBUG;
1413 my $eq = $self->eq_CHECKSUM($fh,$cksum->{$basename}{sha256});
1415 $fh = CPAN::Tarzip->TIEHANDLE($file);
1418 my $dg = Digest::SHA->new(256);
1421 while ($fh->READ($ref, 4096) > 0) {
1424 my $hexdigest = $dg->hexdigest;
1425 $eq += $hexdigest eq $cksum->{$basename}{'sha256-ungz'};
1429 $CPAN::Frontend->myprint("Checksum for $file ok\n");
1430 return $self->{CHECKSUM_STATUS} = "OK";
1432 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
1433 qq{distribution file. }.
1434 qq{Please investigate.\n\n}.
1436 $CPAN::META->instance(
1441 my $wrap = qq{I\'d recommend removing $file. Its
1442 checksum is incorrect. Maybe you have configured your 'urllist' with
1443 a bad URL. Please check this array with 'o conf urllist', and
1446 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
1448 # former versions just returned here but this seems a
1449 # serious threat that deserves a die
1451 # $CPAN::Frontend->myprint("\n\n");
1455 # close $fh if fileno($fh);
1458 unless ($self->{CHECKSUM_STATUS}) {
1459 $CPAN::Frontend->mywarn(qq{
1460 Warning: No checksum for $basename in $chk_file.
1462 The cause for this may be that the file is very new and the checksum
1463 has not yet been calculated, but it may also be that something is
1464 going awry right now.
1466 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed?", "yes");
1467 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
1469 $self->{CHECKSUM_STATUS} = "NIL -- distro not in CHECKSUMS file";
1474 #-> sub CPAN::Distribution::eq_CHECKSUM ;
1476 my($self,$fh,$expect) = @_;
1477 if ($CPAN::META->has_inst("Digest::SHA")) {
1478 my $dg = Digest::SHA->new(256);
1480 while (read($fh, $data, 4096)) {
1483 my $hexdigest = $dg->hexdigest;
1484 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
1485 return $hexdigest eq $expect;
1490 #-> sub CPAN::Distribution::force ;
1492 # Both CPAN::Modules and CPAN::Distributions know if "force" is in
1493 # effect by autoinspection, not by inspecting a global variable. One
1494 # of the reason why this was chosen to work that way was the treatment
1495 # of dependencies. They should not automatically inherit the force
1496 # status. But this has the downside that ^C and die() will return to
1497 # the prompt but will not be able to reset the force_update
1498 # attributes. We try to correct for it currently in the read_metadata
1499 # routine, and immediately before we check for a Signal. I hope this
1500 # works out in one of v1.57_53ff
1502 # "Force get forgets previous error conditions"
1504 #-> sub CPAN::Distribution::fforce ;
1506 my($self, $method) = @_;
1507 $self->force($method,1);
1510 #-> sub CPAN::Distribution::force ;
1512 my($self, $method,$fforce) = @_;
1530 "prereq_pm_detected",
1544 my $methodmatch = 0;
1546 PHASE: for my $phase (qw(unknown get make test install)) { # order matters
1547 $methodmatch = 1 if $fforce || $phase eq $method;
1548 next unless $methodmatch;
1549 ATTRIBUTE: for my $att (@{$phase_map{$phase}}) {
1550 if ($phase eq "get") {
1551 if (substr($self->id,-1,1) eq "."
1552 && $att =~ /(unwrapped|build_dir|archived)/ ) {
1553 # cannot be undone for local distros
1556 if ($att eq "build_dir"
1557 && $self->{build_dir}
1558 && $CPAN::META->{is_tested}
1560 delete $CPAN::META->{is_tested}{$self->{build_dir}};
1562 } elsif ($phase eq "test") {
1563 if ($att eq "make_test"
1564 && $self->{make_test}
1565 && $self->{make_test}{COMMANDID}
1566 && $self->{make_test}{COMMANDID} == $CPAN::CurrentCommandId
1568 # endless loop too likely
1572 delete $self->{$att};
1573 if ($ldebug || $CPAN::DEBUG) {
1574 # local $CPAN::DEBUG = 16; # Distribution
1575 CPAN->debug(sprintf "id[%s]phase[%s]att[%s]", $self->id, $phase, $att);
1579 if ($method && $method =~ /make|test|install/) {
1580 $self->{force_update} = 1; # name should probably have been force_install
1584 #-> sub CPAN::Distribution::notest ;
1586 my($self, $method) = @_;
1587 # $CPAN::Frontend->mywarn("XDEBUG: set notest for $self $method");
1588 $self->{"notest"}++; # name should probably have been force_install
1591 #-> sub CPAN::Distribution::unnotest ;
1594 # warn "XDEBUG: deleting notest";
1595 delete $self->{notest};
1598 #-> sub CPAN::Distribution::unforce ;
1601 delete $self->{force_update};
1604 #-> sub CPAN::Distribution::isa_perl ;
1607 my $file = File::Basename::basename($self->id);
1608 if ($file =~ m{ ^ perl
1617 \.tar[._-](?:gz|bz2)
1621 } elsif ($self->cpan_comment
1623 $self->cpan_comment =~ /isa_perl\(.+?\)/) {
1629 #-> sub CPAN::Distribution::perl ;
1634 carp __PACKAGE__ . "::perl was called without parameters.";
1636 return CPAN::HandleConfig->safe_quote($CPAN::Perl);
1640 #-> sub CPAN::Distribution::make ;
1643 if (my $goto = $self->prefs->{goto}) {
1644 return $self->goto($goto);
1646 my $make = $self->{modulebuild} ? "Build" : "make";
1647 # Emergency brake if they said install Pippi and get newest perl
1648 if ($self->isa_perl) {
1650 $self->called_for ne $self->id &&
1651 ! $self->{force_update}
1653 # if we die here, we break bundles
1656 qq{The most recent version "%s" of the module "%s"
1657 is part of the perl-%s distribution. To install that, you need to run
1658 force install %s --or--
1661 $CPAN::META->instance(
1670 $self->{make} = CPAN::Distrostatus->new("NO isa perl");
1671 $CPAN::Frontend->mysleep(1);
1675 $CPAN::Frontend->myprint(sprintf "Running %s for %s\n", $make, $self->id);
1677 return if $self->prefs->{disabled} && ! $self->{force_update};
1678 if ($self->{configure_requires_later}) {
1681 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
1683 : ($ENV{PERLLIB} || "");
1684 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
1685 $CPAN::META->set_perl5lib;
1686 local $ENV{MAKEFLAGS}; # protect us from outer make calls
1688 if ($CPAN::Signal) {
1689 delete $self->{force_update};
1696 if (!$self->{archived} || $self->{archived} eq "NO") {
1697 push @e, "Is neither a tar nor a zip archive.";
1700 if (!$self->{unwrapped}
1702 UNIVERSAL::can($self->{unwrapped},"failed") ?
1703 $self->{unwrapped}->failed :
1704 $self->{unwrapped} =~ /^NO/
1706 push @e, "Had problems unarchiving. Please build manually";
1709 unless ($self->{force_update}) {
1710 exists $self->{signature_verify} and
1712 UNIVERSAL::can($self->{signature_verify},"failed") ?
1713 $self->{signature_verify}->failed :
1714 $self->{signature_verify} =~ /^NO/
1716 and push @e, "Did not pass the signature test.";
1719 if (exists $self->{writemakefile} &&
1721 UNIVERSAL::can($self->{writemakefile},"failed") ?
1722 $self->{writemakefile}->failed :
1723 $self->{writemakefile} =~ /^NO/
1725 # XXX maybe a retry would be in order?
1726 my $err = UNIVERSAL::can($self->{writemakefile},"text") ?
1727 $self->{writemakefile}->text :
1728 $self->{writemakefile};
1729 $err =~ s/^NO\s*(--\s+)?//;
1730 $err ||= "Had some problem writing Makefile";
1731 $err .= ", won't make";
1735 if (defined $self->{make}) {
1736 if (UNIVERSAL::can($self->{make},"failed") ?
1737 $self->{make}->failed :
1738 $self->{make} =~ /^NO/) {
1739 if ($self->{force_update}) {
1740 # Trying an already failed 'make' (unless somebody else blocks)
1742 # introduced for turning recursion detection into a distrostatus
1743 my $error = length $self->{make}>3
1744 ? substr($self->{make},3) : "Unknown error";
1745 $CPAN::Frontend->mywarn("Could not make: $error\n");
1746 $self->store_persistent_state;
1750 push @e, "Has already been made";
1751 my $wait_for_prereqs = eval { $self->satisfy_requires };
1752 return 1 if $wait_for_prereqs; # tells queuerunner to continue
1753 return $self->goodbye($@) if $@; # tells queuerunner to stop
1757 my $later = $self->{later} || $self->{configure_requires_later};
1758 if ($later) { # see also undelay
1764 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
1765 $builddir = $self->dir or
1766 $CPAN::Frontend->mydie("PANIC: Cannot determine build directory\n");
1767 unless (chdir $builddir) {
1768 push @e, "Couldn't chdir to '$builddir': $!";
1770 $CPAN::Frontend->mywarn(join "", map {" $_\n"} @e) and return if @e;
1772 if ($CPAN::Signal) {
1773 delete $self->{force_update};
1776 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
1777 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
1779 if ($^O eq 'MacOS') {
1780 Mac::BuildTools::make($self);
1785 while (my($k,$v) = each %ENV) {
1786 next unless defined $v;
1792 if ($self->prefs->{pl}) {
1793 $pl_commandline = $self->prefs->{pl}{commandline};
1795 if ($pl_commandline) {
1796 $system = $pl_commandline;
1798 } elsif ($self->{'configure'}) {
1799 $system = $self->{'configure'};
1800 } elsif ($self->{modulebuild}) {
1801 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
1802 $system = "$perl Build.PL $CPAN::Config->{mbuildpl_arg}";
1804 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
1806 # This needs a handler that can be turned on or off:
1807 # $switch = "-MExtUtils::MakeMaker ".
1808 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
1810 my $makepl_arg = $self->_make_phase_arg("pl");
1811 $ENV{PERL5_CPAN_IS_EXECUTING} = File::Spec->catfile($self->{build_dir},
1813 $system = sprintf("%s%s Makefile.PL%s",
1815 $switch ? " $switch" : "",
1816 $makepl_arg ? " $makepl_arg" : "",
1820 if ($self->prefs->{pl}) {
1821 $pl_env = $self->prefs->{pl}{env};
1824 for my $e (keys %$pl_env) {
1825 $ENV{$e} = $pl_env->{$e};
1828 if (exists $self->{writemakefile}) {
1830 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
1831 my($ret,$pid,$output);
1834 if ($CPAN::Config->{inactivity_timeout}) {
1836 if ($Config::Config{d_alarm}
1838 $Config::Config{d_alarm} eq "define"
1842 $CPAN::Frontend->mywarn("Warning: you have configured the config ".
1843 "variable 'inactivity_timeout' to ".
1844 "'$CPAN::Config->{inactivity_timeout}'. But ".
1845 "on this machine the system call 'alarm' ".
1846 "isn't available. This means that we cannot ".
1847 "provide the feature of intercepting long ".
1848 "waiting code and will turn this feature off.\n"
1850 $CPAN::Config->{inactivity_timeout} = 0;
1853 if ($go_via_alarm) {
1854 if ( $self->_should_report('pl') ) {
1855 ($output, $ret) = CPAN::Reporter::record_command(
1857 $CPAN::Config->{inactivity_timeout},
1859 CPAN::Reporter::grade_PL( $self, $system, $output, $ret );
1863 alarm $CPAN::Config->{inactivity_timeout};
1864 local $SIG{CHLD}; # = sub { wait };
1865 if (defined($pid = fork)) {
1870 # note, this exec isn't necessary if
1871 # inactivity_timeout is 0. On the Mac I'd
1872 # suggest, we set it always to 0.
1876 $CPAN::Frontend->myprint("Cannot fork: $!");
1885 $CPAN::Frontend->myprint($err);
1886 $self->{writemakefile} = CPAN::Distrostatus->new("NO $err");
1888 $self->store_persistent_state;
1889 return $self->goodbye("$system -- TIMED OUT");
1893 if (my $expect_model = $self->_prefs_with_expect("pl")) {
1894 # XXX probably want to check _should_report here and warn
1895 # about not being able to use CPAN::Reporter with expect
1896 $ret = $self->_run_via_expect($system,'writemakefile',$expect_model);
1898 && $self->{writemakefile}
1899 && $self->{writemakefile}->failed) {
1904 elsif ( $self->_should_report('pl') ) {
1905 ($output, $ret) = CPAN::Reporter::record_command($system);
1906 CPAN::Reporter::grade_PL( $self, $system, $output, $ret );
1909 $ret = system($system);
1912 $self->{writemakefile} = CPAN::Distrostatus
1913 ->new("NO '$system' returned status $ret");
1914 $CPAN::Frontend->mywarn("Warning: No success on command[$system]\n");
1915 $self->store_persistent_state;
1916 return $self->goodbye("$system -- NOT OK");
1919 if (-f "Makefile" || -f "Build") {
1920 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
1921 delete $self->{make_clean}; # if cleaned before, enable next
1923 my $makefile = $self->{modulebuild} ? "Build" : "Makefile";
1924 my $why = "No '$makefile' created";
1925 $CPAN::Frontend->mywarn($why);
1926 $self->{writemakefile} = CPAN::Distrostatus
1927 ->new(qq{NO -- $why\n});
1928 $self->store_persistent_state;
1929 return $self->goodbye("$system -- NOT OK");
1932 if ($CPAN::Signal) {
1933 delete $self->{force_update};
1936 my $wait_for_prereqs = eval { $self->satisfy_requires };
1937 return 1 if $wait_for_prereqs; # tells queuerunner to continue
1938 return $self->goodbye($@) if $@; # tells queuerunner to stop
1939 if ($CPAN::Signal) {
1940 delete $self->{force_update};
1943 my $make_commandline;
1944 if ($self->prefs->{make}) {
1945 $make_commandline = $self->prefs->{make}{commandline};
1947 if ($make_commandline) {
1948 $system = $make_commandline;
1949 $ENV{PERL} = CPAN::find_perl();
1951 if ($self->{modulebuild}) {
1952 unless (-f "Build") {
1953 my $cwd = CPAN::anycwd();
1954 $CPAN::Frontend->mywarn("Alert: no Build file available for 'make $self->{id}'".
1955 " in cwd[$cwd]. Danger, Will Robinson!\n");
1956 $CPAN::Frontend->mysleep(5);
1958 $system = join " ", $self->_build_command(), $CPAN::Config->{mbuild_arg};
1960 $system = join " ", $self->_make_command(), $CPAN::Config->{make_arg};
1962 $system =~ s/\s+$//;
1963 my $make_arg = $self->_make_phase_arg("make");
1964 $system = sprintf("%s%s",
1966 $make_arg ? " $make_arg" : "",
1970 if ($self->prefs->{make}) {
1971 $make_env = $self->prefs->{make}{env};
1973 if ($make_env) { # overriding the local ENV of PL, not the outer
1974 # ENV, but unlikely to be a risk
1975 for my $e (keys %$make_env) {
1976 $ENV{$e} = $make_env->{$e};
1979 my $expect_model = $self->_prefs_with_expect("make");
1980 my $want_expect = 0;
1981 if ( $expect_model && @{$expect_model->{talk}} ) {
1982 my $can_expect = $CPAN::META->has_inst("Expect");
1986 $CPAN::Frontend->mywarn("Expect not installed, falling back to ".
1992 # XXX probably want to check _should_report here and
1993 # warn about not being able to use CPAN::Reporter with expect
1994 $system_ok = $self->_run_via_expect($system,'make',$expect_model) == 0;
1996 elsif ( $self->_should_report('make') ) {
1997 my ($output, $ret) = CPAN::Reporter::record_command($system);
1998 CPAN::Reporter::grade_make( $self, $system, $output, $ret );
1999 $system_ok = ! $ret;
2002 $system_ok = system($system) == 0;
2004 $self->introduce_myself;
2006 $CPAN::Frontend->myprint(" $system -- OK\n");
2007 $self->{make} = CPAN::Distrostatus->new("YES");
2009 $self->{writemakefile} ||= CPAN::Distrostatus->new("YES");
2010 $self->{make} = CPAN::Distrostatus->new("NO");
2011 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
2013 $self->store_persistent_state;
2016 # CPAN::Distribution::goodbye ;
2018 my($self,$goodbye) = @_;
2019 my $id = $self->pretty_id;
2020 $CPAN::Frontend->mywarn(" $id\n $goodbye\n");
2024 # CPAN::Distribution::_run_via_expect ;
2025 sub _run_via_expect {
2026 my($self,$system,$phase,$expect_model) = @_;
2027 CPAN->debug("system[$system]expect_model[$expect_model]") if $CPAN::DEBUG;
2028 if ($CPAN::META->has_inst("Expect")) {
2029 my $expo = Expect->new; # expo Expect object;
2030 $expo->spawn($system);
2031 $expect_model->{mode} ||= "deterministic";
2032 if ($expect_model->{mode} eq "deterministic") {
2033 return $self->_run_via_expect_deterministic($expo,$phase,$expect_model);
2034 } elsif ($expect_model->{mode} eq "anyorder") {
2035 return $self->_run_via_expect_anyorder($expo,$phase,$expect_model);
2037 die "Panic: Illegal expect mode: $expect_model->{mode}";
2040 $CPAN::Frontend->mywarn("Expect not installed, falling back to system()\n");
2041 return system($system);
2045 sub _run_via_expect_anyorder {
2046 my($self,$expo,$phase,$expect_model) = @_;
2047 my $timeout = $expect_model->{timeout} || 5;
2048 my $reuse = $expect_model->{reuse};
2049 my @expectacopy = @{$expect_model->{talk}}; # we trash it!
2051 my $timeout_start = time;
2053 my($eof,$ran_into_timeout);
2054 # XXX not up to the full power of expect. one could certainly
2055 # wrap all of the talk pairs into a single expect call and on
2056 # success tweak it and step ahead to the next question. The
2057 # current implementation unnecessarily limits itself to a
2059 my @match = $expo->expect(1,
2064 $ran_into_timeout++;
2071 $but .= $expo->clear_accum;
2074 return $expo->exitstatus();
2075 } elsif ($ran_into_timeout) {
2076 # warn "DEBUG: they are asking a question, but[$but]";
2077 for (my $i = 0; $i <= $#expectacopy; $i+=2) {
2078 my($next,$send) = @expectacopy[$i,$i+1];
2079 my $regex = eval "qr{$next}";
2080 # warn "DEBUG: will compare with regex[$regex].";
2081 if ($but =~ /$regex/) {
2082 # warn "DEBUG: will send send[$send]";
2084 # never allow reusing an QA pair unless they told us
2085 splice @expectacopy, $i, 2 unless $reuse;
2089 my $have_waited = time - $timeout_start;
2090 if ($have_waited < $timeout) {
2091 # warn "DEBUG: have_waited[$have_waited]timeout[$timeout]";
2094 my $why = "could not answer a question during the dialog";
2095 $CPAN::Frontend->mywarn("Failing: $why\n");
2097 CPAN::Distrostatus->new("NO $why");
2103 sub _run_via_expect_deterministic {
2104 my($self,$expo,$phase,$expect_model) = @_;
2105 my $ran_into_timeout;
2107 my $timeout = $expect_model->{timeout} || 15; # currently unsettable
2108 my $expecta = $expect_model->{talk};
2109 EXPECT: for (my $i = 0; $i <= $#$expecta; $i+=2) {
2110 my($re,$send) = @$expecta[$i,$i+1];
2111 CPAN->debug("timeout[$timeout]re[$re]") if $CPAN::DEBUG;
2112 my $regex = eval "qr{$re}";
2113 $expo->expect($timeout,
2115 my $but = $expo->clear_accum;
2116 $CPAN::Frontend->mywarn("EOF (maybe harmless)
2117 expected[$regex]\nbut[$but]\n\n");
2121 my $but = $expo->clear_accum;
2122 $CPAN::Frontend->mywarn("TIMEOUT
2123 expected[$regex]\nbut[$but]\n\n");
2124 $ran_into_timeout++;
2127 if ($ran_into_timeout) {
2128 # note that the caller expects 0 for success
2130 CPAN::Distrostatus->new("NO timeout during expect dialog");
2132 } elsif ($ran_into_eof) {
2138 return $expo->exitstatus();
2141 #-> CPAN::Distribution::_validate_distropref
2142 sub _validate_distropref {
2143 my($self,@args) = @_;
2145 $CPAN::META->has_inst("CPAN::Kwalify")
2147 $CPAN::META->has_inst("Kwalify")
2149 eval {CPAN::Kwalify::_validate("distroprefs",@args);};
2151 $CPAN::Frontend->mywarn($@);
2154 CPAN->debug("not validating '@args'") if $CPAN::DEBUG;
2158 #-> CPAN::Distribution::_find_prefs
2161 my $distroid = $self->pretty_id;
2162 #CPAN->debug("distroid[$distroid]") if $CPAN::DEBUG;
2163 my $prefs_dir = $CPAN::Config->{prefs_dir};
2164 return if $prefs_dir =~ /^\s*$/;
2165 eval { File::Path::mkpath($prefs_dir); };
2167 $CPAN::Frontend->mydie("Cannot create directory $prefs_dir");
2169 my $yaml_module = CPAN::_yaml_module();
2172 if ($CPAN::META->has_inst($yaml_module)) {
2173 $ext_map->{yml} = 'CPAN';
2176 if ($CPAN::META->has_inst("Data::Dumper")) {
2177 push @fallbacks, $ext_map->{dd} = 'Data::Dumper';
2179 if ($CPAN::META->has_inst("Storable")) {
2180 push @fallbacks, $ext_map->{st} = 'Storable';
2184 unless ($self->{have_complained_about_missing_yaml}++) {
2185 $CPAN::Frontend->mywarn("'$yaml_module' not installed, falling back ".
2186 "to @fallbacks to read prefs '$prefs_dir'\n");
2189 unless ($self->{have_complained_about_missing_yaml}++) {
2190 $CPAN::Frontend->mywarn("'$yaml_module' not installed, cannot ".
2191 "read prefs '$prefs_dir'\n");
2195 my $finder = CPAN::Distroprefs->find($prefs_dir, $ext_map);
2196 DIRENT: while (my $result = $finder->next) {
2197 if ($result->is_warning) {
2198 $CPAN::Frontend->mywarn($result->as_string);
2199 $CPAN::Frontend->mysleep(1);
2201 } elsif ($result->is_fatal) {
2202 $CPAN::Frontend->mydie($result->as_string);
2205 my @prefs = @{ $result->prefs };
2207 ELEMENT: for my $y (0..$#prefs) {
2208 my $pref = $prefs[$y];
2209 $self->_validate_distropref($pref->data, $result->abs, $y);
2211 # I don't know why we silently skip when there's no match, but
2212 # complain if there's an empty match hashref, and there's no
2213 # comment explaining why -- hdp, 2008-03-18
2214 unless ($pref->has_any_match) {
2218 unless ($pref->has_valid_subkeys) {
2219 $CPAN::Frontend->mydie(sprintf
2220 "Nonconforming .%s file '%s': " .
2221 "missing match/* subattribute. " .
2222 "Please remove, cannot continue.",
2223 $result->ext, $result->abs,
2229 distribution => $distroid,
2230 perl => \&CPAN::find_perl,
2231 perlconfig => \%Config::Config,
2232 module => sub { [ $self->containsmods ] },
2235 if ($pref->matches($arg)) {
2237 prefs => $pref->data,
2238 prefs_file => $result->abs,
2239 prefs_file_doc => $y,
2248 # CPAN::Distribution::prefs
2251 if (exists $self->{negative_prefs_cache}
2253 $self->{negative_prefs_cache} != $CPAN::CurrentCommandId
2255 delete $self->{negative_prefs_cache};
2256 delete $self->{prefs};
2258 if (exists $self->{prefs}) {
2259 return $self->{prefs}; # XXX comment out during debugging
2261 if ($CPAN::Config->{prefs_dir}) {
2262 CPAN->debug("prefs_dir[$CPAN::Config->{prefs_dir}]") if $CPAN::DEBUG;
2263 my $prefs = $self->_find_prefs();
2264 $prefs ||= ""; # avoid warning next line
2265 CPAN->debug("prefs[$prefs]") if $CPAN::DEBUG;
2267 for my $x (qw(prefs prefs_file prefs_file_doc)) {
2268 $self->{$x} = $prefs->{$x};
2272 File::Basename::basename($self->{prefs_file}),
2273 $self->{prefs_file_doc},
2275 my $filler1 = "_" x 22;
2276 my $filler2 = int(66 - length($bs))/2;
2277 $filler2 = 0 if $filler2 < 0;
2278 $filler2 = " " x $filler2;
2279 $CPAN::Frontend->myprint("
2280 $filler1 D i s t r o P r e f s $filler1
2281 $filler2 $bs $filler2
2283 $CPAN::Frontend->mysleep(1);
2284 return $self->{prefs};
2287 $self->{negative_prefs_cache} = $CPAN::CurrentCommandId;
2288 return $self->{prefs} = +{};
2291 # CPAN::Distribution::_make_phase_arg
2292 sub _make_phase_arg {
2293 my($self, $phase) = @_;
2294 my $_make_phase_arg;
2295 my $prefs = $self->prefs;
2298 && exists $prefs->{$phase}
2299 && exists $prefs->{$phase}{args}
2300 && $prefs->{$phase}{args}
2302 $_make_phase_arg = join(" ",
2303 map {CPAN::HandleConfig
2304 ->safe_quote($_)} @{$prefs->{$phase}{args}},
2308 # cpan[2]> o conf make[TAB]
2309 # make make_install_make_command
2310 # make_arg makepl_arg
2312 # cpan[2]> o conf mbuild[TAB]
2313 # mbuild_arg mbuild_install_build_command
2314 # mbuild_install_arg mbuildpl_arg
2316 my $mantra; # must switch make/mbuild here
2317 if ($self->{modulebuild}) {
2325 test => "_test_arg", # does not really exist but maybe
2326 # will some day and now protects
2327 # us from unini warnings
2328 install => "_install_arg",
2330 my $phase_underscore_meshup = $map{$phase};
2331 my $what = sprintf "%s%s", $mantra, $phase_underscore_meshup;
2333 $_make_phase_arg ||= $CPAN::Config->{$what};
2334 return $_make_phase_arg;
2337 # CPAN::Distribution::_make_command
2344 CPAN::HandleConfig->prefs_lookup($self,
2346 || $Config::Config{make}
2350 # Old style call, without object. Deprecated
2351 Carp::confess("CPAN::_make_command() used as function. Don't Do That.");
2354 CPAN::HandleConfig->prefs_lookup($self,q{make})
2355 || $CPAN::Config->{make}
2356 || $Config::Config{make}
2361 #-> sub CPAN::Distribution::follow_prereqs ;
2362 sub follow_prereqs {
2365 my(@prereq_tuples) = grep {$_->[0] ne "perl"} @_;
2366 return unless @prereq_tuples;
2367 my(@good_prereq_tuples);
2368 for my $p (@prereq_tuples) {
2369 # XXX watch out for foul ones
2370 push @good_prereq_tuples, $p;
2372 my $pretty_id = $self->pretty_id;
2374 b => "build_requires",
2378 my($filler1,$filler2,$filler3,$filler4);
2379 my $unsat = "Unsatisfied dependencies detected during";
2380 my $w = length($unsat) > length($pretty_id) ? length($unsat) : length($pretty_id);
2382 my $r = int(($w - length($unsat))/2);
2383 my $l = $w - length($unsat) - $r;
2384 $filler1 = "-"x4 . " "x$l;
2385 $filler2 = " "x$r . "-"x4 . "\n";
2388 my $r = int(($w - length($pretty_id))/2);
2389 my $l = $w - length($pretty_id) - $r;
2390 $filler3 = "-"x4 . " "x$l;
2391 $filler4 = " "x$r . "-"x4 . "\n";
2394 myprint("$filler1 $unsat $filler2".
2395 "$filler3 $pretty_id $filler4".
2396 join("", map {" $_->[0] \[$map{$_->[1]}]\n"} @good_prereq_tuples),
2399 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
2401 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
2402 my $answer = CPAN::Shell::colorable_makemaker_prompt(
2403 "Shall I follow them and prepend them to the queue
2404 of modules we are processing right now?", "yes");
2405 $follow = $answer =~ /^\s*y/i;
2407 my @prereq = map { $_=>[0] } @good_prereq_tuples;
2410 myprint(" Ignoring dependencies on modules @prereq\n");
2414 # color them as dirty
2415 for my $gp (@good_prereq_tuples) {
2416 # warn "calling color_cmd_tmps(0,1)";
2418 my $any = CPAN::Shell->expandany($p);
2419 $self->{$slot . "_for"}{$any->id}++;
2421 $any->color_cmd_tmps(0,2);
2423 $CPAN::Frontend->mywarn("Warning (maybe a bug): Cannot expand prereq '$p'\n");
2424 $CPAN::Frontend->mysleep(2);
2427 # queue them and re-queue yourself
2428 CPAN::Queue->jumpqueue({qmod => $id, reqtype => $self->{reqtype}},
2429 map {+{qmod=>$_->[0],reqtype=>$_->[1]}} reverse @good_prereq_tuples);
2430 $self->{$slot} = "Delayed until after prerequisites";
2431 return 1; # signal success to the queuerunner
2436 sub _feature_depends {
2438 my $meta_yml = $self->parse_meta_yml();
2439 my $optf = $meta_yml->{optional_features} or return;
2440 if (!ref $optf or ref $optf ne "HASH"){
2441 $CPAN::Frontend->mywarn("The content of optional_features is not a HASH reference. Cannot use it.\n");
2444 my $wantf = $self->prefs->{features} or return;
2445 if (!ref $wantf or ref $wantf ne "ARRAY"){
2446 $CPAN::Frontend->mywarn("The content of 'features' is not an ARRAY reference. Cannot use it.\n");
2450 for my $wf (@$wantf) {
2451 if (my $f = $optf->{$wf}) {
2452 $CPAN::Frontend->myprint("Found the demanded feature '$wf' that ".
2453 "is accompanied by this description:\n".
2457 # configure_requires currently not in the spec, unlikely to be useful anyway
2458 for my $reqtype (qw(configure_requires build_requires requires)) {
2459 my $reqhash = $f->{$reqtype} or next;
2460 while (my($k,$v) = each %$reqhash) {
2461 $dep->{$reqtype}{$k} = $v;
2465 $CPAN::Frontend->mywarn("The demanded feature '$wf' was not ".
2466 "found in the META.yml file".
2474 #-> sub CPAN::Distribution::unsat_prereq ;
2475 # return ([Foo,"r"],[Bar,"b"]) for normal modules
2476 # return ([perl=>5.008]) if we need a newer perl than we are running under
2477 # (sorry for the inconsistency, it was an accident)
2479 my($self,$slot) = @_;
2480 my(%merged,$prereq_pm);
2481 my $prefs_depends = $self->prefs->{depends}||{};
2482 my $feature_depends = $self->_feature_depends();
2483 if ($slot eq "configure_requires_later") {
2484 my $meta_yml = $self->parse_meta_yml();
2485 if (defined $meta_yml && (! ref $meta_yml || ref $meta_yml ne "HASH")) {
2486 $CPAN::Frontend->mywarn("The content of META.yml is defined but not a HASH reference. Cannot use it.\n");
2490 %{$meta_yml->{configure_requires}||{}},
2491 %{$prefs_depends->{configure_requires}||{}},
2492 %{$feature_depends->{configure_requires}||{}},
2494 $prereq_pm = {}; # configure_requires defined as "b"
2495 } elsif ($slot eq "later") {
2496 my $prereq_pm_0 = $self->prereq_pm || {};
2497 for my $reqtype (qw(requires build_requires)) {
2498 $prereq_pm->{$reqtype} = {%{$prereq_pm_0->{$reqtype}||{}}}; # copy to not pollute it
2499 for my $dep ($prefs_depends,$feature_depends) {
2500 for my $k (keys %{$dep->{$reqtype}||{}}) {
2501 $prereq_pm->{$reqtype}{$k} = $dep->{$reqtype}{$k};
2505 %merged = (%{$prereq_pm->{requires}||{}},%{$prereq_pm->{build_requires}||{}});
2507 die "Panic: illegal slot '$slot'";
2510 my @merged = %merged;
2511 CPAN->debug("all merged_prereqs[@merged]") if $CPAN::DEBUG;
2512 NEED: while (my($need_module, $need_version) = each %merged) {
2513 my($available_version,$available_file,$nmo);
2514 if ($need_module eq "perl") {
2515 $available_version = $];
2516 $available_file = CPAN::find_perl();
2518 $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
2519 next if $nmo->uptodate;
2520 $available_file = $nmo->available_file;
2522 # if they have not specified a version, we accept any installed one
2523 if (defined $available_file
2524 and ( # a few quick shortcurcuits
2525 not defined $need_version
2526 or $need_version eq '0' # "==" would trigger warning when not numeric
2527 or $need_version eq "undef"
2532 $available_version = $nmo->available_version;
2535 # We only want to install prereqs if either they're not installed
2536 # or if the installed version is too old. We cannot omit this
2537 # check, because if 'force' is in effect, nobody else will check.
2538 if (defined $available_file) {
2539 my $fulfills_all_version_rqs = $self->_fulfills_all_version_rqs
2540 ($need_module,$available_file,$available_version,$need_version);
2541 next NEED if $fulfills_all_version_rqs;
2544 if ($need_module eq "perl") {
2545 return ["perl", $need_version];
2547 $self->{sponsored_mods}{$need_module} ||= 0;
2548 CPAN->debug("need_module[$need_module]s/s/n[$self->{sponsored_mods}{$need_module}]") if $CPAN::DEBUG;
2549 if (my $sponsoring = $self->{sponsored_mods}{$need_module}++) {
2550 # We have already sponsored it and for some reason it's still
2551 # not available. So we do ... what??
2553 # if we push it again, we have a potential infinite loop
2555 # The following "next" was a very problematic construct.
2556 # It helped a lot but broke some day and had to be
2559 # We must be able to deal with modules that come again and
2560 # again as a prereq and have themselves prereqs and the
2561 # queue becomes long but finally we would find the correct
2562 # order. The RecursiveDependency check should trigger a
2563 # die when it's becoming too weird. Unfortunately removing
2564 # this next breaks many other things.
2566 # The bug that brought this up is described in Todo under
2567 # "5.8.9 cannot install Compress::Zlib"
2569 # next; # this is the next that had to go away
2571 # The following "next NEED" are fine and the error message
2572 # explains well what is going on. For example when the DBI
2573 # fails and consequently DBD::SQLite fails and now we are
2574 # processing CPAN::SQLite. Then we must have a "next" for
2575 # DBD::SQLite. How can we get it and how can we identify
2576 # all other cases we must identify?
2578 my $do = $nmo->distribution;
2579 next NEED unless $do; # not on CPAN
2580 if (CPAN::Version->vcmp($need_version, $nmo->ro->{CPAN_VERSION}) > 0){
2581 $CPAN::Frontend->mywarn("Warning: Prerequisite ".
2582 "'$need_module => $need_version' ".
2583 "for '$self->{ID}' seems ".
2584 "not available according to the indices\n"
2588 NOSAYER: for my $nosayer (
2597 if ($do->{$nosayer}) {
2598 my $selfid = $self->pretty_id;
2599 my $did = $do->pretty_id;
2600 if (UNIVERSAL::can($do->{$nosayer},"failed") ?
2601 $do->{$nosayer}->failed :
2602 $do->{$nosayer} =~ /^NO/) {
2603 if ($nosayer eq "make_test"
2605 $do->{make_test}{COMMANDID} != $CPAN::CurrentCommandId
2609 $CPAN::Frontend->mywarn("Warning: Prerequisite ".
2610 "'$need_module => $need_version' ".
2611 "for '$selfid' failed when ".
2612 "processing '$did' with ".
2613 "'$nosayer => $do->{$nosayer}'. Continuing, ".
2614 "but chances to succeed are limited.\n"
2616 $CPAN::Frontend->mysleep($sponsoring/10);
2618 } else { # the other guy succeeded
2619 if ($nosayer =~ /^(install|make_test)$/) {
2621 # DMAKI/DateTime-Calendar-Chinese-0.05.tar.gz
2622 # in 2007-03 for 'make install'
2623 # and 2008-04: #30464 (for 'make test')
2624 $CPAN::Frontend->mywarn("Warning: Prerequisite ".
2625 "'$need_module => $need_version' ".
2626 "for '$selfid' already built ".
2627 "but the result looks suspicious. ".
2628 "Skipping another build attempt, ".
2629 "to prevent looping endlessly.\n"
2637 my $needed_as = exists $prereq_pm->{requires}{$need_module} ? "r" : "b";
2638 push @need, [$need_module,$needed_as];
2640 my @unfolded = map { "[".join(",",@$_)."]" } @need;
2641 CPAN->debug("returning from unsat_prereq[@unfolded]") if $CPAN::DEBUG;
2645 sub _fulfills_all_version_rqs {
2646 my($self,$need_module,$available_file,$available_version,$need_version) = @_;
2647 my(@all_requirements) = split /\s*,\s*/, $need_version;
2650 RQ: for my $rq (@all_requirements) {
2651 if ($rq =~ s|>=\s*||) {
2652 } elsif ($rq =~ s|>\s*||) {
2654 if (CPAN::Version->vgt($available_version,$rq)) {
2658 } elsif ($rq =~ s|!=\s*||) {
2660 if (CPAN::Version->vcmp($available_version,$rq)) {
2666 } elsif ($rq =~ m|<=?\s*|) {
2668 $CPAN::Frontend->mywarn("Downgrading not supported (rq[$rq])\n");
2672 if (! CPAN::Version->vgt($rq, $available_version)) {
2675 CPAN->debug(sprintf("need_module[%s]available_file[%s]".
2676 "available_version[%s]rq[%s]ok[%d]",
2680 CPAN::Version->readable($rq),
2684 return $ok == @all_requirements;
2687 #-> sub CPAN::Distribution::read_yaml ;
2690 return $self->{yaml_content} if exists $self->{yaml_content};
2692 unless ($build_dir = $self->{build_dir}) {
2693 # maybe permission on build_dir was missing
2694 $CPAN::Frontend->mywarn("Warning: cannot determine META.yml without a build_dir.\n");
2697 my $yaml = File::Spec->catfile($build_dir,"META.yml");
2698 $self->debug("yaml[$yaml]") if $CPAN::DEBUG;
2699 return unless -f $yaml;
2700 eval { $self->{yaml_content} = CPAN->_yaml_loadfile($yaml)->[0]; };
2702 $CPAN::Frontend->mywarn("Could not read ".
2703 "'$yaml'. Falling back to other ".
2704 "methods to determine prerequisites\n");
2705 return $self->{yaml_content} = undef; # if we die, then we
2706 # cannot read YAML's own
2709 # not "authoritative"
2710 for ($self->{yaml_content}) {
2711 if (defined $_ && (! ref $_ || ref $_ ne "HASH")) {
2712 $CPAN::Frontend->mywarn("META.yml does not seem to be conforming, cannot use it.\n");
2713 $self->{yaml_content} = +{};
2716 if (not exists $self->{yaml_content}{dynamic_config}
2717 or $self->{yaml_content}{dynamic_config}
2719 $self->{yaml_content} = undef;
2721 $self->debug(sprintf "yaml_content[%s]", $self->{yaml_content} || "UNDEF")
2723 return $self->{yaml_content};
2726 #-> sub CPAN::Distribution::prereq_pm ;
2729 $self->{prereq_pm_detected} ||= 0;
2730 CPAN->debug("ID[$self->{ID}]prereq_pm_detected[$self->{prereq_pm_detected}]") if $CPAN::DEBUG;
2731 return $self->{prereq_pm} if $self->{prereq_pm_detected};
2732 return unless $self->{writemakefile} # no need to have succeeded
2733 # but we must have run it
2734 || $self->{modulebuild};
2735 unless ($self->{build_dir}) {
2738 CPAN->debug(sprintf "writemakefile[%s]modulebuild[%s]",
2739 $self->{writemakefile}||"",
2740 $self->{modulebuild}||"",
2743 if (my $yaml = $self->read_yaml) { # often dynamic_config prevents a result here
2744 $req = $yaml->{requires} || {};
2745 $breq = $yaml->{build_requires} || {};
2746 undef $req unless ref $req eq "HASH" && %$req;
2748 if ($yaml->{generated_by} &&
2749 $yaml->{generated_by} =~ /ExtUtils::MakeMaker version ([\d\._]+)/) {
2750 my $eummv = do { local $^W = 0; $1+0; };
2751 if ($eummv < 6.2501) {
2752 # thanks to Slaven for digging that out: MM before
2753 # that could be wrong because it could reflect a
2760 while (my($k,$v) = each %{$req||{}}) {
2763 } elsif ($k =~ /[A-Za-z]/ &&
2765 $CPAN::META->exists("CPAN::Module",$v)
2767 $CPAN::Frontend->mywarn("Suspicious key-value pair in META.yml's ".
2768 "requires hash: $k => $v; I'll take both ".
2769 "key and value as a module name\n");
2770 $CPAN::Frontend->mysleep(1);
2776 $req = $areq if $do_replace;
2779 unless ($req || $breq) {
2781 unless ( $build_dir = $self->{build_dir} ) {
2784 my $makefile = File::Spec->catfile($build_dir,"Makefile");
2788 $fh = FileHandle->new("<$makefile\0")) {
2789 CPAN->debug("Getting prereq from Makefile") if $CPAN::DEBUG;
2792 last if /MakeMaker post_initialize section/;
2794 \s+PREREQ_PM\s+=>\s+(.+)
2797 # warn "Found prereq expr[$p]";
2799 # Regexp modified by A.Speer to remember actual version of file
2800 # PREREQ_PM hash key wants, then add to
2801 while ( $p =~ m/(?:\s)([\w\:]+)=>(q\[.*?\]|undef),?/g ) {
2802 # In case a prereq is mentioned twice, complain.
2803 if ( defined $req->{$1} ) {
2804 warn "Warning: PREREQ_PM mentions $1 more than once, ".
2805 "last mention wins";
2807 my($m,$n) = ($1,$2);
2808 if ($n =~ /^q\[(.*?)\]$/) {
2817 unless ($req || $breq) {
2818 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
2819 my $buildfile = File::Spec->catfile($build_dir,"Build");
2820 if (-f $buildfile) {
2821 CPAN->debug("Found '$buildfile'") if $CPAN::DEBUG;
2822 my $build_prereqs = File::Spec->catfile($build_dir,"_build","prereqs");
2823 if (-f $build_prereqs) {
2824 CPAN->debug("Getting prerequisites from '$build_prereqs'") if $CPAN::DEBUG;
2825 my $content = do { local *FH;
2826 open FH, $build_prereqs
2827 or $CPAN::Frontend->mydie("Could not open ".
2828 "'$build_prereqs': $!");
2832 my $bphash = eval $content;
2835 $req = $bphash->{requires} || +{};
2836 $breq = $bphash->{build_requires} || +{};
2842 && ! -f "Makefile.PL"
2843 && ! exists $req->{"Module::Build"}
2844 && ! $CPAN::META->has_inst("Module::Build")) {
2845 $CPAN::Frontend->mywarn(" Warning: CPAN.pm discovered Module::Build as ".
2846 "undeclared prerequisite.\n".
2847 " Adding it now as such.\n"
2849 $CPAN::Frontend->mysleep(5);
2850 $req->{"Module::Build"} = 0;
2851 delete $self->{writemakefile};
2853 if ($req || $breq) {
2854 $self->{prereq_pm_detected}++;
2855 return $self->{prereq_pm} = { requires => $req, build_requires => $breq };
2859 #-> sub CPAN::Distribution::test ;
2862 if (my $goto = $self->prefs->{goto}) {
2863 return $self->goto($goto);
2866 return if $self->prefs->{disabled} && ! $self->{force_update};
2867 if ($CPAN::Signal) {
2868 delete $self->{force_update};
2871 # warn "XDEBUG: checking for notest: $self->{notest} $self";
2872 if ($self->{notest}) {
2873 $CPAN::Frontend->myprint("Skipping test because of notest pragma\n");
2877 my $make = $self->{modulebuild} ? "Build" : "make";
2879 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
2881 : ($ENV{PERLLIB} || "");
2883 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
2884 $CPAN::META->set_perl5lib;
2885 local $ENV{MAKEFLAGS}; # protect us from outer make calls
2887 $CPAN::Frontend->myprint("Running $make test\n");
2891 if ($self->{make} or $self->{later}) {
2895 "Make had some problems, won't test";
2898 exists $self->{make} and
2900 UNIVERSAL::can($self->{make},"failed") ?
2901 $self->{make}->failed :
2902 $self->{make} =~ /^NO/
2903 ) and push @e, "Can't test without successful make";
2904 $self->{badtestcnt} ||= 0;
2905 if ($self->{badtestcnt} > 0) {
2906 require Data::Dumper;
2907 CPAN->debug(sprintf "NOREPEAT[%s]", Data::Dumper::Dumper($self)) if $CPAN::DEBUG;
2908 push @e, "Won't repeat unsuccessful test during this command";
2911 push @e, $self->{later} if $self->{later};
2912 push @e, $self->{configure_requires_later} if $self->{configure_requires_later};
2914 if (exists $self->{build_dir}) {
2915 if (exists $self->{make_test}) {
2917 UNIVERSAL::can($self->{make_test},"failed") ?
2918 $self->{make_test}->failed :
2919 $self->{make_test} =~ /^NO/
2922 UNIVERSAL::can($self->{make_test},"commandid")
2924 $self->{make_test}->commandid == $CPAN::CurrentCommandId
2926 push @e, "Has already been tested within this command";
2929 push @e, "Has already been tested successfully";
2930 # if global "is_tested" has been cleared, we need to mark this to
2931 # be added to PERL5LIB if not already installed
2932 if ($self->tested_ok_but_not_installed) {
2933 $CPAN::META->is_tested($self->{build_dir},$self->{make_test}{TIME});
2938 push @e, "Has no own directory";
2940 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
2941 unless (chdir $self->{build_dir}) {
2942 push @e, "Couldn't chdir to '$self->{build_dir}': $!";
2944 $CPAN::Frontend->mywarn(join "", map {" $_\n"} @e) and return if @e;
2946 $self->debug("Changed directory to $self->{build_dir}")
2949 if ($^O eq 'MacOS') {
2950 Mac::BuildTools::make_test($self);
2954 if ($self->{modulebuild}) {
2955 my $thm = CPAN::Shell->expand("Module","Test::Harness");
2956 my $v = $thm->inst_version;
2957 if (CPAN::Version->vlt($v,2.62)) {
2958 # XXX Eric Wilhelm reported this as a bug: klapperl:
2959 # Test::Harness 3.0 self-tests, so that should be 'unless
2960 # installing Test::Harness'
2961 unless ($self->id eq $thm->distribution->id) {
2962 $CPAN::Frontend->mywarn(qq{The version of your Test::Harness is only
2963 '$v', you need at least '2.62'. Please upgrade your Test::Harness.\n});
2964 $self->{make_test} = CPAN::Distrostatus->new("NO Test::Harness too old");
2970 if ( ! $self->{force_update} ) {
2971 # bypass actual tests if "trust_test_report_history" and have a report
2972 my $have_tested_fcn;
2973 if ( $CPAN::Config->{trust_test_report_history}
2974 && $CPAN::META->has_inst("CPAN::Reporter::History")
2975 && ( $have_tested_fcn = CPAN::Reporter::History->can("have_tested" ))) {
2976 if ( my @reports = $have_tested_fcn->( dist => $self->base_id ) ) {
2977 # Do nothing if grade was DISCARD
2978 if ( $reports[-1]->{grade} =~ /^(?:PASS|UNKNOWN)$/ ) {
2979 $self->{make_test} = CPAN::Distrostatus->new("YES");
2980 # if global "is_tested" has been cleared, we need to mark this to
2981 # be added to PERL5LIB if not already installed
2982 if ($self->tested_ok_but_not_installed) {
2983 $CPAN::META->is_tested($self->{build_dir},$self->{make_test}{TIME});
2985 $CPAN::Frontend->myprint("Found prior test report -- OK\n");
2988 elsif ( $reports[-1]->{grade} =~ /^(?:FAIL|NA)$/ ) {
2989 $self->{make_test} = CPAN::Distrostatus->new("NO");
2990 $self->{badtestcnt}++;
2991 $CPAN::Frontend->mywarn("Found prior test report -- NOT OK\n");
2999 my $prefs_test = $self->prefs->{test};
3001 = exists $prefs_test->{commandline} ? $prefs_test->{commandline} : "") {
3002 $system = $commandline;
3003 $ENV{PERL} = CPAN::find_perl();
3004 } elsif ($self->{modulebuild}) {
3005 $system = sprintf "%s test", $self->_build_command();
3006 unless (-e "Build") {
3007 my $id = $self->pretty_id;
3008 $CPAN::Frontend->mywarn("Alert: no 'Build' file found while trying to test '$id'");
3011 $system = join " ", $self->_make_command(), "test";
3013 my $make_test_arg = $self->_make_phase_arg("test");
3014 $system = sprintf("%s%s",
3016 $make_test_arg ? " $make_test_arg" : "",
3020 while (my($k,$v) = each %ENV) {
3021 next unless defined $v;
3026 if ($self->prefs->{test}) {
3027 $test_env = $self->prefs->{test}{env};
3030 for my $e (keys %$test_env) {
3031 $ENV{$e} = $test_env->{$e};
3034 my $expect_model = $self->_prefs_with_expect("test");
3035 my $want_expect = 0;
3036 if ( $expect_model && @{$expect_model->{talk}} ) {
3037 my $can_expect = $CPAN::META->has_inst("Expect");
3041 $CPAN::Frontend->mywarn("Expect not installed, falling back to ".
3042 "testing without\n");
3046 if ($self->_should_report('test')) {
3047 $CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is currently ".
3048 "not supported when distroprefs specify ".
3049 "an interactive test\n");
3051 $tests_ok = $self->_run_via_expect($system,'test',$expect_model) == 0;
3052 } elsif ( $self->_should_report('test') ) {
3053 $tests_ok = CPAN::Reporter::test($self, $system);
3055 $tests_ok = system($system) == 0;
3057 $self->introduce_myself;
3062 # local $CPAN::DEBUG = 16; # Distribution
3063 for my $m (keys %{$self->{sponsored_mods}}) {
3064 next unless $self->{sponsored_mods}{$m} > 0;
3065 my $m_obj = CPAN::Shell->expand("Module",$m) or next;
3066 # XXX we need available_version which reflects
3067 # $ENV{PERL5LIB} so that already tested but not yet
3068 # installed modules are counted.
3069 my $available_version = $m_obj->available_version;
3070 my $available_file = $m_obj->available_file;
3071 if ($available_version &&
3072 !CPAN::Version->vlt($available_version,$self->{prereq_pm}{$m})
3074 CPAN->debug("m[$m] good enough available_version[$available_version]")
3076 } elsif ($available_file
3078 !$self->{prereq_pm}{$m}
3080 $self->{prereq_pm}{$m} == 0
3083 # lex Class::Accessor::Chained::Fast which has no $VERSION
3084 CPAN->debug("m[$m] have available_file[$available_file]")
3092 my $which = join ",", @prereq;
3093 my $but = $cnt == 1 ? "one dependency not OK ($which)" :
3094 "$cnt dependencies missing ($which)";
3095 $CPAN::Frontend->mywarn("Tests succeeded but $but\n");
3096 $self->{make_test} = CPAN::Distrostatus->new("NO $but");
3097 $self->store_persistent_state;
3098 return $self->goodbye("[dependencies] -- NA");
3102 $CPAN::Frontend->myprint(" $system -- OK\n");
3103 $self->{make_test} = CPAN::Distrostatus->new("YES");
3104 $CPAN::META->is_tested($self->{build_dir},$self->{make_test}{TIME});
3105 # probably impossible to need the next line because badtestcnt
3106 # has a lifespan of one command
3107 delete $self->{badtestcnt};
3109 $self->{make_test} = CPAN::Distrostatus->new("NO");
3110 $self->{badtestcnt}++;
3111 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
3112 CPAN::Shell->optprint
3115 ("//hint// to see the cpan-testers results for installing this module, try:
3119 $self->store_persistent_state;
3122 sub _prefs_with_expect {
3123 my($self,$where) = @_;
3124 return unless my $prefs = $self->prefs;
3125 return unless my $where_prefs = $prefs->{$where};
3126 if ($where_prefs->{expect}) {
3128 mode => "deterministic",
3130 talk => $where_prefs->{expect},
3132 } elsif ($where_prefs->{"eexpect"}) {
3133 return $where_prefs->{"eexpect"};
3138 #-> sub CPAN::Distribution::clean ;
3141 my $make = $self->{modulebuild} ? "Build" : "make";
3142 $CPAN::Frontend->myprint("Running $make clean\n");
3143 unless (exists $self->{archived}) {
3144 $CPAN::Frontend->mywarn("Distribution seems to have never been unzipped".
3145 "/untarred, nothing done\n");
3148 unless (exists $self->{build_dir}) {
3149 $CPAN::Frontend->mywarn("Distribution has no own directory, nothing to do.\n");
3152 if (exists $self->{writemakefile}
3153 and $self->{writemakefile}->failed
3155 $CPAN::Frontend->mywarn("No Makefile, don't know how to 'make clean'\n");
3160 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
3161 push @e, "make clean already called once";
3162 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3164 chdir $self->{build_dir} or
3165 Carp::confess("Couldn't chdir to $self->{build_dir}: $!");
3166 $self->debug("Changed directory to $self->{build_dir}") if $CPAN::DEBUG;
3168 if ($^O eq 'MacOS') {
3169 Mac::BuildTools::make_clean($self);
3174 if ($self->{modulebuild}) {
3175 unless (-f "Build") {
3176 my $cwd = CPAN::anycwd();
3177 $CPAN::Frontend->mywarn("Alert: no Build file available for 'clean $self->{id}".
3178 " in cwd[$cwd]. Danger, Will Robinson!");
3179 $CPAN::Frontend->mysleep(5);
3181 $system = sprintf "%s clean", $self->_build_command();
3183 $system = join " ", $self->_make_command(), "clean";
3185 my $system_ok = system($system) == 0;
3186 $self->introduce_myself;
3188 $CPAN::Frontend->myprint(" $system -- OK\n");
3192 # Jost Krieger pointed out that this "force" was wrong because
3193 # it has the effect that the next "install" on this distribution
3194 # will untar everything again. Instead we should bring the
3195 # object's state back to where it is after untarring.
3206 $self->{make_clean} = CPAN::Distrostatus->new("YES");
3209 # Hmmm, what to do if make clean failed?
3211 $self->{make_clean} = CPAN::Distrostatus->new("NO");
3212 $CPAN::Frontend->mywarn(qq{ $system -- NOT OK\n});
3214 # 2006-02-27: seems silly to me to force a make now
3215 # $self->force("make"); # so that this directory won't be used again
3218 $self->store_persistent_state;
3221 #-> sub CPAN::Distribution::goto ;
3223 my($self,$goto) = @_;
3224 $goto = $self->normalize($goto);
3226 "Goto '$goto' via prefs file '%s' doc %d",
3227 $self->{prefs_file},
3228 $self->{prefs_file_doc},
3230 $self->{unwrapped} = CPAN::Distrostatus->new("NO $why");
3231 # 2007-07-16 akoenig : Better than NA would be if we could inherit
3232 # the status of the $goto distro but given the exceptional nature
3233 # of 'goto' I feel reluctant to implement it
3234 my $goodbye_message = "[goto] -- NA $why";
3235 $self->goodbye($goodbye_message);
3237 # inject into the queue
3239 CPAN::Queue->delete($self->id);
3240 CPAN::Queue->jumpqueue({qmod => $goto, reqtype => $self->{reqtype}});
3242 # and run where we left off
3244 my($method) = (caller(1))[3];
3245 CPAN->instance("CPAN::Distribution",$goto)->$method();
3246 CPAN::Queue->delete_first($goto);
3249 #-> sub CPAN::Distribution::install ;
3252 if (my $goto = $self->prefs->{goto}) {
3253 return $self->goto($goto);
3255 unless ($self->{badtestcnt}) {
3258 if ($CPAN::Signal) {
3259 delete $self->{force_update};
3262 my $make = $self->{modulebuild} ? "Build" : "make";
3263 $CPAN::Frontend->myprint("Running $make install\n");
3266 if ($self->{make} or $self->{later}) {
3270 "Make had some problems, won't install";
3273 exists $self->{make} and
3275 UNIVERSAL::can($self->{make},"failed") ?
3276 $self->{make}->failed :
3277 $self->{make} =~ /^NO/
3279 push @e, "Make had returned bad status, install seems impossible";
3281 if (exists $self->{build_dir}) {
3283 push @e, "Has no own directory";
3286 if (exists $self->{make_test} and
3288 UNIVERSAL::can($self->{make_test},"failed") ?
3289 $self->{make_test}->failed :
3290 $self->{make_test} =~ /^NO/
3292 if ($self->{force_update}) {
3293 $self->{make_test}->text("FAILED but failure ignored because ".
3294 "'force' in effect");
3296 push @e, "make test had returned bad status, ".
3297 "won't install without force"
3300 if (exists $self->{install}) {
3301 if (UNIVERSAL::can($self->{install},"text") ?
3302 $self->{install}->text eq "YES" :
3303 $self->{install} =~ /^YES/
3305 $CPAN::Frontend->myprint(" Already done\n");
3306 $CPAN::META->is_installed($self->{build_dir});
3309 # comment in Todo on 2006-02-11; maybe retry?
3310 push @e, "Already tried without success";
3314 push @e, $self->{later} if $self->{later};
3315 push @e, $self->{configure_requires_later} if $self->{configure_requires_later};
3317 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3318 unless (chdir $self->{build_dir}) {
3319 push @e, "Couldn't chdir to '$self->{build_dir}': $!";
3321 $CPAN::Frontend->mywarn(join "", map {" $_\n"} @e) and return if @e;
3323 $self->debug("Changed directory to $self->{build_dir}")
3326 if ($^O eq 'MacOS') {
3327 Mac::BuildTools::make_install($self);
3332 if (my $commandline = $self->prefs->{install}{commandline}) {
3333 $system = $commandline;
3334 $ENV{PERL} = CPAN::find_perl();
3335 } elsif ($self->{modulebuild}) {
3336 my($mbuild_install_build_command) =
3337 exists $CPAN::HandleConfig::keys{mbuild_install_build_command} &&
3338 $CPAN::Config->{mbuild_install_build_command} ?
3339 $CPAN::Config->{mbuild_install_build_command} :
3340 $self->_build_command();
3341 $system = sprintf("%s install %s",
3342 $mbuild_install_build_command,
3343 $CPAN::Config->{mbuild_install_arg},
3346 my($make_install_make_command) =
3347 CPAN::HandleConfig->prefs_lookup($self,
3348 q{make_install_make_command})
3349 || $self->_make_command();
3350 $system = sprintf("%s install %s",
3351 $make_install_make_command,
3352 $CPAN::Config->{make_install_arg},
3356 my($stderr) = $^O eq "MSWin32" ? "" : " 2>&1 ";
3357 my $brip = CPAN::HandleConfig->prefs_lookup($self,
3358 q{build_requires_install_policy});
3361 my $reqtype = $self->{reqtype} ||= "c"; # in doubt it was a command
3362 my $want_install = "yes";
3363 if ($reqtype eq "b") {
3364 if ($brip eq "no") {
3365 $want_install = "no";
3366 } elsif ($brip =~ m|^ask/(.+)|) {
3368 $default = "yes" unless $default =~ /^(y|n)/i;
3370 CPAN::Shell::colorable_makemaker_prompt
3371 ("$id is just needed temporarily during building or testing. ".
3372 "Do you want to install it permanently? (Y/n)",
3376 unless ($want_install =~ /^y/i) {
3377 my $is_only = "is only 'build_requires'";
3378 $CPAN::Frontend->mywarn("Not installing because $is_only\n");
3379 $self->{install} = CPAN::Distrostatus->new("NO -- $is_only");
3380 delete $self->{force_update};
3383 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
3385 : ($ENV{PERLLIB} || "");
3387 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
3388 $CPAN::META->set_perl5lib;
3389 my($pipe) = FileHandle->new("$system $stderr |") || Carp::croak
3390 ("Can't execute $system: $!");
3393 print $_; # intentionally NOT use Frontend->myprint because it
3394 # looks irritating when we markup in color what we
3395 # just pass through from an external program
3399 my $close_ok = $? == 0;
3400 $self->introduce_myself;
3402 $CPAN::Frontend->myprint(" $system -- OK\n");
3403 $CPAN::META->is_installed($self->{build_dir});
3404 $self->{install} = CPAN::Distrostatus->new("YES");
3406 $self->{install} = CPAN::Distrostatus->new("NO");
3407 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
3409 CPAN::HandleConfig->prefs_lookup($self,
3410 q{make_install_make_command});
3412 $makeout =~ /permission/s
3416 || $mimc eq (CPAN::HandleConfig->prefs_lookup($self,
3420 $CPAN::Frontend->myprint(
3422 qq{ You may have to su }.
3423 qq{to root to install the package\n}.
3424 qq{ (Or you may want to run something like\n}.
3425 qq{ o conf make_install_make_command 'sudo make'\n}.
3426 qq{ to raise your permissions.}
3430 delete $self->{force_update};
3431 $self->store_persistent_state;
3434 sub introduce_myself {
3436 $CPAN::Frontend->myprint(sprintf(" %s\n",$self->pretty_id));
3439 #-> sub CPAN::Distribution::dir ;
3444 #-> sub CPAN::Distribution::perldoc ;
3448 my($dist) = $self->id;
3449 my $package = $self->called_for;
3451 if ($CPAN::META->has_inst("Pod::Perldocs")) {
3452 my($perl) = $self->perl
3453 or $CPAN::Frontend->mydie("Couldn't find executable perl\n");
3454 my @args = ($perl, q{-MPod::Perldocs}, q{-e},
3455 q{Pod::Perldocs->run()}, $package);
3457 unless ( ($wstatus = system(@args)) == 0 ) {
3458 my $estatus = $wstatus >> 8;
3459 $CPAN::Frontend->myprint(qq{
3460 Function system("@args")
3461 returned status $estatus (wstat $wstatus)
3466 $self->_display_url( $CPAN::Defaultdocs . $package );
3470 #-> sub CPAN::Distribution::_check_binary ;
3472 my ($dist,$shell,$binary) = @_;
3475 $CPAN::Frontend->myprint(qq{ + _check_binary($binary)\n})
3478 if ($CPAN::META->has_inst("File::Which")) {
3479 return File::Which::which($binary);
3482 $pid = open README, "which $binary|"
3483 or $CPAN::Frontend->mywarn(qq{Could not fork 'which $binary': $!\n});
3489 or $CPAN::Frontend->mywarn("Could not run 'which $binary': $!\n")
3493 $CPAN::Frontend->myprint(qq{ + $out \n})
3494 if $CPAN::DEBUG && $out;
3499 #-> sub CPAN::Distribution::_display_url ;
3501 my($self,$url) = @_;
3502 my($res,$saved_file,$pid,$out);
3504 $CPAN::Frontend->myprint(qq{ + _display_url($url)\n})
3507 # should we define it in the config instead?
3508 my $html_converter = "html2text.pl";
3510 my $web_browser = $CPAN::Config->{'lynx'} || undef;
3511 my $web_browser_out = $web_browser
3512 ? CPAN::Distribution->_check_binary($self,$web_browser)
3515 if ($web_browser_out) {
3516 # web browser found, run the action
3517 my $browser = CPAN::HandleConfig->safe_quote($CPAN::Config->{'lynx'});
3518 $CPAN::Frontend->myprint(qq{system[$browser $url]})
3520 $CPAN::Frontend->myprint(qq{
3523 with browser $browser
3525 $CPAN::Frontend->mysleep(1);
3526 system("$browser $url");
3527 if ($saved_file) { 1 while unlink($saved_file) }
3529 # web browser not found, let's try text only
3530 my $html_converter_out =
3531 CPAN::Distribution->_check_binary($self,$html_converter);
3532 $html_converter_out = CPAN::HandleConfig->safe_quote($html_converter_out);
3534 if ($html_converter_out ) {
3535 # html2text found, run it
3536 $saved_file = CPAN::Distribution->_getsave_url( $self, $url );
3537 $CPAN::Frontend->mydie(qq{ERROR: problems while getting $url\n})
3538 unless defined($saved_file);
3541 $pid = open README, "$html_converter $saved_file |"
3542 or $CPAN::Frontend->mydie(qq{
3543 Could not fork '$html_converter $saved_file': $!});
3545 if ($CPAN::META->has_usable("File::Temp")) {
3546 $fh = File::Temp->new(
3547 dir => File::Spec->tmpdir,
3548 template => 'cpan_htmlconvert_XXXX',
3552 $filename = $fh->filename;
3554 $filename = "cpan_htmlconvert_$$.txt";
3555 $fh = FileHandle->new();
3556 open $fh, ">$filename" or die;
3562 $CPAN::Frontend->mydie(qq{Could not run '$html_converter $saved_file': $!});
3563 my $tmpin = $fh->filename;
3564 $CPAN::Frontend->myprint(sprintf(qq{
3566 saved output to %s\n},
3574 or $CPAN::Frontend->mydie(qq{Could not open "$tmpin": $!});
3575 my $fh_pager = FileHandle->new;
3576 local($SIG{PIPE}) = "IGNORE";
3577 my $pager = $CPAN::Config->{'pager'} || "cat";
3578 $fh_pager->open("|$pager")
3579 or $CPAN::Frontend->mydie(qq{
3580 Could not open pager '$pager': $!});
3581 $CPAN::Frontend->myprint(qq{
3586 $CPAN::Frontend->mysleep(1);
3587 $fh_pager->print(<FH>);
3590 # coldn't find the web browser or html converter
3591 $CPAN::Frontend->myprint(qq{
3592 You need to install lynx or $html_converter to use this feature.});
3597 #-> sub CPAN::Distribution::_getsave_url ;
3599 my($dist, $shell, $url) = @_;
3601 $CPAN::Frontend->myprint(qq{ + _getsave_url($url)\n})
3605 if ($CPAN::META->has_usable("File::Temp")) {
3606 $fh = File::Temp->new(
3607 dir => File::Spec->tmpdir,
3608 template => "cpan_getsave_url_XXXX",
3612 $filename = $fh->filename;
3614 $fh = FileHandle->new;
3615 $filename = "cpan_getsave_url_$$.html";
3617 my $tmpin = $filename;
3618 if ($CPAN::META->has_usable('LWP')) {
3619 $CPAN::Frontend->myprint("Fetching with LWP:
3623 CPAN::LWP::UserAgent->config;
3624 eval { $Ua = CPAN::LWP::UserAgent->new; };
3626 $CPAN::Frontend->mywarn("ERROR: CPAN::LWP::UserAgent->new dies with $@\n");
3630 $Ua->proxy('http', $var)
3631 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
3633 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
3636 my $req = HTTP::Request->new(GET => $url);
3637 $req->header('Accept' => 'text/html');
3638 my $res = $Ua->request($req);
3639 if ($res->is_success) {
3640 $CPAN::Frontend->myprint(" + request successful.\n")
3642 print $fh $res->content;
3644 $CPAN::Frontend->myprint(qq{ + saved content to $tmpin \n})
3648 $CPAN::Frontend->myprint(sprintf(
3649 "LWP failed with code[%s], message[%s]\n",
3656 $CPAN::Frontend->mywarn(" LWP not available\n");
3661 #-> sub CPAN::Distribution::_build_command
3662 sub _build_command {
3664 if ($^O eq "MSWin32") { # special code needed at least up to
3665 # Module::Build 0.2611 and 0.2706; a fix
3666 # in M:B has been promised 2006-01-30
3667 my($perl) = $self->perl or $CPAN::Frontend->mydie("Couldn't find executable perl\n");
3668 return "$perl ./Build";
3673 #-> sub CPAN::Distribution::_should_report
3674 sub _should_report {
3675 my($self, $phase) = @_;
3676 die "_should_report() requires a 'phase' argument"
3677 if ! defined $phase;
3680 my $test_report = CPAN::HandleConfig->prefs_lookup($self,
3682 return unless $test_report;
3684 # don't repeat if we cached a result
3685 return $self->{should_report}
3686 if exists $self->{should_report};
3688 # don't report if we generated a Makefile.PL
3689 if ( $self->{had_no_makefile_pl} ) {
3690 $CPAN::Frontend->mywarn(
3691 "Will not send CPAN Testers report with generated Makefile.PL.\n"
3693 return $self->{should_report} = 0;
3697 if ( ! $CPAN::META->has_inst("CPAN::Reporter")) {
3698 $CPAN::Frontend->mywarn(
3699 "CPAN::Reporter not installed. No reports will be sent.\n"
3701 return $self->{should_report} = 0;
3705 my $crv = CPAN::Reporter->VERSION;
3706 if ( CPAN::Version->vlt( $crv, 0.99 ) ) {
3707 # don't cache $self->{should_report} -- need to check each phase
3708 if ( $phase eq 'test' ) {
3712 $CPAN::Frontend->mywarn(
3713 "Reporting on the '$phase' phase requires CPAN::Reporter 0.99, but \n" .
3714 "you only have version $crv\. Only 'test' phase reports will be sent.\n"
3721 if ($self->is_dot_dist) {
3722 $CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is disabled ".
3723 "for local directories\n");
3724 return $self->{should_report} = 0;
3726 if ($self->prefs->{patches}
3728 @{$self->prefs->{patches}}
3732 $CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is disabled ".
3733 "when the source has been patched\n");
3734 return $self->{should_report} = 0;
3737 # proceed and cache success
3738 return $self->{should_report} = 1;
3741 #-> sub CPAN::Distribution::reports
3744 my $pathname = $self->id;
3745 $CPAN::Frontend->myprint("Distribution: $pathname\n");
3747 unless ($CPAN::META->has_inst("CPAN::DistnameInfo")) {
3748 $CPAN::Frontend->mydie("CPAN::DistnameInfo not installed; cannot continue");
3750 unless ($CPAN::META->has_usable("LWP")) {
3751 $CPAN::Frontend->mydie("LWP not installed; cannot continue");
3753 unless ($CPAN::META->has_usable("File::Temp")) {
3754 $CPAN::Frontend->mydie("File::Temp not installed; cannot continue");
3757 my $d = CPAN::DistnameInfo->new($pathname);
3759 my $dist = $d->dist; # "CPAN-DistnameInfo"
3760 my $version = $d->version; # "0.02"
3761 my $maturity = $d->maturity; # "released"
3762 my $filename = $d->filename; # "CPAN-DistnameInfo-0.02.tar.gz"
3763 my $cpanid = $d->cpanid; # "GBARR"
3764 my $distvname = $d->distvname; # "CPAN-DistnameInfo-0.02"
3766 my $url = sprintf "http://www.cpantesters.org/show/%s.yaml", $dist;
3768 CPAN::LWP::UserAgent->config;
3770 eval { $Ua = CPAN::LWP::UserAgent->new; };
3772 $CPAN::Frontend->mydie("CPAN::LWP::UserAgent->new dies with $@\n");
3774 $CPAN::Frontend->myprint("Fetching '$url'...");
3775 my $resp = $Ua->get($url);
3776 unless ($resp->is_success) {
3777 $CPAN::Frontend->mydie(sprintf "Could not download '%s': %s\n", $url, $resp->code);
3779 $CPAN::Frontend->myprint("DONE\n\n");
3780 my $yaml = $resp->content;
3781 # was fuer ein Umweg!
3782 my $fh = File::Temp->new(
3783 dir => File::Spec->tmpdir,
3784 template => 'cpan_reports_XXXX',
3788 my $tfilename = $fh->filename;
3790 close $fh or $CPAN::Frontend->mydie("Could not close '$tfilename': $!");
3791 my $unserialized = CPAN->_yaml_loadfile($tfilename)->[0];
3792 unlink $tfilename or $CPAN::Frontend->mydie("Could not unlink '$tfilename': $!");
3794 my $this_version_seen;
3795 for my $rep (@$unserialized) {
3796 my $rversion = $rep->{version};
3797 if ($rversion eq $version) {
3798 unless ($this_version_seen++) {
3799 $CPAN::Frontend->myprint ("$rep->{version}:\n");
3801 $CPAN::Frontend->myprint
3802 (sprintf("%1s%1s%-4s %s on %s %s (%s)\n",
3803 $rep->{archname} eq $Config::Config{archname}?"*":"",
3804 $rep->{action}eq"PASS"?"+":$rep->{action}eq"FAIL"?"-":"",
3807 ucfirst $rep->{osname},
3812 $other_versions{$rep->{version}}++;
3815 unless ($this_version_seen) {
3816 $CPAN::Frontend->myprint("No reports found for version '$version'
3817 Reports for other versions:\n");
3818 for my $v (sort keys %other_versions) {
3819 $CPAN::Frontend->myprint(" $v\: $other_versions{$v}\n");
3822 $url =~ s/\.yaml/.html/;
3823 $CPAN::Frontend->myprint("See $url for details\n");