1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
4 $VERSION = eval $VERSION;
7 use CPAN::HandleConfig;
16 use ExtUtils::MakeMaker qw(prompt); # for some unknown reason,
17 # 5.005_04 does not work without
19 use File::Basename ();
26 use Sys::Hostname qw(hostname);
27 use Text::ParseWords ();
29 no lib "."; # we need to run chdir all over and we would get at wrong
32 require Mac::BuildTools if $^O eq 'MacOS';
34 END { $CPAN::End++; &cleanup; }
37 $CPAN::Frontend ||= "CPAN::Shell";
38 @CPAN::Defaultsites = ("http://www.perl.org/CPAN/","ftp://ftp.perl.org/pub/CPAN/")
39 unless @CPAN::Defaultsites;
40 # $CPAN::iCwd (i for initial) is going to be initialized during find_perl
41 $CPAN::Perl ||= CPAN::find_perl();
42 $CPAN::Defaultdocs ||= "http://search.cpan.org/perldoc?";
43 $CPAN::Defaultrecent ||= "http://search.cpan.org/recent";
49 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $HAS_USABLE $term
50 $Signal $Suppress_readline $Frontend
51 @Defaultsites $Have_warned $Defaultdocs $Defaultrecent
54 @CPAN::ISA = qw(CPAN::Debug Exporter);
56 # note that these functions live in CPAN::Shell and get executed via
57 # AUTOLOAD when called directly
78 sub soft_chdir_with_alternatives ($);
80 #-> sub CPAN::AUTOLOAD ;
85 @EXPORT{@EXPORT} = '';
86 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
87 if (exists $EXPORT{$l}){
90 die(qq{Unknown CPAN command "$AUTOLOAD". }.
91 qq{Type ? for help.\n});
98 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
99 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
101 my $oprompt = shift || CPAN::Prompt->new;
102 my $prompt = $oprompt;
103 my $commandline = shift || "";
104 $CPAN::CurrentCommandId ||= 1;
107 unless ($Suppress_readline) {
108 require Term::ReadLine;
111 $term->ReadLine eq "Term::ReadLine::Stub"
113 $term = Term::ReadLine->new('CPAN Monitor');
115 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
116 my $attribs = $term->Attribs;
117 $attribs->{attempted_completion_function} = sub {
118 &CPAN::Complete::gnu_cpl;
121 $readline::rl_completion_function =
122 $readline::rl_completion_function = 'CPAN::Complete::cpl';
124 if (my $histfile = $CPAN::Config->{'histfile'}) {{
125 unless ($term->can("AddHistory")) {
126 $CPAN::Frontend->mywarn("Terminal does not support AddHistory.\n");
129 my($fh) = FileHandle->new;
130 open $fh, "<$histfile" or last;
134 $term->AddHistory($_);
138 # $term->OUT is autoflushed anyway
139 my $odef = select STDERR;
146 # no strict; # I do not recall why no strict was here (2000-09-03)
150 File::Spec->can("tmpdir") ? File::Spec->tmpdir() : (),
151 File::Spec->rootdir(),
153 my $try_detect_readline;
154 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
155 my $rl_avail = $Suppress_readline ? "suppressed" :
156 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
157 "available (try 'install Bundle::CPAN')";
159 $CPAN::Frontend->myprint(
161 cpan shell -- CPAN exploration and modules installation (v%s)
168 unless $CPAN::Config->{'inhibit_startup_message'} ;
169 my($continuation) = "";
170 SHELLCOMMAND: while () {
171 if ($Suppress_readline) {
173 last SHELLCOMMAND unless defined ($_ = <> );
176 last SHELLCOMMAND unless
177 defined ($_ = $term->readline($prompt, $commandline));
179 $_ = "$continuation$_" if $continuation;
181 next SHELLCOMMAND if /^$/;
182 $_ = 'h' if /^\s*\?/;
183 if (/^(?:q(?:uit)?|bye|exit)$/i) {
194 use vars qw($import_done);
195 CPAN->import(':DEFAULT') unless $import_done++;
196 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
203 if ($] < 5.00322) { # parsewords had a bug until recently
206 eval { @line = Text::ParseWords::shellwords($_) };
207 warn($@), next SHELLCOMMAND if $@;
208 warn("Text::Parsewords could not parse the line [$_]"),
209 next SHELLCOMMAND unless @line;
211 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
212 my $command = shift @line;
213 eval { CPAN::Shell->$command(@line) };
215 if ($command =~ /^(make|test|install|force|notest)$/) {
216 CPAN::Shell->failed($CPAN::CurrentCommandId,1);
218 soft_chdir_with_alternatives(\@cwd);
219 $CPAN::Frontend->myprint("\n");
221 $CPAN::CurrentCommandId++;
225 $commandline = ""; # I do want to be able to pass a default to
226 # shell, but on the second command I see no
229 CPAN::Queue->nullify_queue;
230 if ($try_detect_readline) {
231 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
233 $CPAN::META->has_inst("Term::ReadLine::Perl")
235 delete $INC{"Term/ReadLine.pm"};
237 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
238 require Term::ReadLine;
239 $CPAN::Frontend->myprint("\n$redef subroutines in ".
240 "Term::ReadLine redefined\n");
246 soft_chdir_with_alternatives(\@cwd);
249 sub soft_chdir_with_alternatives ($) {
251 while (not chdir $cwd->[0]) {
253 $CPAN::Frontend->mywarn(qq{Could not chdir to "$cwd->[0]": $!
254 Trying to chdir to "$cwd->[1]" instead.
258 $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd->[0]": $!});
263 package CPAN::CacheMgr;
265 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
270 use vars qw($Ua $Thesite $ThesiteURL $Themethod);
271 @CPAN::FTP::ISA = qw(CPAN::Debug);
273 package CPAN::LWP::UserAgent;
275 use vars qw(@ISA $USER $PASSWD $SETUPDONE);
276 # we delay requiring LWP::UserAgent and setting up inheritance until we need it
278 package CPAN::Complete;
280 @CPAN::Complete::ISA = qw(CPAN::Debug);
281 @CPAN::Complete::COMMANDS = sort qw(
282 ! a b d h i m o q r u
304 use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03);
305 @CPAN::Index::ISA = qw(CPAN::Debug);
308 # use constant PROTOCOL => "2.0"; # outcommented to avoid warning on upgrade from 1.57
311 package CPAN::InfoObj;
313 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
315 package CPAN::Author;
317 @CPAN::Author::ISA = qw(CPAN::InfoObj);
319 package CPAN::Distribution;
321 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
323 package CPAN::Bundle;
325 @CPAN::Bundle::ISA = qw(CPAN::Module);
327 package CPAN::Module;
329 @CPAN::Module::ISA = qw(CPAN::InfoObj);
331 package CPAN::Exception::RecursiveDependency;
333 use overload '""' => "as_string";
340 for my $dep (@$deps) {
342 last if $seen{$dep}++;
344 bless { deps => \@deps }, $class;
349 "\nRecursive dependency detected:\n " .
350 join("\n => ", @{$self->{deps}}) .
351 ".\nCannot continue.\n";
354 package CPAN::Prompt; use overload '""' => "as_string";
355 use vars qw($prompt);
357 $CPAN::CurrentCommandId ||= 0;
362 if ($CPAN::Config->{commandnumber_in_prompt}) {
363 sprintf "cpan[%d]> ", $CPAN::CurrentCommandId;
369 package CPAN::Distrostatus;
370 use overload '""' => "as_string",
373 my($class,$arg) = @_;
376 FAILED => substr($arg,0,2) eq "NO",
377 COMMANDID => $CPAN::CurrentCommandId,
380 sub commandid { shift->{COMMANDID} }
381 sub failed { shift->{FAILED} }
385 $self->{TEXT} = $set;
396 use vars qw($AUTOLOAD @ISA $COLOR_REGISTERED $ADVANCED_QUERY $PRINT_ORNAMENTING);
397 @CPAN::Shell::ISA = qw(CPAN::Debug);
398 $COLOR_REGISTERED ||= 0;
399 $PRINT_ORNAMENTING ||= 0;
401 #-> sub CPAN::Shell::AUTOLOAD ;
403 my($autoload) = $AUTOLOAD;
404 my $class = shift(@_);
405 # warn "autoload[$autoload] class[$class]";
406 $autoload =~ s/.*:://;
407 if ($autoload =~ /^w/) {
408 if ($CPAN::META->has_inst('CPAN::WAIT')) {
409 CPAN::WAIT->$autoload(@_);
411 $CPAN::Frontend->mywarn(qq{
412 Commands starting with "w" require CPAN::WAIT to be installed.
413 Please consider installing CPAN::WAIT to use the fulltext index.
414 For this you just need to type
419 $CPAN::Frontend->mywarn(qq{Unknown shell command '$autoload'. }.
428 # One use of the queue is to determine if we should or shouldn't
429 # announce the availability of a new CPAN module
431 # Now we try to use it for dependency tracking. For that to happen
432 # we need to draw a dependency tree and do the leaves first. This can
433 # easily be reached by running CPAN.pm recursively, but we don't want
434 # to waste memory and run into deep recursion. So what we can do is
437 # CPAN::Queue is the package where the queue is maintained. Dependencies
438 # often have high priority and must be brought to the head of the queue,
439 # possibly by jumping the queue if they are already there. My first code
440 # attempt tried to be extremely correct. Whenever a module needed
441 # immediate treatment, I either unshifted it to the front of the queue,
442 # or, if it was already in the queue, I spliced and let it bypass the
443 # others. This became a too correct model that made it impossible to put
444 # an item more than once into the queue. Why would you need that? Well,
445 # you need temporary duplicates as the manager of the queue is a loop
448 # (1) looks at the first item in the queue without shifting it off
450 # (2) cares for the item
452 # (3) removes the item from the queue, *even if its agenda failed and
453 # even if the item isn't the first in the queue anymore* (that way
454 # protecting against never ending queues)
456 # So if an item has prerequisites, the installation fails now, but we
457 # want to retry later. That's easy if we have it twice in the queue.
459 # I also expect insane dependency situations where an item gets more
460 # than two lives in the queue. Simplest example is triggered by 'install
461 # Foo Foo Foo'. People make this kind of mistakes and I don't want to
462 # get in the way. I wanted the queue manager to be a dumb servant, not
463 # one that knows everything.
465 # Who would I tell in this model that the user wants to be asked before
466 # processing? I can't attach that information to the module object,
467 # because not modules are installed but distributions. So I'd have to
468 # tell the distribution object that it should ask the user before
469 # processing. Where would the question be triggered then? Most probably
470 # in CPAN::Distribution::rematein.
471 # Hope that makes sense, my head is a bit off:-) -- AK
478 my $self = bless { qmod => $s }, $class;
483 # CPAN::Queue::first ;
489 # CPAN::Queue::delete_first ;
491 my($class,$what) = @_;
493 for my $i (0..$#All) {
494 if ( $All[$i]->{qmod} eq $what ) {
501 # CPAN::Queue::jumpqueue ;
505 CPAN->debug(sprintf("before jumpqueue All[%s] what[%s]",
506 join(",",map {$_->{qmod}} @All),
509 WHAT: for my $what (reverse @what) {
511 for (my $i=0; $i<$#All;$i++) { #prevent deep recursion
512 CPAN->debug("i[$All[$i]]what[$what]") if $CPAN::DEBUG;
513 if ($All[$i]->{qmod} eq $what){
515 if ($jumped > 100) { # one's OK if e.g. just
516 # processing now; more are OK if
517 # user typed it several times
518 $CPAN::Frontend->mywarn(
519 qq{Object [$what] queued more than 100 times, ignoring}
525 my $obj = bless { qmod => $what }, $class;
528 CPAN->debug(sprintf("after jumpqueue All[%s] what[%s]",
529 join(",",map {$_->{qmod}} @All),
534 # CPAN::Queue::exists ;
536 my($self,$what) = @_;
537 my @all = map { $_->{qmod} } @All;
538 my $exists = grep { $_->{qmod} eq $what } @All;
539 # warn "in exists what[$what] all[@all] exists[$exists]";
543 # CPAN::Queue::delete ;
546 @All = grep { $_->{qmod} ne $mod } @All;
549 # CPAN::Queue::nullify_queue ;
559 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
561 # from here on only subs.
562 ################################################################################
564 #-> sub CPAN::all_objects ;
566 my($mgr,$class) = @_;
567 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
568 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
570 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
572 *all = \&all_objects;
574 # Called by shell, not in batch mode. In batch mode I see no risk in
575 # having many processes updating something as installations are
576 # continually checked at runtime. In shell mode I suspect it is
577 # unintentional to open more than one shell at a time
579 #-> sub CPAN::checklock ;
582 my $lockfile = File::Spec->catfile($CPAN::Config->{cpan_home},".lock");
583 if (-f $lockfile && -M _ > 0) {
584 my $fh = FileHandle->new($lockfile) or
585 $CPAN::Frontend->mydie("Could not open lockfile '$lockfile': $!");
586 my $otherpid = <$fh>;
587 my $otherhost = <$fh>;
589 if (defined $otherpid && $otherpid) {
592 if (defined $otherhost && $otherhost) {
595 my $thishost = hostname();
596 if (defined $otherhost && defined $thishost &&
597 $otherhost ne '' && $thishost ne '' &&
598 $otherhost ne $thishost) {
599 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile '$lockfile'\n".
600 "reports other host $otherhost and other ".
601 "process $otherpid.\n".
602 "Cannot proceed.\n"));
604 elsif (defined $otherpid && $otherpid) {
605 return if $$ == $otherpid; # should never happen
606 $CPAN::Frontend->mywarn(
608 There seems to be running another CPAN process (pid $otherpid). Contacting...
610 if (kill 0, $otherpid) {
611 $CPAN::Frontend->mydie(qq{Other job is running.
612 You may want to kill it and delete the lockfile, maybe. On UNIX try:
616 } elsif (-w $lockfile) {
618 ExtUtils::MakeMaker::prompt
619 (qq{Other job not responding. Shall I overwrite }.
620 qq{the lockfile '$lockfile'? (Y/n)},"y");
621 $CPAN::Frontend->myexit("Ok, bye\n")
622 unless $ans =~ /^y/i;
625 qq{Lockfile '$lockfile' not writeable by you. }.
626 qq{Cannot proceed.\n}.
628 qq{ rm '$lockfile'\n}.
629 qq{ and then rerun us.\n}
633 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile '$lockfile'\n".
634 "reports other process with ID ".
635 "$otherpid. Cannot proceed.\n"));
638 my $dotcpan = $CPAN::Config->{cpan_home};
639 eval { File::Path::mkpath($dotcpan);};
641 # A special case at least for Jarkko.
646 $symlinkcpan = readlink $dotcpan;
647 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
648 eval { File::Path::mkpath($symlinkcpan); };
652 $CPAN::Frontend->mywarn(qq{
653 Working directory $symlinkcpan created.
657 unless (-d $dotcpan) {
659 Your configuration suggests "$dotcpan" as your
660 CPAN.pm working directory. I could not create this directory due
661 to this error: $firsterror\n};
663 As "$dotcpan" is a symlink to "$symlinkcpan",
664 I tried to create that, but I failed with this error: $seconderror
667 Please make sure the directory exists and is writable.
669 $CPAN::Frontend->mydie($diemess);
671 } # $@ after eval mkpath $dotcpan
673 unless ($fh = FileHandle->new(">$lockfile")) {
674 if ($! =~ /Permission/) {
675 my $incc = $INC{'CPAN/Config.pm'};
676 my $myincc = File::Spec->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
677 $CPAN::Frontend->myprint(qq{
679 Your configuration suggests that CPAN.pm should use a working
681 $CPAN::Config->{cpan_home}
682 Unfortunately we could not create the lock file
684 due to permission problems.
686 Please make sure that the configuration variable
687 \$CPAN::Config->{cpan_home}
688 points to a directory where you can write a .lock file. You can set
689 this variable in either
694 if(!$INC{'CPAN/MyConfig.pm'}) {
695 $CPAN::Frontend->myprint("You don't seem to have a user ".
696 "configuration (MyConfig.pm) yet.\n");
697 my $new = ExtUtils::MakeMaker::prompt("Do you want to create a ".
698 "user configuration now? (Y/n)",
701 CPAN::Shell->mkmyconfig();
706 $CPAN::Frontend->mydie("Could not open >$lockfile: $!");
708 $fh->print($$, "\n");
709 $fh->print(hostname(), "\n");
710 $self->{LOCK} = $lockfile;
714 $CPAN::Frontend->mydie("Got SIGTERM, leaving");
719 $CPAN::Frontend->mydie("Got another SIGINT") if $Signal;
720 print "Caught SIGINT\n";
724 # From: Larry Wall <larry@wall.org>
725 # Subject: Re: deprecating SIGDIE
726 # To: perl5-porters@perl.org
727 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
729 # The original intent of __DIE__ was only to allow you to substitute one
730 # kind of death for another on an application-wide basis without respect
731 # to whether you were in an eval or not. As a global backstop, it should
732 # not be used any more lightly (or any more heavily :-) than class
733 # UNIVERSAL. Any attempt to build a general exception model on it should
734 # be politely squashed. Any bug that causes every eval {} to have to be
735 # modified should be not so politely squashed.
737 # Those are my current opinions. It is also my optinion that polite
738 # arguments degenerate to personal arguments far too frequently, and that
739 # when they do, it's because both people wanted it to, or at least didn't
740 # sufficiently want it not to.
744 # global backstop to cleanup if we should really die
745 $SIG{__DIE__} = \&cleanup;
746 $self->debug("Signal handler set.") if $CPAN::DEBUG;
749 #-> sub CPAN::DESTROY ;
751 &cleanup; # need an eval?
754 #-> sub CPAN::anycwd ;
757 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
762 sub cwd {Cwd::cwd();}
764 #-> sub CPAN::getcwd ;
765 sub getcwd {Cwd::getcwd();}
767 #-> sub CPAN::fastcwd ;
768 sub fastcwd {Cwd::fastcwd();}
770 #-> sub CPAN::backtickcwd ;
771 sub backtickcwd {my $cwd = `cwd`; chomp $cwd; $cwd}
773 #-> sub CPAN::find_perl ;
775 my($perl) = File::Spec->file_name_is_absolute($^X) ? $^X : "";
776 my $pwd = $CPAN::iCwd = CPAN::anycwd();
777 my $candidate = File::Spec->catfile($pwd,$^X);
778 $perl ||= $candidate if MM->maybe_command($candidate);
781 my ($component,$perl_name);
782 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
783 PATH_COMPONENT: foreach $component (File::Spec->path(),
784 $Config::Config{'binexp'}) {
785 next unless defined($component) && $component;
786 my($abs) = File::Spec->catfile($component,$perl_name);
787 if (MM->maybe_command($abs)) {
799 #-> sub CPAN::exists ;
801 my($mgr,$class,$id) = @_;
802 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
804 ### Carp::croak "exists called without class argument" unless $class;
806 $id =~ s/:+/::/g if $class eq "CPAN::Module";
807 exists $META->{readonly}{$class}{$id} or
808 exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
811 #-> sub CPAN::delete ;
813 my($mgr,$class,$id) = @_;
814 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
815 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
818 #-> sub CPAN::has_usable
819 # has_inst is sometimes too optimistic, we should replace it with this
820 # has_usable whenever a case is given
822 my($self,$mod,$message) = @_;
823 return 1 if $HAS_USABLE->{$mod};
824 my $has_inst = $self->has_inst($mod,$message);
825 return unless $has_inst;
828 LWP => [ # we frequently had "Can't locate object
829 # method "new" via package "LWP::UserAgent" at
830 # (eval 69) line 2006
832 sub {require LWP::UserAgent},
833 sub {require HTTP::Request},
834 sub {require URI::URL},
837 sub {require Net::FTP},
838 sub {require Net::Config},
841 if ($usable->{$mod}) {
842 for my $c (0..$#{$usable->{$mod}}) {
843 my $code = $usable->{$mod}[$c];
844 my $ret = eval { &$code() };
846 warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
851 return $HAS_USABLE->{$mod} = 1;
854 #-> sub CPAN::has_inst
856 my($self,$mod,$message) = @_;
857 Carp::croak("CPAN->has_inst() called without an argument")
859 my %dont = map { $_ => 1 } keys %{$CPAN::META->{dontload_hash}||{}},
860 keys %{$CPAN::Config->{dontload_hash}||{}},
861 @{$CPAN::Config->{dontload_list}||[]};
862 if (defined $message && $message eq "no" # afair only used by Nox
866 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
874 # checking %INC is wrong, because $INC{LWP} may be true
875 # although $INC{"URI/URL.pm"} may have failed. But as
876 # I really want to say "bla loaded OK", I have to somehow
878 ### warn "$file in %INC"; #debug
880 } elsif (eval { require $file }) {
881 # eval is good: if we haven't yet read the database it's
882 # perfect and if we have installed the module in the meantime,
883 # it tries again. The second require is only a NOOP returning
884 # 1 if we had success, otherwise it's retrying
886 $CPAN::Frontend->myprint("CPAN: $mod loaded ok\n");
887 if ($mod eq "CPAN::WAIT") {
888 push @CPAN::Shell::ISA, 'CPAN::WAIT';
891 } elsif ($mod eq "Net::FTP") {
892 $CPAN::Frontend->mywarn(qq{
893 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
895 install Bundle::libnet
897 }) unless $Have_warned->{"Net::FTP"}++;
899 } elsif ($mod eq "Digest::SHA"){
900 if ($Have_warned->{"Digest::SHA"}++) {
901 $CPAN::Frontend->myprint(qq{CPAN: checksum security checks disabled}.
902 qq{because Digest::SHA not installed.\n});
904 $CPAN::Frontend->myprint(qq{
905 CPAN: checksum security checks disabled because Digest::SHA not installed.
906 Please consider installing the Digest::SHA module.
911 } elsif ($mod eq "Module::Signature"){
912 unless ($Have_warned->{"Module::Signature"}++) {
913 # No point in complaining unless the user can
914 # reasonably install and use it.
915 if (eval { require Crypt::OpenPGP; 1 } ||
916 defined $CPAN::Config->{'gpg'}) {
917 $CPAN::Frontend->myprint(qq{
918 CPAN: Module::Signature security checks disabled because Module::Signature
919 not installed. Please consider installing the Module::Signature module.
920 You may also need to be able to connect over the Internet to the public
921 keyservers like pgp.mit.edu (port 11371).
928 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
933 #-> sub CPAN::instance ;
935 my($mgr,$class,$id) = @_;
938 # unsafe meta access, ok?
939 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
940 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
948 #-> sub CPAN::cleanup ;
950 # warn "cleanup called with arg[@_] End[$CPAN::End] Signal[$Signal]";
951 local $SIG{__DIE__} = '';
956 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
958 $subroutine eq '(eval)';
960 return if $ineval && !$CPAN::End;
961 return unless defined $META->{LOCK};
962 return unless -f $META->{LOCK};
964 unlink $META->{LOCK};
966 # Carp::cluck("DEBUGGING");
967 $CPAN::Frontend->mywarn("Lockfile removed.\n");
970 #-> sub CPAN::savehist
973 my($histfile,$histsize);
974 unless ($histfile = $CPAN::Config->{'histfile'}){
975 $CPAN::Frontend->mywarn("No history written (no histfile specified).\n");
978 $histsize = $CPAN::Config->{'histsize'} || 100;
980 unless ($CPAN::term->can("GetHistory")) {
981 $CPAN::Frontend->mywarn("Terminal does not support GetHistory.\n");
987 my @h = $CPAN::term->GetHistory;
988 splice @h, 0, @h-$histsize if @h>$histsize;
989 my($fh) = FileHandle->new;
990 open $fh, ">$histfile" or $CPAN::Frontend->mydie("Couldn't open >$histfile: $!");
991 local $\ = local $, = "\n";
997 my($self,$what) = @_;
998 $self->{is_tested}{$what} = 1;
1002 my($self,$what) = @_;
1003 delete $self->{is_tested}{$what};
1008 $self->{is_tested} ||= {};
1009 return unless %{$self->{is_tested}};
1010 my $env = $ENV{PERL5LIB};
1011 $env = $ENV{PERLLIB} unless defined $env;
1013 push @env, $env if defined $env and length $env;
1014 my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}};
1015 $CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
1016 $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1019 package CPAN::CacheMgr;
1022 #-> sub CPAN::CacheMgr::as_string ;
1024 eval { require Data::Dumper };
1026 return shift->SUPER::as_string;
1028 return Data::Dumper::Dumper(shift);
1032 #-> sub CPAN::CacheMgr::cachesize ;
1037 #-> sub CPAN::CacheMgr::tidyup ;
1040 return unless -d $self->{ID};
1041 while ($self->{DU} > $self->{'MAX'} ) {
1042 my($toremove) = shift @{$self->{FIFO}};
1043 $CPAN::Frontend->myprint(sprintf(
1044 "Deleting from cache".
1045 ": $toremove (%.1f>%.1f MB)\n",
1046 $self->{DU}, $self->{'MAX'})
1048 return if $CPAN::Signal;
1049 $self->force_clean_cache($toremove);
1050 return if $CPAN::Signal;
1054 #-> sub CPAN::CacheMgr::dir ;
1059 #-> sub CPAN::CacheMgr::entries ;
1061 my($self,$dir) = @_;
1062 return unless defined $dir;
1063 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
1064 $dir ||= $self->{ID};
1065 my($cwd) = CPAN::anycwd();
1066 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
1067 my $dh = DirHandle->new(File::Spec->curdir)
1068 or Carp::croak("Couldn't opendir $dir: $!");
1071 next if $_ eq "." || $_ eq "..";
1073 push @entries, File::Spec->catfile($dir,$_);
1075 push @entries, File::Spec->catdir($dir,$_);
1077 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
1080 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
1081 sort { -M $b <=> -M $a} @entries;
1084 #-> sub CPAN::CacheMgr::disk_usage ;
1086 my($self,$dir) = @_;
1087 return if exists $self->{SIZE}{$dir};
1088 return if $CPAN::Signal;
1092 unless (chmod 0755, $dir) {
1093 $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
1094 "permission to change the permission; cannot ".
1095 "estimate disk usage of '$dir'\n");
1096 $CPAN::Frontend->mysleep(5);
1101 $CPAN::Frontend->mywarn("Directory '$dir' has gone. Cannot continue.\n");
1102 $CPAN::Frontend->mysleep(2);
1107 $File::Find::prune++ if $CPAN::Signal;
1109 if ($^O eq 'MacOS') {
1111 my $cat = Mac::Files::FSpGetCatInfo($_);
1112 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
1116 unless (chmod 0755, $_) {
1117 $CPAN::Frontend->mywarn("I have neither the -x permission nor ".
1118 "the permission to change the permission; ".
1119 "can only partially estimate disk usage ".
1132 return if $CPAN::Signal;
1133 $self->{SIZE}{$dir} = $Du/1024/1024;
1134 push @{$self->{FIFO}}, $dir;
1135 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
1136 $self->{DU} += $Du/1024/1024;
1140 #-> sub CPAN::CacheMgr::force_clean_cache ;
1141 sub force_clean_cache {
1142 my($self,$dir) = @_;
1143 return unless -e $dir;
1144 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
1146 File::Path::rmtree($dir);
1147 $self->{DU} -= $self->{SIZE}{$dir};
1148 delete $self->{SIZE}{$dir};
1151 #-> sub CPAN::CacheMgr::new ;
1158 ID => $CPAN::Config->{'build_dir'},
1159 MAX => $CPAN::Config->{'build_cache'},
1160 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
1163 File::Path::mkpath($self->{ID});
1164 my $dh = DirHandle->new($self->{ID});
1165 bless $self, $class;
1168 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
1170 CPAN->debug($debug) if $CPAN::DEBUG;
1174 #-> sub CPAN::CacheMgr::scan_cache ;
1177 return if $self->{SCAN} eq 'never';
1178 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
1179 unless $self->{SCAN} eq 'atstart';
1180 $CPAN::Frontend->myprint(
1181 sprintf("Scanning cache %s for sizes\n",
1184 for $e ($self->entries($self->{ID})) {
1185 next if $e eq ".." || $e eq ".";
1186 $self->disk_usage($e);
1187 return if $CPAN::Signal;
1192 package CPAN::Shell;
1195 #-> sub CPAN::Shell::h ;
1197 my($class,$about) = @_;
1198 if (defined $about) {
1199 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
1201 my $filler = " " x (80 - 28 - length($CPAN::VERSION));
1202 $CPAN::Frontend->myprint(qq{
1203 Display Information $filler (ver $CPAN::VERSION)
1204 command argument description
1205 a,b,d,m WORD or /REGEXP/ about authors, bundles, distributions, modules
1206 i WORD or /REGEXP/ about any of the above
1207 r NONE report updatable modules
1208 ls AUTHOR or GLOB about files in the author's directory
1209 (with WORD being a module, bundle or author name or a distribution
1210 name of the form AUTHOR/DISTRIBUTION)
1212 Download, Test, Make, Install...
1213 get download clean make clean
1214 make make (implies get) look open subshell in dist directory
1215 test make test (implies make) readme display these README files
1216 install make install (implies test) perldoc display POD documentation
1219 force COMMAND unconditionally do command
1220 notest COMMAND skip testing
1223 h,? display this menu ! perl-code eval a perl command
1224 o conf [opt] set and query options q quit the cpan shell
1225 reload cpan load CPAN.pm again reload index load newer indices
1226 autobundle Snapshot recent latest CPAN uploads});
1232 #-> sub CPAN::Shell::a ;
1234 my($self,@arg) = @_;
1235 # authors are always UPPERCASE
1237 $_ = uc $_ unless /=/;
1239 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1242 #-> sub CPAN::Shell::globls ;
1244 my($self,$s,$pragmas) = @_;
1245 # ls is really very different, but we had it once as an ordinary
1246 # command in the Shell (upto rev. 321) and we could not handle
1248 my(@accept,@preexpand);
1249 if ($s =~ /[\*\?\/]/) {
1250 if ($CPAN::META->has_inst("Text::Glob")) {
1251 if (my($au,$pathglob) = $s =~ m|(.*?)/(.*)|) {
1252 my $rau = Text::Glob::glob_to_regex(uc $au);
1253 CPAN::Shell->debug("au[$au]pathglob[$pathglob]rau[$rau]")
1255 push @preexpand, map { $_->id . "/" . $pathglob }
1256 CPAN::Shell->expand_by_method('CPAN::Author',['id'],"/$rau/");
1258 my $rau = Text::Glob::glob_to_regex(uc $s);
1259 push @preexpand, map { $_->id }
1260 CPAN::Shell->expand_by_method('CPAN::Author',
1265 $CPAN::Frontend->mydie("Text::Glob not installed, cannot proceed");
1268 push @preexpand, uc $s;
1271 unless (/^[A-Z0-9\-]+(\/|$)/i) {
1272 $CPAN::Frontend->mywarn("ls command rejects argument $_: not an author\n");
1277 my $silent = @accept>1;
1278 my $last_alpha = "";
1280 for my $a (@accept){
1281 my($author,$pathglob);
1282 if ($a =~ m|(.*?)/(.*)|) {
1285 $author = CPAN::Shell->expand_by_method('CPAN::Author',
1287 $a2) or die "No author found for $a2";
1289 $author = CPAN::Shell->expand_by_method('CPAN::Author',
1291 $a) or die "No author found for $a";
1294 my $alpha = substr $author->id, 0, 1;
1296 if ($alpha eq $last_alpha) {
1300 $last_alpha = $alpha;
1302 $CPAN::Frontend->myprint($ad);
1304 for my $pragma (@$pragmas) {
1305 if ($author->can($pragma)) {
1309 push @results, $author->ls($pathglob,$silent); # silent if
1312 for my $pragma (@$pragmas) {
1313 my $meth = "un$pragma";
1314 if ($author->can($meth)) {
1322 #-> sub CPAN::Shell::local_bundles ;
1324 my($self,@which) = @_;
1325 my($incdir,$bdir,$dh);
1326 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1327 my @bbase = "Bundle";
1328 while (my $bbase = shift @bbase) {
1329 $bdir = File::Spec->catdir($incdir,split /::/, $bbase);
1330 CPAN->debug("bdir[$bdir]\@bbase[@bbase]") if $CPAN::DEBUG;
1331 if ($dh = DirHandle->new($bdir)) { # may fail
1333 for $entry ($dh->read) {
1334 next if $entry =~ /^\./;
1335 next unless $entry =~ /^\w+(\.pm)?(?!\n)\Z/;
1336 if (-d File::Spec->catdir($bdir,$entry)){
1337 push @bbase, "$bbase\::$entry";
1339 next unless $entry =~ s/\.pm(?!\n)\Z//;
1340 $CPAN::META->instance('CPAN::Bundle',"$bbase\::$entry");
1348 #-> sub CPAN::Shell::b ;
1350 my($self,@which) = @_;
1351 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1352 $self->local_bundles;
1353 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1356 #-> sub CPAN::Shell::d ;
1357 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1359 #-> sub CPAN::Shell::m ;
1360 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
1362 $CPAN::Frontend->myprint($self->format_result('Module',@_));
1365 #-> sub CPAN::Shell::i ;
1369 @args = '/./' unless @args;
1371 for my $type (qw/Bundle Distribution Module/) {
1372 push @result, $self->expand($type,@args);
1374 # Authors are always uppercase.
1375 push @result, $self->expand("Author", map { uc $_ } @args);
1377 my $result = @result == 1 ?
1378 $result[0]->as_string :
1380 "No objects found of any type for argument @args\n" :
1382 (map {$_->as_glimpse} @result),
1383 scalar @result, " items found\n",
1385 $CPAN::Frontend->myprint($result);
1388 #-> sub CPAN::Shell::o ;
1390 # CPAN::Shell::o and CPAN::Config::edit are closely related. 'o conf'
1391 # should have been called set and 'o debug' maybe 'set debug'
1393 my($self,$o_type,@o_what) = @_;
1396 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1397 if ($o_type eq 'conf') {
1398 if (!@o_what) { # print all things, "o conf"
1400 $CPAN::Frontend->myprint("CPAN::Config options");
1401 if (exists $INC{'CPAN/Config.pm'}) {
1402 $CPAN::Frontend->myprint(" from $INC{'CPAN/Config.pm'}");
1404 if (exists $INC{'CPAN/MyConfig.pm'}) {
1405 $CPAN::Frontend->myprint(" and $INC{'CPAN/MyConfig.pm'}");
1407 $CPAN::Frontend->myprint(":\n");
1408 for $k (sort keys %CPAN::HandleConfig::can) {
1409 $v = $CPAN::HandleConfig::can{$k};
1410 $CPAN::Frontend->myprint(sprintf " %-18s [%s]\n", $k, $v);
1412 $CPAN::Frontend->myprint("\n");
1413 for $k (sort keys %$CPAN::Config) {
1414 CPAN::HandleConfig->prettyprint($k);
1416 $CPAN::Frontend->myprint("\n");
1417 } elsif (!CPAN::HandleConfig->edit(@o_what)) {
1418 $CPAN::Frontend->myprint(qq{Type 'o conf' to view all configuration }.
1421 } elsif ($o_type eq 'debug') {
1423 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1426 my($what) = shift @o_what;
1427 if ($what =~ s/^-// && exists $CPAN::DEBUG{$what}) {
1428 $CPAN::DEBUG &= $CPAN::DEBUG ^ $CPAN::DEBUG{$what};
1431 if ( exists $CPAN::DEBUG{$what} ) {
1432 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1433 } elsif ($what =~ /^\d/) {
1434 $CPAN::DEBUG = $what;
1435 } elsif (lc $what eq 'all') {
1437 for (values %CPAN::DEBUG) {
1440 $CPAN::DEBUG = $max;
1443 for (keys %CPAN::DEBUG) {
1444 next unless lc($_) eq lc($what);
1445 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1448 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1453 my $raw = "Valid options for debug are ".
1454 join(", ",sort(keys %CPAN::DEBUG), 'all').
1455 qq{ or a number. Completion works on the options. }.
1456 qq{Case is ignored.};
1458 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
1459 $CPAN::Frontend->myprint("\n\n");
1462 $CPAN::Frontend->myprint("Options set for debugging:\n");
1464 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1465 $v = $CPAN::DEBUG{$k};
1466 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
1467 if $v & $CPAN::DEBUG;
1470 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1473 $CPAN::Frontend->myprint(qq{
1475 conf set or get configuration variables
1476 debug set or get debugging options
1481 sub paintdots_onreload {
1484 if ( $_[0] =~ /[Ss]ubroutine ([\w:]+) redefined/ ) {
1488 # $CPAN::Frontend->myprint(".($subr)");
1489 $CPAN::Frontend->myprint(".");
1496 #-> sub CPAN::Shell::reload ;
1498 my($self,$command,@arg) = @_;
1500 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1501 if ($command =~ /cpan/i) {
1503 chdir $CPAN::iCwd if $CPAN::iCwd; # may fail
1505 MFILE: for my $f (qw(CPAN.pm CPAN/HandleConfig.pm CPAN/FirstTime.pm CPAN/Tarzip.pm
1506 CPAN/Debug.pm CPAN/Version.pm)) {
1507 local($SIG{__WARN__}) = paintdots_onreload(\$redef);
1508 $self->reload_this($f) or $failed++;
1510 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1511 $failed++ unless $redef;
1513 $CPAN::Frontend->mywarn("\n$failed errors during reload. You better quit ".
1516 } elsif ($command =~ /index/) {
1517 CPAN::Index->force_reload;
1519 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN.pm file
1520 index re-reads the index files\n});
1526 return 1 unless $INC{$f};
1527 my $pwd = CPAN::anycwd();
1528 CPAN->debug("reloading the whole '$f' from '$INC{$f}' while pwd='$pwd'")
1531 for my $inc (@INC) {
1532 $read = File::Spec->catfile($inc,split /\//, $f);
1539 $CPAN::Frontend->mywarn("Found no file to reload for '$f'\n");
1542 my $fh = FileHandle->new($read) or
1543 $CPAN::Frontend->mydie("Could not open $read: $!");
1547 CPAN->debug(sprintf("evaling [%s...]\n",substr($eval,0,64)))
1557 #-> sub CPAN::Shell::mkmyconfig ;
1559 my($self, $cpanpm, %args) = @_;
1560 require CPAN::FirstTime;
1561 $cpanpm = $INC{'CPAN/MyConfig.pm'} || "$ENV{HOME}/.cpan/CPAN/MyConfig.pm";
1562 File::Path::mkpath(File::Basename::dirname($cpanpm)) unless -e $cpanpm;
1563 if(!$INC{'CPAN/Config.pm'}) {
1564 eval { require CPAN::Config; };
1566 $CPAN::Config ||= {};
1571 keep_source_where => undef,
1574 CPAN::FirstTime::init($cpanpm, %args);
1577 #-> sub CPAN::Shell::_binary_extensions ;
1578 sub _binary_extensions {
1579 my($self) = shift @_;
1580 my(@result,$module,%seen,%need,$headerdone);
1581 for $module ($self->expand('Module','/./')) {
1582 my $file = $module->cpan_file;
1583 next if $file eq "N/A";
1584 next if $file =~ /^Contact Author/;
1585 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
1586 next if $dist->isa_perl;
1587 next unless $module->xs_file;
1589 $CPAN::Frontend->myprint(".");
1590 push @result, $module;
1592 # print join " | ", @result;
1593 $CPAN::Frontend->myprint("\n");
1597 #-> sub CPAN::Shell::recompile ;
1599 my($self) = shift @_;
1600 my($module,@module,$cpan_file,%dist);
1601 @module = $self->_binary_extensions();
1602 for $module (@module){ # we force now and compile later, so we
1604 $cpan_file = $module->cpan_file;
1605 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1607 $dist{$cpan_file}++;
1609 for $cpan_file (sort keys %dist) {
1610 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1611 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1613 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1614 # stop a package from recompiling,
1615 # e.g. IO-1.12 when we have perl5.003_10
1619 #-> sub CPAN::Shell::_u_r_common ;
1621 my($self) = shift @_;
1622 my($what) = shift @_;
1623 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1624 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
1625 $what && $what =~ /^[aru]$/;
1627 @args = '/./' unless @args;
1628 my(@result,$module,%seen,%need,$headerdone,
1629 $version_undefs,$version_zeroes);
1630 $version_undefs = $version_zeroes = 0;
1631 my $sprintf = "%s%-25s%s %9s %9s %s\n";
1632 my @expand = $self->expand('Module',@args);
1633 my $expand = scalar @expand;
1634 if (0) { # Looks like noise to me, was very useful for debugging
1635 # for metadata cache
1636 $CPAN::Frontend->myprint(sprintf "%d matches in the database\n", $expand);
1638 MODULE: for $module (@expand) {
1639 my $file = $module->cpan_file;
1640 next MODULE unless defined $file; # ??
1641 $file =~ s|^./../||;
1642 my($latest) = $module->cpan_version;
1643 my($inst_file) = $module->inst_file;
1645 return if $CPAN::Signal;
1648 $have = $module->inst_version;
1649 } elsif ($what eq "r") {
1650 $have = $module->inst_version;
1652 if ($have eq "undef"){
1654 } elsif ($have == 0){
1657 next MODULE unless CPAN::Version->vgt($latest, $have);
1658 # to be pedantic we should probably say:
1659 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1660 # to catch the case where CPAN has a version 0 and we have a version undef
1661 } elsif ($what eq "u") {
1667 } elsif ($what eq "r") {
1669 } elsif ($what eq "u") {
1673 return if $CPAN::Signal; # this is sometimes lengthy
1676 push @result, sprintf "%s %s\n", $module->id, $have;
1677 } elsif ($what eq "r") {
1678 push @result, $module->id;
1679 next MODULE if $seen{$file}++;
1680 } elsif ($what eq "u") {
1681 push @result, $module->id;
1682 next MODULE if $seen{$file}++;
1683 next MODULE if $file =~ /^Contact/;
1685 unless ($headerdone++){
1686 $CPAN::Frontend->myprint("\n");
1687 $CPAN::Frontend->myprint(sprintf(
1690 "Package namespace",
1702 $CPAN::META->has_inst("Term::ANSIColor")
1704 $module->description
1706 $color_on = Term::ANSIColor::color("green");
1707 $color_off = Term::ANSIColor::color("reset");
1709 $CPAN::Frontend->myprint(sprintf $sprintf,
1716 $need{$module->id}++;
1720 $CPAN::Frontend->myprint("No modules found for @args\n");
1721 } elsif ($what eq "r") {
1722 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1726 if ($version_zeroes) {
1727 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1728 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1729 qq{a version number of 0\n});
1731 if ($version_undefs) {
1732 my $s_has = $version_undefs > 1 ? "s have" : " has";
1733 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1734 qq{parseable version number\n});
1740 #-> sub CPAN::Shell::r ;
1742 shift->_u_r_common("r",@_);
1745 #-> sub CPAN::Shell::u ;
1747 shift->_u_r_common("u",@_);
1750 #-> sub CPAN::Shell::failed ;
1752 my($self,$only_id,$silent) = @_;
1754 DIST: for my $d ($CPAN::META->all_objects("CPAN::Distribution")) {
1763 next unless exists $d->{$nosayer};
1765 $d->{$nosayer}->can("failed") ?
1766 $d->{$nosayer}->failed :
1767 $d->{$nosayer} =~ /^NO/
1772 next DIST unless $failed;
1773 next DIST if $only_id && $only_id != (
1774 $d->{$failed}->can("commandid")
1776 $d->{$failed}->commandid
1778 $CPAN::CurrentCommandId
1783 # " %-45s: %s %s\n",
1786 $d->{$failed}->can("failed") ?
1788 $d->{$failed}->commandid,
1791 $d->{$failed}->text,
1801 my $scope = $only_id ? "command" : "session";
1803 my $print = join "",
1804 map { sprintf " %-45s: %s %s\n", @$_[1,2,3] }
1805 sort { $a->[0] <=> $b->[0] } @failed;
1806 $CPAN::Frontend->myprint("Failed during this $scope:\n$print");
1807 } elsif (!$only_id || !$silent) {
1808 $CPAN::Frontend->myprint("Nothing failed in this $scope\n");
1812 # XXX intentionally undocumented because completely bogus, unportable,
1815 #-> sub CPAN::Shell::status ;
1818 require Devel::Size;
1819 my $ps = FileHandle->new;
1820 open $ps, "/proc/$$/status";
1823 next unless /VmSize:\s+(\d+)/;
1827 $CPAN::Frontend->mywarn(sprintf(
1828 "%-27s %6d\n%-27s %6d\n",
1832 Devel::Size::total_size($CPAN::META)/1024,
1834 for my $k (sort keys %$CPAN::META) {
1835 next unless substr($k,0,4) eq "read";
1836 warn sprintf " %-26s %6d\n", $k, Devel::Size::total_size($CPAN::META->{$k})/1024;
1837 for my $k2 (sort keys %{$CPAN::META->{$k}}) {
1838 warn sprintf " %-25s %6d %6d\n",
1840 Devel::Size::total_size($CPAN::META->{$k}{$k2})/1024,
1841 scalar keys %{$CPAN::META->{$k}{$k2}};
1846 #-> sub CPAN::Shell::autobundle ;
1849 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
1850 my(@bundle) = $self->_u_r_common("a",@_);
1851 my($todir) = File::Spec->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1852 File::Path::mkpath($todir);
1853 unless (-d $todir) {
1854 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
1857 my($y,$m,$d) = (localtime)[5,4,3];
1861 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1862 my($to) = File::Spec->catfile($todir,"$me.pm");
1864 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1865 $to = File::Spec->catfile($todir,"$me.pm");
1867 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1869 "package Bundle::$me;\n\n",
1870 "\$VERSION = '0.01';\n\n",
1874 "Bundle::$me - Snapshot of installation on ",
1875 $Config::Config{'myhostname'},
1878 "\n\n=head1 SYNOPSIS\n\n",
1879 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1880 "=head1 CONTENTS\n\n",
1881 join("\n", @bundle),
1882 "\n\n=head1 CONFIGURATION\n\n",
1884 "\n\n=head1 AUTHOR\n\n",
1885 "This Bundle has been generated automatically ",
1886 "by the autobundle routine in CPAN.pm.\n",
1889 $CPAN::Frontend->myprint("\nWrote bundle file
1893 #-> sub CPAN::Shell::expandany ;
1896 CPAN->debug("s[$s]") if $CPAN::DEBUG;
1897 if ($s =~ m|/|) { # looks like a file
1898 $s = CPAN::Distribution->normalize($s);
1899 return $CPAN::META->instance('CPAN::Distribution',$s);
1900 # Distributions spring into existence, not expand
1901 } elsif ($s =~ m|^Bundle::|) {
1902 $self->local_bundles; # scanning so late for bundles seems
1903 # both attractive and crumpy: always
1904 # current state but easy to forget
1906 return $self->expand('Bundle',$s);
1908 return $self->expand('Module',$s)
1909 if $CPAN::META->exists('CPAN::Module',$s);
1914 #-> sub CPAN::Shell::expand ;
1917 my($type,@args) = @_;
1918 CPAN->debug("type[$type]args[@args]") if $CPAN::DEBUG;
1919 my $class = "CPAN::$type";
1920 my $methods = ['id'];
1921 for my $meth (qw(name)) {
1922 next if $] < 5.00303; # no "can"
1923 next unless $class->can($meth);
1924 push @$methods, $meth;
1926 $self->expand_by_method($class,$methods,@args);
1929 sub expand_by_method {
1931 my($class,$methods,@args) = @_;
1934 my($regex,$command);
1935 if ($arg =~ m|^/(.*)/$|) {
1937 } elsif ($arg =~ m/=/) {
1941 CPAN->debug(sprintf "class[%s]regex[%s]command[%s]",
1943 defined $regex ? $regex : "UNDEFINED",
1944 defined $command ? $command : "UNDEFINED",
1946 if (defined $regex) {
1948 $CPAN::META->all_objects($class)
1951 # BUG, we got an empty object somewhere
1952 require Data::Dumper;
1953 CPAN->debug(sprintf(
1954 "Bug in CPAN: Empty id on obj[%s][%s]",
1956 Data::Dumper::Dumper($obj)
1960 for my $method (@$methods) {
1961 if ($obj->$method() =~ /$regex/i) {
1967 } elsif ($command) {
1968 die "equal sign in command disabled (immature interface), ".
1970 ! \$CPAN::Shell::ADVANCED_QUERY=1
1971 to enable it. But please note, this is HIGHLY EXPERIMENTAL code
1972 that may go away anytime.\n"
1973 unless $ADVANCED_QUERY;
1974 my($method,$criterion) = $arg =~ /(.+?)=(.+)/;
1975 my($matchcrit) = $criterion =~ m/^~(.+)/;
1979 $CPAN::META->all_objects($class)
1981 my $lhs = $self->$method() or next; # () for 5.00503
1983 push @m, $self if $lhs =~ m/$matchcrit/;
1985 push @m, $self if $lhs eq $criterion;
1990 if ( $class eq 'CPAN::Bundle' ) {
1991 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
1992 } elsif ($class eq "CPAN::Distribution") {
1993 $xarg = CPAN::Distribution->normalize($arg);
1997 if ($CPAN::META->exists($class,$xarg)) {
1998 $obj = $CPAN::META->instance($class,$xarg);
1999 } elsif ($CPAN::META->exists($class,$arg)) {
2000 $obj = $CPAN::META->instance($class,$arg);
2007 @m = sort {$a->id cmp $b->id} @m;
2008 if ( $CPAN::DEBUG ) {
2009 my $wantarray = wantarray;
2010 my $join_m = join ",", map {$_->id} @m;
2011 $self->debug("wantarray[$wantarray]join_m[$join_m]");
2013 return wantarray ? @m : $m[0];
2016 #-> sub CPAN::Shell::format_result ;
2019 my($type,@args) = @_;
2020 @args = '/./' unless @args;
2021 my(@result) = $self->expand($type,@args);
2022 my $result = @result == 1 ?
2023 $result[0]->as_string :
2025 "No objects of type $type found for argument @args\n" :
2027 (map {$_->as_glimpse} @result),
2028 scalar @result, " items found\n",
2033 #-> sub CPAN::Shell::report_fh ;
2035 my $installation_report_fh;
2036 my $previously_noticed = 0;
2039 return $installation_report_fh if $installation_report_fh;
2040 if ($CPAN::META->has_inst("File::Temp")) {
2041 $installation_report_fh
2043 template => 'cpan_install_XXXX',
2048 unless ( $installation_report_fh ) {
2049 warn("Couldn't open installation report file; " .
2050 "no report file will be generated."
2051 ) unless $previously_noticed++;
2057 # The only reason for this method is currently to have a reliable
2058 # debugging utility that reveals which output is going through which
2059 # channel. No, I don't like the colors ;-)
2061 #-> sub CPAN::Shell::print_ornameted ;
2062 sub print_ornamented {
2063 my($self,$what,$ornament) = @_;
2065 return unless defined $what;
2067 local $| = 1; # Flush immediately
2068 if ( $CPAN::Be_Silent ) {
2069 print {report_fh()} $what;
2073 if ($CPAN::Config->{term_is_latin}){
2076 =~ s{([\xC0-\xDF])([\x80-\xBF])}{chr(ord($1)<<6&0xC0|ord($2)&0x3F)}eg; #};
2078 if ($PRINT_ORNAMENTING) {
2079 unless (defined &color) {
2080 if ($CPAN::META->has_inst("Term::ANSIColor")) {
2081 import Term::ANSIColor "color";
2083 *color = sub { return "" };
2087 for $line (split /\n/, $what) {
2088 $longest = length($line) if length($line) > $longest;
2090 my $sprintf = "%-" . $longest . "s";
2092 $what =~ s/(.*\n?)//m;
2095 my($nl) = chomp $line ? "\n" : "";
2096 # print "line[$line]ornament[$ornament]sprintf[$sprintf]\n";
2097 print color($ornament), sprintf($sprintf,$line), color("reset"), $nl;
2101 # $what .= "\n"; # newlines unless $PRINT_ORNAMENTING
2107 my($self,$what) = @_;
2109 $self->print_ornamented($what, 'bold blue on_yellow');
2113 my($self,$what) = @_;
2114 $self->myprint($what);
2119 my($self,$what) = @_;
2120 $self->print_ornamented($what, 'bold red on_yellow');
2124 # my($self,$what) = @_;
2125 # $self->print_ornamented($what, 'bold red on_white');
2126 # Carp::confess "died";
2129 # only to be used for shell commands
2131 my($self,$what) = @_;
2132 $self->print_ornamented($what, 'bold red on_white');
2134 # If it is the shell, we want that the following die to be silent,
2135 # but if it is not the shell, we would need a 'die $what'. We need
2136 # to take care that only shell commands use mydie. Is this
2142 # use this only for unrecoverable errors!
2143 sub unrecoverable_error {
2144 my($self,$what) = @_;
2145 my @lines = split /\n/, $what;
2147 for my $l (@lines) {
2148 $longest = length $l if length $l > $longest;
2150 $longest = 62 if $longest > 62;
2151 for my $l (@lines) {
2157 if (length $l < 66) {
2158 $l = pack "A66 A*", $l, "<==";
2162 unshift @lines, "\n";
2163 $self->mydie(join "", @lines);
2167 my($self, $sleep) = @_;
2172 return if -t STDOUT;
2173 my $odef = select STDERR;
2180 #-> sub CPAN::Shell::rematein ;
2181 # RE-adme||MA-ke||TE-st||IN-stall
2184 my($meth,@some) = @_;
2186 while($meth =~ /^(force|notest)$/) {
2187 push @pragma, $meth;
2188 $meth = shift @some or
2189 $CPAN::Frontend->mydie("Pragma $pragma[-1] used without method: ".
2193 CPAN->debug("pragma[@pragma]meth[$meth]some[@some]") if $CPAN::DEBUG;
2195 # Here is the place to set "test_count" on all involved parties to
2196 # 0. We then can pass this counter on to the involved
2197 # distributions and those can refuse to test if test_count > X. In
2198 # the first stab at it we could use a 1 for "X".
2200 # But when do I reset the distributions to start with 0 again?
2201 # Jost suggested to have a random or cycling interaction ID that
2202 # we pass through. But the ID is something that is just left lying
2203 # around in addition to the counter, so I'd prefer to set the
2204 # counter to 0 now, and repeat at the end of the loop. But what
2205 # about dependencies? They appear later and are not reset, they
2206 # enter the queue but not its copy. How do they get a sensible
2209 # construct the queue
2211 STHING: foreach $s (@some) {
2214 CPAN->debug("s is an object[$s]") if $CPAN::DEBUG;
2216 } elsif ($s =~ m|^/|) { # looks like a regexp
2217 $CPAN::Frontend->mywarn("Sorry, $meth with a regular expression is ".
2221 } elsif ($meth eq "ls") {
2222 $self->globls($s,\@pragma);
2225 CPAN->debug("calling expandany [$s]") if $CPAN::DEBUG;
2226 $obj = CPAN::Shell->expandany($s);
2229 $obj->color_cmd_tmps(0,1);
2230 CPAN::Queue->new($obj->id);
2232 } elsif ($CPAN::META->exists('CPAN::Author',uc($s))) {
2233 $obj = $CPAN::META->instance('CPAN::Author',uc($s));
2234 if ($meth =~ /^(dump|ls)$/) {
2237 $CPAN::Frontend->myprint(
2239 "Don't be silly, you can't $meth ",
2247 ->myprint(qq{Warning: Cannot $meth $s, }.
2248 qq{don\'t know what it is.
2253 to find objects with matching identifiers.
2259 # queuerunner (please be warned: when I started to change the
2260 # queue to hold objects instead of names, I made one or two
2261 # mistakes and never found which. I reverted back instead)
2262 while ($s = CPAN::Queue->first) {
2265 $obj = $s; # I do not believe, we would survive if this happened
2267 $obj = CPAN::Shell->expandany($s);
2269 for my $pragma (@pragma) {
2272 ($] < 5.00303 || $obj->can($pragma))){
2273 ### compatibility with 5.003
2274 $obj->$pragma($meth); # the pragma "force" in
2275 # "CPAN::Distribution" must know
2276 # what we are intending
2279 if ($]>=5.00303 && $obj->can('called_for')) {
2280 $obj->called_for($s);
2283 qq{pragma[@pragma]meth[$meth]obj[$obj]as_string[$obj->{ID}]}
2287 CPAN::Queue->delete($s);
2289 CPAN->debug("failed");
2293 CPAN::Queue->delete_first($s);
2295 for my $obj (@qcopy) {
2296 $obj->color_cmd_tmps(0,0);
2297 delete $obj->{incommandcolor};
2301 #-> sub CPAN::Shell::recent ;
2305 CPAN::Distribution::_display_url( $self, $CPAN::Defaultrecent );
2310 # set up the dispatching methods
2312 for my $command (qw(
2327 *$command = sub { shift->rematein($command, @_); };
2331 package CPAN::LWP::UserAgent;
2335 return if $SETUPDONE;
2336 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2337 require LWP::UserAgent;
2338 @ISA = qw(Exporter LWP::UserAgent);
2341 $CPAN::Frontend->mywarn("LWP::UserAgent not available\n");
2345 sub get_basic_credentials {
2346 my($self, $realm, $uri, $proxy) = @_;
2347 return unless $proxy;
2348 if ($USER && $PASSWD) {
2349 } elsif (defined $CPAN::Config->{proxy_user} &&
2350 defined $CPAN::Config->{proxy_pass}) {
2351 $USER = $CPAN::Config->{proxy_user};
2352 $PASSWD = $CPAN::Config->{proxy_pass};
2354 ExtUtils::MakeMaker->import(qw(prompt));
2355 $USER = prompt("Proxy authentication needed!
2356 (Note: to permanently configure username and password run
2357 o conf proxy_user your_username
2358 o conf proxy_pass your_password
2360 if ($CPAN::META->has_inst("Term::ReadKey")) {
2361 Term::ReadKey::ReadMode("noecho");
2363 $CPAN::Frontend->mywarn("Warning: Term::ReadKey seems not to be available, your password will be echoed to the terminal!\n");
2365 $PASSWD = prompt("Password:");
2366 if ($CPAN::META->has_inst("Term::ReadKey")) {
2367 Term::ReadKey::ReadMode("restore");
2369 $CPAN::Frontend->myprint("\n\n");
2371 return($USER,$PASSWD);
2374 # mirror(): Its purpose is to deal with proxy authentication. When we
2375 # call SUPER::mirror, we relly call the mirror method in
2376 # LWP::UserAgent. LWP::UserAgent will then call
2377 # $self->get_basic_credentials or some equivalent and this will be
2378 # $self->dispatched to our own get_basic_credentials method.
2380 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
2382 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
2383 # although we have gone through our get_basic_credentials, the proxy
2384 # server refuses to connect. This could be a case where the username or
2385 # password has changed in the meantime, so I'm trying once again without
2386 # $USER and $PASSWD to give the get_basic_credentials routine another
2387 # chance to set $USER and $PASSWD.
2389 # mirror(): Its purpose is to deal with proxy authentication. When we
2390 # call SUPER::mirror, we relly call the mirror method in
2391 # LWP::UserAgent. LWP::UserAgent will then call
2392 # $self->get_basic_credentials or some equivalent and this will be
2393 # $self->dispatched to our own get_basic_credentials method.
2395 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
2397 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
2398 # although we have gone through our get_basic_credentials, the proxy
2399 # server refuses to connect. This could be a case where the username or
2400 # password has changed in the meantime, so I'm trying once again without
2401 # $USER and $PASSWD to give the get_basic_credentials routine another
2402 # chance to set $USER and $PASSWD.
2405 my($self,$url,$aslocal) = @_;
2406 my $result = $self->SUPER::mirror($url,$aslocal);
2407 if ($result->code == 407) {
2410 $result = $self->SUPER::mirror($url,$aslocal);
2418 #-> sub CPAN::FTP::ftp_get ;
2420 my($class,$host,$dir,$file,$target) = @_;
2422 qq[Going to fetch file [$file] from dir [$dir]
2423 on host [$host] as local [$target]\n]
2425 my $ftp = Net::FTP->new($host);
2427 $CPAN::Frontend->mywarn(" Could not connect to host '$host' with Net::FTP\n");
2430 return 0 unless defined $ftp;
2431 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
2432 $class->debug(qq[Going to login("anonymous","$Config::Config{cf_email}")]);
2433 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
2434 my $msg = $ftp->message;
2435 $CPAN::Frontend->mywarn(" Couldn't login on $host: $msg");
2438 unless ( $ftp->cwd($dir) ){
2439 my $msg = $ftp->message;
2440 $CPAN::Frontend->mywarn(" Couldn't cwd $dir: $msg");
2444 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
2445 unless ( $ftp->get($file,$target) ){
2446 my $msg = $ftp->message;
2447 $CPAN::Frontend->mywarn(" Couldn't fetch $file from $host: $msg");
2450 $ftp->quit; # it's ok if this fails
2454 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
2456 # > *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
2457 # > --- /tmp/cp Wed Sep 24 13:26:40 1997
2459 # > *** 1562,1567 ****
2460 # > --- 1562,1580 ----
2461 # > return 1 if substr($url,0,4) eq "file";
2462 # > return 1 unless $url =~ m|://([^/]+)|;
2464 # > + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
2466 # > + $proxy =~ m|://([^/:]+)|;
2468 # > + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
2469 # > + if ($noproxy) {
2470 # > + if ($host !~ /$noproxy$/) {
2471 # > + $host = $proxy;
2474 # > + $host = $proxy;
2477 # > require Net::Ping;
2478 # > return 1 unless $Net::Ping::VERSION >= 2;
2482 #-> sub CPAN::FTP::localize ;
2484 my($self,$file,$aslocal,$force) = @_;
2486 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
2487 unless defined $aslocal;
2488 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
2491 if ($^O eq 'MacOS') {
2492 # Comment by AK on 2000-09-03: Uniq short filenames would be
2493 # available in CHECKSUMS file
2494 my($name, $path) = File::Basename::fileparse($aslocal, '');
2495 if (length($name) > 31) {
2506 my $size = 31 - length($suf);
2507 while (length($name) > $size) {
2511 $aslocal = File::Spec->catfile($path, $name);
2515 if (-f $aslocal && -r _ && !($force & 1)){
2517 if ($size = -s $aslocal) {
2518 $self->debug("aslocal[$aslocal]size[$size]") if $CPAN::DEBUG;
2521 # empty file from a previous unsuccessful attempt to download it
2523 $CPAN::Frontend->mydie("Found a zero-length '$aslocal' that I could not remove.");
2528 rename $aslocal, "$aslocal.bak";
2532 my($aslocal_dir) = File::Basename::dirname($aslocal);
2533 File::Path::mkpath($aslocal_dir);
2534 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
2535 qq{directory "$aslocal_dir".
2536 I\'ll continue, but if you encounter problems, they may be due
2537 to insufficient permissions.\n}) unless -w $aslocal_dir;
2539 # Inheritance is not easier to manage than a few if/else branches
2540 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2542 CPAN::LWP::UserAgent->config;
2543 eval {$Ua = CPAN::LWP::UserAgent->new;}; # Why is has_usable still not fit enough?
2545 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n")
2549 $Ua->proxy('ftp', $var)
2550 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
2551 $Ua->proxy('http', $var)
2552 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
2555 # >>>>> On Wed, 13 Dec 2000 09:21:34 -0500, "Robison, Jonathon (J.M.)" <jrobiso2@visteon.com> said:
2557 # > I note that although CPAN.pm can use proxies, it doesn't seem equipped to
2558 # > use ones that require basic autorization.
2560 # > Example of when I use it manually in my own stuff:
2562 # > $ua->proxy(['http','ftp'], http://my.proxy.server:83');
2563 # > $req->proxy_authorization_basic("username","password");
2564 # > $res = $ua->request($req);
2568 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
2572 for my $prx (qw(ftp_proxy http_proxy no_proxy)) {
2573 $ENV{$prx} = $CPAN::Config->{$prx} if $CPAN::Config->{$prx};
2576 # Try the list of urls for each single object. We keep a record
2577 # where we did get a file from
2578 my(@reordered,$last);
2579 $CPAN::Config->{urllist} ||= [];
2580 unless (ref $CPAN::Config->{urllist} eq 'ARRAY') {
2581 $CPAN::Frontend->mywarn("Malformed urllist; ignoring. Configuration file corrupt?\n");
2582 $CPAN::Config->{urllist} = [];
2584 $last = $#{$CPAN::Config->{urllist}};
2585 if ($force & 2) { # local cpans probably out of date, don't reorder
2586 @reordered = (0..$last);
2590 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
2592 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
2594 defined($ThesiteURL)
2596 ($CPAN::Config->{urllist}[$b] eq $ThesiteURL)
2598 ($CPAN::Config->{urllist}[$a] eq $ThesiteURL)
2603 @levels = ($Themethod, grep {$_ ne $Themethod} qw/easy hard hardest/);
2605 @levels = qw/easy hard hardest/;
2607 @levels = qw/easy/ if $^O eq 'MacOS';
2609 local $ENV{FTP_PASSIVE} =
2610 exists $CPAN::Config->{ftp_passive} ?
2611 $CPAN::Config->{ftp_passive} : 1;
2612 for $levelno (0..$#levels) {
2613 my $level = $levels[$levelno];
2614 my $method = "host$level";
2615 my @host_seq = $level eq "easy" ?
2616 @reordered : 0..$last; # reordered has CDROM up front
2617 my @urllist = map { $CPAN::Config->{urllist}[$_] } @host_seq;
2618 for my $u (@urllist) {
2619 $u .= "/" unless substr($u,-1) eq "/";
2621 for my $u (@CPAN::Defaultsites) {
2622 push @urllist, $u unless grep { $_ eq $u } @urllist;
2624 $self->debug("synth. urllist[@urllist]") if $CPAN::DEBUG;
2625 my $ret = $self->$method(\@urllist,$file,$aslocal);
2627 $Themethod = $level;
2629 # utime $now, $now, $aslocal; # too bad, if we do that, we
2630 # might alter a local mirror
2631 $self->debug("level[$level]") if $CPAN::DEBUG;
2635 last if $CPAN::Signal; # need to cleanup
2638 unless ($CPAN::Signal) {
2641 qq{Please check, if the URLs I found in your configuration file \(}.
2642 join(", ", @{$CPAN::Config->{urllist}}).
2643 qq{\) are valid. The urllist can be edited.},
2644 qq{E.g. with 'o conf urllist push ftp://myurl/'};
2645 $CPAN::Frontend->myprint(Text::Wrap::wrap("","",@mess). "\n\n");
2647 $CPAN::Frontend->myprint("Could not fetch $file\n");
2650 rename "$aslocal.bak", $aslocal;
2651 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
2652 $self->ls($aslocal));
2658 # package CPAN::FTP;
2660 my($self,$host_seq,$file,$aslocal) = @_;
2662 HOSTEASY: for $ro_url (@$host_seq) {
2663 my $url .= "$ro_url$file";
2664 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
2665 if ($url =~ /^file:/) {
2667 if ($CPAN::META->has_inst('URI::URL')) {
2668 my $u = URI::URL->new($url);
2670 } else { # works only on Unix, is poorly constructed, but
2671 # hopefully better than nothing.
2672 # RFC 1738 says fileurl BNF is
2673 # fileurl = "file://" [ host | "localhost" ] "/" fpath
2674 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
2676 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
2677 $l =~ s|^file:||; # assume they
2681 if ! -f $l && $l =~ m|^/\w:|; # e.g. /P:
2683 $self->debug("local file[$l]") if $CPAN::DEBUG;
2684 if ( -f $l && -r _) {
2685 $ThesiteURL = $ro_url;
2688 if ($l =~ /(.+)\.gz$/) {
2690 if ( -f $ungz && -r _) {
2691 $ThesiteURL = $ro_url;
2695 # Maybe mirror has compressed it?
2697 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
2698 CPAN::Tarzip->new("$l.gz")->gunzip($aslocal);
2700 $ThesiteURL = $ro_url;
2705 if ($CPAN::META->has_usable('LWP')) {
2706 $CPAN::Frontend->myprint("Fetching with LWP:
2710 CPAN::LWP::UserAgent->config;
2711 eval { $Ua = CPAN::LWP::UserAgent->new; };
2713 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n");
2716 my $res = $Ua->mirror($url, $aslocal);
2717 if ($res->is_success) {
2718 $ThesiteURL = $ro_url;
2720 utime $now, $now, $aslocal; # download time is more
2721 # important than upload time
2723 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2724 my $gzurl = "$url.gz";
2725 $CPAN::Frontend->myprint("Fetching with LWP:
2728 $res = $Ua->mirror($gzurl, "$aslocal.gz");
2729 if ($res->is_success &&
2730 CPAN::Tarzip->new("$aslocal.gz")->gunzip($aslocal)
2732 $ThesiteURL = $ro_url;
2736 $CPAN::Frontend->myprint(sprintf(
2737 "LWP failed with code[%s] message[%s]\n",
2741 # Alan Burlison informed me that in firewall environments
2742 # Net::FTP can still succeed where LWP fails. So we do not
2743 # skip Net::FTP anymore when LWP is available.
2746 $CPAN::Frontend->myprint("LWP not available\n");
2748 return if $CPAN::Signal;
2749 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2750 # that's the nice and easy way thanks to Graham
2751 my($host,$dir,$getfile) = ($1,$2,$3);
2752 if ($CPAN::META->has_usable('Net::FTP')) {
2754 $CPAN::Frontend->myprint("Fetching with Net::FTP:
2757 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
2758 "aslocal[$aslocal]") if $CPAN::DEBUG;
2759 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
2760 $ThesiteURL = $ro_url;
2763 if ($aslocal !~ /\.gz(?!\n)\Z/) {
2764 my $gz = "$aslocal.gz";
2765 $CPAN::Frontend->myprint("Fetching with Net::FTP
2768 if (CPAN::FTP->ftp_get($host,
2772 CPAN::Tarzip->new($gz)->gunzip($aslocal)
2774 $ThesiteURL = $ro_url;
2781 return if $CPAN::Signal;
2785 # package CPAN::FTP;
2787 my($self,$host_seq,$file,$aslocal) = @_;
2789 # Came back if Net::FTP couldn't establish connection (or
2790 # failed otherwise) Maybe they are behind a firewall, but they
2791 # gave us a socksified (or other) ftp program...
2794 my($devnull) = $CPAN::Config->{devnull} || "";
2796 my($aslocal_dir) = File::Basename::dirname($aslocal);
2797 File::Path::mkpath($aslocal_dir);
2798 HOSTHARD: for $ro_url (@$host_seq) {
2799 my $url = "$ro_url$file";
2800 my($proto,$host,$dir,$getfile);
2802 # Courtesy Mark Conty mark_conty@cargill.com change from
2803 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2805 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
2806 # proto not yet used
2807 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
2809 next HOSTHARD; # who said, we could ftp anything except ftp?
2811 next HOSTHARD if $proto eq "file"; # file URLs would have had
2812 # success above. Likely a bogus URL
2814 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
2816 # Try the most capable first and leave ncftp* for last as it only
2818 DLPRG: for my $f (qw(curl wget lynx ncftpget ncftp)) {
2819 my $funkyftp = $CPAN::Config->{$f};
2820 next unless defined $funkyftp;
2821 next if $funkyftp =~ /^\s*$/;
2823 my($asl_ungz, $asl_gz);
2824 ($asl_ungz = $aslocal) =~ s/\.gz//;
2825 $asl_gz = "$asl_ungz.gz";
2827 my($src_switch) = "";
2829 my($stdout_redir) = " > $asl_ungz";
2831 $src_switch = " -source";
2832 } elsif ($f eq "ncftp"){
2833 $src_switch = " -c";
2834 } elsif ($f eq "wget"){
2835 $src_switch = " -O $asl_ungz";
2837 } elsif ($f eq 'curl'){
2838 $src_switch = ' -L -f -s -S --netrc-optional';
2841 if ($f eq "ncftpget"){
2842 $chdir = "cd $aslocal_dir && ";
2845 $CPAN::Frontend->myprint(
2847 Trying with "$funkyftp$src_switch" to get
2851 "$chdir$funkyftp$src_switch \"$url\" $devnull$stdout_redir";
2852 $self->debug("system[$system]") if $CPAN::DEBUG;
2853 my($wstatus) = system($system);
2855 # lynx returns 0 when it fails somewhere
2857 my $content = do { local *FH; open FH, $asl_ungz or die; local $/; <FH> };
2858 if ($content =~ /^<.*<title>[45]/si) {
2859 $CPAN::Frontend->myprint(qq{
2860 No success, the file that lynx has has downloaded looks like an error message:
2863 $CPAN::Frontend->mysleep(1);
2867 $CPAN::Frontend->myprint(qq{
2868 No success, the file that lynx has has downloaded is an empty file.
2873 if ($wstatus == 0) {
2876 } elsif ($asl_ungz ne $aslocal) {
2877 # test gzip integrity
2878 if (CPAN::Tarzip->new($asl_ungz)->gtest) {
2879 # e.g. foo.tar is gzipped --> foo.tar.gz
2880 rename $asl_ungz, $aslocal;
2882 CPAN::Tarzip->new($asl_gz)->gzip($asl_ungz);
2885 $ThesiteURL = $ro_url;
2887 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2889 -f $asl_ungz && -s _ == 0;
2890 my $gz = "$aslocal.gz";
2891 my $gzurl = "$url.gz";
2892 $CPAN::Frontend->myprint(
2894 Trying with "$funkyftp$src_switch" to get
2897 my($system) = "$funkyftp$src_switch \"$url.gz\" $devnull > $asl_gz";
2898 $self->debug("system[$system]") if $CPAN::DEBUG;
2900 if (($wstatus = system($system)) == 0
2904 # test gzip integrity
2905 my $ct = CPAN::Tarzip->new($asl_gz);
2907 $ct->gunzip($aslocal);
2909 # somebody uncompressed file for us?
2910 rename $asl_ungz, $aslocal;
2912 $ThesiteURL = $ro_url;
2915 unlink $asl_gz if -f $asl_gz;
2918 my $estatus = $wstatus >> 8;
2919 my $size = -f $aslocal ?
2920 ", left\n$aslocal with size ".-s _ :
2921 "\nWarning: expected file [$aslocal] doesn't exist";
2922 $CPAN::Frontend->myprint(qq{
2923 System call "$system"
2924 returned status $estatus (wstat $wstatus)$size
2927 return if $CPAN::Signal;
2928 } # transfer programs
2932 # package CPAN::FTP;
2934 my($self,$host_seq,$file,$aslocal) = @_;
2937 my($aslocal_dir) = File::Basename::dirname($aslocal);
2938 File::Path::mkpath($aslocal_dir);
2939 my $ftpbin = $CPAN::Config->{ftp};
2940 unless (length $ftpbin && MM->maybe_command($ftpbin)) {
2941 $CPAN::Frontend->myprint("No external ftp command available\n\n");
2944 $CPAN::Frontend->myprint(qq{
2945 As a last ressort we now switch to the external ftp command '$ftpbin'
2948 Doing so often leads to problems that are hard to diagnose, even endless
2949 loops may be encountered.
2951 If you're victim of such problems, please consider unsetting the ftp
2952 config variable with
2958 $CPAN::Frontend->mysleep(4);
2959 HOSTHARDEST: for $ro_url (@$host_seq) {
2960 my $url = "$ro_url$file";
2961 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
2962 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2965 my($host,$dir,$getfile) = ($1,$2,$3);
2967 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
2968 $ctime,$blksize,$blocks) = stat($aslocal);
2969 $timestamp = $mtime ||= 0;
2970 my($netrc) = CPAN::FTP::netrc->new;
2971 my($netrcfile) = $netrc->netrc;
2972 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
2973 my $targetfile = File::Basename::basename($aslocal);
2979 map("cd $_", split /\//, $dir), # RFC 1738
2981 "get $getfile $targetfile",
2985 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
2986 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
2987 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
2989 $netrc->contains($host))) if $CPAN::DEBUG;
2990 if ($netrc->protected) {
2991 my $dialog = join "", map { " $_\n" } @dialog;
2993 if ($netrc->contains($host)) {
2994 $netrc_explain = "Relying that your .netrc entry for '$host' ".
2995 "manages the login";
2997 $netrc_explain = "Relying that your default .netrc entry ".
2998 "manages the login";
3000 $CPAN::Frontend->myprint(qq{
3001 Trying with external ftp to get
3004 Going to send the dialog
3008 $self->talk_ftp("$ftpbin$verbose $host",
3010 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3011 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
3013 if ($mtime > $timestamp) {
3014 $CPAN::Frontend->myprint("GOT $aslocal\n");
3015 $ThesiteURL = $ro_url;
3018 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
3020 return if $CPAN::Signal;
3022 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
3023 qq{correctly protected.\n});
3026 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
3027 nor does it have a default entry\n");
3030 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
3031 # then and login manually to host, using e-mail as
3033 $CPAN::Frontend->myprint(qq{Issuing "$ftpbin$verbose -n"\n});
3037 "user anonymous $Config::Config{'cf_email'}"
3039 my $dialog = join "", map { " $_\n" } @dialog;
3040 $CPAN::Frontend->myprint(qq{
3041 Trying with external ftp to get
3043 Going to send the dialog
3047 $self->talk_ftp("$ftpbin$verbose -n", @dialog);
3048 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3049 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
3051 if ($mtime > $timestamp) {
3052 $CPAN::Frontend->myprint("GOT $aslocal\n");
3053 $ThesiteURL = $ro_url;
3056 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
3058 return if $CPAN::Signal;
3059 $CPAN::Frontend->myprint("Can't access URL $url.\n\n");
3064 # package CPAN::FTP;
3066 my($self,$command,@dialog) = @_;
3067 my $fh = FileHandle->new;
3068 $fh->open("|$command") or die "Couldn't open ftp: $!";
3069 foreach (@dialog) { $fh->print("$_\n") }
3070 $fh->close; # Wait for process to complete
3072 my $estatus = $wstatus >> 8;
3073 $CPAN::Frontend->myprint(qq{
3074 Subprocess "|$command"
3075 returned status $estatus (wstat $wstatus)
3079 # find2perl needs modularization, too, all the following is stolen
3083 my($self,$name) = @_;
3084 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
3085 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
3087 my($perms,%user,%group);
3091 $blocks = int(($blocks + 1) / 2);
3094 $blocks = int(($sizemm + 1023) / 1024);
3097 if (-f _) { $perms = '-'; }
3098 elsif (-d _) { $perms = 'd'; }
3099 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
3100 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
3101 elsif (-p _) { $perms = 'p'; }
3102 elsif (-S _) { $perms = 's'; }
3103 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
3105 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
3106 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
3107 my $tmpmode = $mode;
3108 my $tmp = $rwx[$tmpmode & 7];
3110 $tmp = $rwx[$tmpmode & 7] . $tmp;
3112 $tmp = $rwx[$tmpmode & 7] . $tmp;
3113 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
3114 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
3115 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
3118 my $user = $user{$uid} || $uid; # too lazy to implement lookup
3119 my $group = $group{$gid} || $gid;
3121 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
3123 my($moname) = $moname[$mon];
3124 if (-M _ > 365.25 / 2) {
3125 $timeyear = $year + 1900;
3128 $timeyear = sprintf("%02d:%02d", $hour, $min);
3131 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
3145 package CPAN::FTP::netrc;
3148 # package CPAN::FTP::netrc;
3151 my $file = File::Spec->catfile($ENV{HOME},".netrc");
3153 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3154 $atime,$mtime,$ctime,$blksize,$blocks)
3159 my($fh,@machines,$hasdefault);
3161 $fh = FileHandle->new or die "Could not create a filehandle";
3163 if($fh->open($file)){
3164 $protected = ($mode & 077) == 0;
3166 NETRC: while (<$fh>) {
3167 my(@tokens) = split " ", $_;
3168 TOKEN: while (@tokens) {
3169 my($t) = shift @tokens;
3170 if ($t eq "default"){
3174 last TOKEN if $t eq "macdef";
3175 if ($t eq "machine") {
3176 push @machines, shift @tokens;
3181 $file = $hasdefault = $protected = "";
3185 'mach' => [@machines],
3187 'hasdefault' => $hasdefault,
3188 'protected' => $protected,
3192 # CPAN::FTP::netrc::hasdefault;
3193 sub hasdefault { shift->{'hasdefault'} }
3194 sub netrc { shift->{'netrc'} }
3195 sub protected { shift->{'protected'} }
3197 my($self,$mach) = @_;
3198 for ( @{$self->{'mach'}} ) {
3199 return 1 if $_ eq $mach;
3204 package CPAN::Complete;
3208 my($text, $line, $start, $end) = @_;
3209 my(@perlret) = cpl($text, $line, $start);
3210 # find longest common match. Can anybody show me how to peruse
3211 # T::R::Gnu to have this done automatically? Seems expensive.
3212 return () unless @perlret;
3213 my($newtext) = $text;
3214 for (my $i = length($text)+1;;$i++) {
3215 last unless length($perlret[0]) && length($perlret[0]) >= $i;
3216 my $try = substr($perlret[0],0,$i);
3217 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
3218 # warn "try[$try]tries[@tries]";
3219 if (@tries == @perlret) {
3225 ($newtext,@perlret);
3228 #-> sub CPAN::Complete::cpl ;
3230 my($word,$line,$pos) = @_;
3234 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3236 if ($line =~ s/^(force\s*)//) {
3241 @return = grep /^$word/, @CPAN::Complete::COMMANDS;
3242 } elsif ( $line !~ /^[\!abcdghimorutl]/ ) {
3244 } elsif ($line =~ /^(a|ls)\s/) {
3245 @return = cplx('CPAN::Author',uc($word));
3246 } elsif ($line =~ /^b\s/) {
3247 CPAN::Shell->local_bundles;
3248 @return = cplx('CPAN::Bundle',$word);
3249 } elsif ($line =~ /^d\s/) {
3250 @return = cplx('CPAN::Distribution',$word);
3251 } elsif ($line =~ m/^(
3252 [mru]|make|clean|dump|get|test|install|readme|look|cvs_import|perldoc|recent
3254 if ($word =~ /^Bundle::/) {
3255 CPAN::Shell->local_bundles;
3257 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
3258 } elsif ($line =~ /^i\s/) {
3259 @return = cpl_any($word);
3260 } elsif ($line =~ /^reload\s/) {
3261 @return = cpl_reload($word,$line,$pos);
3262 } elsif ($line =~ /^o\s/) {
3263 @return = cpl_option($word,$line,$pos);
3264 } elsif ($line =~ m/^\S+\s/ ) {
3265 # fallback for future commands and what we have forgotten above
3266 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
3273 #-> sub CPAN::Complete::cplx ;
3275 my($class, $word) = @_;
3276 # I believed for many years that this was sorted, today I
3277 # realized, it wasn't sorted anymore. Now (rev 1.301 / v 1.55) I
3278 # make it sorted again. Maybe sort was dropped when GNU-readline
3279 # support came in? The RCS file is difficult to read on that:-(
3280 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
3283 #-> sub CPAN::Complete::cpl_any ;
3287 cplx('CPAN::Author',$word),
3288 cplx('CPAN::Bundle',$word),
3289 cplx('CPAN::Distribution',$word),
3290 cplx('CPAN::Module',$word),
3294 #-> sub CPAN::Complete::cpl_reload ;
3296 my($word,$line,$pos) = @_;
3298 my(@words) = split " ", $line;
3299 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3300 my(@ok) = qw(cpan index);
3301 return @ok if @words == 1;
3302 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
3305 #-> sub CPAN::Complete::cpl_option ;
3307 my($word,$line,$pos) = @_;
3309 my(@words) = split " ", $line;
3310 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3311 my(@ok) = qw(conf debug);
3312 return @ok if @words == 1;
3313 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
3315 } elsif ($words[1] eq 'index') {
3317 } elsif ($words[1] eq 'conf') {
3318 return CPAN::HandleConfig::cpl(@_);
3319 } elsif ($words[1] eq 'debug') {
3320 return sort grep /^\Q$word\E/i,
3321 sort keys %CPAN::DEBUG, 'all';
3325 package CPAN::Index;
3328 #-> sub CPAN::Index::force_reload ;
3331 $CPAN::Index::LAST_TIME = 0;
3335 #-> sub CPAN::Index::reload ;
3337 my($cl,$force) = @_;
3340 # XXX check if a newer one is available. (We currently read it
3341 # from time to time)
3342 for ($CPAN::Config->{index_expire}) {
3343 $_ = 0.001 unless $_ && $_ > 0.001;
3345 unless (1 || $CPAN::Have_warned->{readmetadatacache}++) {
3346 # debug here when CPAN doesn't seem to read the Metadata
3348 Carp::cluck("META-PROTOCOL[$CPAN::META->{PROTOCOL}]");
3350 unless ($CPAN::META->{PROTOCOL}) {
3351 $cl->read_metadata_cache;
3352 $CPAN::META->{PROTOCOL} ||= "1.0";
3354 if ( $CPAN::META->{PROTOCOL} < PROTOCOL ) {
3355 # warn "Setting last_time to 0";
3356 $LAST_TIME = 0; # No warning necessary
3358 return if $LAST_TIME + $CPAN::Config->{index_expire}*86400 > $time
3361 # IFF we are developing, it helps to wipe out the memory
3362 # between reloads, otherwise it is not what a user expects.
3363 undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
3364 $CPAN::META = CPAN->new;
3368 local $LAST_TIME = $time;
3369 local $CPAN::META->{PROTOCOL} = PROTOCOL;
3371 my $needshort = $^O eq "dos";
3373 $cl->rd_authindex($cl
3375 "authors/01mailrc.txt.gz",
3377 File::Spec->catfile('authors', '01mailrc.gz') :
3378 File::Spec->catfile('authors', '01mailrc.txt.gz'),
3381 $debug = "timing reading 01[".($t2 - $time)."]";
3383 return if $CPAN::Signal; # this is sometimes lengthy
3384 $cl->rd_modpacks($cl
3386 "modules/02packages.details.txt.gz",
3388 File::Spec->catfile('modules', '02packag.gz') :
3389 File::Spec->catfile('modules', '02packages.details.txt.gz'),
3392 $debug .= "02[".($t2 - $time)."]";
3394 return if $CPAN::Signal; # this is sometimes lengthy
3397 "modules/03modlist.data.gz",
3399 File::Spec->catfile('modules', '03mlist.gz') :
3400 File::Spec->catfile('modules', '03modlist.data.gz'),
3402 $cl->write_metadata_cache;
3404 $debug .= "03[".($t2 - $time)."]";
3406 CPAN->debug($debug) if $CPAN::DEBUG;
3409 $CPAN::META->{PROTOCOL} = PROTOCOL;
3412 #-> sub CPAN::Index::reload_x ;
3414 my($cl,$wanted,$localname,$force) = @_;
3415 $force |= 2; # means we're dealing with an index here
3416 CPAN::HandleConfig->load; # we should guarantee loading wherever we rely
3418 $localname ||= $wanted;
3419 my $abs_wanted = File::Spec->catfile($CPAN::Config->{'keep_source_where'},
3423 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
3426 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
3427 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
3428 qq{day$s. I\'ll use that.});
3431 $force |= 1; # means we're quite serious about it.
3433 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
3436 #-> sub CPAN::Index::rd_authindex ;
3438 my($cl, $index_target) = @_;
3440 return unless defined $index_target;
3441 $CPAN::Frontend->myprint("Going to read $index_target\n");
3443 tie *FH, 'CPAN::Tarzip', $index_target;
3446 push @lines, split /\012/ while <FH>;
3448 my($userid,$fullname,$email) =
3449 m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
3450 next unless $userid && $fullname && $email;
3452 # instantiate an author object
3453 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
3454 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
3455 return if $CPAN::Signal;
3460 my($self,$dist) = @_;
3461 $dist = $self->{'id'} unless defined $dist;
3462 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
3466 #-> sub CPAN::Index::rd_modpacks ;
3468 my($self, $index_target) = @_;
3470 return unless defined $index_target;
3471 $CPAN::Frontend->myprint("Going to read $index_target\n");
3472 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3475 while ($_ = $fh->READLINE) {
3477 my @ls = map {"$_\n"} split /\n/, $_;
3478 unshift @ls, "\n" x length($1) if /^(\n+)/;
3482 my($line_count,$last_updated);
3484 my $shift = shift(@lines);
3485 last if $shift =~ /^\s*$/;
3486 $shift =~ /^Line-Count:\s+(\d+)/ and $line_count = $1;
3487 $shift =~ /^Last-Updated:\s+(.+)/ and $last_updated = $1;
3489 if (not defined $line_count) {
3491 warn qq{Warning: Your $index_target does not contain a Line-Count header.
3492 Please check the validity of the index file by comparing it to more
3493 than one CPAN mirror. I'll continue but problems seem likely to
3498 } elsif ($line_count != scalar @lines) {
3500 warn sprintf qq{Warning: Your %s
3501 contains a Line-Count header of %d but I see %d lines there. Please
3502 check the validity of the index file by comparing it to more than one
3503 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
3504 $index_target, $line_count, scalar(@lines);
3507 if (not defined $last_updated) {
3509 warn qq{Warning: Your $index_target does not contain a Last-Updated header.
3510 Please check the validity of the index file by comparing it to more
3511 than one CPAN mirror. I'll continue but problems seem likely to
3519 ->myprint(sprintf qq{ Database was generated on %s\n},
3521 $DATE_OF_02 = $last_updated;
3524 if ($CPAN::META->has_inst('HTTP::Date')) {
3526 $age -= HTTP::Date::str2time($last_updated);
3528 $CPAN::Frontend->myprint(" HTTP::Date not available\n");
3529 require Time::Local;
3530 my(@d) = $last_updated =~ / (\d+) (\w+) (\d+) (\d+):(\d+):(\d+) /;
3531 $d[1] = index("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", $d[1])/4;
3532 $age -= $d[1]>=0 ? Time::Local::timegm(@d[5,4,3,0,1,2]) : 0;
3539 qq{Warning: This index file is %d days old.
3540 Please check the host you chose as your CPAN mirror for staleness.
3541 I'll continue but problems seem likely to happen.\a\n},
3544 } elsif ($age < -1) {
3548 qq{Warning: Your system date is %d days behind this index file!
3550 Timestamp index file: %s
3551 Please fix your system time, problems with the make command expected.\n},
3561 # A necessity since we have metadata_cache: delete what isn't
3563 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
3564 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
3568 # before 1.56 we split into 3 and discarded the rest. From
3569 # 1.57 we assign remaining text to $comment thus allowing to
3570 # influence isa_perl
3571 my($mod,$version,$dist,$comment) = split " ", $_, 4;
3572 my($bundle,$id,$userid);
3574 if ($mod eq 'CPAN' &&
3576 CPAN::Queue->exists('Bundle::CPAN') ||
3577 CPAN::Queue->exists('CPAN')
3581 if ($version > $CPAN::VERSION){
3582 $CPAN::Frontend->myprint(qq{
3583 There's a new CPAN.pm version (v$version) available!
3584 [Current version is v$CPAN::VERSION]
3585 You might want to try
3588 without quitting the current session. It should be a seamless upgrade
3589 while we are running...
3592 $CPAN::Frontend->myprint(qq{\n});
3594 last if $CPAN::Signal;
3595 } elsif ($mod =~ /^Bundle::(.*)/) {
3600 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
3601 # Let's make it a module too, because bundles have so much
3602 # in common with modules.
3604 # Changed in 1.57_63: seems like memory bloat now without
3605 # any value, so commented out
3607 # $CPAN::META->instance('CPAN::Module',$mod);
3611 # instantiate a module object
3612 $id = $CPAN::META->instance('CPAN::Module',$mod);
3616 # Although CPAN prohibits same name with different version the
3617 # indexer may have changed the version for the same distro
3618 # since the last time ("Force Reindexing" feature)
3619 if ($id->cpan_file ne $dist
3621 $id->cpan_version ne $version
3623 $userid = $id->userid || $self->userid($dist);
3625 'CPAN_USERID' => $userid,
3626 'CPAN_VERSION' => $version,
3627 'CPAN_FILE' => $dist,
3631 # instantiate a distribution object
3632 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
3633 # we do not need CONTAINSMODS unless we do something with
3634 # this dist, so we better produce it on demand.
3636 ## my $obj = $CPAN::META->instance(
3637 ## 'CPAN::Distribution' => $dist
3639 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
3641 $CPAN::META->instance(
3642 'CPAN::Distribution' => $dist
3644 'CPAN_USERID' => $userid,
3645 'CPAN_COMMENT' => $comment,
3649 for my $name ($mod,$dist) {
3650 CPAN->debug("exists name[$name]") if $CPAN::DEBUG;
3651 $exists{$name} = undef;
3654 return if $CPAN::Signal;
3658 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
3659 for my $o ($CPAN::META->all_objects($class)) {
3660 next if exists $exists{$o->{ID}};
3661 $CPAN::META->delete($class,$o->{ID});
3662 CPAN->debug("deleting ID[$o->{ID}] in class[$class]")
3669 #-> sub CPAN::Index::rd_modlist ;
3671 my($cl,$index_target) = @_;
3672 return unless defined $index_target;
3673 $CPAN::Frontend->myprint("Going to read $index_target\n");
3674 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3678 while ($_ = $fh->READLINE) {
3680 my @ls = map {"$_\n"} split /\n/, $_;
3681 unshift @ls, "\n" x length($1) if /^(\n+)/;
3685 my $shift = shift(@eval);
3686 if ($shift =~ /^Date:\s+(.*)/){
3687 return if $DATE_OF_03 eq $1;
3690 last if $shift =~ /^\s*$/;
3693 push @eval, q{CPAN::Modulelist->data;};
3695 my($comp) = Safe->new("CPAN::Safe1");
3696 my($eval) = join("", @eval);
3697 my $ret = $comp->reval($eval);
3698 Carp::confess($@) if $@;
3699 return if $CPAN::Signal;
3701 my $obj = $CPAN::META->instance("CPAN::Module",$_);
3702 delete $ret->{$_}{modid}; # not needed here, maybe elsewhere
3703 $obj->set(%{$ret->{$_}});
3704 return if $CPAN::Signal;
3708 #-> sub CPAN::Index::write_metadata_cache ;
3709 sub write_metadata_cache {
3711 return unless $CPAN::Config->{'cache_metadata'};
3712 return unless $CPAN::META->has_usable("Storable");
3714 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
3715 CPAN::Distribution)) {
3716 $cache->{$k} = $CPAN::META->{readonly}{$k}; # unsafe meta access, ok
3718 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3719 $cache->{last_time} = $LAST_TIME;
3720 $cache->{DATE_OF_02} = $DATE_OF_02;
3721 $cache->{PROTOCOL} = PROTOCOL;
3722 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
3723 eval { Storable::nstore($cache, $metadata_file) };
3724 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
3727 #-> sub CPAN::Index::read_metadata_cache ;
3728 sub read_metadata_cache {
3730 return unless $CPAN::Config->{'cache_metadata'};
3731 return unless $CPAN::META->has_usable("Storable");
3732 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3733 return unless -r $metadata_file and -f $metadata_file;
3734 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
3736 eval { $cache = Storable::retrieve($metadata_file) };
3737 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
3738 if (!$cache || ref $cache ne 'HASH'){
3742 if (exists $cache->{PROTOCOL}) {
3743 if (PROTOCOL > $cache->{PROTOCOL}) {
3744 $CPAN::Frontend->mywarn(sprintf("Ignoring Metadata cache written ".
3745 "with protocol v%s, requiring v%s\n",
3752 $CPAN::Frontend->mywarn("Ignoring Metadata cache written ".
3753 "with protocol v1.0\n");
3758 while(my($class,$v) = each %$cache) {
3759 next unless $class =~ /^CPAN::/;
3760 $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok
3761 while (my($id,$ro) = each %$v) {
3762 $CPAN::META->{readwrite}{$class}{$id} ||=
3763 $class->new(ID=>$id, RO=>$ro);
3768 unless ($clcnt) { # sanity check
3769 $CPAN::Frontend->myprint("Warning: Found no data in $metadata_file\n");
3772 if ($idcnt < 1000) {
3773 $CPAN::Frontend->myprint("Warning: Found only $idcnt objects ".
3774 "in $metadata_file\n");
3777 $CPAN::META->{PROTOCOL} ||=
3778 $cache->{PROTOCOL}; # reading does not up or downgrade, but it
3779 # does initialize to some protocol
3780 $LAST_TIME = $cache->{last_time};
3781 $DATE_OF_02 = $cache->{DATE_OF_02};
3782 $CPAN::Frontend->myprint(" Database was generated on $DATE_OF_02\n")
3783 if defined $DATE_OF_02; # An old cache may not contain DATE_OF_02
3787 package CPAN::InfoObj;
3792 exists $self->{RO} and return $self->{RO};
3797 my $ro = $self->ro or return;
3798 return $ro->{CPAN_USERID};
3801 sub id { shift->{ID}; }
3803 #-> sub CPAN::InfoObj::new ;
3805 my $this = bless {}, shift;
3810 # The set method may only be used by code that reads index data or
3811 # otherwise "objective" data from the outside world. All session
3812 # related material may do anything else with instance variables but
3813 # must not touch the hash under the RO attribute. The reason is that
3814 # the RO hash gets written to Metadata file and is thus persistent.
3816 #-> sub CPAN::InfoObj::safe_chdir ;
3818 my($self,$todir) = @_;
3819 # we die if we cannot chdir and we are debuggable
3820 Carp::confess("safe_chdir called without todir argument")
3821 unless defined $todir and length $todir;
3823 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
3827 unless (-x $todir) {
3828 unless (chmod 0755, $todir) {
3829 my $cwd = CPAN::anycwd();
3830 $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
3831 "permission to change the permission; cannot ".
3832 "chdir to '$todir'\n");
3833 $CPAN::Frontend->mysleep(5);
3834 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
3835 qq{to todir[$todir]: $!});
3839 $CPAN::Frontend->mydie("Directory '$todir' has gone. Cannot continue.\n");
3842 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
3845 my $cwd = CPAN::anycwd();
3846 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
3847 qq{to todir[$todir] (a chmod has been issued): $!});
3852 #-> sub CPAN::InfoObj::set ;
3854 my($self,%att) = @_;
3855 my $class = ref $self;
3857 # This must be ||=, not ||, because only if we write an empty
3858 # reference, only then the set method will write into the readonly
3859 # area. But for Distributions that spring into existence, maybe
3860 # because of a typo, we do not like it that they are written into
3861 # the readonly area and made permanent (at least for a while) and
3862 # that is why we do not "allow" other places to call ->set.
3863 unless ($self->id) {
3864 CPAN->debug("Bug? Empty ID, rejecting");
3867 my $ro = $self->{RO} =
3868 $CPAN::META->{readonly}{$class}{$self->id} ||= {};
3870 while (my($k,$v) = each %att) {
3875 #-> sub CPAN::InfoObj::as_glimpse ;
3879 my $class = ref($self);
3880 $class =~ s/^CPAN:://;
3881 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
3885 #-> sub CPAN::InfoObj::as_string ;
3889 my $class = ref($self);
3890 $class =~ s/^CPAN:://;
3891 push @m, $class, " id = $self->{ID}\n";
3893 unless ($ro = $self->ro) {
3894 $CPAN::Frontend->mydie("Unknown object $self->{ID}");
3896 for (sort keys %$ro) {
3897 # next if m/^(ID|RO)$/;
3899 if ($_ eq "CPAN_USERID") {
3901 $extra .= $self->fullname;
3902 my $email; # old perls!
3903 if ($email = $CPAN::META->instance("CPAN::Author",
3906 $extra .= " <$email>";
3908 $extra .= " <no email>";
3911 } elsif ($_ eq "FULLNAME") { # potential UTF-8 conversion
3912 push @m, sprintf " %-12s %s\n", $_, $self->fullname;
3915 next unless defined $ro->{$_};
3916 push @m, sprintf " %-12s %s%s\n", $_, $ro->{$_}, $extra;
3918 for (sort keys %$self) {
3919 next if m/^(ID|RO)$/;
3920 if (ref($self->{$_}) eq "ARRAY") {
3921 push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
3922 } elsif (ref($self->{$_}) eq "HASH") {
3926 join(" ",sort keys %{$self->{$_}}),
3929 push @m, sprintf " %-12s %s\n", $_, $self->{$_};
3935 #-> sub CPAN::InfoObj::fullname ;
3938 $CPAN::META->instance("CPAN::Author",$self->cpan_userid)->fullname;
3941 #-> sub CPAN::InfoObj::dump ;
3944 require Data::Dumper;
3945 local $Data::Dumper::Sortkeys;
3946 $Data::Dumper::Sortkeys = 1;
3947 print Data::Dumper::Dumper($self);
3950 package CPAN::Author;
3953 #-> sub CPAN::Author::force
3959 #-> sub CPAN::Author::force
3962 delete $self->{force};
3965 #-> sub CPAN::Author::id
3968 my $id = $self->{ID};
3969 $CPAN::Frontend->mydie("Illegal author id[$id]") unless $id =~ /^[A-Z]/;
3973 #-> sub CPAN::Author::as_glimpse ;
3977 my $class = ref($self);
3978 $class =~ s/^CPAN:://;
3979 push @m, sprintf(qq{%-15s %s ("%s" <%s>)\n},
3987 #-> sub CPAN::Author::fullname ;
3989 shift->ro->{FULLNAME};
3993 #-> sub CPAN::Author::email ;
3994 sub email { shift->ro->{EMAIL}; }
3996 #-> sub CPAN::Author::ls ;
3999 my $glob = shift || "";
4000 my $silent = shift || 0;
4003 # adapted from CPAN::Distribution::verifyCHECKSUM ;
4004 my(@csf); # chksumfile
4005 @csf = $self->id =~ /(.)(.)(.*)/;
4006 $csf[1] = join "", @csf[0,1];
4007 $csf[2] = join "", @csf[1,2]; # ("A","AN","ANDK")
4009 @dl = $self->dir_listing([$csf[0],"CHECKSUMS"], 0, 1);
4010 unless (grep {$_->[2] eq $csf[1]} @dl) {
4011 $CPAN::Frontend->myprint("Directory $csf[1]/ does not exist\n") unless $silent ;
4014 @dl = $self->dir_listing([@csf[0,1],"CHECKSUMS"], 0, 1);
4015 unless (grep {$_->[2] eq $csf[2]} @dl) {
4016 $CPAN::Frontend->myprint("Directory $id/ does not exist\n") unless $silent;
4019 @dl = $self->dir_listing([@csf,"CHECKSUMS"], 1, 1);
4021 if ($CPAN::META->has_inst("Text::Glob")) {
4022 my $rglob = Text::Glob::glob_to_regex($glob);
4023 @dl = grep { $_->[2] =~ /$rglob/ } @dl;
4025 $CPAN::Frontend->mydie("Text::Glob not installed, cannot proceed");
4028 $CPAN::Frontend->myprint(join "", map {
4029 sprintf("%8d %10s %s/%s\n", $_->[0], $_->[1], $id, $_->[2])
4030 } sort { $a->[2] cmp $b->[2] } @dl);
4034 # returns an array of arrays, the latter contain (size,mtime,filename)
4035 #-> sub CPAN::Author::dir_listing ;
4038 my $chksumfile = shift;
4039 my $recursive = shift;
4040 my $may_ftp = shift;
4043 File::Spec->catfile($CPAN::Config->{keep_source_where},
4044 "authors", "id", @$chksumfile);
4048 # Purge and refetch old (pre-PGP) CHECKSUMS; they are a security
4049 # hazard. (Without GPG installed they are not that much better,
4051 $fh = FileHandle->new;
4052 if (open($fh, $lc_want)) {
4053 my $line = <$fh>; close $fh;
4054 unlink($lc_want) unless $line =~ /PGP/;
4058 # connect "force" argument with "index_expire".
4059 my $force = $self->{force};
4060 if (my @stat = stat $lc_want) {
4061 $force ||= $stat[9] + $CPAN::Config->{index_expire}*86400 <= time;
4065 $lc_file = CPAN::FTP->localize(
4066 "authors/id/@$chksumfile",
4071 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
4072 $chksumfile->[-1] .= ".gz";
4073 $lc_file = CPAN::FTP->localize("authors/id/@$chksumfile",
4076 $lc_file =~ s{\.gz(?!\n)\Z}{}; #};
4077 CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file);
4083 $lc_file = $lc_want;
4084 # we *could* second-guess and if the user has a file: URL,
4085 # then we could look there. But on the other hand, if they do
4086 # have a file: URL, wy did they choose to set
4087 # $CPAN::Config->{show_upload_date} to false?
4090 # adapted from CPAN::Distribution::CHECKSUM_check_file ;
4091 $fh = FileHandle->new;
4093 if (open $fh, $lc_file){
4096 $eval =~ s/\015?\012/\n/g;
4098 my($comp) = Safe->new();
4099 $cksum = $comp->reval($eval);
4101 rename $lc_file, "$lc_file.bad";
4102 Carp::confess($@) if $@;
4104 } elsif ($may_ftp) {
4105 Carp::carp "Could not open '$lc_file' for reading.";
4107 # Maybe should warn: "You may want to set show_upload_date to a true value"
4111 for $f (sort keys %$cksum) {
4112 if (exists $cksum->{$f}{isdir}) {
4114 my(@dir) = @$chksumfile;
4116 push @dir, $f, "CHECKSUMS";
4118 [$_->[0], $_->[1], "$f/$_->[2]"]
4119 } $self->dir_listing(\@dir,1,$may_ftp);
4121 push @result, [ 0, "-", $f ];
4125 ($cksum->{$f}{"size"}||0),
4126 $cksum->{$f}{"mtime"}||"---",
4134 package CPAN::Distribution;
4140 my $ro = $self->ro or return;
4144 # CPAN::Distribution::undelay
4147 delete $self->{later};
4150 # add the A/AN/ stuff
4151 # CPAN::Distribution::normalize
4154 $s = $self->id unless defined $s;
4158 $s !~ m|[A-Z]/[A-Z-]{2}/[A-Z-]{2,}/|
4160 return $s if $s =~ m:^N/A|^Contact Author: ;
4161 $s =~ s|^(.)(.)([^/]*/)(.+)$|$1/$1$2/$1$2$3$4| or
4162 $CPAN::Frontend->mywarn("Strange distribution name [$s]\n");
4163 CPAN->debug("s[$s]") if $CPAN::DEBUG;
4168 #-> sub CPAN::Distribution::author ;
4171 my($authorid) = $self->pretty_id =~ /^([\w\-]+)/;
4172 CPAN::Shell->expand("Author",$authorid);
4175 # tries to get the yaml from CPAN instead of the distro itself:
4176 # EXPERIMENTAL, UNDOCUMENTED AND UNTESTED, for Tels
4179 my $meta = $self->pretty_id;
4180 $meta =~ s/\.(tar.gz|tgz|zip|tar.bz2)/.meta/;
4181 my(@ls) = CPAN::Shell->globls($meta);
4182 my $norm = $self->normalize($meta);
4186 File::Spec->catfile(
4187 $CPAN::Config->{keep_source_where},
4192 $self->debug("Doing localize") if $CPAN::DEBUG;
4193 unless ($local_file =
4194 CPAN::FTP->localize("authors/id/$norm",
4196 $CPAN::Frontend->mydie("Giving up on downloading yaml file '$local_wanted'\n");
4198 if ($CPAN::META->has_inst("YAML")) {
4199 my $yaml = YAML::LoadFile($local_file);
4202 $CPAN::Frontend->mydie("Yaml not installed, cannot parse '$local_file'\n");
4209 return $id unless $id =~ m|^./../|;
4213 # mark as dirty/clean
4214 #-> sub CPAN::Distribution::color_cmd_tmps ;
4215 sub color_cmd_tmps {
4217 my($depth) = shift || 0;
4218 my($color) = shift || 0;
4219 my($ancestors) = shift || [];
4220 # a distribution needs to recurse into its prereq_pms
4222 return if exists $self->{incommandcolor}
4223 && $self->{incommandcolor}==$color;
4225 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
4227 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
4228 my $prereq_pm = $self->prereq_pm;
4229 if (defined $prereq_pm) {
4230 PREREQ: for my $pre (keys %$prereq_pm) {
4232 unless ($premo = CPAN::Shell->expand("Module",$pre)) {
4233 $CPAN::Frontend->mywarn("prerequisite module[$pre] not known\n");
4234 $CPAN::Frontend->mysleep(2);
4237 $premo->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
4241 delete $self->{sponsored_mods};
4242 delete $self->{badtestcnt};
4244 $self->{incommandcolor} = $color;
4247 #-> sub CPAN::Distribution::as_string ;
4250 $self->containsmods;
4252 $self->SUPER::as_string(@_);
4255 #-> sub CPAN::Distribution::containsmods ;
4258 return keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
4259 my $dist_id = $self->{ID};
4260 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
4261 my $mod_file = $mod->cpan_file or next;
4262 my $mod_id = $mod->{ID} or next;
4263 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
4265 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
4267 keys %{$self->{CONTAINSMODS}};
4270 #-> sub CPAN::Distribution::upload_date ;
4273 return $self->{UPLOAD_DATE} if exists $self->{UPLOAD_DATE};
4274 my(@local_wanted) = split(/\//,$self->id);
4275 my $filename = pop @local_wanted;
4276 push @local_wanted, "CHECKSUMS";
4277 my $author = CPAN::Shell->expand("Author",$self->cpan_userid);
4278 return unless $author;
4279 my @dl = $author->dir_listing(\@local_wanted,0,$CPAN::Config->{show_upload_date});
4281 my($dirent) = grep { $_->[2] eq $filename } @dl;
4282 # warn sprintf "dirent[%s]id[%s]", $dirent, $self->id;
4283 return unless $dirent->[1];
4284 return $self->{UPLOAD_DATE} = $dirent->[1];
4287 #-> sub CPAN::Distribution::uptodate ;
4291 foreach $c ($self->containsmods) {
4292 my $obj = CPAN::Shell->expandany($c);
4293 return 0 unless $obj->uptodate;
4298 #-> sub CPAN::Distribution::called_for ;
4301 $self->{CALLED_FOR} = $id if defined $id;
4302 return $self->{CALLED_FOR};
4305 #-> sub CPAN::Distribution::get ;
4310 exists $self->{'build_dir'} and push @e,
4311 "Is already unwrapped into directory $self->{'build_dir'}";
4312 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4314 my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
4317 # Get the file on local disk
4322 File::Spec->catfile(
4323 $CPAN::Config->{keep_source_where},
4326 split(/\//,$self->id)
4329 $self->debug("Doing localize") if $CPAN::DEBUG;
4330 unless ($local_file =
4331 CPAN::FTP->localize("authors/id/$self->{ID}",
4334 if ($CPAN::Index::DATE_OF_02) {
4335 $note = "Note: Current database in memory was generated ".
4336 "on $CPAN::Index::DATE_OF_02\n";
4338 $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n$note");
4340 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
4341 $self->{localfile} = $local_file;
4342 return if $CPAN::Signal;
4347 if ($CPAN::META->has_inst("Digest::SHA")) {
4348 $self->debug("Digest::SHA is installed, verifying");
4349 $self->verifyCHECKSUM;
4351 $self->debug("Digest::SHA is NOT installed");
4353 return if $CPAN::Signal;
4356 # Create a clean room and go there
4358 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
4359 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
4360 $self->safe_chdir($builddir);
4361 $self->debug("Removing tmp") if $CPAN::DEBUG;
4362 File::Path::rmtree("tmp");
4363 unless (mkdir "tmp", 0755) {
4364 $CPAN::Frontend->unrecoverable_error(<<EOF);
4365 Couldn't mkdir '$builddir/tmp': $!
4367 Cannot continue: Please find the reason why I cannot make the
4370 and fix the problem, then retry.
4375 $self->safe_chdir($sub_wd);
4378 $self->safe_chdir("tmp");
4383 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
4384 my $ct = CPAN::Tarzip->new($local_file);
4385 if ($local_file =~ /(\.tar\.(bz2|gz|Z)|\.tgz)(?!\n)\Z/i){
4386 $self->{was_uncompressed}++ unless $ct->gtest();
4387 $self->untar_me($ct);
4388 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
4389 $self->unzip_me($ct);
4390 } elsif ( $local_file =~ /\.pm(\.(gz|Z))?(?!\n)\Z/) {
4391 $self->{was_uncompressed}++ unless $ct->gtest();
4392 $self->debug("calling pm2dir for local_file[$local_file]") if $CPAN::DEBUG;
4393 $self->pm2dir_me($local_file);
4395 $self->{archived} = "NO";
4396 $self->safe_chdir($sub_wd);
4400 # we are still in the tmp directory!
4401 # Let's check if the package has its own directory.
4402 my $dh = DirHandle->new(File::Spec->curdir)
4403 or Carp::croak("Couldn't opendir .: $!");
4404 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
4406 my ($distdir,$packagedir);
4407 if (@readdir == 1 && -d $readdir[0]) {
4408 $distdir = $readdir[0];
4409 $packagedir = File::Spec->catdir($builddir,$distdir);
4410 $self->debug("packagedir[$packagedir]builddir[$builddir]distdir[$distdir]")
4412 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
4414 File::Path::rmtree($packagedir);
4415 unless (File::Copy::move($distdir,$packagedir)) {
4416 $CPAN::Frontend->unrecoverable_error(<<EOF);
4417 Couldn't move '$distdir' to '$packagedir': $!
4419 Cannot continue: Please find the reason why I cannot move
4420 $builddir/tmp/$distdir
4423 and fix the problem, then retry
4427 $self->debug(sprintf("moved distdir[%s] to packagedir[%s] -e[%s]-d[%s]",
4434 my $userid = $self->cpan_userid;
4436 CPAN->debug("no userid? self[$self]");
4439 my $pragmatic_dir = $userid . '000';
4440 $pragmatic_dir =~ s/\W_//g;
4441 $pragmatic_dir++ while -d "../$pragmatic_dir";
4442 $packagedir = File::Spec->catdir($builddir,$pragmatic_dir);
4443 $self->debug("packagedir[$packagedir]") if $CPAN::DEBUG;
4444 File::Path::mkpath($packagedir);
4446 for $f (@readdir) { # is already without "." and ".."
4447 my $to = File::Spec->catdir($packagedir,$f);
4448 File::Copy::move($f,$to) or Carp::confess("Couldn't move $f to $to: $!");
4452 $self->safe_chdir($sub_wd);
4456 $self->{'build_dir'} = $packagedir;
4457 $self->safe_chdir($builddir);
4458 File::Path::rmtree("tmp");
4460 $self->safe_chdir($packagedir);
4461 if ($CPAN::META->has_inst("Module::Signature")) {
4462 if (-f "SIGNATURE") {
4463 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
4464 my $rv = Module::Signature::verify();
4465 if ($rv != Module::Signature::SIGNATURE_OK() and
4466 $rv != Module::Signature::SIGNATURE_MISSING()) {
4467 $CPAN::Frontend->myprint(
4468 qq{\nSignature invalid for }.
4469 qq{distribution file. }.
4470 qq{Please investigate.\n\n}.
4472 $CPAN::META->instance(
4479 sprintf(qq{I'd recommend removing %s. Its signature
4480 is invalid. Maybe you have configured your 'urllist' with
4481 a bad URL. Please check this array with 'o conf urllist', and
4482 retry. For more information, try opening a subshell with
4490 $self->{signature_verify} = CPAN::Distrostatus->new("NO");
4491 $CPAN::Frontend->mywarn(Text::Wrap::wrap("","",$wrap));
4492 $CPAN::Frontend->mysleep(5) if $CPAN::Frontend->can("mysleep");
4494 $self->{signature_verify} = CPAN::Distrostatus->new("YES");
4497 $CPAN::Frontend->myprint(qq{Package came without SIGNATURE\n\n});
4500 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
4502 $self->safe_chdir($builddir);
4503 return if $CPAN::Signal;
4506 my($mpl) = File::Spec->catfile($packagedir,"Makefile.PL");
4507 my($mpl_exists) = -f $mpl;
4508 unless ($mpl_exists) {
4509 # NFS has been reported to have racing problems after the
4510 # renaming of a directory in some environments.
4513 my $mpldh = DirHandle->new($packagedir)
4514 or Carp::croak("Couldn't opendir $packagedir: $!");
4515 $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read;
4518 my $prefer_installer = "eumm"; # eumm|mb
4519 if (-f File::Spec->catfile($packagedir,"Build.PL")) {
4520 if ($mpl_exists) { # they *can* choose
4521 if ($CPAN::META->has_inst("Module::Build")) {
4522 $prefer_installer = $CPAN::Config->{prefer_installer};
4525 $prefer_installer = "mb";
4528 if (lc($prefer_installer) eq "mb") {
4529 $self->{modulebuild} = 1;
4530 } elsif (! $mpl_exists) {
4531 $self->debug(sprintf("makefilepl[%s]anycwd[%s]",
4535 my($configure) = File::Spec->catfile($packagedir,"Configure");
4536 if (-f $configure) {
4537 # do we have anything to do?
4538 $self->{'configure'} = $configure;
4539 } elsif (-f File::Spec->catfile($packagedir,"Makefile")) {
4540 $CPAN::Frontend->myprint(qq{
4541 Package comes with a Makefile and without a Makefile.PL.
4542 We\'ll try to build it with that Makefile then.
4544 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
4547 my $cf = $self->called_for || "unknown";
4552 $cf =~ s|[/\\:]||g; # risk of filesystem damage
4553 $cf = "unknown" unless length($cf);
4554 $CPAN::Frontend->myprint(qq{Package seems to come without Makefile.PL.
4555 (The test -f "$mpl" returned false.)
4556 Writing one on our own (setting NAME to $cf)\a\n});
4557 $self->{had_no_makefile_pl}++;
4560 # Writing our own Makefile.PL
4562 my $fh = FileHandle->new;
4564 or Carp::croak("Could not open >$mpl: $!");
4566 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
4567 # because there was no Makefile.PL supplied.
4568 # Autogenerated on: }.scalar localtime().qq{
4570 use ExtUtils::MakeMaker;
4571 WriteMakefile(NAME => q[$cf]);
4581 # CPAN::Distribution::untar_me ;
4584 $self->{archived} = "tar";
4586 $self->{unwrapped} = "YES";
4588 $self->{unwrapped} = "NO";
4592 # CPAN::Distribution::unzip_me ;
4595 $self->{archived} = "zip";
4597 $self->{unwrapped} = "YES";
4599 $self->{unwrapped} = "NO";
4605 my($self,$local_file) = @_;
4606 $self->{archived} = "pm";
4607 my $to = File::Basename::basename($local_file);
4608 if ($to =~ s/\.(gz|Z)(?!\n)\Z//) {
4609 if (CPAN::Tarzip->new($local_file)->gunzip($to)) {
4610 $self->{unwrapped} = "YES";
4612 $self->{unwrapped} = "NO";
4615 File::Copy::cp($local_file,".");
4616 $self->{unwrapped} = "YES";
4620 #-> sub CPAN::Distribution::new ;
4622 my($class,%att) = @_;
4624 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
4626 my $this = { %att };
4627 return bless $this, $class;
4630 #-> sub CPAN::Distribution::look ;
4634 if ($^O eq 'MacOS') {
4635 $self->Mac::BuildTools::look;
4639 if ( $CPAN::Config->{'shell'} ) {
4640 $CPAN::Frontend->myprint(qq{
4641 Trying to open a subshell in the build directory...
4644 $CPAN::Frontend->myprint(qq{
4645 Your configuration does not define a value for subshells.
4646 Please define it with "o conf shell <your shell>"
4650 my $dist = $self->id;
4652 unless ($dir = $self->dir) {
4655 unless ($dir ||= $self->dir) {
4656 $CPAN::Frontend->mywarn(qq{
4657 Could not determine which directory to use for looking at $dist.
4661 my $pwd = CPAN::anycwd();
4662 $self->safe_chdir($dir);
4663 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
4665 local $ENV{CPAN_SHELL_LEVEL} = $ENV{CPAN_SHELL_LEVEL}||0;
4666 $ENV{CPAN_SHELL_LEVEL} += 1;
4667 unless (system($CPAN::Config->{'shell'}) == 0) {
4669 $CPAN::Frontend->mywarn("Subprocess shell exit code $code\n");
4672 $self->safe_chdir($pwd);
4675 # CPAN::Distribution::cvs_import ;
4679 my $dir = $self->dir;
4681 my $package = $self->called_for;
4682 my $module = $CPAN::META->instance('CPAN::Module', $package);
4683 my $version = $module->cpan_version;
4685 my $userid = $self->cpan_userid;
4687 my $cvs_dir = (split /\//, $dir)[-1];
4688 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
4690 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
4692 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
4693 if ($cvs_site_perl) {
4694 $cvs_dir = "$cvs_site_perl/$cvs_dir";
4696 my $cvs_log = qq{"imported $package $version sources"};
4697 $version =~ s/\./_/g;
4698 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
4699 "$cvs_dir", $userid, "v$version");
4701 my $pwd = CPAN::anycwd();
4702 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
4704 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
4706 $CPAN::Frontend->myprint(qq{@cmd\n});
4707 system(@cmd) == 0 or
4708 $CPAN::Frontend->mydie("cvs import failed");
4709 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
4712 #-> sub CPAN::Distribution::readme ;
4715 my($dist) = $self->id;
4716 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
4717 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
4720 File::Spec->catfile(
4721 $CPAN::Config->{keep_source_where},
4724 split(/\//,"$sans.readme"),
4726 $self->debug("Doing localize") if $CPAN::DEBUG;
4727 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
4729 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
4731 if ($^O eq 'MacOS') {
4732 Mac::BuildTools::launch_file($local_file);
4736 my $fh_pager = FileHandle->new;
4737 local($SIG{PIPE}) = "IGNORE";
4738 $fh_pager->open("|$CPAN::Config->{'pager'}")
4739 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
4740 my $fh_readme = FileHandle->new;
4741 $fh_readme->open($local_file)
4742 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
4743 $CPAN::Frontend->myprint(qq{
4746 with pager "$CPAN::Config->{'pager'}"
4749 $fh_pager->print(<$fh_readme>);
4753 #-> sub CPAN::Distribution::verifyCHECKSUM ;
4754 sub verifyCHECKSUM {
4758 $self->{CHECKSUM_STATUS} ||= "";
4759 $self->{CHECKSUM_STATUS} eq "OK" and push @e, "Checksum was ok";
4760 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4762 my($lc_want,$lc_file,@local,$basename);
4763 @local = split(/\//,$self->id);
4765 push @local, "CHECKSUMS";
4767 File::Spec->catfile($CPAN::Config->{keep_source_where},
4768 "authors", "id", @local);
4770 if (my $size = -s $lc_want) {
4771 $self->debug("lc_want[$lc_want]size[$size]") if $CPAN::DEBUG;
4772 if ($self->CHECKSUM_check_file($lc_want,1)) {
4773 return $self->{CHECKSUM_STATUS} = "OK";
4776 $lc_file = CPAN::FTP->localize("authors/id/@local",
4779 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
4780 $local[-1] .= ".gz";
4781 $lc_file = CPAN::FTP->localize("authors/id/@local",
4784 $lc_file =~ s/\.gz(?!\n)\Z//;
4785 CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file);
4790 if ($self->CHECKSUM_check_file($lc_file)) {
4791 return $self->{CHECKSUM_STATUS} = "OK";
4795 #-> sub CPAN::Distribution::SIG_check_file ;
4796 sub SIG_check_file {
4797 my($self,$chk_file) = @_;
4798 my $rv = eval { Module::Signature::_verify($chk_file) };
4800 if ($rv == Module::Signature::SIGNATURE_OK()) {
4801 $CPAN::Frontend->myprint("Signature for $chk_file ok\n");
4802 return $self->{SIG_STATUS} = "OK";
4804 $CPAN::Frontend->myprint(qq{\nSignature invalid for }.
4805 qq{distribution file. }.
4806 qq{Please investigate.\n\n}.
4808 $CPAN::META->instance(
4813 my $wrap = qq{I\'d recommend removing $chk_file. Its signature
4814 is invalid. Maybe you have configured your 'urllist' with
4815 a bad URL. Please check this array with 'o conf urllist', and
4818 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
4822 #-> sub CPAN::Distribution::CHECKSUM_check_file ;
4824 # sloppy is 1 when we have an old checksums file that maybe is good
4827 sub CHECKSUM_check_file {
4828 my($self,$chk_file,$sloppy) = @_;
4829 my($cksum,$file,$basename);
4832 $self->debug("chk_file[$chk_file]sloppy[$sloppy]") if $CPAN::DEBUG;
4833 if ($CPAN::META->has_inst("Module::Signature") and Module::Signature->VERSION >= 0.26) {
4834 $self->debug("Module::Signature is installed, verifying");
4835 $self->SIG_check_file($chk_file);
4837 $self->debug("Module::Signature is NOT installed");
4840 $file = $self->{localfile};
4841 $basename = File::Basename::basename($file);
4842 my $fh = FileHandle->new;
4843 if (open $fh, $chk_file){
4846 $eval =~ s/\015?\012/\n/g;
4848 my($comp) = Safe->new();
4849 $cksum = $comp->reval($eval);
4851 rename $chk_file, "$chk_file.bad";
4852 Carp::confess($@) if $@;
4855 Carp::carp "Could not open $chk_file for reading";
4858 if (! ref $cksum or ref $cksum ne "HASH") {
4859 $CPAN::Frontend->mywarn(qq{
4860 Warning: checksum file '$chk_file' broken.
4862 When trying to read that file I expected to get a hash reference
4863 for further processing, but got garbage instead.
4865 my $answer = ExtUtils::MakeMaker::prompt("Proceed nonetheless?", "no");
4866 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
4867 $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS file broken";
4869 } elsif (exists $cksum->{$basename}{sha256}) {
4870 $self->debug("Found checksum for $basename:" .
4871 "$cksum->{$basename}{sha256}\n") if $CPAN::DEBUG;
4875 my $eq = $self->eq_CHECKSUM($fh,$cksum->{$basename}{sha256});
4877 $fh = CPAN::Tarzip->TIEHANDLE($file);
4880 my $dg = Digest::SHA->new(256);
4883 while ($fh->READ($ref, 4096) > 0){
4886 my $hexdigest = $dg->hexdigest;
4887 $eq += $hexdigest eq $cksum->{$basename}{'sha256-ungz'};
4891 $CPAN::Frontend->myprint("Checksum for $file ok\n");
4892 return $self->{CHECKSUM_STATUS} = "OK";
4894 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
4895 qq{distribution file. }.
4896 qq{Please investigate.\n\n}.
4898 $CPAN::META->instance(
4903 my $wrap = qq{I\'d recommend removing $file. Its
4904 checksum is incorrect. Maybe you have configured your 'urllist' with
4905 a bad URL. Please check this array with 'o conf urllist', and
4908 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
4910 # former versions just returned here but this seems a
4911 # serious threat that deserves a die
4913 # $CPAN::Frontend->myprint("\n\n");
4917 # close $fh if fileno($fh);
4920 unless ($self->{CHECKSUM_STATUS}) {
4921 $CPAN::Frontend->mywarn(qq{
4922 Warning: No checksum for $basename in $chk_file.
4924 The cause for this may be that the file is very new and the checksum
4925 has not yet been calculated, but it may also be that something is
4926 going awry right now.
4928 my $answer = ExtUtils::MakeMaker::prompt("Proceed?", "yes");
4929 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
4931 $self->{CHECKSUM_STATUS} = "NIL -- distro not in CHECKSUMS file";
4936 #-> sub CPAN::Distribution::eq_CHECKSUM ;
4938 my($self,$fh,$expect) = @_;
4939 my $dg = Digest::SHA->new(256);
4941 while (read($fh, $data, 4096)){
4944 my $hexdigest = $dg->hexdigest;
4945 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
4946 $hexdigest eq $expect;
4949 #-> sub CPAN::Distribution::force ;
4951 # Both CPAN::Modules and CPAN::Distributions know if "force" is in
4952 # effect by autoinspection, not by inspecting a global variable. One
4953 # of the reason why this was chosen to work that way was the treatment
4954 # of dependencies. They should not automatically inherit the force
4955 # status. But this has the downside that ^C and die() will return to
4956 # the prompt but will not be able to reset the force_update
4957 # attributes. We try to correct for it currently in the read_metadata
4958 # routine, and immediately before we check for a Signal. I hope this
4959 # works out in one of v1.57_53ff
4961 # "Force get forgets previous error conditions"
4963 #-> sub CPAN::Distribution::force ;
4965 my($self, $method) = @_;
4967 CHECKSUM_STATUS archived build_dir localfile make install unwrapped
4968 writemakefile modulebuild make_test
4970 delete $self->{$att};
4972 if ($method && $method =~ /make|test|install/) {
4973 $self->{"force_update"}++; # name should probably have been force_install
4978 my($self, $method) = @_;
4979 # warn "XDEBUG: set notest for $self $method";
4980 $self->{"notest"}++; # name should probably have been force_install
4985 # warn "XDEBUG: deleting notest";
4986 delete $self->{'notest'};
4989 #-> sub CPAN::Distribution::unforce ;
4992 delete $self->{'force_update'};
4995 #-> sub CPAN::Distribution::isa_perl ;
4998 my $file = File::Basename::basename($self->id);
4999 if ($file =~ m{ ^ perl
5012 } elsif ($self->cpan_comment
5014 $self->cpan_comment =~ /isa_perl\(.+?\)/){
5020 #-> sub CPAN::Distribution::perl ;
5026 #-> sub CPAN::Distribution::make ;
5029 my $make = $self->{modulebuild} ? "Build" : "make";
5030 $CPAN::Frontend->myprint(sprintf "Running %s for %s\n", $make, $self->id);
5031 # Emergency brake if they said install Pippi and get newest perl
5032 if ($self->isa_perl) {
5034 $self->called_for ne $self->id &&
5035 ! $self->{force_update}
5037 # if we die here, we break bundles
5038 $CPAN::Frontend->mywarn(sprintf qq{
5039 The most recent version "%s" of the module "%s"
5040 comes with the current version of perl (%s).
5041 I\'ll build that only if you ask for something like
5046 $CPAN::META->instance(
5059 delete $self->{force_update};
5064 !$self->{archived} || $self->{archived} eq "NO" and push @e,
5065 "Is neither a tar nor a zip archive.";
5067 !$self->{unwrapped} || $self->{unwrapped} eq "NO" and push @e,
5068 "Had problems unarchiving. Please build manually";
5070 unless ($self->{force_update}) {
5071 exists $self->{signature_verify} and (
5072 $self->{signature_verify}->can("failed") ?
5073 $self->{signature_verify}->failed :
5074 $self->{signature_verify} =~ /^NO/
5076 and push @e, "Did not pass the signature test.";
5079 if (exists $self->{writemakefile} &&
5081 $self->{writemakefile}->can("failed") ?
5082 $self->{writemakefile}->failed :
5083 $self->{writemakefile} =~ /^NO/
5085 # XXX maybe a retry would be in order?
5086 my $err = $self->{writemakefile}->can("text") ?
5087 $self->{writemakefile}->text :
5088 $self->{writemakefile};
5090 $err ||= "Had some problem writing Makefile";
5091 $err .= ", won't make";
5095 defined $self->{make} and push @e,
5096 "Has already been processed within this session";
5098 if (exists $self->{later} and length($self->{later})) {
5099 if ($self->unsat_prereq) {
5100 push @e, $self->{later};
5102 delete $self->{later};
5106 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5109 delete $self->{force_update};
5112 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
5113 my $builddir = $self->dir or
5114 $CPAN::Frontend->mydie("PANIC: Cannot determine build directory\n");
5115 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
5116 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
5118 if ($^O eq 'MacOS') {
5119 Mac::BuildTools::make($self);
5124 if ($self->{'configure'}) {
5125 $system = $self->{'configure'};
5126 } elsif ($self->{modulebuild}) {
5127 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
5128 $system = "$perl Build.PL $CPAN::Config->{mbuildpl_arg}";
5130 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
5132 # This needs a handler that can be turned on or off:
5133 # $switch = "-MExtUtils::MakeMaker ".
5134 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
5136 $system = sprintf("%s%s Makefile.PL%s",
5138 $switch ? " $switch" : "",
5139 $CPAN::Config->{makepl_arg} ? " $CPAN::Config->{makepl_arg}" : "",
5142 unless (exists $self->{writemakefile}) {
5143 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
5146 if ($CPAN::Config->{inactivity_timeout}) {
5148 alarm $CPAN::Config->{inactivity_timeout};
5149 local $SIG{CHLD}; # = sub { wait };
5150 if (defined($pid = fork)) {
5155 # note, this exec isn't necessary if
5156 # inactivity_timeout is 0. On the Mac I'd
5157 # suggest, we set it always to 0.
5161 $CPAN::Frontend->myprint("Cannot fork: $!");
5169 $CPAN::Frontend->myprint($@);
5170 $self->{writemakefile} = CPAN::Distrostatus->new("NO $@");
5175 $ret = system($system);
5177 $self->{writemakefile} = CPAN::Distrostatus
5178 ->new("NO '$system' returned status $ret");
5182 if (-f "Makefile" || -f "Build") {
5183 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
5184 delete $self->{make_clean}; # if cleaned before, enable next
5186 $self->{writemakefile} = CPAN::Distrostatus
5187 ->new(qq{NO -- Unknown reason.});
5191 delete $self->{force_update};
5194 if (my @prereq = $self->unsat_prereq){
5195 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
5197 if ($self->{modulebuild}) {
5198 $system = sprintf "%s %s", $self->_build_command(), $CPAN::Config->{mbuild_arg};
5200 $system = join " ", _make_command(), $CPAN::Config->{make_arg};
5202 if (system($system) == 0) {
5203 $CPAN::Frontend->myprint(" $system -- OK\n");
5204 $self->{make} = CPAN::Distrostatus->new("YES");
5206 $self->{writemakefile} ||= CPAN::Distrostatus->new("YES");
5207 $self->{make} = CPAN::Distrostatus->new("NO");
5208 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
5213 return $CPAN::Config->{make} || $Config::Config{make} || 'make';
5216 #-> sub CPAN::Distribution::follow_prereqs ;
5217 sub follow_prereqs {
5219 my(@prereq) = grep {$_ ne "perl"} @_;
5220 return unless @prereq;
5222 $CPAN::Frontend->myprint("---- Unsatisfied dependencies detected ".
5223 "during [$id] -----\n");
5225 for my $p (@prereq) {
5226 $CPAN::Frontend->myprint(" $p\n");
5229 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
5231 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
5232 my $answer = ExtUtils::MakeMaker::prompt(
5233 "Shall I follow them and prepend them to the queue
5234 of modules we are processing right now?", "yes");
5235 $follow = $answer =~ /^\s*y/i;
5239 myprint(" Ignoring dependencies on modules @prereq\n");
5242 # color them as dirty
5243 for my $p (@prereq) {
5244 # warn "calling color_cmd_tmps(0,1)";
5245 CPAN::Shell->expandany($p)->color_cmd_tmps(0,1);
5247 CPAN::Queue->jumpqueue(@prereq,$id); # queue them and requeue yourself
5248 $self->{later} = "Delayed until after prerequisites";
5249 return 1; # signal success to the queuerunner
5253 #-> sub CPAN::Distribution::unsat_prereq ;
5256 my $prereq_pm = $self->prereq_pm or return;
5258 NEED: while (my($need_module, $need_version) = each %$prereq_pm) {
5259 my $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
5260 # we were too demanding:
5261 next if $nmo->uptodate;
5263 # if they have not specified a version, we accept any installed one
5264 if (not defined $need_version or
5265 $need_version eq "0" or
5266 $need_version eq "undef") {
5267 next if defined $nmo->inst_file;
5270 # We only want to install prereqs if either they're not installed
5271 # or if the installed version is too old. We cannot omit this
5272 # check, because if 'force' is in effect, nobody else will check.
5273 if (defined $nmo->inst_file) {
5274 my(@all_requirements) = split /\s*,\s*/, $need_version;
5277 RQ: for my $rq (@all_requirements) {
5278 if ($rq =~ s|>=\s*||) {
5279 } elsif ($rq =~ s|>\s*||) {
5281 if (CPAN::Version->vgt($nmo->inst_version,$rq)){
5285 } elsif ($rq =~ s|!=\s*||) {
5287 if (CPAN::Version->vcmp($nmo->inst_version,$rq)){
5293 } elsif ($rq =~ m|<=?\s*|) {
5295 $CPAN::Frontend->mywarn("Downgrading not supported (rq[$rq])");
5299 if (! CPAN::Version->vgt($rq, $nmo->inst_version)){
5302 CPAN->debug(sprintf "id[%s]inst_file[%s]inst_version[%s]rq[%s]ok[%d]",
5306 CPAN::Version->readable($rq),
5310 next NEED if $ok == @all_requirements;
5313 if ($self->{sponsored_mods}{$need_module}++){
5314 # We have already sponsored it and for some reason it's still
5315 # not available. So we do nothing. Or what should we do?
5316 # if we push it again, we have a potential infinite loop
5319 push @need, $need_module;
5324 #-> sub CPAN::Distribution::read_yaml ;
5327 return $self->{yaml_content} if exists $self->{yaml_content};
5328 my $build_dir = $self->{build_dir};
5329 my $yaml = File::Spec->catfile($build_dir,"META.yml");
5330 $self->debug("yaml[$yaml]") if $CPAN::DEBUG;
5331 return unless -f $yaml;
5332 if ($CPAN::META->has_inst("YAML")) {
5333 eval { $self->{yaml_content} = YAML::LoadFile($yaml); };
5335 $CPAN::Frontend->mywarn("Error while parsing META.yml: $@");
5339 $self->debug("yaml_content[$self->{yaml_content}]") if $CPAN::DEBUG;
5340 return $self->{yaml_content};
5343 #-> sub CPAN::Distribution::prereq_pm ;
5346 return $self->{prereq_pm} if
5347 exists $self->{prereq_pm_detected} && $self->{prereq_pm_detected};
5348 return unless $self->{writemakefile} # no need to have succeeded
5349 # but we must have run it
5350 || $self->{modulebuild};
5352 if (my $yaml = $self->read_yaml) {
5353 $req = $yaml->{requires};
5354 undef $req unless ref $req eq "HASH" && %$req;
5356 if ($yaml->{generated_by} =~ /ExtUtils::MakeMaker version ([\d\._]+)/) {
5357 my $eummv = do { local $^W = 0; $1+0; };
5358 if ($eummv < 6.2501) {
5359 # thanks to Slaven for digging that out: MM before
5360 # that could be wrong because it could reflect a
5367 while (my($k,$v) = each %{$req||{}}) {
5370 } elsif ($k =~ /[A-Za-z]/ &&
5372 $CPAN::META->exists("Module",$v)
5374 $CPAN::Frontend->mywarn("Suspicious key-value pair in META.yml's ".
5375 "requires hash: $k => $v; I'll take both ".
5376 "key and value as a module name\n");
5383 $req = $areq if $do_replace;
5385 if ($yaml->{build_requires}
5386 && ref $yaml->{build_requires}
5387 && ref $yaml->{build_requires} eq "HASH") {
5388 while (my($k,$v) = each %{$yaml->{build_requires}}) {
5390 # merging of two "requires"-type values--what should we do?
5397 delete $req->{perl};
5401 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
5402 my $makefile = File::Spec->catfile($build_dir,"Makefile");
5406 $fh = FileHandle->new("<$makefile\0")) {
5409 last if /MakeMaker post_initialize section/;
5411 \s+PREREQ_PM\s+=>\s+(.+)
5414 # warn "Found prereq expr[$p]";
5416 # Regexp modified by A.Speer to remember actual version of file
5417 # PREREQ_PM hash key wants, then add to
5418 while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
5419 # In case a prereq is mentioned twice, complain.
5420 if ( defined $req->{$1} ) {
5421 warn "Warning: PREREQ_PM mentions $1 more than once, ".
5422 "last mention wins";
5428 } elsif (-f "Build") {
5429 if ($CPAN::META->has_inst("Module::Build")) {
5430 my $requires = Module::Build->current->requires();
5431 my $brequires = Module::Build->current->build_requires();
5432 $req = { %$requires, %$brequires };
5436 if (-f "Build.PL" && ! -f "Makefile.PL" && ! exists $req->{"Module::Build"}) {
5437 $CPAN::Frontend->mywarn(" Warning: CPAN.pm discovered Module::Build as ".
5438 "undeclared prerequisite.\n".
5439 " Adding it now as a prerequisite.\n"
5441 $CPAN::Frontend->mysleep(5);
5442 $req->{"Module::Build"} = 0;
5443 delete $self->{writemakefile};
5445 $self->{prereq_pm_detected}++;
5446 return $self->{prereq_pm} = $req;
5449 #-> sub CPAN::Distribution::test ;
5454 delete $self->{force_update};
5457 # warn "XDEBUG: checking for notest: $self->{notest} $self";
5458 if ($self->{notest}) {
5459 $CPAN::Frontend->myprint("Skipping test because of notest pragma\n");
5463 my $make = $self->{modulebuild} ? "Build" : "make";
5464 $CPAN::Frontend->myprint("Running $make test\n");
5465 if (my @prereq = $self->unsat_prereq){
5466 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
5470 unless (exists $self->{make} or exists $self->{later}) {
5472 "Make had some problems, won't test";
5475 exists $self->{make} and
5477 $self->{make}->can("failed") ?
5478 $self->{make}->failed :
5479 $self->{make} =~ /^NO/
5480 ) and push @e, "Can't test without successful make";
5482 exists $self->{build_dir} or push @e, "Has no own directory";
5483 $self->{badtestcnt} ||= 0;
5484 $self->{badtestcnt} > 0 and
5485 push @e, "Won't repeat unsuccessful test during this command";
5487 exists $self->{later} and length($self->{later}) and
5488 push @e, $self->{later};
5490 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5492 chdir $self->{'build_dir'} or
5493 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
5494 $self->debug("Changed directory to $self->{'build_dir'}")
5497 if ($^O eq 'MacOS') {
5498 Mac::BuildTools::make_test($self);
5502 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
5504 : ($ENV{PERLLIB} || "");
5506 $CPAN::META->set_perl5lib;
5507 local $ENV{MAKEFLAGS}; # protect us from outer make calls
5510 if ($self->{modulebuild}) {
5511 $system = sprintf "%s test", $self->_build_command();
5513 $system = join " ", _make_command(), "test";
5515 if (system($system) == 0) {
5516 $CPAN::Frontend->myprint(" $system -- OK\n");
5517 $CPAN::META->is_tested($self->{'build_dir'});
5518 $self->{make_test} = CPAN::Distrostatus->new("YES");
5520 $self->{make_test} = CPAN::Distrostatus->new("NO");
5521 $self->{badtestcnt}++;
5522 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
5526 #-> sub CPAN::Distribution::clean ;
5529 my $make = $self->{modulebuild} ? "Build" : "make";
5530 $CPAN::Frontend->myprint("Running $make clean\n");
5531 unless (exists $self->{archived}) {
5532 $CPAN::Frontend->mywarn("Distribution seems to have never been unzipped".
5533 "/untarred, nothing done\n");
5536 unless (exists $self->{build_dir}) {
5537 $CPAN::Frontend->mywarn("Distribution has no own directory, nothing to do.\n");
5542 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
5543 push @e, "make clean already called once";
5544 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5546 chdir $self->{'build_dir'} or
5547 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
5548 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
5550 if ($^O eq 'MacOS') {
5551 Mac::BuildTools::make_clean($self);
5556 if ($self->{modulebuild}) {
5557 $system = sprintf "%s clean", $self->_build_command();
5559 $system = join " ", _make_command(), "clean";
5561 if (system($system) == 0) {
5562 $CPAN::Frontend->myprint(" $system -- OK\n");
5566 # Jost Krieger pointed out that this "force" was wrong because
5567 # it has the effect that the next "install" on this distribution
5568 # will untar everything again. Instead we should bring the
5569 # object's state back to where it is after untarring.
5580 $self->{make_clean} = "YES";
5583 # Hmmm, what to do if make clean failed?
5585 $CPAN::Frontend->myprint(qq{ $system -- NOT OK
5587 make clean did not succeed, marking directory as unusable for further work.
5589 $self->force("make"); # so that this directory won't be used again
5594 #-> sub CPAN::Distribution::install ;
5599 delete $self->{force_update};
5602 my $make = $self->{modulebuild} ? "Build" : "make";
5603 $CPAN::Frontend->myprint("Running $make install\n");
5606 exists $self->{build_dir} or push @e, "Has no own directory";
5608 unless (exists $self->{make} or exists $self->{later}) {
5610 "Make had some problems, won't install";
5613 exists $self->{make} and
5615 $self->{make}->can("failed") ?
5616 $self->{make}->failed :
5617 $self->{make} =~ /^NO/
5619 push @e, "make had returned bad status, install seems impossible";
5621 if (exists $self->{make_test} and
5623 $self->{make_test}->can("failed") ?
5624 $self->{make_test}->failed :
5625 $self->{make_test} =~ /^NO/
5627 if ($self->{force_update}) {
5628 $self->{make_test}->text("FAILED but failure ignored because ".
5629 "'force' in effect");
5631 push @e, "make test had returned bad status, ".
5632 "won't install without force"
5635 if (exists $self->{'install'}) {
5636 if ($self->{'install'}->can("text") ?
5637 $self->{'install'}->text eq "YES" :
5638 $self->{'install'} =~ /^YES/
5640 push @e, "Already done";
5642 # comment in Todo on 2006-02-11; maybe retry?
5643 push @e, "Already tried without success";
5647 exists $self->{later} and length($self->{later}) and
5648 push @e, $self->{later};
5650 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5652 chdir $self->{'build_dir'} or
5653 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
5654 $self->debug("Changed directory to $self->{'build_dir'}")
5657 if ($^O eq 'MacOS') {
5658 Mac::BuildTools::make_install($self);
5663 if ($self->{modulebuild}) {
5664 my($mbuild_install_build_command) =
5665 exists $CPAN::HandleConfig::keys{mbuild_install_build_command} &&
5666 $CPAN::Config->{mbuild_install_build_command} ?
5667 $CPAN::Config->{mbuild_install_build_command} :
5668 $self->_build_command();
5669 $system = sprintf("%s install %s",
5670 $mbuild_install_build_command,
5671 $CPAN::Config->{mbuild_install_arg},
5674 my($make_install_make_command) = $CPAN::Config->{make_install_make_command} ||
5676 $system = sprintf("%s install %s",
5677 $make_install_make_command,
5678 $CPAN::Config->{make_install_arg},
5682 my($stderr) = $^O =~ /Win/i ? "" : " 2>&1 ";
5683 my($pipe) = FileHandle->new("$system $stderr |");
5686 $CPAN::Frontend->myprint($_);
5691 $CPAN::Frontend->myprint(" $system -- OK\n");
5692 $CPAN::META->is_installed($self->{build_dir});
5693 return $self->{install} = CPAN::Distrostatus->new("YES");
5695 $self->{install} = CPAN::Distrostatus->new("NO");
5696 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
5698 $makeout =~ /permission/s
5701 ! $CPAN::Config->{make_install_make_command}
5702 || $CPAN::Config->{make_install_make_command} eq $CPAN::Config->{make}
5705 $CPAN::Frontend->myprint(
5707 qq{ You may have to su }.
5708 qq{to root to install the package\n}.
5709 qq{ (Or you may want to run something like\n}.
5710 qq{ o conf make_install_make_command 'sudo make'\n}.
5711 qq{ to raise your permissions.}
5715 delete $self->{force_update};
5718 #-> sub CPAN::Distribution::dir ;
5720 shift->{'build_dir'};
5723 #-> sub CPAN::Distribution::perldoc ;
5727 my($dist) = $self->id;
5728 my $package = $self->called_for;
5730 $self->_display_url( $CPAN::Defaultdocs . $package );
5733 #-> sub CPAN::Distribution::_check_binary ;
5735 my ($dist,$shell,$binary) = @_;
5738 $CPAN::Frontend->myprint(qq{ + _check_binary($binary)\n})
5742 $pid = open README, "which $binary|"
5743 or $CPAN::Frontend->mydie(qq{Could not fork 'which $binary': $!});
5747 close README or die "Could not run 'which $binary': $!";
5749 $CPAN::Frontend->myprint(qq{ + $out \n})
5750 if $CPAN::DEBUG && $out;
5755 #-> sub CPAN::Distribution::_display_url ;
5757 my($self,$url) = @_;
5758 my($res,$saved_file,$pid,$out);
5760 $CPAN::Frontend->myprint(qq{ + _display_url($url)\n})
5763 # should we define it in the config instead?
5764 my $html_converter = "html2text";
5766 my $web_browser = $CPAN::Config->{'lynx'} || undef;
5767 my $web_browser_out = $web_browser
5768 ? CPAN::Distribution->_check_binary($self,$web_browser)
5771 if ($web_browser_out) {
5772 # web browser found, run the action
5773 my $browser = $CPAN::Config->{'lynx'};
5774 $CPAN::Frontend->myprint(qq{system[$browser $url]})
5776 $CPAN::Frontend->myprint(qq{
5779 with browser $browser
5782 system("$browser $url");
5783 if ($saved_file) { 1 while unlink($saved_file) }
5785 # web browser not found, let's try text only
5786 my $html_converter_out =
5787 CPAN::Distribution->_check_binary($self,$html_converter);
5789 if ($html_converter_out ) {
5790 # html2text found, run it
5791 $saved_file = CPAN::Distribution->_getsave_url( $self, $url );
5792 $CPAN::Frontend->mydie(qq{ERROR: problems while getting $url\n})
5793 unless defined($saved_file);
5796 $pid = open README, "$html_converter $saved_file |"
5797 or $CPAN::Frontend->mydie(qq{
5798 Could not fork '$html_converter $saved_file': $!});
5800 if ($CPAN::META->has_inst("File::Temp")) {
5801 $fh = File::Temp->new(
5802 template => 'cpan_htmlconvert_XXXX',
5806 $filename = $fh->filename;
5808 $filename = "cpan_htmlconvert_$$.txt";
5809 $fh = FileHandle->new();
5810 open $fh, ">$filename" or die;
5816 $CPAN::Frontend->mydie(qq{Could not run '$html_converter $saved_file': $!});
5817 my $tmpin = $fh->filename;
5818 $CPAN::Frontend->myprint(sprintf(qq{
5820 saved output to %s\n},
5828 or $CPAN::Frontend->mydie(qq{Could not open "$tmpin": $!});
5829 my $fh_pager = FileHandle->new;
5830 local($SIG{PIPE}) = "IGNORE";
5831 $fh_pager->open("|$CPAN::Config->{'pager'}")
5832 or $CPAN::Frontend->mydie(qq{
5833 Could not open pager $CPAN::Config->{'pager'}: $!});
5834 $CPAN::Frontend->myprint(qq{
5837 with pager "$CPAN::Config->{'pager'}"
5840 $fh_pager->print(<FH>);
5843 # coldn't find the web browser or html converter
5844 $CPAN::Frontend->myprint(qq{
5845 You need to install lynx or $html_converter to use this feature.});
5850 #-> sub CPAN::Distribution::_getsave_url ;
5852 my($dist, $shell, $url) = @_;
5854 $CPAN::Frontend->myprint(qq{ + _getsave_url($url)\n})
5858 if ($CPAN::META->has_inst("File::Temp")) {
5859 $fh = File::Temp->new(
5860 template => "cpan_getsave_url_XXXX",
5864 $filename = $fh->filename;
5866 $fh = FileHandle->new;
5867 $filename = "cpan_getsave_url_$$.html";
5869 my $tmpin = $filename;
5870 if ($CPAN::META->has_usable('LWP')) {
5871 $CPAN::Frontend->myprint("Fetching with LWP:
5875 CPAN::LWP::UserAgent->config;
5876 eval { $Ua = CPAN::LWP::UserAgent->new; };
5878 $CPAN::Frontend->mywarn("ERROR: CPAN::LWP::UserAgent->new dies with $@\n");
5882 $Ua->proxy('http', $var)
5883 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
5885 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
5888 my $req = HTTP::Request->new(GET => $url);
5889 $req->header('Accept' => 'text/html');
5890 my $res = $Ua->request($req);
5891 if ($res->is_success) {
5892 $CPAN::Frontend->myprint(" + request successful.\n")
5894 print $fh $res->content;
5896 $CPAN::Frontend->myprint(qq{ + saved content to $tmpin \n})
5900 $CPAN::Frontend->myprint(sprintf(
5901 "LWP failed with code[%s], message[%s]\n",
5908 $CPAN::Frontend->myprint("LWP not available\n");
5913 # sub CPAN::Distribution::_build_command
5914 sub _build_command {
5916 if ($^O eq "MSWin32") { # special code needed at least up to
5917 # Module::Build 0.2611 and 0.2706; a fix
5918 # in M:B has been promised 2006-01-30
5919 my($perl) = $self->perl or $CPAN::Frontend->mydie("Couldn't find executable perl\n");
5920 return "$perl ./Build";
5925 package CPAN::Bundle;
5930 $CPAN::Frontend->myprint($self->as_string);
5935 delete $self->{later};
5936 for my $c ( $self->contains ) {
5937 my $obj = CPAN::Shell->expandany($c) or next;
5942 # mark as dirty/clean
5943 #-> sub CPAN::Bundle::color_cmd_tmps ;
5944 sub color_cmd_tmps {
5946 my($depth) = shift || 0;
5947 my($color) = shift || 0;
5948 my($ancestors) = shift || [];
5949 # a module needs to recurse to its cpan_file, a distribution needs
5950 # to recurse into its prereq_pms, a bundle needs to recurse into its modules
5952 return if exists $self->{incommandcolor}
5953 && $self->{incommandcolor}==$color;
5955 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
5957 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
5959 for my $c ( $self->contains ) {
5960 my $obj = CPAN::Shell->expandany($c) or next;
5961 CPAN->debug("c[$c]obj[$obj]") if $CPAN::DEBUG;
5962 $obj->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
5965 delete $self->{badtestcnt};
5967 $self->{incommandcolor} = $color;
5970 #-> sub CPAN::Bundle::as_string ;
5974 # following line must be "=", not "||=" because we have a moving target
5975 $self->{INST_VERSION} = $self->inst_version;
5976 return $self->SUPER::as_string;
5979 #-> sub CPAN::Bundle::contains ;
5982 my($inst_file) = $self->inst_file || "";
5983 my($id) = $self->id;
5984 $self->debug("inst_file[$inst_file]id[$id]") if $CPAN::DEBUG;
5985 if ($inst_file && CPAN::Version->vlt($self->inst_version,$self->cpan_version)) {
5988 unless ($inst_file) {
5989 # Try to get at it in the cpan directory
5990 $self->debug("no inst_file") if $CPAN::DEBUG;
5992 $CPAN::Frontend->mydie("I don't know a bundle with ID $id\n") unless
5993 $cpan_file = $self->cpan_file;
5994 if ($cpan_file eq "N/A") {
5995 $CPAN::Frontend->mydie("Bundle $id not found on disk and not on CPAN.
5996 Maybe stale symlink? Maybe removed during session? Giving up.\n");
5998 my $dist = $CPAN::META->instance('CPAN::Distribution',
6001 $self->debug("id[$dist->{ID}]") if $CPAN::DEBUG;
6002 my($todir) = $CPAN::Config->{'cpan_home'};
6003 my(@me,$from,$to,$me);
6004 @me = split /::/, $self->id;
6006 $me = File::Spec->catfile(@me);
6007 $from = $self->find_bundle_file($dist->{'build_dir'},join('/',@me));
6008 $to = File::Spec->catfile($todir,$me);
6009 File::Path::mkpath(File::Basename::dirname($to));
6010 File::Copy::copy($from, $to)
6011 or Carp::confess("Couldn't copy $from to $to: $!");
6015 my $fh = FileHandle->new;
6017 open($fh,$inst_file) or die "Could not open '$inst_file': $!";
6019 $self->debug("inst_file[$inst_file]") if $CPAN::DEBUG;
6021 $in_cont = m/^=(?!head1\s+CONTENTS)/ ? 0 :
6022 m/^=head1\s+CONTENTS/ ? 1 : $in_cont;
6023 next unless $in_cont;
6028 push @result, (split " ", $_, 2)[0];
6031 delete $self->{STATUS};
6032 $self->{CONTAINS} = \@result;
6033 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
6035 $CPAN::Frontend->mywarn(qq{
6036 The bundle file "$inst_file" may be a broken
6037 bundlefile. It seems not to contain any bundle definition.
6038 Please check the file and if it is bogus, please delete it.
6039 Sorry for the inconvenience.
6045 #-> sub CPAN::Bundle::find_bundle_file
6046 # $where is in local format, $what is in unix format
6047 sub find_bundle_file {
6048 my($self,$where,$what) = @_;
6049 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
6050 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
6051 ### my $bu = File::Spec->catfile($where,$what);
6052 ### return $bu if -f $bu;
6053 my $manifest = File::Spec->catfile($where,"MANIFEST");
6054 unless (-f $manifest) {
6055 require ExtUtils::Manifest;
6056 my $cwd = CPAN::anycwd();
6057 $self->safe_chdir($where);
6058 ExtUtils::Manifest::mkmanifest();
6059 $self->safe_chdir($cwd);
6061 my $fh = FileHandle->new($manifest)
6062 or Carp::croak("Couldn't open $manifest: $!");
6064 my $bundle_filename = $what;
6065 $bundle_filename =~ s|Bundle.*/||;
6066 my $bundle_unixpath;
6069 my($file) = /(\S+)/;
6070 if ($file =~ m|\Q$what\E$|) {
6071 $bundle_unixpath = $file;
6072 # return File::Spec->catfile($where,$bundle_unixpath); # bad
6075 # retry if she managed to have no Bundle directory
6076 $bundle_unixpath = $file if $file =~ m|\Q$bundle_filename\E$|;
6078 return File::Spec->catfile($where, split /\//, $bundle_unixpath)
6079 if $bundle_unixpath;
6080 Carp::croak("Couldn't find a Bundle file in $where");
6083 # needs to work quite differently from Module::inst_file because of
6084 # cpan_home/Bundle/ directory and the possibility that we have
6085 # shadowing effect. As it makes no sense to take the first in @INC for
6086 # Bundles, we parse them all for $VERSION and take the newest.
6088 #-> sub CPAN::Bundle::inst_file ;
6093 @me = split /::/, $self->id;
6096 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
6097 my $bfile = File::Spec->catfile($incdir, @me);
6098 CPAN->debug("bfile[$bfile]") if $CPAN::DEBUG;
6099 next unless -f $bfile;
6100 my $foundv = MM->parse_version($bfile);
6101 if (!$bestv || CPAN::Version->vgt($foundv,$bestv)) {
6102 $self->{INST_FILE} = $bfile;
6103 $self->{INST_VERSION} = $bestv = $foundv;
6109 #-> sub CPAN::Bundle::inst_version ;
6112 $self->inst_file; # finds INST_VERSION as side effect
6113 $self->{INST_VERSION};
6116 #-> sub CPAN::Bundle::rematein ;
6118 my($self,$meth) = @_;
6119 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
6120 my($id) = $self->id;
6121 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
6122 unless $self->inst_file || $self->cpan_file;
6124 for $s ($self->contains) {
6125 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
6126 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
6127 if ($type eq 'CPAN::Distribution') {
6128 $CPAN::Frontend->mywarn(qq{
6129 The Bundle }.$self->id.qq{ contains
6130 explicitly a file $s.
6134 # possibly noisy action:
6135 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
6136 my $obj = $CPAN::META->instance($type,$s);
6138 if ($obj->isa('CPAN::Bundle')
6140 exists $obj->{install_failed}
6142 ref($obj->{install_failed}) eq "HASH"
6144 for (keys %{$obj->{install_failed}}) {
6145 $self->{install_failed}{$_} = undef; # propagate faiure up
6148 $fail{$s} = 1; # the bundle itself may have succeeded but
6153 $success = $obj->can("uptodate") ? $obj->uptodate : 0;
6154 $success ||= $obj->{'install'} && $obj->{'install'} eq "YES";
6156 delete $self->{install_failed}{$s};
6163 # recap with less noise
6164 if ( $meth eq "install" ) {
6167 my $raw = sprintf(qq{Bundle summary:
6168 The following items in bundle %s had installation problems:},
6171 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
6172 $CPAN::Frontend->myprint("\n");
6175 for $s ($self->contains) {
6177 $paragraph .= "$s ";
6178 $self->{install_failed}{$s} = undef;
6179 $reported{$s} = undef;
6182 my $report_propagated;
6183 for $s (sort keys %{$self->{install_failed}}) {
6184 next if exists $reported{$s};
6185 $paragraph .= "and the following items had problems
6186 during recursive bundle calls: " unless $report_propagated++;
6187 $paragraph .= "$s ";
6189 $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
6190 $CPAN::Frontend->myprint("\n");
6192 $self->{'install'} = 'YES';
6197 #sub CPAN::Bundle::xs_file
6199 # If a bundle contains another that contains an xs_file we have
6200 # here, we just don't bother I suppose
6204 #-> sub CPAN::Bundle::force ;
6205 sub force { shift->rematein('force',@_); }
6206 #-> sub CPAN::Bundle::notest ;
6207 sub notest { shift->rematein('notest',@_); }
6208 #-> sub CPAN::Bundle::get ;
6209 sub get { shift->rematein('get',@_); }
6210 #-> sub CPAN::Bundle::make ;
6211 sub make { shift->rematein('make',@_); }
6212 #-> sub CPAN::Bundle::test ;
6215 $self->{badtestcnt} ||= 0;
6216 $self->rematein('test',@_);
6218 #-> sub CPAN::Bundle::install ;
6221 $self->rematein('install',@_);
6223 #-> sub CPAN::Bundle::clean ;
6224 sub clean { shift->rematein('clean',@_); }
6226 #-> sub CPAN::Bundle::uptodate ;
6229 return 0 unless $self->SUPER::uptodate; # we mut have the current Bundle def
6231 foreach $c ($self->contains) {
6232 my $obj = CPAN::Shell->expandany($c);
6233 return 0 unless $obj->uptodate;
6238 #-> sub CPAN::Bundle::readme ;
6241 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
6242 No File found for bundle } . $self->id . qq{\n}), return;
6243 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
6244 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
6247 package CPAN::Module;
6251 # sub CPAN::Module::userid
6256 return $ro->{userid} || $ro->{CPAN_USERID};
6258 # sub CPAN::Module::description
6261 my $ro = $self->ro or return "";
6267 CPAN::Shell->expand("Distribution",$self->cpan_file);
6270 # sub CPAN::Module::undelay
6273 delete $self->{later};
6274 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
6279 # mark as dirty/clean
6280 #-> sub CPAN::Module::color_cmd_tmps ;
6281 sub color_cmd_tmps {
6283 my($depth) = shift || 0;
6284 my($color) = shift || 0;
6285 my($ancestors) = shift || [];
6286 # a module needs to recurse to its cpan_file
6288 return if exists $self->{incommandcolor}
6289 && $self->{incommandcolor}==$color;
6290 return if $depth>=1 && $self->uptodate;
6292 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
6294 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
6296 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
6297 $dist->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
6300 delete $self->{badtestcnt};
6302 $self->{incommandcolor} = $color;
6305 #-> sub CPAN::Module::as_glimpse ;
6309 my $class = ref($self);
6310 $class =~ s/^CPAN:://;
6314 $CPAN::Shell::COLOR_REGISTERED
6316 $CPAN::META->has_inst("Term::ANSIColor")
6320 $color_on = Term::ANSIColor::color("green");
6321 $color_off = Term::ANSIColor::color("reset");
6323 push @m, sprintf("%-8s %s%-22s%s (%s)\n",
6328 $self->distribution ? $self->distribution->pretty_id : $self->id,
6333 #-> sub CPAN::Module::as_string ;
6337 CPAN->debug("$self entering as_string") if $CPAN::DEBUG;
6338 my $class = ref($self);
6339 $class =~ s/^CPAN:://;
6341 push @m, $class, " id = $self->{ID}\n";
6342 my $sprintf = " %-12s %s\n";
6343 push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
6344 if $self->description;
6345 my $sprintf2 = " %-12s %s (%s)\n";
6347 $userid = $self->userid;
6350 if ($author = CPAN::Shell->expand('Author',$userid)) {
6353 if ($m = $author->email) {
6360 $author->fullname . $email
6364 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
6365 if $self->cpan_version;
6366 if (my $cpan_file = $self->cpan_file){
6367 push @m, sprintf($sprintf, 'CPAN_FILE', $cpan_file);
6368 if (my $dist = CPAN::Shell->expand("Distribution",$cpan_file)) {
6369 my $upload_date = $dist->upload_date;
6371 push @m, sprintf($sprintf, 'UPLOAD_DATE', $upload_date);
6375 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
6376 my(%statd,%stats,%statl,%stati);
6377 @statd{qw,? i c a b R M S,} = qw,unknown idea
6378 pre-alpha alpha beta released mature standard,;
6379 @stats{qw,? m d u n a,} = qw,unknown mailing-list
6380 developer comp.lang.perl.* none abandoned,;
6381 @statl{qw,? p c + o h,} = qw,unknown perl C C++ other hybrid,;
6382 @stati{qw,? f r O h,} = qw,unknown functions
6383 references+ties object-oriented hybrid,;
6384 $statd{' '} = 'unknown';
6385 $stats{' '} = 'unknown';
6386 $statl{' '} = 'unknown';
6387 $stati{' '} = 'unknown';
6396 $statd{$ro->{statd}},
6397 $stats{$ro->{stats}},
6398 $statl{$ro->{statl}},
6399 $stati{$ro->{stati}}
6400 ) if $ro && $ro->{statd};
6401 my $local_file = $self->inst_file;
6402 unless ($self->{MANPAGE}) {
6404 $self->{MANPAGE} = $self->manpage_headline($local_file);
6406 # If we have already untarred it, we should look there
6407 my $dist = $CPAN::META->instance('CPAN::Distribution',
6409 # warn "dist[$dist]";
6410 # mff=manifest file; mfh=manifest handle
6415 (-f ($mff = File::Spec->catfile($dist->{build_dir}, "MANIFEST")))
6417 $mfh = FileHandle->new($mff)
6419 CPAN->debug("mff[$mff]") if $CPAN::DEBUG;
6420 my $lfre = $self->id; # local file RE
6423 my($lfl); # local file file
6425 my(@mflines) = <$mfh>;
6430 while (length($lfre)>5 and !$lfl) {
6431 ($lfl) = grep /$lfre/, @mflines;
6432 CPAN->debug("lfl[$lfl]lfre[$lfre]") if $CPAN::DEBUG;
6435 $lfl =~ s/\s.*//; # remove comments
6436 $lfl =~ s/\s+//g; # chomp would maybe be too system-specific
6437 my $lfl_abs = File::Spec->catfile($dist->{build_dir},$lfl);
6438 # warn "lfl_abs[$lfl_abs]";
6440 $self->{MANPAGE} = $self->manpage_headline($lfl_abs);
6446 for $item (qw/MANPAGE/) {
6447 push @m, sprintf($sprintf, $item, $self->{$item})
6448 if exists $self->{$item};
6450 for $item (qw/CONTAINS/) {
6451 push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
6452 if exists $self->{$item} && @{$self->{$item}};
6454 push @m, sprintf($sprintf, 'INST_FILE',
6455 $local_file || "(not installed)");
6456 push @m, sprintf($sprintf, 'INST_VERSION',
6457 $self->inst_version) if $local_file;
6461 sub manpage_headline {
6462 my($self,$local_file) = @_;
6463 my(@local_file) = $local_file;
6464 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
6465 push @local_file, $local_file;
6467 for $locf (@local_file) {
6468 next unless -f $locf;
6469 my $fh = FileHandle->new($locf)
6470 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
6474 $inpod = m/^=(?!head1\s+NAME\s*$)/ ? 0 :
6475 m/^=head1\s+NAME\s*$/ ? 1 : $inpod;
6492 #-> sub CPAN::Module::cpan_file ;
6493 # Note: also inherited by CPAN::Bundle
6496 CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
6497 unless ($self->ro) {
6498 CPAN::Index->reload;
6501 if ($ro && defined $ro->{CPAN_FILE}){
6502 return $ro->{CPAN_FILE};
6504 my $userid = $self->userid;
6506 if ($CPAN::META->exists("CPAN::Author",$userid)) {
6507 my $author = $CPAN::META->instance("CPAN::Author",
6509 my $fullname = $author->fullname;
6510 my $email = $author->email;
6511 unless (defined $fullname && defined $email) {
6512 return sprintf("Contact Author %s",
6516 return "Contact Author $fullname <$email>";
6518 return "Contact Author $userid (Email address not available)";
6526 #-> sub CPAN::Module::cpan_version ;
6532 # Can happen with modules that are not on CPAN
6535 $ro->{CPAN_VERSION} = 'undef'
6536 unless defined $ro->{CPAN_VERSION};
6537 $ro->{CPAN_VERSION};
6540 #-> sub CPAN::Module::force ;
6543 $self->{'force_update'}++;
6548 # warn "XDEBUG: set notest for Module";
6549 $self->{'notest'}++;
6552 #-> sub CPAN::Module::rematein ;
6554 my($self,$meth) = @_;
6555 $CPAN::Frontend->myprint(sprintf("Running %s for module %s\n",
6558 my $cpan_file = $self->cpan_file;
6559 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
6560 $CPAN::Frontend->mywarn(sprintf qq{
6561 The module %s isn\'t available on CPAN.
6563 Either the module has not yet been uploaded to CPAN, or it is
6564 temporary unavailable. Please contact the author to find out
6565 more about the status. Try 'i %s'.
6572 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
6573 $pack->called_for($self->id);
6574 $pack->force($meth) if exists $self->{'force_update'};
6575 $pack->notest($meth) if exists $self->{'notest'};
6580 $pack->unforce if $pack->can("unforce") && exists $self->{'force_update'};
6581 $pack->unnotest if $pack->can("unnotest") && exists $self->{'notest'};
6582 delete $self->{'force_update'};
6583 delete $self->{'notest'};
6589 #-> sub CPAN::Module::perldoc ;
6590 sub perldoc { shift->rematein('perldoc') }
6591 #-> sub CPAN::Module::readme ;
6592 sub readme { shift->rematein('readme') }
6593 #-> sub CPAN::Module::look ;
6594 sub look { shift->rematein('look') }
6595 #-> sub CPAN::Module::cvs_import ;
6596 sub cvs_import { shift->rematein('cvs_import') }
6597 #-> sub CPAN::Module::get ;
6598 sub get { shift->rematein('get',@_) }
6599 #-> sub CPAN::Module::make ;
6600 sub make { shift->rematein('make') }
6601 #-> sub CPAN::Module::test ;
6604 $self->{badtestcnt} ||= 0;
6605 $self->rematein('test',@_);
6607 #-> sub CPAN::Module::uptodate ;
6610 my($latest) = $self->cpan_version;
6612 my($inst_file) = $self->inst_file;
6614 if (defined $inst_file) {
6615 $have = $self->inst_version;
6620 ! CPAN::Version->vgt($latest, $have)
6622 CPAN->debug("returning uptodate. inst_file[$inst_file] ".
6623 "latest[$latest] have[$have]") if $CPAN::DEBUG;
6628 #-> sub CPAN::Module::install ;
6634 not exists $self->{'force_update'}
6636 $CPAN::Frontend->myprint(sprintf("%s is up to date (%s).\n",
6638 $self->inst_version,
6644 if ($ro && $ro->{stats} && $ro->{stats} eq "a") {
6645 $CPAN::Frontend->mywarn(qq{
6646 \n\n\n ***WARNING***
6647 The module $self->{ID} has no active maintainer.\n\n\n
6651 $self->rematein('install') if $doit;
6653 #-> sub CPAN::Module::clean ;
6654 sub clean { shift->rematein('clean') }
6656 #-> sub CPAN::Module::inst_file ;
6660 @packpath = split /::/, $self->{ID};
6661 $packpath[-1] .= ".pm";
6662 foreach $dir (@INC) {
6663 my $pmfile = File::Spec->catfile($dir,@packpath);
6671 #-> sub CPAN::Module::xs_file ;
6675 @packpath = split /::/, $self->{ID};
6676 push @packpath, $packpath[-1];
6677 $packpath[-1] .= "." . $Config::Config{'dlext'};
6678 foreach $dir (@INC) {
6679 my $xsfile = File::Spec->catfile($dir,'auto',@packpath);
6687 #-> sub CPAN::Module::inst_version ;
6690 my $parsefile = $self->inst_file or return;
6691 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
6694 $have = MM->parse_version($parsefile) || "undef";
6695 $have =~ s/^ //; # since the %vd hack these two lines here are needed
6696 $have =~ s/ $//; # trailing whitespace happens all the time
6698 # My thoughts about why %vd processing should happen here
6700 # Alt1 maintain it as string with leading v:
6701 # read index files do nothing
6702 # compare it use utility for compare
6703 # print it do nothing
6705 # Alt2 maintain it as what it is
6706 # read index files convert
6707 # compare it use utility because there's still a ">" vs "gt" issue
6708 # print it use CPAN::Version for print
6710 # Seems cleaner to hold it in memory as a string starting with a "v"
6712 # If the author of this module made a mistake and wrote a quoted
6713 # "v1.13" instead of v1.13, we simply leave it at that with the
6714 # effect that *we* will treat it like a v-tring while the rest of
6715 # perl won't. Seems sensible when we consider that any action we
6716 # could take now would just add complexity.
6718 $have = CPAN::Version->readable($have);
6720 $have =~ s/\s*//g; # stringify to float around floating point issues
6721 $have; # no stringify needed, \s* above matches always
6733 CPAN - query, download and build perl modules from CPAN sites
6739 perl -MCPAN -e shell;
6747 $mod = "Acme::Meta";
6749 CPAN::Shell->install($mod); # same thing
6750 CPAN::Shell->expandany($mod)->install; # same thing
6751 CPAN::Shell->expand("Module",$mod)->install; # same thing
6752 CPAN::Shell->expand("Module",$mod)
6753 ->distribution->install; # same thing
6757 $distro = "NWCLARK/Acme-Meta-0.01.tar.gz";
6758 install $distro; # same thing
6759 CPAN::Shell->install($distro); # same thing
6760 CPAN::Shell->expandany($distro)->install; # same thing
6761 CPAN::Shell->expand("Module",$distro)->install; # same thing
6765 This module will eventually be replaced by CPANPLUS. CPANPLUS is kind
6766 of a modern rewrite from ground up with greater extensibility and more
6767 features but no full compatibility. If you're new to CPAN.pm, you
6768 probably should investigate if CPANPLUS is the better choice for you.
6770 If you're already used to CPAN.pm you're welcome to continue using it.
6771 I intend to support it until somebody convinces me that there is a
6772 both superior and sufficiently compatible drop-in replacement.
6774 =head1 COMPATIBILITY
6776 CPAN.pm is regularly tested to run under 5.004, 5.005, and assorted
6777 newer versions. It is getting more and more difficult to get the
6778 minimal prerequisites working on older perls. It is close to
6779 impossible to get the whole Bundle::CPAN working there. If you're in
6780 the position to have only these old versions, be advised that CPAN is
6781 designed to work fine without the Bundle::CPAN installed.
6783 To get things going, note that GBARR/Scalar-List-Utils-1.18.tar.gz is
6784 compatible with ancient perls and that File::Temp is listed as a
6785 prerequisite but CPAN has reasonable workarounds if it is missing.
6789 The CPAN module is designed to automate the make and install of perl
6790 modules and extensions. It includes some primitive searching
6791 capabilities and knows how to use Net::FTP or LWP (or some external
6792 download clients) to fetch the raw data from the net.
6794 Modules are fetched from one or more of the mirrored CPAN
6795 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
6798 The CPAN module also supports the concept of named and versioned
6799 I<bundles> of modules. Bundles simplify the handling of sets of
6800 related modules. See Bundles below.
6802 The package contains a session manager and a cache manager. There is
6803 no status retained between sessions. The session manager keeps track
6804 of what has been fetched, built and installed in the current
6805 session. The cache manager keeps track of the disk space occupied by
6806 the make processes and deletes excess space according to a simple FIFO
6809 All methods provided are accessible in a programmer style and in an
6810 interactive shell style.
6812 =head2 Interactive Mode
6814 The interactive mode is entered by running
6816 perl -MCPAN -e shell
6818 which puts you into a readline interface. You will have the most fun if
6819 you install Term::ReadKey and Term::ReadLine to enjoy both history and
6822 Once you are on the command line, type 'h' and the rest should be
6825 The function call C<shell> takes two optional arguments, one is the
6826 prompt, the second is the default initial command line (the latter
6827 only works if a real ReadLine interface module is installed).
6829 The most common uses of the interactive modes are
6833 =item Searching for authors, bundles, distribution files and modules
6835 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
6836 for each of the four categories and another, C<i> for any of the
6837 mentioned four. Each of the four entities is implemented as a class
6838 with slightly differing methods for displaying an object.
6840 Arguments you pass to these commands are either strings exactly matching
6841 the identification string of an object or regular expressions that are
6842 then matched case-insensitively against various attributes of the
6843 objects. The parser recognizes a regular expression only if you
6844 enclose it between two slashes.
6846 The principle is that the number of found objects influences how an
6847 item is displayed. If the search finds one item, the result is
6848 displayed with the rather verbose method C<as_string>, but if we find
6849 more than one, we display each object with the terse method
6852 =item make, test, install, clean modules or distributions
6854 These commands take any number of arguments and investigate what is
6855 necessary to perform the action. If the argument is a distribution
6856 file name (recognized by embedded slashes), it is processed. If it is
6857 a module, CPAN determines the distribution file in which this module
6858 is included and processes that, following any dependencies named in
6859 the module's META.yml or Makefile.PL (this behavior is controlled by
6860 the configuration parameter C<prerequisites_policy>.)
6862 Any C<make> or C<test> are run unconditionally. An
6864 install <distribution_file>
6866 also is run unconditionally. But for
6870 CPAN checks if an install is actually needed for it and prints
6871 I<module up to date> in the case that the distribution file containing
6872 the module doesn't need to be updated.
6874 CPAN also keeps track of what it has done within the current session
6875 and doesn't try to build a package a second time regardless if it
6876 succeeded or not. The C<force> pragma may precede another command
6877 (currently: C<make>, C<test>, or C<install>) and executes the
6878 command from scratch and tries to continue in case of some errors.
6882 cpan> install OpenGL
6883 OpenGL is up to date.
6884 cpan> force install OpenGL
6887 OpenGL-0.4/COPYRIGHT
6890 The C<notest> pragma may be set to skip the test part in the build
6895 cpan> notest install Tk
6897 A C<clean> command results in a
6901 being executed within the distribution file's working directory.
6903 =item get, readme, perldoc, look module or distribution
6905 C<get> downloads a distribution file without further action. C<readme>
6906 displays the README file of the associated distribution. C<Look> gets
6907 and untars (if not yet done) the distribution file, changes to the
6908 appropriate directory and opens a subshell process in that directory.
6909 C<perldoc> displays the pod documentation of the module in html or
6914 =item ls globbing_expression
6916 The first form lists all distribution files in and below an author's
6917 CPAN directory as they are stored in the CHECKUMS files distributed on
6918 CPAN. The listing goes recursive into all subdirectories.
6920 The second form allows to limit or expand the output with shell
6921 globbing as in the following examples:
6927 The last example is very slow and outputs extra progress indicators
6928 that break the alignment of the result.
6930 Note that globbing only lists directories explicitly asked for, for
6931 example FOO/* will not list FOO/bar/Acme-Sthg-n.nn.tar.gz. This may be
6932 regarded as a bug and may be changed in future versions.
6936 The C<failed> command reports all distributions that failed on one of
6937 C<make>, C<test> or C<install> for some reason in the currently
6938 running shell session.
6942 Interactive sessions maintain a lockfile, per default C<~/.cpan/.lock>
6943 (but the directory can be configured via the C<cpan_home> config
6944 variable). The shell is a bit picky if you try to start another CPAN
6945 session. It dies immediately if there is a lockfile and the lock seems
6946 to belong to a running process. In case you want to run a second shell
6947 session, it is probably safest to maintain another directory, say
6948 C<~/.cpan-for-X/> and a C<~/.cpan-for-X/CPAN/MyConfig.pm> that
6949 contains the configuration options. Then you can start the second
6952 perl -I ~/.cpan-for-X -MCPAN::MyConfig -MCPAN -e shell
6956 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
6957 in the cpan-shell it is intended that you can press C<^C> anytime and
6958 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
6959 to clean up and leave the shell loop. You can emulate the effect of a
6960 SIGTERM by sending two consecutive SIGINTs, which usually means by
6961 pressing C<^C> twice.
6963 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
6964 SIGALRM is used during the run of the C<perl Makefile.PL> or C<perl
6965 Build.PL> subprocess.
6971 The commands that are available in the shell interface are methods in
6972 the package CPAN::Shell. If you enter the shell command, all your
6973 input is split by the Text::ParseWords::shellwords() routine which
6974 acts like most shells do. The first word is being interpreted as the
6975 method to be called and the rest of the words are treated as arguments
6976 to this method. Continuation lines are supported if a line ends with a
6981 C<autobundle> writes a bundle file into the
6982 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
6983 a list of all modules that are both available from CPAN and currently
6984 installed within @INC. The name of the bundle file is based on the
6985 current date and a counter.
6989 recompile() is a very special command in that it takes no argument and
6990 runs the make/test/install cycle with brute force over all installed
6991 dynamically loadable extensions (aka XS modules) with 'force' in
6992 effect. The primary purpose of this command is to finish a network
6993 installation. Imagine, you have a common source tree for two different
6994 architectures. You decide to do a completely independent fresh
6995 installation. You start on one architecture with the help of a Bundle
6996 file produced earlier. CPAN installs the whole Bundle for you, but
6997 when you try to repeat the job on the second architecture, CPAN
6998 responds with a C<"Foo up to date"> message for all modules. So you
6999 invoke CPAN's recompile on the second architecture and you're done.
7001 Another popular use for C<recompile> is to act as a rescue in case your
7002 perl breaks binary compatibility. If one of the modules that CPAN uses
7003 is in turn depending on binary compatibility (so you cannot run CPAN
7004 commands), then you should try the CPAN::Nox module for recovery.
7008 mkmyconfig() writes your own CPAN::MyConfig file into your ~/.cpan/
7009 directory so that you can save your own preferences instead of the
7012 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
7014 Although it may be considered internal, the class hierarchy does matter
7015 for both users and programmer. CPAN.pm deals with above mentioned four
7016 classes, and all those classes share a set of methods. A classical
7017 single polymorphism is in effect. A metaclass object registers all
7018 objects of all kinds and indexes them with a string. The strings
7019 referencing objects have a separated namespace (well, not completely
7024 words containing a "/" (slash) Distribution
7025 words starting with Bundle:: Bundle
7026 everything else Module or Author
7028 Modules know their associated Distribution objects. They always refer
7029 to the most recent official release. Developers may mark their releases
7030 as unstable development versions (by inserting an underbar into the
7031 module version number which will also be reflected in the distribution
7032 name when you run 'make dist'), so the really hottest and newest
7033 distribution is not always the default. If a module Foo circulates
7034 on CPAN in both version 1.23 and 1.23_90, CPAN.pm offers a convenient
7035 way to install version 1.23 by saying
7039 This would install the complete distribution file (say
7040 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
7041 like to install version 1.23_90, you need to know where the
7042 distribution file resides on CPAN relative to the authors/id/
7043 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
7044 so you would have to say
7046 install BAR/Foo-1.23_90.tar.gz
7048 The first example will be driven by an object of the class
7049 CPAN::Module, the second by an object of class CPAN::Distribution.
7051 =head2 Programmer's interface
7053 If you do not enter the shell, the available shell commands are both
7054 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
7055 functions in the calling package (C<install(...)>).
7057 There's currently only one class that has a stable interface -
7058 CPAN::Shell. All commands that are available in the CPAN shell are
7059 methods of the class CPAN::Shell. Each of the commands that produce
7060 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
7061 the IDs of all modules within the list.
7065 =item expand($type,@things)
7067 The IDs of all objects available within a program are strings that can
7068 be expanded to the corresponding real objects with the
7069 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
7070 list of CPAN::Module objects according to the C<@things> arguments
7071 given. In scalar context it only returns the first element of the
7074 =item expandany(@things)
7076 Like expand, but returns objects of the appropriate type, i.e.
7077 CPAN::Bundle objects for bundles, CPAN::Module objects for modules and
7078 CPAN::Distribution objects for distributions. Note: it does not expand
7079 to CPAN::Author objects.
7081 =item Programming Examples
7083 This enables the programmer to do operations that combine
7084 functionalities that are available in the shell.
7086 # install everything that is outdated on my disk:
7087 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
7089 # install my favorite programs if necessary:
7090 for $mod (qw(Net::FTP Digest::SHA Data::Dumper)){
7091 my $obj = CPAN::Shell->expand('Module',$mod);
7095 # list all modules on my disk that have no VERSION number
7096 for $mod (CPAN::Shell->expand("Module","/./")){
7097 next unless $mod->inst_file;
7098 # MakeMaker convention for undefined $VERSION:
7099 next unless $mod->inst_version eq "undef";
7100 print "No VERSION in ", $mod->id, "\n";
7103 # find out which distribution on CPAN contains a module:
7104 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
7106 Or if you want to write a cronjob to watch The CPAN, you could list
7107 all modules that need updating. First a quick and dirty way:
7109 perl -e 'use CPAN; CPAN::Shell->r;'
7111 If you don't want to get any output in the case that all modules are
7112 up to date, you can parse the output of above command for the regular
7113 expression //modules are up to date// and decide to mail the output
7114 only if it doesn't match. Ick?
7116 If you prefer to do it more in a programmer style in one single
7117 process, maybe something like this suits you better:
7119 # list all modules on my disk that have newer versions on CPAN
7120 for $mod (CPAN::Shell->expand("Module","/./")){
7121 next unless $mod->inst_file;
7122 next if $mod->uptodate;
7123 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
7124 $mod->id, $mod->inst_version, $mod->cpan_version;
7127 If that gives you too much output every day, you maybe only want to
7128 watch for three modules. You can write
7130 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")){
7132 as the first line instead. Or you can combine some of the above
7135 # watch only for a new mod_perl module
7136 $mod = CPAN::Shell->expand("Module","mod_perl");
7137 exit if $mod->uptodate;
7138 # new mod_perl arrived, let me know all update recommendations
7143 =head2 Methods in the other Classes
7145 The programming interface for the classes CPAN::Module,
7146 CPAN::Distribution, CPAN::Bundle, and CPAN::Author is still considered
7147 beta and partially even alpha. In the following paragraphs only those
7148 methods are documented that have proven useful over a longer time and
7149 thus are unlikely to change.
7153 =item CPAN::Author::as_glimpse()
7155 Returns a one-line description of the author
7157 =item CPAN::Author::as_string()
7159 Returns a multi-line description of the author
7161 =item CPAN::Author::email()
7163 Returns the author's email address
7165 =item CPAN::Author::fullname()
7167 Returns the author's name
7169 =item CPAN::Author::name()
7171 An alias for fullname
7173 =item CPAN::Bundle::as_glimpse()
7175 Returns a one-line description of the bundle
7177 =item CPAN::Bundle::as_string()
7179 Returns a multi-line description of the bundle
7181 =item CPAN::Bundle::clean()
7183 Recursively runs the C<clean> method on all items contained in the bundle.
7185 =item CPAN::Bundle::contains()
7187 Returns a list of objects' IDs contained in a bundle. The associated
7188 objects may be bundles, modules or distributions.
7190 =item CPAN::Bundle::force($method,@args)
7192 Forces CPAN to perform a task that normally would have failed. Force
7193 takes as arguments a method name to be called and any number of
7194 additional arguments that should be passed to the called method. The
7195 internals of the object get the needed changes so that CPAN.pm does
7196 not refuse to take the action. The C<force> is passed recursively to
7197 all contained objects.
7199 =item CPAN::Bundle::get()
7201 Recursively runs the C<get> method on all items contained in the bundle
7203 =item CPAN::Bundle::inst_file()
7205 Returns the highest installed version of the bundle in either @INC or
7206 C<$CPAN::Config->{cpan_home}>. Note that this is different from
7207 CPAN::Module::inst_file.
7209 =item CPAN::Bundle::inst_version()
7211 Like CPAN::Bundle::inst_file, but returns the $VERSION
7213 =item CPAN::Bundle::uptodate()
7215 Returns 1 if the bundle itself and all its members are uptodate.
7217 =item CPAN::Bundle::install()
7219 Recursively runs the C<install> method on all items contained in the bundle
7221 =item CPAN::Bundle::make()
7223 Recursively runs the C<make> method on all items contained in the bundle
7225 =item CPAN::Bundle::readme()
7227 Recursively runs the C<readme> method on all items contained in the bundle
7229 =item CPAN::Bundle::test()
7231 Recursively runs the C<test> method on all items contained in the bundle
7233 =item CPAN::Distribution::as_glimpse()
7235 Returns a one-line description of the distribution
7237 =item CPAN::Distribution::as_string()
7239 Returns a multi-line description of the distribution
7241 =item CPAN::Distribution::author
7243 Returns the CPAN::Author object of the maintainer who uploaded this
7246 =item CPAN::Distribution::clean()
7248 Changes to the directory where the distribution has been unpacked and
7249 runs C<make clean> there.
7251 =item CPAN::Distribution::containsmods()
7253 Returns a list of IDs of modules contained in a distribution file.
7254 Only works for distributions listed in the 02packages.details.txt.gz
7255 file. This typically means that only the most recent version of a
7256 distribution is covered.
7258 =item CPAN::Distribution::cvs_import()
7260 Changes to the directory where the distribution has been unpacked and
7263 cvs -d $cvs_root import -m $cvs_log $cvs_dir $userid v$version
7267 =item CPAN::Distribution::dir()
7269 Returns the directory into which this distribution has been unpacked.
7271 =item CPAN::Distribution::force($method,@args)
7273 Forces CPAN to perform a task that normally would have failed. Force
7274 takes as arguments a method name to be called and any number of
7275 additional arguments that should be passed to the called method. The
7276 internals of the object get the needed changes so that CPAN.pm does
7277 not refuse to take the action.
7279 =item CPAN::Distribution::get()
7281 Downloads the distribution from CPAN and unpacks it. Does nothing if
7282 the distribution has already been downloaded and unpacked within the
7285 =item CPAN::Distribution::install()
7287 Changes to the directory where the distribution has been unpacked and
7288 runs the external command C<make install> there. If C<make> has not
7289 yet been run, it will be run first. A C<make test> will be issued in
7290 any case and if this fails, the install will be canceled. The
7291 cancellation can be avoided by letting C<force> run the C<install> for
7294 =item CPAN::Distribution::isa_perl()
7296 Returns 1 if this distribution file seems to be a perl distribution.
7297 Normally this is derived from the file name only, but the index from
7298 CPAN can contain a hint to achieve a return value of true for other
7301 =item CPAN::Distribution::look()
7303 Changes to the directory where the distribution has been unpacked and
7304 opens a subshell there. Exiting the subshell returns.
7306 =item CPAN::Distribution::make()
7308 First runs the C<get> method to make sure the distribution is
7309 downloaded and unpacked. Changes to the directory where the
7310 distribution has been unpacked and runs the external commands C<perl
7311 Makefile.PL> or C<perl Build.PL> and C<make> there.
7313 =item CPAN::Distribution::perldoc()
7315 Downloads the pod documentation of the file associated with a
7316 distribution (in html format) and runs it through the external
7317 command lynx specified in C<$CPAN::Config->{lynx}>. If lynx
7318 isn't available, it converts it to plain text with external
7319 command html2text and runs it through the pager specified
7320 in C<$CPAN::Config->{pager}>
7322 =item CPAN::Distribution::prereq_pm()
7324 Returns the hash reference that has been announced by a distribution
7325 as the merge of the C<requires> element and the C<build_requires>
7326 element of the META.yml or the C<PREREQ_PM> hash in the
7327 C<Makefile.PL>. Note: works only after an attempt has been made to
7328 C<make> the distribution. Returns undef otherwise.
7330 =item CPAN::Distribution::readme()
7332 Downloads the README file associated with a distribution and runs it
7333 through the pager specified in C<$CPAN::Config->{pager}>.
7335 =item CPAN::Distribution::read_yaml()
7337 Returns the content of the META.yml of this distro as a hashref. Note:
7338 works only after an attempt has been made to C<make> the distribution.
7339 Returns undef otherwise.
7341 =item CPAN::Distribution::test()
7343 Changes to the directory where the distribution has been unpacked and
7344 runs C<make test> there.
7346 =item CPAN::Distribution::uptodate()
7348 Returns 1 if all the modules contained in the distribution are
7349 uptodate. Relies on containsmods.
7351 =item CPAN::Index::force_reload()
7353 Forces a reload of all indices.
7355 =item CPAN::Index::reload()
7357 Reloads all indices if they have not been read for more than
7358 C<$CPAN::Config->{index_expire}> days.
7360 =item CPAN::InfoObj::dump()
7362 CPAN::Author, CPAN::Bundle, CPAN::Module, and CPAN::Distribution
7363 inherit this method. It prints the data structure associated with an
7364 object. Useful for debugging. Note: the data structure is considered
7365 internal and thus subject to change without notice.
7367 =item CPAN::Module::as_glimpse()
7369 Returns a one-line description of the module
7371 =item CPAN::Module::as_string()
7373 Returns a multi-line description of the module
7375 =item CPAN::Module::clean()
7377 Runs a clean on the distribution associated with this module.
7379 =item CPAN::Module::cpan_file()
7381 Returns the filename on CPAN that is associated with the module.
7383 =item CPAN::Module::cpan_version()
7385 Returns the latest version of this module available on CPAN.
7387 =item CPAN::Module::cvs_import()
7389 Runs a cvs_import on the distribution associated with this module.
7391 =item CPAN::Module::description()
7393 Returns a 44 character description of this module. Only available for
7394 modules listed in The Module List (CPAN/modules/00modlist.long.html
7395 or 00modlist.long.txt.gz)
7397 =item CPAN::Module::distribution()
7399 Returns the CPAN::Distribution object that contains the current
7400 version of this module.
7402 =item CPAN::Module::force($method,@args)
7404 Forces CPAN to perform a task that normally would have failed. Force
7405 takes as arguments a method name to be called and any number of
7406 additional arguments that should be passed to the called method. The
7407 internals of the object get the needed changes so that CPAN.pm does
7408 not refuse to take the action.
7410 =item CPAN::Module::get()
7412 Runs a get on the distribution associated with this module.
7414 =item CPAN::Module::inst_file()
7416 Returns the filename of the module found in @INC. The first file found
7417 is reported just like perl itself stops searching @INC when it finds a
7420 =item CPAN::Module::inst_version()
7422 Returns the version number of the module in readable format.
7424 =item CPAN::Module::install()
7426 Runs an C<install> on the distribution associated with this module.
7428 =item CPAN::Module::look()
7430 Changes to the directory where the distribution associated with this
7431 module has been unpacked and opens a subshell there. Exiting the
7434 =item CPAN::Module::make()
7436 Runs a C<make> on the distribution associated with this module.
7438 =item CPAN::Module::manpage_headline()
7440 If module is installed, peeks into the module's manpage, reads the
7441 headline and returns it. Moreover, if the module has been downloaded
7442 within this session, does the equivalent on the downloaded module even
7443 if it is not installed.
7445 =item CPAN::Module::perldoc()
7447 Runs a C<perldoc> on this module.
7449 =item CPAN::Module::readme()
7451 Runs a C<readme> on the distribution associated with this module.
7453 =item CPAN::Module::test()
7455 Runs a C<test> on the distribution associated with this module.
7457 =item CPAN::Module::uptodate()
7459 Returns 1 if the module is installed and up-to-date.
7461 =item CPAN::Module::userid()
7463 Returns the author's ID of the module.
7467 =head2 Cache Manager
7469 Currently the cache manager only keeps track of the build directory
7470 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
7471 deletes complete directories below C<build_dir> as soon as the size of
7472 all directories there gets bigger than $CPAN::Config->{build_cache}
7473 (in MB). The contents of this cache may be used for later
7474 re-installations that you intend to do manually, but will never be
7475 trusted by CPAN itself. This is due to the fact that the user might
7476 use these directories for building modules on different architectures.
7478 There is another directory ($CPAN::Config->{keep_source_where}) where
7479 the original distribution files are kept. This directory is not
7480 covered by the cache manager and must be controlled by the user. If
7481 you choose to have the same directory as build_dir and as
7482 keep_source_where directory, then your sources will be deleted with
7483 the same fifo mechanism.
7487 A bundle is just a perl module in the namespace Bundle:: that does not
7488 define any functions or methods. It usually only contains documentation.
7490 It starts like a perl module with a package declaration and a $VERSION
7491 variable. After that the pod section looks like any other pod with the
7492 only difference being that I<one special pod section> exists starting with
7497 In this pod section each line obeys the format
7499 Module_Name [Version_String] [- optional text]
7501 The only required part is the first field, the name of a module
7502 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
7503 of the line is optional. The comment part is delimited by a dash just
7504 as in the man page header.
7506 The distribution of a bundle should follow the same convention as
7507 other distributions.
7509 Bundles are treated specially in the CPAN package. If you say 'install
7510 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
7511 the modules in the CONTENTS section of the pod. You can install your
7512 own Bundles locally by placing a conformant Bundle file somewhere into
7513 your @INC path. The autobundle() command which is available in the
7514 shell interface does that for you by including all currently installed
7515 modules in a snapshot bundle file.
7517 =head2 Prerequisites
7519 If you have a local mirror of CPAN and can access all files with
7520 "file:" URLs, then you only need a perl better than perl5.003 to run
7521 this module. Otherwise Net::FTP is strongly recommended. LWP may be
7522 required for non-UNIX systems or if your nearest CPAN site is
7523 associated with a URL that is not C<ftp:>.
7525 If you have neither Net::FTP nor LWP, there is a fallback mechanism
7526 implemented for an external ftp command or for an external lynx
7529 =head2 Finding packages and VERSION
7531 This module presumes that all packages on CPAN
7537 declare their $VERSION variable in an easy to parse manner. This
7538 prerequisite can hardly be relaxed because it consumes far too much
7539 memory to load all packages into the running program just to determine
7540 the $VERSION variable. Currently all programs that are dealing with
7541 version use something like this
7543 perl -MExtUtils::MakeMaker -le \
7544 'print MM->parse_version(shift)' filename
7546 If you are author of a package and wonder if your $VERSION can be
7547 parsed, please try the above method.
7551 come as compressed or gzipped tarfiles or as zip files and contain a
7552 C<Makefile.PL> or C<Build.PL> (well, we try to handle a bit more, but
7553 without much enthusiasm).
7559 The debugging of this module is a bit complex, because we have
7560 interferences of the software producing the indices on CPAN, of the
7561 mirroring process on CPAN, of packaging, of configuration, of
7562 synchronicity, and of bugs within CPAN.pm.
7564 For code debugging in interactive mode you can try "o debug" which
7565 will list options for debugging the various parts of the code. You
7566 should know that "o debug" has built-in completion support.
7568 For data debugging there is the C<dump> command which takes the same
7569 arguments as make/test/install and outputs the object's Data::Dumper
7572 =head2 Floppy, Zip, Offline Mode
7574 CPAN.pm works nicely without network too. If you maintain machines
7575 that are not networked at all, you should consider working with file:
7576 URLs. Of course, you have to collect your modules somewhere first. So
7577 you might use CPAN.pm to put together all you need on a networked
7578 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
7579 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
7580 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
7581 with this floppy. See also below the paragraph about CD-ROM support.
7583 =head1 CONFIGURATION
7585 When the CPAN module is used for the first time, a configuration
7586 dialog tries to determine a couple of site specific options. The
7587 result of the dialog is stored in a hash reference C< $CPAN::Config >
7588 in a file CPAN/Config.pm.
7590 The default values defined in the CPAN/Config.pm file can be
7591 overridden in a user specific file: CPAN/MyConfig.pm. Such a file is
7592 best placed in $HOME/.cpan/CPAN/MyConfig.pm, because $HOME/.cpan is
7593 added to the search path of the CPAN module before the use() or
7594 require() statements.
7596 The configuration dialog can be started any time later again by
7597 issuing the command C< o conf init > in the CPAN shell.
7599 Currently the following keys in the hash reference $CPAN::Config are
7602 build_cache size of cache for directories to build modules
7603 build_dir locally accessible directory to build modules
7604 cache_metadata use serializer to cache metadata
7605 cpan_home local directory reserved for this package
7606 dontload_list arrayref: modules in the list will not be
7607 loaded by the CPAN::has_inst() routine
7609 gzip location of external program gzip
7610 histfile file to maintain history between sessions
7611 histsize maximum number of lines to keep in histfile
7612 inactivity_timeout breaks interactive Makefile.PLs or Build.PLs
7613 after this many seconds inactivity. Set to 0 to
7615 index_expire after this many days refetch index files
7616 inhibit_startup_message
7617 if true, does not print the startup message
7618 keep_source_where directory in which to keep the source (if we do)
7619 make location of external make program
7620 make_arg arguments that should always be passed to 'make'
7621 make_install_make_command
7622 the make command for running 'make install', for
7624 make_install_arg same as make_arg for 'make install'
7625 makepl_arg arguments passed to 'perl Makefile.PL'
7626 mbuild_arg arguments passed to './Build'
7627 mbuild_install_arg arguments passed to './Build install'
7628 mbuild_install_build_command
7629 command to use instead of './Build' when we are
7630 in the install stage, for example 'sudo ./Build'
7631 mbuildpl_arg arguments passed to 'perl Build.PL'
7632 pager location of external program more (or any pager)
7633 prefer_installer legal values are MB and EUMM: if a module comes
7634 with both a Makefile.PL and a Build.PL, use the
7635 former (EUMM) or the latter (MB); if the module
7636 comes with only one of the two, that one will be
7638 prerequisites_policy
7639 what to do if you are missing module prerequisites
7640 ('follow' automatically, 'ask' me, or 'ignore')
7641 proxy_user username for accessing an authenticating proxy
7642 proxy_pass password for accessing an authenticating proxy
7643 scan_cache controls scanning of cache ('atstart' or 'never')
7644 tar location of external program tar
7645 term_is_latin if true internal UTF-8 is translated to ISO-8859-1
7646 (and nonsense for characters outside latin range)
7647 unzip location of external program unzip
7648 urllist arrayref to nearby CPAN sites (or equivalent locations)
7649 wait_list arrayref to a wait server to try (See CPAN::WAIT)
7650 ftp_passive if set, the envariable FTP_PASSIVE is set for downloads
7651 ftp_proxy, } the three usual variables for configuring
7652 http_proxy, } proxy requests. Both as CPAN::Config variables
7653 no_proxy } and as environment variables configurable.
7655 You can set and query each of these options interactively in the cpan
7656 shell with the command set defined within the C<o conf> command:
7660 =item C<o conf E<lt>scalar optionE<gt>>
7662 prints the current value of the I<scalar option>
7664 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
7666 Sets the value of the I<scalar option> to I<value>
7668 =item C<o conf E<lt>list optionE<gt>>
7670 prints the current value of the I<list option> in MakeMaker's
7673 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
7675 shifts or pops the array in the I<list option> variable
7677 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
7679 works like the corresponding perl commands.
7683 =head2 Not on config variable getcwd
7685 CPAN.pm changes the current working directory often and needs to
7686 determine its own current working directory. Per default it uses
7687 Cwd::cwd but if this doesn't work on your system for some reason,
7688 alternatives can be configured according to the following table:
7692 fastcwd Cwd::fastcwd
7693 backtickcwd external command cwd
7695 =head2 Note on urllist parameter's format
7697 urllist parameters are URLs according to RFC 1738. We do a little
7698 guessing if your URL is not compliant, but if you have problems with
7699 file URLs, please try the correct format. Either:
7701 file://localhost/whatever/ftp/pub/CPAN/
7705 file:///home/ftp/pub/CPAN/
7707 =head2 urllist parameter has CD-ROM support
7709 The C<urllist> parameter of the configuration table contains a list of
7710 URLs that are to be used for downloading. If the list contains any
7711 C<file> URLs, CPAN always tries to get files from there first. This
7712 feature is disabled for index files. So the recommendation for the
7713 owner of a CD-ROM with CPAN contents is: include your local, possibly
7714 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
7716 o conf urllist push file://localhost/CDROM/CPAN
7718 CPAN.pm will then fetch the index files from one of the CPAN sites
7719 that come at the beginning of urllist. It will later check for each
7720 module if there is a local copy of the most recent version.
7722 Another peculiarity of urllist is that the site that we could
7723 successfully fetch the last file from automatically gets a preference
7724 token and is tried as the first site for the next request. So if you
7725 add a new site at runtime it may happen that the previously preferred
7726 site will be tried another time. This means that if you want to disallow
7727 a site for the next transfer, it must be explicitly removed from
7732 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
7733 install foreign, unmasked, unsigned code on your machine. We compare
7734 to a checksum that comes from the net just as the distribution file
7735 itself. But we try to make it easy to add security on demand:
7737 =head2 Cryptographically signed modules
7739 Since release 1.77 CPAN.pm has been able to verify cryptographically
7740 signed module distributions using Module::Signature. The CPAN modules
7741 can be signed by their authors, thus giving more security. The simple
7742 unsigned MD5 checksums that were used before by CPAN protect mainly
7743 against accidental file corruption.
7745 You will need to have Module::Signature installed, which in turn
7746 requires that you have at least one of Crypt::OpenPGP module or the
7747 command-line F<gpg> tool installed.
7749 You will also need to be able to connect over the Internet to the public
7750 keyservers, like pgp.mit.edu, and their port 11731 (the HKP protocol).
7754 Most functions in package CPAN are exported per default. The reason
7755 for this is that the primary use is intended for the cpan shell or for
7760 When the CPAN shell enters a subshell via the look command, it sets
7761 the environment CPAN_SHELL_LEVEL to 1 or increments it if it is
7764 When the config variable ftp_passive is set, all downloads will be run
7765 with the environment variable FTP_PASSIVE set to this value. This is
7766 in general a good idea as it influences both Net::FTP and LWP based
7767 connections. The same effect can be achieved by starting the cpan
7768 shell with this environment variable set. For Net::FTP alone, one can
7769 also always set passive mode by running libnetcfg.
7771 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
7773 Populating a freshly installed perl with my favorite modules is pretty
7774 easy if you maintain a private bundle definition file. To get a useful
7775 blueprint of a bundle definition file, the command autobundle can be used
7776 on the CPAN shell command line. This command writes a bundle definition
7777 file for all modules that are installed for the currently running perl
7778 interpreter. It's recommended to run this command only once and from then
7779 on maintain the file manually under a private name, say
7780 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
7782 cpan> install Bundle::my_bundle
7784 then answer a few questions and then go out for a coffee.
7786 Maintaining a bundle definition file means keeping track of two
7787 things: dependencies and interactivity. CPAN.pm sometimes fails on
7788 calculating dependencies because not all modules define all MakeMaker
7789 attributes correctly, so a bundle definition file should specify
7790 prerequisites as early as possible. On the other hand, it's a bit
7791 annoying that many distributions need some interactive configuring. So
7792 what I try to accomplish in my private bundle file is to have the
7793 packages that need to be configured early in the file and the gentle
7794 ones later, so I can go out after a few minutes and leave CPAN.pm
7797 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
7799 Thanks to Graham Barr for contributing the following paragraphs about
7800 the interaction between perl, and various firewall configurations. For
7801 further information on firewalls, it is recommended to consult the
7802 documentation that comes with the ncftp program. If you are unable to
7803 go through the firewall with a simple Perl setup, it is very likely
7804 that you can configure ncftp so that it works for your firewall.
7806 =head2 Three basic types of firewalls
7808 Firewalls can be categorized into three basic types.
7814 This is where the firewall machine runs a web server and to access the
7815 outside world you must do it via the web server. If you set environment
7816 variables like http_proxy or ftp_proxy to a values beginning with http://
7817 or in your web browser you have to set proxy information then you know
7818 you are running an http firewall.
7820 To access servers outside these types of firewalls with perl (even for
7821 ftp) you will need to use LWP.
7825 This where the firewall machine runs an ftp server. This kind of
7826 firewall will only let you access ftp servers outside the firewall.
7827 This is usually done by connecting to the firewall with ftp, then
7828 entering a username like "user@outside.host.com"
7830 To access servers outside these type of firewalls with perl you
7831 will need to use Net::FTP.
7833 =item One way visibility
7835 I say one way visibility as these firewalls try to make themselves look
7836 invisible to the users inside the firewall. An FTP data connection is
7837 normally created by sending the remote server your IP address and then
7838 listening for the connection. But the remote server will not be able to
7839 connect to you because of the firewall. So for these types of firewall
7840 FTP connections need to be done in a passive mode.
7842 There are two that I can think off.
7848 If you are using a SOCKS firewall you will need to compile perl and link
7849 it with the SOCKS library, this is what is normally called a 'socksified'
7850 perl. With this executable you will be able to connect to servers outside
7851 the firewall as if it is not there.
7855 This is the firewall implemented in the Linux kernel, it allows you to
7856 hide a complete network behind one IP address. With this firewall no
7857 special compiling is needed as you can access hosts directly.
7859 For accessing ftp servers behind such firewalls you usually need to
7860 set the environment variable C<FTP_PASSIVE> or the config variable
7861 ftp_passive to a true value.
7867 =head2 Configuring lynx or ncftp for going through a firewall
7869 If you can go through your firewall with e.g. lynx, presumably with a
7872 /usr/local/bin/lynx -pscott:tiger
7874 then you would configure CPAN.pm with the command
7876 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
7878 That's all. Similarly for ncftp or ftp, you would configure something
7881 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
7883 Your mileage may vary...
7891 I installed a new version of module X but CPAN keeps saying,
7892 I have the old version installed
7894 Most probably you B<do> have the old version installed. This can
7895 happen if a module installs itself into a different directory in the
7896 @INC path than it was previously installed. This is not really a
7897 CPAN.pm problem, you would have the same problem when installing the
7898 module manually. The easiest way to prevent this behaviour is to add
7899 the argument C<UNINST=1> to the C<make install> call, and that is why
7900 many people add this argument permanently by configuring
7902 o conf make_install_arg UNINST=1
7906 So why is UNINST=1 not the default?
7908 Because there are people who have their precise expectations about who
7909 may install where in the @INC path and who uses which @INC array. In
7910 fine tuned environments C<UNINST=1> can cause damage.
7914 I want to clean up my mess, and install a new perl along with
7915 all modules I have. How do I go about it?
7917 Run the autobundle command for your old perl and optionally rename the
7918 resulting bundle file (e.g. Bundle/mybundle.pm), install the new perl
7919 with the Configure option prefix, e.g.
7921 ./Configure -Dprefix=/usr/local/perl-5.6.78.9
7923 Install the bundle file you produced in the first step with something like
7925 cpan> install Bundle::mybundle
7931 When I install bundles or multiple modules with one command
7932 there is too much output to keep track of.
7934 You may want to configure something like
7936 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
7937 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
7939 so that STDOUT is captured in a file for later inspection.
7944 I am not root, how can I install a module in a personal directory?
7946 First of all, you will want to use your own configuration, not the one
7947 that your root user installed. If you do not have permission to write
7948 in the cpan directory that root has configured, you will be asked if
7949 you want to create your own config. Answering "yes" will bring you into
7950 CPAN's configuration stage, using the system config for all defaults except
7951 things that have to do with CPAN's work directory, saving your choices to
7952 your MyConfig.pm file.
7954 You can also manually initiate this process with the following command:
7956 % perl -MCPAN -e 'mkmyconfig'
7962 from the CPAN shell.
7964 You will most probably also want to configure something like this:
7966 o conf makepl_arg "LIB=~/myperl/lib \
7967 INSTALLMAN1DIR=~/myperl/man/man1 \
7968 INSTALLMAN3DIR=~/myperl/man/man3"
7970 You can make this setting permanent like all C<o conf> settings with
7973 You will have to add ~/myperl/man to the MANPATH environment variable
7974 and also tell your perl programs to look into ~/myperl/lib, e.g. by
7977 use lib "$ENV{HOME}/myperl/lib";
7979 or setting the PERL5LIB environment variable.
7981 Another thing you should bear in mind is that the UNINST parameter can
7982 be dnagerous when you are installing into a private area because you
7983 might accidentally remove modules that other people depend on that are
7984 not using the private area.
7988 How to get a package, unwrap it, and make a change before building it?
7990 look Sybase::Sybperl
7994 I installed a Bundle and had a couple of fails. When I
7995 retried, everything resolved nicely. Can this be fixed to work
7998 The reason for this is that CPAN does not know the dependencies of all
7999 modules when it starts out. To decide about the additional items to
8000 install, it just uses data found in the META.yml file or the generated
8001 Makefile. An undetected missing piece breaks the process. But it may
8002 well be that your Bundle installs some prerequisite later than some
8003 depending item and thus your second try is able to resolve everything.
8004 Please note, CPAN.pm does not know the dependency tree in advance and
8005 cannot sort the queue of things to install in a topologically correct
8006 order. It resolves perfectly well IF all modules declare the
8007 prerequisites correctly with the PREREQ_PM attribute to MakeMaker or
8008 the C<requires> stanza of Module::Build. For bundles which fail and
8009 you need to install often, it is recommended to sort the Bundle
8010 definition file manually.
8014 In our intranet we have many modules for internal use. How
8015 can I integrate these modules with CPAN.pm but without uploading
8016 the modules to CPAN?
8018 Have a look at the CPAN::Site module.
8022 When I run CPAN's shell, I get an error message about things in my
8023 /etc/inputrc (or ~/.inputrc) file.
8025 These are readline issues and can only be fixed by studying readline
8026 configuration on your architecture and adjusting the referenced file
8027 accordingly. Please make a backup of the /etc/inputrc or ~/.inputrc
8028 and edit them. Quite often harmless changes like uppercasing or
8029 lowercasing some arguments solves the problem.
8033 Some authors have strange characters in their names.
8035 Internally CPAN.pm uses the UTF-8 charset. If your terminal is
8036 expecting ISO-8859-1 charset, a converter can be activated by setting
8037 term_is_latin to a true value in your config file. One way of doing so
8040 cpan> o conf term_is_latin 1
8042 If other charset support is needed, please file a bugreport against
8043 CPAN.pm at rt.cpan.org and describe your needs. Maybe we can extend
8044 the support or maybe UTF-8 terminals become widely available.
8048 When an install fails for some reason and then I correct the error
8049 condition and retry, CPAN.pm refuses to install the module, saying
8050 C<Already tried without success>.
8052 Use the force pragma like so
8054 force install Foo::Bar
8056 This does a bit more than really needed because it untars the
8057 distribution again and runs make and test and only then install.
8059 Or, if you find this is too fast and you would prefer to do smaller
8064 first and then continue as always. C<Force get> I<forgets> previous
8071 and then 'make install' directly in the subshell.
8073 Or you leave the CPAN shell and start it again.
8075 For the really curious, by accessing internals directly, you I<could>
8077 !delete CPAN::Shell->expandany("Foo::Bar")->distribution->{install}
8079 but this is neither guaranteed to work in the future nor is it a
8084 How do I install a "DEVELOPER RELEASE" of a module?
8086 By default, CPAN will install the latest non-developer release of a module.
8087 If you want to install a dev release, you have to specify a partial path to
8088 the tarball you wish to install, like so:
8090 cpan> install KWILLIAMS/Module-Build-0.27_07.tar.gz
8094 How do I install a module and all its dependencies from the commandline,
8095 without being prompted for anything, despite my CPAN configuration
8098 CPAN uses ExtUtils::MakeMaker's prompt() function to ask its questions, so
8099 if you set the PERL_MM_USE_DEFAULT environment variable, you shouldn't be
8100 asked any questions at all (assuming the modules you are installing are
8101 nice about obeying that variable as well):
8103 % PERL_MM_USE_DEFAULT=1 perl -MCPAN -e 'install My::Module'
8107 I only know the usual options for ExtUtils::MakeMaker(Module::Build),
8108 how do I find out the corresponding options in
8109 Module::Build(ExtUtils::MakeMaker)?
8111 http://search.cpan.org/search?query=Module::Build::Convert
8113 http://accognoscere.org/papers/perl-module-build-convert/module-build-convert.html
8120 Please report bugs via http://rt.cpan.org/
8122 Before submitting a bug, please make sure that the traditional method
8123 of building a Perl module package from a shell by following the
8124 installation instructions of that package still works in your
8129 Andreas Koenig C<< <andk@cpan.org> >>
8133 Kawai,Takanori provides a Japanese translation of this manpage at
8134 http://member.nifty.ne.jp/hippo2000/perltips/CPAN.htm
8138 cpan(1), CPAN::Nox(3pm), CPAN::Version(3pm)