1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
4 # $Id: CPAN.pm,v 1.385 2001/02/09 21:37:57 k Exp $
6 # only used during development:
8 # $Revision = "[".substr(q$Revision: 1.385 $, 10)."]";
15 use ExtUtils::MakeMaker (); # $SelfLoader::DEBUG=1;
16 use File::Basename ();
22 use Text::ParseWords ();
25 no lib "."; # we need to run chdir all over and we would get at wrong
28 require Mac::BuildTools if $^O eq 'MacOS';
30 END { $End++; &cleanup; }
53 $CPAN::Frontend ||= "CPAN::Shell";
54 $CPAN::Defaultsite ||= "ftp://ftp.perl.org/pub/CPAN";
59 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $HAS_USABLE $term
60 $Revision $Signal $End $Suppress_readline $Frontend
61 $Defaultsite $Have_warned);
63 @CPAN::ISA = qw(CPAN::Debug Exporter);
66 autobundle bundle expand force get cvs_import
67 install make readme recompile shell test clean
70 #-> sub CPAN::AUTOLOAD ;
75 @EXPORT{@EXPORT} = '';
76 CPAN::Config->load unless $CPAN::Config_loaded++;
77 if (exists $EXPORT{$l}){
80 $CPAN::Frontend->mywarn(qq{Unknown command "$AUTOLOAD". }.
89 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
90 CPAN::Config->load unless $CPAN::Config_loaded++;
92 my $oprompt = shift || "cpan> ";
93 my $prompt = $oprompt;
94 my $commandline = shift || "";
97 unless ($Suppress_readline) {
98 require Term::ReadLine;
101 $term->ReadLine eq "Term::ReadLine::Stub"
103 $term = Term::ReadLine->new('CPAN Monitor');
105 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
106 my $attribs = $term->Attribs;
107 $attribs->{attempted_completion_function} = sub {
108 &CPAN::Complete::gnu_cpl;
111 $readline::rl_completion_function =
112 $readline::rl_completion_function = 'CPAN::Complete::cpl';
114 # $term->OUT is autoflushed anyway
115 my $odef = select STDERR;
122 # no strict; # I do not recall why no strict was here (2000-09-03)
124 my $cwd = CPAN::anycwd();
125 my $try_detect_readline;
126 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
127 my $rl_avail = $Suppress_readline ? "suppressed" :
128 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
129 "available (try 'install Bundle::CPAN')";
131 $CPAN::Frontend->myprint(
133 cpan shell -- CPAN exploration and modules installation (v%s%s)
141 unless $CPAN::Config->{'inhibit_startup_message'} ;
142 my($continuation) = "";
143 SHELLCOMMAND: while () {
144 if ($Suppress_readline) {
146 last SHELLCOMMAND unless defined ($_ = <> );
149 last SHELLCOMMAND unless
150 defined ($_ = $term->readline($prompt, $commandline));
152 $_ = "$continuation$_" if $continuation;
154 next SHELLCOMMAND if /^$/;
155 $_ = 'h' if /^\s*\?/;
156 if (/^(?:q(?:uit)?|bye|exit)$/i) {
166 use vars qw($import_done);
167 CPAN->import(':DEFAULT') unless $import_done++;
168 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
175 if ($] < 5.00322) { # parsewords had a bug until recently
178 eval { @line = Text::ParseWords::shellwords($_) };
179 warn($@), next SHELLCOMMAND if $@;
180 warn("Text::Parsewords could not parse the line [$_]"),
181 next SHELLCOMMAND unless @line;
183 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
184 my $command = shift @line;
185 eval { CPAN::Shell->$command(@line) };
187 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
188 $CPAN::Frontend->myprint("\n");
193 $commandline = ""; # I do want to be able to pass a default to
194 # shell, but on the second command I see no
197 CPAN::Queue->nullify_queue;
198 if ($try_detect_readline) {
199 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
201 $CPAN::META->has_inst("Term::ReadLine::Perl")
203 delete $INC{"Term/ReadLine.pm"};
205 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
206 require Term::ReadLine;
207 $CPAN::Frontend->myprint("\n$redef subroutines in ".
208 "Term::ReadLine redefined\n");
214 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
217 package CPAN::CacheMgr;
218 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
221 package CPAN::Config;
222 use vars qw(%can $dot_cpan);
225 'commit' => "Commit changes to disk",
226 'defaults' => "Reload defaults from disk",
227 'init' => "Interactive setting of all options",
231 use vars qw($Ua $Thesite $Themethod);
232 @CPAN::FTP::ISA = qw(CPAN::Debug);
234 package CPAN::LWP::UserAgent;
235 use vars qw(@ISA $USER $PASSWD $SETUPDONE);
236 # we delay requiring LWP::UserAgent and setting up inheritence until we need it
238 package CPAN::Complete;
239 @CPAN::Complete::ISA = qw(CPAN::Debug);
240 @CPAN::Complete::COMMANDS = sort qw(
241 ! a b d h i m o q r u autobundle clean dump
242 make test install force readme reload look
244 ) unless @CPAN::Complete::COMMANDS;
247 use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03);
248 @CPAN::Index::ISA = qw(CPAN::Debug);
251 # use constant PROTOCOL => "2.0"; # outcommented to avoid warning on upgrade from 1.57
254 package CPAN::InfoObj;
255 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
257 package CPAN::Author;
258 @CPAN::Author::ISA = qw(CPAN::InfoObj);
260 package CPAN::Distribution;
261 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
263 package CPAN::Bundle;
264 @CPAN::Bundle::ISA = qw(CPAN::Module);
266 package CPAN::Module;
267 @CPAN::Module::ISA = qw(CPAN::InfoObj);
270 use vars qw($AUTOLOAD @ISA $COLOR_REGISTERED $ADVANCED_QUERY $PRINT_ORNAMENTING);
271 @CPAN::Shell::ISA = qw(CPAN::Debug);
272 $COLOR_REGISTERED ||= 0;
273 $PRINT_ORNAMENTING ||= 0;
275 #-> sub CPAN::Shell::AUTOLOAD ;
277 my($autoload) = $AUTOLOAD;
278 my $class = shift(@_);
279 # warn "autoload[$autoload] class[$class]";
280 $autoload =~ s/.*:://;
281 if ($autoload =~ /^w/) {
282 if ($CPAN::META->has_inst('CPAN::WAIT')) {
283 CPAN::WAIT->$autoload(@_);
285 $CPAN::Frontend->mywarn(qq{
286 Commands starting with "w" require CPAN::WAIT to be installed.
287 Please consider installing CPAN::WAIT to use the fulltext index.
288 For this you just need to type
293 $CPAN::Frontend->mywarn(qq{Unknown command '$autoload'. }.
299 package CPAN::Tarzip;
300 use vars qw($AUTOLOAD @ISA $BUGHUNTING);
301 @CPAN::Tarzip::ISA = qw(CPAN::Debug);
302 $BUGHUNTING = 0; # released code must have turned off
306 # One use of the queue is to determine if we should or shouldn't
307 # announce the availability of a new CPAN module
309 # Now we try to use it for dependency tracking. For that to happen
310 # we need to draw a dependency tree and do the leaves first. This can
311 # easily be reached by running CPAN.pm recursively, but we don't want
312 # to waste memory and run into deep recursion. So what we can do is
315 # CPAN::Queue is the package where the queue is maintained. Dependencies
316 # often have high priority and must be brought to the head of the queue,
317 # possibly by jumping the queue if they are already there. My first code
318 # attempt tried to be extremely correct. Whenever a module needed
319 # immediate treatment, I either unshifted it to the front of the queue,
320 # or, if it was already in the queue, I spliced and let it bypass the
321 # others. This became a too correct model that made it impossible to put
322 # an item more than once into the queue. Why would you need that? Well,
323 # you need temporary duplicates as the manager of the queue is a loop
326 # (1) looks at the first item in the queue without shifting it off
328 # (2) cares for the item
330 # (3) removes the item from the queue, *even if its agenda failed and
331 # even if the item isn't the first in the queue anymore* (that way
332 # protecting against never ending queues)
334 # So if an item has prerequisites, the installation fails now, but we
335 # want to retry later. That's easy if we have it twice in the queue.
337 # I also expect insane dependency situations where an item gets more
338 # than two lives in the queue. Simplest example is triggered by 'install
339 # Foo Foo Foo'. People make this kind of mistakes and I don't want to
340 # get in the way. I wanted the queue manager to be a dumb servant, not
341 # one that knows everything.
343 # Who would I tell in this model that the user wants to be asked before
344 # processing? I can't attach that information to the module object,
345 # because not modules are installed but distributions. So I'd have to
346 # tell the distribution object that it should ask the user before
347 # processing. Where would the question be triggered then? Most probably
348 # in CPAN::Distribution::rematein.
349 # Hope that makes sense, my head is a bit off:-) -- AK
356 my $self = bless { qmod => $s }, $class;
361 # CPAN::Queue::first ;
367 # CPAN::Queue::delete_first ;
369 my($class,$what) = @_;
371 for my $i (0..$#All) {
372 if ( $All[$i]->{qmod} eq $what ) {
379 # CPAN::Queue::jumpqueue ;
383 CPAN->debug(sprintf("before jumpqueue All[%s] what[%s]",
384 join(",",map {$_->{qmod}} @All),
387 WHAT: for my $what (reverse @what) {
389 for (my $i=0; $i<$#All;$i++) { #prevent deep recursion
390 CPAN->debug("i[$All[$i]]what[$what]") if $CPAN::DEBUG;
391 if ($All[$i]->{qmod} eq $what){
393 if ($jumped > 100) { # one's OK if e.g. just
394 # processing now; more are OK if
395 # user typed it several times
396 $CPAN::Frontend->mywarn(
397 qq{Object [$what] queued more than 100 times, ignoring}
403 my $obj = bless { qmod => $what }, $class;
406 CPAN->debug(sprintf("after jumpqueue All[%s] what[%s]",
407 join(",",map {$_->{qmod}} @All),
412 # CPAN::Queue::exists ;
414 my($self,$what) = @_;
415 my @all = map { $_->{qmod} } @All;
416 my $exists = grep { $_->{qmod} eq $what } @All;
417 # warn "in exists what[$what] all[@all] exists[$exists]";
421 # CPAN::Queue::delete ;
424 @All = grep { $_->{qmod} ne $mod } @All;
427 # CPAN::Queue::nullify_queue ;
436 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
438 # from here on only subs.
439 ################################################################################
441 #-> sub CPAN::all_objects ;
443 my($mgr,$class) = @_;
444 CPAN::Config->load unless $CPAN::Config_loaded++;
445 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
447 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
449 *all = \&all_objects;
451 # Called by shell, not in batch mode. In batch mode I see no risk in
452 # having many processes updating something as installations are
453 # continually checked at runtime. In shell mode I suspect it is
454 # unintentional to open more than one shell at a time
456 #-> sub CPAN::checklock ;
459 my $lockfile = File::Spec->catfile($CPAN::Config->{cpan_home},".lock");
460 if (-f $lockfile && -M _ > 0) {
461 my $fh = FileHandle->new($lockfile) or
462 $CPAN::Frontend->mydie("Could not open $lockfile: $!");
465 if (defined $other && $other) {
467 return if $$==$other; # should never happen
468 $CPAN::Frontend->mywarn(
470 There seems to be running another CPAN process ($other). Contacting...
472 if (kill 0, $other) {
473 $CPAN::Frontend->mydie(qq{Other job is running.
474 You may want to kill it and delete the lockfile, maybe. On UNIX try:
478 } elsif (-w $lockfile) {
480 ExtUtils::MakeMaker::prompt
481 (qq{Other job not responding. Shall I overwrite }.
482 qq{the lockfile? (Y/N)},"y");
483 $CPAN::Frontend->myexit("Ok, bye\n")
484 unless $ans =~ /^y/i;
487 qq{Lockfile $lockfile not writeable by you. }.
488 qq{Cannot proceed.\n}.
491 qq{ and then rerun us.\n}
495 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile $lockfile ".
496 "reports other process with ID ".
497 "$other. Cannot proceed.\n"));
500 my $dotcpan = $CPAN::Config->{cpan_home};
501 eval { File::Path::mkpath($dotcpan);};
503 # A special case at least for Jarkko.
508 $symlinkcpan = readlink $dotcpan;
509 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
510 eval { File::Path::mkpath($symlinkcpan); };
514 $CPAN::Frontend->mywarn(qq{
515 Working directory $symlinkcpan created.
519 unless (-d $dotcpan) {
521 Your configuration suggests "$dotcpan" as your
522 CPAN.pm working directory. I could not create this directory due
523 to this error: $firsterror\n};
525 As "$dotcpan" is a symlink to "$symlinkcpan",
526 I tried to create that, but I failed with this error: $seconderror
529 Please make sure the directory exists and is writable.
531 $CPAN::Frontend->mydie($diemess);
535 unless ($fh = FileHandle->new(">$lockfile")) {
536 if ($! =~ /Permission/) {
537 my $incc = $INC{'CPAN/Config.pm'};
538 my $myincc = File::Spec->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
539 $CPAN::Frontend->myprint(qq{
541 Your configuration suggests that CPAN.pm should use a working
543 $CPAN::Config->{cpan_home}
544 Unfortunately we could not create the lock file
546 due to permission problems.
548 Please make sure that the configuration variable
549 \$CPAN::Config->{cpan_home}
550 points to a directory where you can write a .lock file. You can set
551 this variable in either
558 $CPAN::Frontend->mydie("Could not open >$lockfile: $!");
560 $fh->print($$, "\n");
561 $self->{LOCK} = $lockfile;
565 $CPAN::Frontend->mydie("Got SIGTERM, leaving");
570 $CPAN::Frontend->mydie("Got another SIGINT") if $Signal;
571 print "Caught SIGINT\n";
575 # From: Larry Wall <larry@wall.org>
576 # Subject: Re: deprecating SIGDIE
577 # To: perl5-porters@perl.org
578 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
580 # The original intent of __DIE__ was only to allow you to substitute one
581 # kind of death for another on an application-wide basis without respect
582 # to whether you were in an eval or not. As a global backstop, it should
583 # not be used any more lightly (or any more heavily :-) than class
584 # UNIVERSAL. Any attempt to build a general exception model on it should
585 # be politely squashed. Any bug that causes every eval {} to have to be
586 # modified should be not so politely squashed.
588 # Those are my current opinions. It is also my optinion that polite
589 # arguments degenerate to personal arguments far too frequently, and that
590 # when they do, it's because both people wanted it to, or at least didn't
591 # sufficiently want it not to.
595 # global backstop to cleanup if we should really die
596 $SIG{__DIE__} = \&cleanup;
597 $self->debug("Signal handler set.") if $CPAN::DEBUG;
600 #-> sub CPAN::DESTROY ;
602 &cleanup; # need an eval?
605 #-> sub CPAN::anycwd ;
608 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
613 sub cwd {Cwd::cwd();}
615 #-> sub CPAN::getcwd ;
616 sub getcwd {Cwd::getcwd();}
618 #-> sub CPAN::exists ;
620 my($mgr,$class,$id) = @_;
621 CPAN::Config->load unless $CPAN::Config_loaded++;
623 ### Carp::croak "exists called without class argument" unless $class;
625 exists $META->{readonly}{$class}{$id} or
626 exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
629 #-> sub CPAN::delete ;
631 my($mgr,$class,$id) = @_;
632 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
633 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
636 #-> sub CPAN::has_usable
637 # has_inst is sometimes too optimistic, we should replace it with this
638 # has_usable whenever a case is given
640 my($self,$mod,$message) = @_;
641 return 1 if $HAS_USABLE->{$mod};
642 my $has_inst = $self->has_inst($mod,$message);
643 return unless $has_inst;
646 LWP => [ # we frequently had "Can't locate object
647 # method "new" via package "LWP::UserAgent" at
648 # (eval 69) line 2006
650 sub {require LWP::UserAgent},
651 sub {require HTTP::Request},
652 sub {require URI::URL},
655 sub {require Net::FTP},
656 sub {require Net::Config},
659 if ($usable->{$mod}) {
660 for my $c (0..$#{$usable->{$mod}}) {
661 my $code = $usable->{$mod}[$c];
662 my $ret = eval { &$code() };
664 warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
669 return $HAS_USABLE->{$mod} = 1;
672 #-> sub CPAN::has_inst
674 my($self,$mod,$message) = @_;
675 Carp::croak("CPAN->has_inst() called without an argument")
677 if (defined $message && $message eq "no"
679 exists $CPAN::META->{dontload_hash}{$mod} # unsafe meta access, ok
681 exists $CPAN::Config->{dontload_hash}{$mod}
683 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
689 $file =~ s|/|\\|g if $^O eq 'MSWin32';
692 # checking %INC is wrong, because $INC{LWP} may be true
693 # although $INC{"URI/URL.pm"} may have failed. But as
694 # I really want to say "bla loaded OK", I have to somehow
696 ### warn "$file in %INC"; #debug
698 } elsif (eval { require $file }) {
699 # eval is good: if we haven't yet read the database it's
700 # perfect and if we have installed the module in the meantime,
701 # it tries again. The second require is only a NOOP returning
702 # 1 if we had success, otherwise it's retrying
704 $CPAN::Frontend->myprint("CPAN: $mod loaded ok\n");
705 if ($mod eq "CPAN::WAIT") {
706 push @CPAN::Shell::ISA, CPAN::WAIT;
709 } elsif ($mod eq "Net::FTP") {
710 $CPAN::Frontend->mywarn(qq{
711 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
713 install Bundle::libnet
715 }) unless $Have_warned->{"Net::FTP"}++;
717 } elsif ($mod eq "Digest::MD5"){
718 $CPAN::Frontend->myprint(qq{
719 CPAN: MD5 security checks disabled because Digest::MD5 not installed.
720 Please consider installing the Digest::MD5 module.
725 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
730 #-> sub CPAN::instance ;
732 my($mgr,$class,$id) = @_;
735 # unsafe meta access, ok?
736 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
737 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
745 #-> sub CPAN::cleanup ;
747 # warn "cleanup called with arg[@_] End[$End] Signal[$Signal]";
748 local $SIG{__DIE__} = '';
753 0 && # disabled, try reload cpan with it
754 $] > 5.004_60 # thereabouts
759 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
761 $subroutine eq '(eval)';
764 return if $ineval && !$End;
765 return unless defined $META->{LOCK}; # unsafe meta access, ok
766 return unless -f $META->{LOCK}; # unsafe meta access, ok
767 unlink $META->{LOCK}; # unsafe meta access, ok
769 # Carp::cluck("DEBUGGING");
770 $CPAN::Frontend->mywarn("Lockfile removed.\n");
773 package CPAN::CacheMgr;
775 #-> sub CPAN::CacheMgr::as_string ;
777 eval { require Data::Dumper };
779 return shift->SUPER::as_string;
781 return Data::Dumper::Dumper(shift);
785 #-> sub CPAN::CacheMgr::cachesize ;
790 #-> sub CPAN::CacheMgr::tidyup ;
793 return unless -d $self->{ID};
794 while ($self->{DU} > $self->{'MAX'} ) {
795 my($toremove) = shift @{$self->{FIFO}};
796 $CPAN::Frontend->myprint(sprintf(
797 "Deleting from cache".
798 ": $toremove (%.1f>%.1f MB)\n",
799 $self->{DU}, $self->{'MAX'})
801 return if $CPAN::Signal;
802 $self->force_clean_cache($toremove);
803 return if $CPAN::Signal;
807 #-> sub CPAN::CacheMgr::dir ;
812 #-> sub CPAN::CacheMgr::entries ;
815 return unless defined $dir;
816 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
817 $dir ||= $self->{ID};
818 my($cwd) = CPAN::anycwd();
819 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
820 my $dh = DirHandle->new(File::Spec->curdir)
821 or Carp::croak("Couldn't opendir $dir: $!");
824 next if $_ eq "." || $_ eq "..";
826 push @entries, File::Spec->catfile($dir,$_);
828 push @entries, File::Spec->catdir($dir,$_);
830 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
833 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
834 sort { -M $b <=> -M $a} @entries;
837 #-> sub CPAN::CacheMgr::disk_usage ;
840 return if exists $self->{SIZE}{$dir};
841 return if $CPAN::Signal;
845 $File::Find::prune++ if $CPAN::Signal;
847 if ($^O eq 'MacOS') {
849 my $cat = Mac::Files::FSpGetCatInfo($_);
850 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
857 return if $CPAN::Signal;
858 $self->{SIZE}{$dir} = $Du/1024/1024;
859 push @{$self->{FIFO}}, $dir;
860 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
861 $self->{DU} += $Du/1024/1024;
865 #-> sub CPAN::CacheMgr::force_clean_cache ;
866 sub force_clean_cache {
868 return unless -e $dir;
869 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
871 File::Path::rmtree($dir);
872 $self->{DU} -= $self->{SIZE}{$dir};
873 delete $self->{SIZE}{$dir};
876 #-> sub CPAN::CacheMgr::new ;
883 ID => $CPAN::Config->{'build_dir'},
884 MAX => $CPAN::Config->{'build_cache'},
885 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
888 File::Path::mkpath($self->{ID});
889 my $dh = DirHandle->new($self->{ID});
893 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
895 CPAN->debug($debug) if $CPAN::DEBUG;
899 #-> sub CPAN::CacheMgr::scan_cache ;
902 return if $self->{SCAN} eq 'never';
903 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
904 unless $self->{SCAN} eq 'atstart';
905 $CPAN::Frontend->myprint(
906 sprintf("Scanning cache %s for sizes\n",
909 for $e ($self->entries($self->{ID})) {
910 next if $e eq ".." || $e eq ".";
911 $self->disk_usage($e);
912 return if $CPAN::Signal;
919 #-> sub CPAN::Debug::debug ;
922 my($caller,$func,$line,@rest) = caller(1); # caller(0) eg
923 # Complete, caller(1)
925 ($caller) = caller(0);
927 $arg = "" unless defined $arg;
928 my $rest = join "|", map { defined $_ ? $_ : "UNDEF" } @rest;
929 if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
930 if ($arg and ref $arg) {
931 eval { require Data::Dumper };
933 $CPAN::Frontend->myprint($arg->as_string);
935 $CPAN::Frontend->myprint(Data::Dumper::Dumper($arg));
938 $CPAN::Frontend->myprint("Debug($caller:$func,$line,[$rest]): $arg\n");
943 package CPAN::Config;
945 #-> sub CPAN::Config::edit ;
946 # returns true on successful action
948 my($self,@args) = @_;
950 CPAN->debug("self[$self]args[".join(" | ",@args)."]");
951 my($o,$str,$func,$args,$key_exists);
957 CPAN->debug("o[$o]") if $CPAN::DEBUG;
961 CPAN->debug("func[$func]") if $CPAN::DEBUG;
963 # Let's avoid eval, it's easier to comprehend without.
964 if ($func eq "push") {
965 push @{$CPAN::Config->{$o}}, @args;
967 } elsif ($func eq "pop") {
968 pop @{$CPAN::Config->{$o}};
970 } elsif ($func eq "shift") {
971 shift @{$CPAN::Config->{$o}};
973 } elsif ($func eq "unshift") {
974 unshift @{$CPAN::Config->{$o}}, @args;
976 } elsif ($func eq "splice") {
977 splice @{$CPAN::Config->{$o}}, @args;
980 $CPAN::Config->{$o} = [@args];
983 $self->prettyprint($o);
985 if ($o eq "urllist" && $changed) {
986 # reset the cached values
987 undef $CPAN::FTP::Thesite;
988 undef $CPAN::FTP::Themethod;
992 $CPAN::Config->{$o} = $args[0] if defined $args[0];
993 $self->prettyprint($o);
1000 my $v = $CPAN::Config->{$k};
1002 my(@report) = ref $v eq "ARRAY" ?
1004 map { sprintf(" %-18s => %s\n",
1006 defined $v->{$_} ? $v->{$_} : "UNDEFINED"
1008 $CPAN::Frontend->myprint(
1015 map {"\t$_\n"} @report
1018 } elsif (defined $v) {
1019 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1021 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, "UNDEFINED");
1025 #-> sub CPAN::Config::commit ;
1027 my($self,$configpm) = @_;
1028 unless (defined $configpm){
1029 $configpm ||= $INC{"CPAN/MyConfig.pm"};
1030 $configpm ||= $INC{"CPAN/Config.pm"};
1031 $configpm || Carp::confess(q{
1032 CPAN::Config::commit called without an argument.
1033 Please specify a filename where to save the configuration or try
1034 "o conf init" to have an interactive course through configing.
1039 $mode = (stat $configpm)[2];
1040 if ($mode && ! -w _) {
1041 Carp::confess("$configpm is not writable");
1046 $msg = <<EOF unless $configpm =~ /MyConfig/;
1048 # This is CPAN.pm's systemwide configuration file. This file provides
1049 # defaults for users, and the values can be changed in a per-user
1050 # configuration file. The user-config file is being looked for as
1051 # ~/.cpan/CPAN/MyConfig.pm.
1055 my($fh) = FileHandle->new;
1056 rename $configpm, "$configpm~" if -f $configpm;
1057 open $fh, ">$configpm" or
1058 $CPAN::Frontend->mydie("Couldn't open >$configpm: $!");
1059 $fh->print(qq[$msg\$CPAN::Config = \{\n]);
1060 foreach (sort keys %$CPAN::Config) {
1063 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}),
1068 $fh->print("};\n1;\n__END__\n");
1071 #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
1072 #chmod $mode, $configpm;
1073 ###why was that so? $self->defaults;
1074 $CPAN::Frontend->myprint("commit: wrote $configpm\n");
1078 *default = \&defaults;
1079 #-> sub CPAN::Config::defaults ;
1089 undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
1098 #-> sub CPAN::Config::load ;
1103 eval {require CPAN::Config;}; # We eval because of some
1104 # MakeMaker problems
1105 unless ($dot_cpan++){
1106 unshift @INC, File::Spec->catdir($ENV{HOME},".cpan");
1107 eval {require CPAN::MyConfig;}; # where you can override
1108 # system wide settings
1111 return unless @miss = $self->missing_config_data;
1113 require CPAN::FirstTime;
1114 my($configpm,$fh,$redo,$theycalled);
1116 $theycalled++ if @miss==1 && $miss[0] eq 'inhibit_startup_message';
1117 if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
1118 $configpm = $INC{"CPAN/Config.pm"};
1120 } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
1121 $configpm = $INC{"CPAN/MyConfig.pm"};
1124 my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
1125 my($configpmdir) = File::Spec->catdir($path_to_cpan,"CPAN");
1126 my($configpmtest) = File::Spec->catfile($configpmdir,"Config.pm");
1127 if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
1128 if (-w $configpmtest) {
1129 $configpm = $configpmtest;
1130 } elsif (-w $configpmdir) {
1131 #_#_# following code dumped core on me with 5.003_11, a.k.
1132 unlink "$configpmtest.bak" if -f "$configpmtest.bak";
1133 rename $configpmtest, "$configpmtest.bak" if -f $configpmtest;
1134 my $fh = FileHandle->new;
1135 if ($fh->open(">$configpmtest")) {
1137 $configpm = $configpmtest;
1139 # Should never happen
1140 Carp::confess("Cannot open >$configpmtest");
1144 unless ($configpm) {
1145 $configpmdir = File::Spec->catdir($ENV{HOME},".cpan","CPAN");
1146 File::Path::mkpath($configpmdir);
1147 $configpmtest = File::Spec->catfile($configpmdir,"MyConfig.pm");
1148 if (-w $configpmtest) {
1149 $configpm = $configpmtest;
1150 } elsif (-w $configpmdir) {
1151 #_#_# following code dumped core on me with 5.003_11, a.k.
1152 my $fh = FileHandle->new;
1153 if ($fh->open(">$configpmtest")) {
1155 $configpm = $configpmtest;
1157 # Should never happen
1158 Carp::confess("Cannot open >$configpmtest");
1161 Carp::confess(qq{WARNING: CPAN.pm is unable to }.
1162 qq{create a configuration file.});
1167 $CPAN::Frontend->myprint(<<END) if $redo && ! $theycalled;
1168 We have to reconfigure CPAN.pm due to following uninitialized parameters:
1172 $CPAN::Frontend->myprint(qq{
1173 $configpm initialized.
1176 CPAN::FirstTime::init($configpm);
1179 #-> sub CPAN::Config::missing_config_data ;
1180 sub missing_config_data {
1183 "cpan_home", "keep_source_where", "build_dir", "build_cache",
1184 "scan_cache", "index_expire", "gzip", "tar", "unzip", "make",
1186 "makepl_arg", "make_arg", "make_install_arg", "urllist",
1187 "inhibit_startup_message", "ftp_proxy", "http_proxy", "no_proxy",
1188 "prerequisites_policy",
1191 push @miss, $_ unless defined $CPAN::Config->{$_};
1196 #-> sub CPAN::Config::unload ;
1198 delete $INC{'CPAN/MyConfig.pm'};
1199 delete $INC{'CPAN/Config.pm'};
1202 #-> sub CPAN::Config::help ;
1204 $CPAN::Frontend->myprint(q[
1206 defaults reload default config values from disk
1207 commit commit session changes to disk
1208 init go through a dialog to set all parameters
1210 You may edit key values in the follow fashion (the "o" is a literal
1213 o conf build_cache 15
1215 o conf build_dir "/foo/bar"
1217 o conf urllist shift
1219 o conf urllist unshift ftp://ftp.foo.bar/
1222 undef; #don't reprint CPAN::Config
1225 #-> sub CPAN::Config::cpl ;
1227 my($word,$line,$pos) = @_;
1229 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1230 my(@words) = split " ", substr($line,0,$pos+1);
1235 $words[2] =~ /list$/ && @words == 3
1237 $words[2] =~ /list$/ && @words == 4 && length($word)
1240 return grep /^\Q$word\E/, qw(splice shift unshift pop push);
1241 } elsif (@words >= 4) {
1244 my(@o_conf) = (keys %CPAN::Config::can, keys %$CPAN::Config);
1245 return grep /^\Q$word\E/, @o_conf;
1248 package CPAN::Shell;
1250 #-> sub CPAN::Shell::h ;
1252 my($class,$about) = @_;
1253 if (defined $about) {
1254 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
1256 $CPAN::Frontend->myprint(q{
1258 command argument description
1259 a,b,d,m WORD or /REGEXP/ about authors, bundles, distributions, modules
1260 i WORD or /REGEXP/ about anything of above
1261 r NONE reinstall recommendations
1262 ls AUTHOR about files in the author's directory
1264 Download, Test, Make, Install...
1266 make make (implies get)
1267 test MODULES, make test (implies make)
1268 install DISTS, BUNDLES make install (implies test)
1270 look open subshell in these dists' directories
1271 readme display these dists' README files
1274 h,? display this menu ! perl-code eval a perl command
1275 o conf [opt] set and query options q quit the cpan shell
1276 reload cpan load CPAN.pm again reload index load newer indices
1277 autobundle Snapshot force cmd unconditionally do cmd});
1283 #-> sub CPAN::Shell::a ;
1285 my($self,@arg) = @_;
1286 # authors are always UPPERCASE
1288 $_ = uc $_ unless /=/;
1290 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1293 #-> sub CPAN::Shell::ls ;
1295 my($self,@arg) = @_;
1298 unless (/^[A-Z\-]+$/i) {
1299 $CPAN::Frontend->mywarn("ls command rejects argument $_: not an author");
1302 push @accept, uc $_;
1304 for my $a (@accept){
1305 my $author = $self->expand('Author',$a) or die "No author found for $a";
1310 #-> sub CPAN::Shell::local_bundles ;
1312 my($self,@which) = @_;
1313 my($incdir,$bdir,$dh);
1314 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1315 my @bbase = "Bundle";
1316 while (my $bbase = shift @bbase) {
1317 $bdir = File::Spec->catdir($incdir,split /::/, $bbase);
1318 CPAN->debug("bdir[$bdir]\@bbase[@bbase]") if $CPAN::DEBUG;
1319 if ($dh = DirHandle->new($bdir)) { # may fail
1321 for $entry ($dh->read) {
1322 next if $entry =~ /^\./;
1323 if (-d File::Spec->catdir($bdir,$entry)){
1324 push @bbase, "$bbase\::$entry";
1326 next unless $entry =~ s/\.pm(?!\n)\Z//;
1327 $CPAN::META->instance('CPAN::Bundle',"$bbase\::$entry");
1335 #-> sub CPAN::Shell::b ;
1337 my($self,@which) = @_;
1338 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1339 $self->local_bundles;
1340 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1343 #-> sub CPAN::Shell::d ;
1344 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1346 #-> sub CPAN::Shell::m ;
1347 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
1348 $CPAN::Frontend->myprint(shift->format_result('Module',@_));
1351 #-> sub CPAN::Shell::i ;
1356 @type = qw/Author Bundle Distribution Module/;
1357 @args = '/./' unless @args;
1360 push @result, $self->expand($type,@args);
1362 my $result = @result == 1 ?
1363 $result[0]->as_string :
1365 "No objects found of any type for argument @args\n" :
1367 (map {$_->as_glimpse} @result),
1368 scalar @result, " items found\n",
1370 $CPAN::Frontend->myprint($result);
1373 #-> sub CPAN::Shell::o ;
1375 # CPAN::Shell::o and CPAN::Config::edit are closely related. 'o conf'
1376 # should have been called set and 'o debug' maybe 'set debug'
1378 my($self,$o_type,@o_what) = @_;
1380 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1381 if ($o_type eq 'conf') {
1382 shift @o_what if @o_what && $o_what[0] eq 'help';
1383 if (!@o_what) { # print all things, "o conf"
1385 $CPAN::Frontend->myprint("CPAN::Config options");
1386 if (exists $INC{'CPAN/Config.pm'}) {
1387 $CPAN::Frontend->myprint(" from $INC{'CPAN/Config.pm'}");
1389 if (exists $INC{'CPAN/MyConfig.pm'}) {
1390 $CPAN::Frontend->myprint(" and $INC{'CPAN/MyConfig.pm'}");
1392 $CPAN::Frontend->myprint(":\n");
1393 for $k (sort keys %CPAN::Config::can) {
1394 $v = $CPAN::Config::can{$k};
1395 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1397 $CPAN::Frontend->myprint("\n");
1398 for $k (sort keys %$CPAN::Config) {
1399 CPAN::Config->prettyprint($k);
1401 $CPAN::Frontend->myprint("\n");
1402 } elsif (!CPAN::Config->edit(@o_what)) {
1403 $CPAN::Frontend->myprint(qq{Type 'o conf' to view configuration }.
1404 qq{edit options\n\n});
1406 } elsif ($o_type eq 'debug') {
1408 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1411 my($what) = shift @o_what;
1412 if ($what =~ s/^-// && exists $CPAN::DEBUG{$what}) {
1413 $CPAN::DEBUG &= $CPAN::DEBUG ^ $CPAN::DEBUG{$what};
1416 if ( exists $CPAN::DEBUG{$what} ) {
1417 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1418 } elsif ($what =~ /^\d/) {
1419 $CPAN::DEBUG = $what;
1420 } elsif (lc $what eq 'all') {
1422 for (values %CPAN::DEBUG) {
1425 $CPAN::DEBUG = $max;
1428 for (keys %CPAN::DEBUG) {
1429 next unless lc($_) eq lc($what);
1430 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1433 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1438 my $raw = "Valid options for debug are ".
1439 join(", ",sort(keys %CPAN::DEBUG), 'all').
1440 qq{ or a number. Completion works on the options. }.
1441 qq{Case is ignored.};
1443 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
1444 $CPAN::Frontend->myprint("\n\n");
1447 $CPAN::Frontend->myprint("Options set for debugging:\n");
1449 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1450 $v = $CPAN::DEBUG{$k};
1451 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
1452 if $v & $CPAN::DEBUG;
1455 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1458 $CPAN::Frontend->myprint(qq{
1460 conf set or get configuration variables
1461 debug set or get debugging options
1466 sub paintdots_onreload {
1469 if ( $_[0] =~ /[Ss]ubroutine (\w+) redefined/ ) {
1473 # $CPAN::Frontend->myprint(".($subr)");
1474 $CPAN::Frontend->myprint(".");
1481 #-> sub CPAN::Shell::reload ;
1483 my($self,$command,@arg) = @_;
1485 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1486 if ($command =~ /cpan/i) {
1487 CPAN->debug("reloading the whole CPAN.pm") if $CPAN::DEBUG;
1488 my $fh = FileHandle->new($INC{'CPAN.pm'});
1491 local($SIG{__WARN__}) = paintdots_onreload(\$redef);
1494 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1495 } elsif ($command =~ /index/) {
1496 CPAN::Index->force_reload;
1498 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN.pm file
1499 index re-reads the index files\n});
1503 #-> sub CPAN::Shell::_binary_extensions ;
1504 sub _binary_extensions {
1505 my($self) = shift @_;
1506 my(@result,$module,%seen,%need,$headerdone);
1507 for $module ($self->expand('Module','/./')) {
1508 my $file = $module->cpan_file;
1509 next if $file eq "N/A";
1510 next if $file =~ /^Contact Author/;
1511 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
1512 next if $dist->isa_perl;
1513 next unless $module->xs_file;
1515 $CPAN::Frontend->myprint(".");
1516 push @result, $module;
1518 # print join " | ", @result;
1519 $CPAN::Frontend->myprint("\n");
1523 #-> sub CPAN::Shell::recompile ;
1525 my($self) = shift @_;
1526 my($module,@module,$cpan_file,%dist);
1527 @module = $self->_binary_extensions();
1528 for $module (@module){ # we force now and compile later, so we
1530 $cpan_file = $module->cpan_file;
1531 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1533 $dist{$cpan_file}++;
1535 for $cpan_file (sort keys %dist) {
1536 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1537 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1539 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1540 # stop a package from recompiling,
1541 # e.g. IO-1.12 when we have perl5.003_10
1545 #-> sub CPAN::Shell::_u_r_common ;
1547 my($self) = shift @_;
1548 my($what) = shift @_;
1549 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1550 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
1551 $what && $what =~ /^[aru]$/;
1553 @args = '/./' unless @args;
1554 my(@result,$module,%seen,%need,$headerdone,
1555 $version_undefs,$version_zeroes);
1556 $version_undefs = $version_zeroes = 0;
1557 my $sprintf = "%s%-25s%s %9s %9s %s\n";
1558 my @expand = $self->expand('Module',@args);
1559 my $expand = scalar @expand;
1560 if (0) { # Looks like noise to me, was very useful for debugging
1561 # for metadata cache
1562 $CPAN::Frontend->myprint(sprintf "%d matches in the database\n", $expand);
1564 for $module (@expand) {
1565 my $file = $module->cpan_file;
1566 next unless defined $file; # ??
1567 my($latest) = $module->cpan_version;
1568 my($inst_file) = $module->inst_file;
1570 return if $CPAN::Signal;
1573 $have = $module->inst_version;
1574 } elsif ($what eq "r") {
1575 $have = $module->inst_version;
1577 if ($have eq "undef"){
1579 } elsif ($have == 0){
1582 next unless CPAN::Version->vgt($latest, $have);
1583 # to be pedantic we should probably say:
1584 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1585 # to catch the case where CPAN has a version 0 and we have a version undef
1586 } elsif ($what eq "u") {
1592 } elsif ($what eq "r") {
1594 } elsif ($what eq "u") {
1598 return if $CPAN::Signal; # this is sometimes lengthy
1601 push @result, sprintf "%s %s\n", $module->id, $have;
1602 } elsif ($what eq "r") {
1603 push @result, $module->id;
1604 next if $seen{$file}++;
1605 } elsif ($what eq "u") {
1606 push @result, $module->id;
1607 next if $seen{$file}++;
1608 next if $file =~ /^Contact/;
1610 unless ($headerdone++){
1611 $CPAN::Frontend->myprint("\n");
1612 $CPAN::Frontend->myprint(sprintf(
1615 "Package namespace",
1627 $CPAN::META->has_inst("Term::ANSIColor")
1629 $module->{RO}{description}
1631 $color_on = Term::ANSIColor::color("green");
1632 $color_off = Term::ANSIColor::color("reset");
1634 $CPAN::Frontend->myprint(sprintf $sprintf,
1641 $need{$module->id}++;
1645 $CPAN::Frontend->myprint("No modules found for @args\n");
1646 } elsif ($what eq "r") {
1647 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1651 if ($version_zeroes) {
1652 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1653 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1654 qq{a version number of 0\n});
1656 if ($version_undefs) {
1657 my $s_has = $version_undefs > 1 ? "s have" : " has";
1658 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1659 qq{parseable version number\n});
1665 #-> sub CPAN::Shell::r ;
1667 shift->_u_r_common("r",@_);
1670 #-> sub CPAN::Shell::u ;
1672 shift->_u_r_common("u",@_);
1675 #-> sub CPAN::Shell::autobundle ;
1678 CPAN::Config->load unless $CPAN::Config_loaded++;
1679 my(@bundle) = $self->_u_r_common("a",@_);
1680 my($todir) = File::Spec->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1681 File::Path::mkpath($todir);
1682 unless (-d $todir) {
1683 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
1686 my($y,$m,$d) = (localtime)[5,4,3];
1690 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1691 my($to) = File::Spec->catfile($todir,"$me.pm");
1693 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1694 $to = File::Spec->catfile($todir,"$me.pm");
1696 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1698 "package Bundle::$me;\n\n",
1699 "\$VERSION = '0.01';\n\n",
1703 "Bundle::$me - Snapshot of installation on ",
1704 $Config::Config{'myhostname'},
1707 "\n\n=head1 SYNOPSIS\n\n",
1708 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1709 "=head1 CONTENTS\n\n",
1710 join("\n", @bundle),
1711 "\n\n=head1 CONFIGURATION\n\n",
1713 "\n\n=head1 AUTHOR\n\n",
1714 "This Bundle has been generated automatically ",
1715 "by the autobundle routine in CPAN.pm.\n",
1718 $CPAN::Frontend->myprint("\nWrote bundle file
1722 #-> sub CPAN::Shell::expandany ;
1725 CPAN->debug("s[$s]") if $CPAN::DEBUG;
1726 if ($s =~ m|/|) { # looks like a file
1727 $s = CPAN::Distribution->normalize($s);
1728 return $CPAN::META->instance('CPAN::Distribution',$s);
1729 # Distributions spring into existence, not expand
1730 } elsif ($s =~ m|^Bundle::|) {
1731 $self->local_bundles; # scanning so late for bundles seems
1732 # both attractive and crumpy: always
1733 # current state but easy to forget
1735 return $self->expand('Bundle',$s);
1737 return $self->expand('Module',$s)
1738 if $CPAN::META->exists('CPAN::Module',$s);
1743 #-> sub CPAN::Shell::expand ;
1746 my($type,@args) = @_;
1748 CPAN->debug("type[$type]args[@args]") if $CPAN::DEBUG;
1750 my($regex,$command);
1751 if ($arg =~ m|^/(.*)/$|) {
1753 } elsif ($arg =~ m/=/) {
1756 my $class = "CPAN::$type";
1758 CPAN->debug(sprintf "class[%s]regex[%s]command[%s]",
1760 defined $regex ? $regex : "UNDEFINED",
1761 $command || "UNDEFINED",
1763 if (defined $regex) {
1767 $CPAN::META->all_objects($class)
1770 # BUG, we got an empty object somewhere
1771 require Data::Dumper;
1772 CPAN->debug(sprintf(
1773 "Bug in CPAN: Empty id on obj[%s][%s]",
1775 Data::Dumper::Dumper($obj)
1780 if $obj->id =~ /$regex/i
1784 $] < 5.00303 ### provide sort of
1785 ### compatibility with 5.003
1790 $obj->name =~ /$regex/i
1793 } elsif ($command) {
1794 die "equal sign in command disabled (immature interface), ".
1796 ! \$CPAN::Shell::ADVANCED_QUERY=1
1797 to enable it. But please note, this is HIGHLY EXPERIMENTAL code
1798 that may go away anytime.\n"
1799 unless $ADVANCED_QUERY;
1800 my($method,$criterion) = $arg =~ /(.+?)=(.+)/;
1801 my($matchcrit) = $criterion =~ m/^~(.+)/;
1805 $CPAN::META->all_objects($class)
1807 my $lhs = $self->$method() or next; # () for 5.00503
1809 push @m, $self if $lhs =~ m/$matchcrit/;
1811 push @m, $self if $lhs eq $criterion;
1816 if ( $type eq 'Bundle' ) {
1817 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
1818 } elsif ($type eq "Distribution") {
1819 $xarg = CPAN::Distribution->normalize($arg);
1821 if ($CPAN::META->exists($class,$xarg)) {
1822 $obj = $CPAN::META->instance($class,$xarg);
1823 } elsif ($CPAN::META->exists($class,$arg)) {
1824 $obj = $CPAN::META->instance($class,$arg);
1831 return wantarray ? @m : $m[0];
1834 #-> sub CPAN::Shell::format_result ;
1837 my($type,@args) = @_;
1838 @args = '/./' unless @args;
1839 my(@result) = $self->expand($type,@args);
1840 my $result = @result == 1 ?
1841 $result[0]->as_string :
1843 "No objects of type $type found for argument @args\n" :
1845 (map {$_->as_glimpse} @result),
1846 scalar @result, " items found\n",
1851 # The only reason for this method is currently to have a reliable
1852 # debugging utility that reveals which output is going through which
1853 # channel. No, I don't like the colors ;-)
1855 #-> sub CPAN::Shell::print_ornameted ;
1856 sub print_ornamented {
1857 my($self,$what,$ornament) = @_;
1859 return unless defined $what;
1861 if ($CPAN::Config->{term_is_latin}){
1864 =~ s{([\xC0-\xDF])([\x80-\xBF])}{chr(ord($1)<<6&0xC0|ord($2)&0x3F)}eg; #};
1866 if ($PRINT_ORNAMENTING) {
1867 unless (defined &color) {
1868 if ($CPAN::META->has_inst("Term::ANSIColor")) {
1869 import Term::ANSIColor "color";
1871 *color = sub { return "" };
1875 for $line (split /\n/, $what) {
1876 $longest = length($line) if length($line) > $longest;
1878 my $sprintf = "%-" . $longest . "s";
1880 $what =~ s/(.*\n?)//m;
1883 my($nl) = chomp $line ? "\n" : "";
1884 # print "line[$line]ornament[$ornament]sprintf[$sprintf]\n";
1885 print color($ornament), sprintf($sprintf,$line), color("reset"), $nl;
1893 my($self,$what) = @_;
1895 $self->print_ornamented($what, 'bold blue on_yellow');
1899 my($self,$what) = @_;
1900 $self->myprint($what);
1905 my($self,$what) = @_;
1906 $self->print_ornamented($what, 'bold red on_yellow');
1910 my($self,$what) = @_;
1911 $self->print_ornamented($what, 'bold red on_white');
1912 Carp::confess "died";
1916 my($self,$what) = @_;
1917 $self->print_ornamented($what, 'bold red on_white');
1922 return if -t STDOUT;
1923 my $odef = select STDERR;
1930 #-> sub CPAN::Shell::rematein ;
1931 # RE-adme||MA-ke||TE-st||IN-stall
1934 my($meth,@some) = @_;
1936 if ($meth eq 'force') {
1938 $meth = shift @some;
1941 CPAN->debug("pragma[$pragma]meth[$meth] some[@some]") if $CPAN::DEBUG;
1943 # Here is the place to set "test_count" on all involved parties to
1944 # 0. We then can pass this counter on to the involved
1945 # distributions and those can refuse to test if test_count > X. In
1946 # the first stab at it we could use a 1 for "X".
1948 # But when do I reset the distributions to start with 0 again?
1949 # Jost suggested to have a random or cycling interaction ID that
1950 # we pass through. But the ID is something that is just left lying
1951 # around in addition to the counter, so I'd prefer to set the
1952 # counter to 0 now, and repeat at the end of the loop. But what
1953 # about dependencies? They appear later and are not reset, they
1954 # enter the queue but not its copy. How do they get a sensible
1957 # construct the queue
1959 foreach $s (@some) {
1962 CPAN->debug("s is an object[$s]") if $CPAN::DEBUG;
1964 } elsif ($s =~ m|^/|) { # looks like a regexp
1965 $CPAN::Frontend->mywarn("Sorry, $meth with a regular expression is ".
1970 CPAN->debug("calling expandany [$s]") if $CPAN::DEBUG;
1971 $obj = CPAN::Shell->expandany($s);
1974 $obj->color_cmd_tmps(0,1);
1975 CPAN::Queue->new($obj->id);
1977 } elsif ($CPAN::META->exists('CPAN::Author',$s)) {
1978 $obj = $CPAN::META->instance('CPAN::Author',$s);
1979 if ($meth eq "dump") {
1982 $CPAN::Frontend->myprint(
1984 "Don't be silly, you can't $meth ",
1992 ->myprint(qq{Warning: Cannot $meth $s, }.
1993 qq{don\'t know what it is.
1998 to find objects with matching identifiers.
2004 # queuerunner (please be warned: when I started to change the
2005 # queue to hold objects instead of names, I made one or two
2006 # mistakes and never found which. I reverted back instead)
2007 while ($s = CPAN::Queue->first) {
2010 $obj = $s; # I do not believe, we would survive if this happened
2012 $obj = CPAN::Shell->expandany($s);
2016 ($] < 5.00303 || $obj->can($pragma))){
2017 ### compatibility with 5.003
2018 $obj->$pragma($meth); # the pragma "force" in
2019 # "CPAN::Distribution" must know
2020 # what we are intending
2022 if ($]>=5.00303 && $obj->can('called_for')) {
2023 $obj->called_for($s);
2026 qq{pragma[$pragma]meth[$meth]obj[$obj]as_string\[}.
2032 CPAN::Queue->delete($s);
2034 CPAN->debug("failed");
2038 CPAN::Queue->delete_first($s);
2040 for my $obj (@qcopy) {
2041 $obj->color_cmd_tmps(0,0);
2045 #-> sub CPAN::Shell::dump ;
2046 sub dump { shift->rematein('dump',@_); }
2047 #-> sub CPAN::Shell::force ;
2048 sub force { shift->rematein('force',@_); }
2049 #-> sub CPAN::Shell::get ;
2050 sub get { shift->rematein('get',@_); }
2051 #-> sub CPAN::Shell::readme ;
2052 sub readme { shift->rematein('readme',@_); }
2053 #-> sub CPAN::Shell::make ;
2054 sub make { shift->rematein('make',@_); }
2055 #-> sub CPAN::Shell::test ;
2056 sub test { shift->rematein('test',@_); }
2057 #-> sub CPAN::Shell::install ;
2058 sub install { shift->rematein('install',@_); }
2059 #-> sub CPAN::Shell::clean ;
2060 sub clean { shift->rematein('clean',@_); }
2061 #-> sub CPAN::Shell::look ;
2062 sub look { shift->rematein('look',@_); }
2063 #-> sub CPAN::Shell::cvs_import ;
2064 sub cvs_import { shift->rematein('cvs_import',@_); }
2066 package CPAN::LWP::UserAgent;
2069 return if $SETUPDONE;
2070 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2071 require LWP::UserAgent;
2072 @ISA = qw(Exporter LWP::UserAgent);
2075 $CPAN::Frontent->mywarn("LWP::UserAgent not available\n");
2079 sub get_basic_credentials {
2080 my($self, $realm, $uri, $proxy) = @_;
2081 return unless $proxy;
2082 if ($USER && $PASSWD) {
2083 } elsif (defined $CPAN::Config->{proxy_user} &&
2084 defined $CPAN::Config->{proxy_pass}) {
2085 $USER = $CPAN::Config->{proxy_user};
2086 $PASSWD = $CPAN::Config->{proxy_pass};
2088 require ExtUtils::MakeMaker;
2089 ExtUtils::MakeMaker->import(qw(prompt));
2090 $USER = prompt("Proxy authentication needed!
2091 (Note: to permanently configure username and password run
2092 o conf proxy_user your_username
2093 o conf proxy_pass your_password
2095 if ($CPAN::META->has_inst("Term::ReadKey")) {
2096 Term::ReadKey::ReadMode("noecho");
2098 $CPAN::Frontend->mywarn("Warning: Term::ReadKey seems not to be available, your password will be echoed to the terminal!\n");
2100 $PASSWD = prompt("Password:");
2101 if ($CPAN::META->has_inst("Term::ReadKey")) {
2102 Term::ReadKey::ReadMode("restore");
2104 $CPAN::Frontend->myprint("\n\n");
2106 return($USER,$PASSWD);
2110 my($self,$url,$aslocal) = @_;
2111 my $result = $self->SUPER::mirror($url,$aslocal);
2112 if ($result->code == 407) {
2115 $result = $self->SUPER::mirror($url,$aslocal);
2122 #-> sub CPAN::FTP::ftp_get ;
2124 my($class,$host,$dir,$file,$target) = @_;
2126 qq[Going to fetch file [$file] from dir [$dir]
2127 on host [$host] as local [$target]\n]
2129 my $ftp = Net::FTP->new($host);
2130 return 0 unless defined $ftp;
2131 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
2132 $class->debug(qq[Going to login("anonymous","$Config::Config{cf_email}")]);
2133 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
2134 warn "Couldn't login on $host";
2137 unless ( $ftp->cwd($dir) ){
2138 warn "Couldn't cwd $dir";
2142 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
2143 unless ( $ftp->get($file,$target) ){
2144 warn "Couldn't fetch $file from $host\n";
2147 $ftp->quit; # it's ok if this fails
2151 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
2153 # > *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
2154 # > --- /tmp/cp Wed Sep 24 13:26:40 1997
2156 # > *** 1562,1567 ****
2157 # > --- 1562,1580 ----
2158 # > return 1 if substr($url,0,4) eq "file";
2159 # > return 1 unless $url =~ m|://([^/]+)|;
2161 # > + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
2163 # > + $proxy =~ m|://([^/:]+)|;
2165 # > + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
2166 # > + if ($noproxy) {
2167 # > + if ($host !~ /$noproxy$/) {
2168 # > + $host = $proxy;
2171 # > + $host = $proxy;
2174 # > require Net::Ping;
2175 # > return 1 unless $Net::Ping::VERSION >= 2;
2179 #-> sub CPAN::FTP::localize ;
2181 my($self,$file,$aslocal,$force) = @_;
2183 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
2184 unless defined $aslocal;
2185 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
2188 if ($^O eq 'MacOS') {
2189 # Comment by AK on 2000-09-03: Uniq short filenames would be
2190 # available in CHECKSUMS file
2191 my($name, $path) = File::Basename::fileparse($aslocal, '');
2192 if (length($name) > 31) {
2203 my $size = 31 - length($suf);
2204 while (length($name) > $size) {
2208 $aslocal = File::Spec->catfile($path, $name);
2212 return $aslocal if -f $aslocal && -r _ && !($force & 1);
2215 rename $aslocal, "$aslocal.bak";
2219 my($aslocal_dir) = File::Basename::dirname($aslocal);
2220 File::Path::mkpath($aslocal_dir);
2221 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
2222 qq{directory "$aslocal_dir".
2223 I\'ll continue, but if you encounter problems, they may be due
2224 to insufficient permissions.\n}) unless -w $aslocal_dir;
2226 # Inheritance is not easier to manage than a few if/else branches
2227 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2229 CPAN::LWP::UserAgent->config;
2230 eval {$Ua = CPAN::LWP::UserAgent->new;}; # Why is has_usable still not fit enough?
2232 $CPAN::Frontent->mywarn("CPAN::LWP::UserAgent->new dies with $@")
2236 $Ua->proxy('ftp', $var)
2237 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
2238 $Ua->proxy('http', $var)
2239 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
2242 # >>>>> On Wed, 13 Dec 2000 09:21:34 -0500, "Robison, Jonathon (J.M.)" <jrobiso2@visteon.com> said:
2244 # > I note that although CPAN.pm can use proxies, it doesn't seem equipped to
2245 # > use ones that require basic autorization.
2247 # > Example of when I use it manually in my own stuff:
2249 # > $ua->proxy(['http','ftp'], http://my.proxy.server:83');
2250 # > $req->proxy_authorization_basic("username","password");
2251 # > $res = $ua->request($req);
2255 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
2259 $ENV{ftp_proxy} = $CPAN::Config->{ftp_proxy} if $CPAN::Config->{ftp_proxy};
2260 $ENV{http_proxy} = $CPAN::Config->{http_proxy}
2261 if $CPAN::Config->{http_proxy};
2262 $ENV{no_proxy} = $CPAN::Config->{no_proxy} if $CPAN::Config->{no_proxy};
2264 # Try the list of urls for each single object. We keep a record
2265 # where we did get a file from
2266 my(@reordered,$last);
2267 $CPAN::Config->{urllist} ||= [];
2268 $last = $#{$CPAN::Config->{urllist}};
2269 if ($force & 2) { # local cpans probably out of date, don't reorder
2270 @reordered = (0..$last);
2274 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
2276 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
2287 @levels = ($Themethod, grep {$_ ne $Themethod} qw/easy hard hardest/);
2289 @levels = qw/easy hard hardest/;
2291 @levels = qw/easy/ if $^O eq 'MacOS';
2293 for $levelno (0..$#levels) {
2294 my $level = $levels[$levelno];
2295 my $method = "host$level";
2296 my @host_seq = $level eq "easy" ?
2297 @reordered : 0..$last; # reordered has CDROM up front
2298 @host_seq = (0) unless @host_seq;
2299 my $ret = $self->$method(\@host_seq,$file,$aslocal);
2301 $Themethod = $level;
2303 # utime $now, $now, $aslocal; # too bad, if we do that, we
2304 # might alter a local mirror
2305 $self->debug("level[$level]") if $CPAN::DEBUG;
2309 last if $CPAN::Signal; # need to cleanup
2312 unless ($CPAN::Signal) {
2315 qq{Please check, if the URLs I found in your configuration file \(}.
2316 join(", ", @{$CPAN::Config->{urllist}}).
2317 qq{\) are valid. The urllist can be edited.},
2318 qq{E.g. with 'o conf urllist push ftp://myurl/'};
2319 $CPAN::Frontend->myprint(Text::Wrap::wrap("","",@mess). "\n\n");
2321 $CPAN::Frontend->myprint("Could not fetch $file\n");
2324 rename "$aslocal.bak", $aslocal;
2325 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
2326 $self->ls($aslocal));
2333 my($self,$host_seq,$file,$aslocal) = @_;
2335 HOSTEASY: for $i (@$host_seq) {
2336 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2337 $url .= "/" unless substr($url,-1) eq "/";
2339 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
2340 if ($url =~ /^file:/) {
2342 if ($CPAN::META->has_inst('URI::URL')) {
2343 my $u = URI::URL->new($url);
2345 } else { # works only on Unix, is poorly constructed, but
2346 # hopefully better than nothing.
2347 # RFC 1738 says fileurl BNF is
2348 # fileurl = "file://" [ host | "localhost" ] "/" fpath
2349 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
2351 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
2352 $l =~ s|^file:||; # assume they
2355 $l =~ s|^/||s unless -f $l; # e.g. /P:
2356 $self->debug("without URI::URL we try local file $l") if $CPAN::DEBUG;
2358 if ( -f $l && -r _) {
2362 # Maybe mirror has compressed it?
2364 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
2365 CPAN::Tarzip->gunzip("$l.gz", $aslocal);
2372 if ($CPAN::META->has_usable('LWP')) {
2373 $CPAN::Frontend->myprint("Fetching with LWP:
2377 CPAN::LWP::UserAgent->config;
2378 eval { $Ua = CPAN::LWP::UserAgent->new; };
2380 $CPAN::Frontent->mywarn("CPAN::LWP::UserAgent->new dies with $@");
2383 my $res = $Ua->mirror($url, $aslocal);
2384 if ($res->is_success) {
2387 utime $now, $now, $aslocal; # download time is more
2388 # important than upload time
2390 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2391 my $gzurl = "$url.gz";
2392 $CPAN::Frontend->myprint("Fetching with LWP:
2395 $res = $Ua->mirror($gzurl, "$aslocal.gz");
2396 if ($res->is_success &&
2397 CPAN::Tarzip->gunzip("$aslocal.gz",$aslocal)
2403 $CPAN::Frontend->myprint(sprintf(
2404 "LWP failed with code[%s] message[%s]\n",
2408 # Alan Burlison informed me that in firewall environments
2409 # Net::FTP can still succeed where LWP fails. So we do not
2410 # skip Net::FTP anymore when LWP is available.
2413 $CPAN::Frontend->myprint("LWP not available\n");
2415 return if $CPAN::Signal;
2416 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2417 # that's the nice and easy way thanks to Graham
2418 my($host,$dir,$getfile) = ($1,$2,$3);
2419 if ($CPAN::META->has_usable('Net::FTP')) {
2421 $CPAN::Frontend->myprint("Fetching with Net::FTP:
2424 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
2425 "aslocal[$aslocal]") if $CPAN::DEBUG;
2426 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
2430 if ($aslocal !~ /\.gz(?!\n)\Z/) {
2431 my $gz = "$aslocal.gz";
2432 $CPAN::Frontend->myprint("Fetching with Net::FTP
2435 if (CPAN::FTP->ftp_get($host,
2439 CPAN::Tarzip->gunzip($gz,$aslocal)
2448 return if $CPAN::Signal;
2453 my($self,$host_seq,$file,$aslocal) = @_;
2455 # Came back if Net::FTP couldn't establish connection (or
2456 # failed otherwise) Maybe they are behind a firewall, but they
2457 # gave us a socksified (or other) ftp program...
2460 my($devnull) = $CPAN::Config->{devnull} || "";
2462 my($aslocal_dir) = File::Basename::dirname($aslocal);
2463 File::Path::mkpath($aslocal_dir);
2464 HOSTHARD: for $i (@$host_seq) {
2465 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2466 $url .= "/" unless substr($url,-1) eq "/";
2468 my($proto,$host,$dir,$getfile);
2470 # Courtesy Mark Conty mark_conty@cargill.com change from
2471 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2473 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
2474 # proto not yet used
2475 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
2477 next HOSTHARD; # who said, we could ftp anything except ftp?
2479 next HOSTHARD if $proto eq "file"; # file URLs would have had
2480 # success above. Likely a bogus URL
2482 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
2484 for $f ('lynx','ncftpget','ncftp','wget') {
2485 next unless exists $CPAN::Config->{$f};
2486 $funkyftp = $CPAN::Config->{$f};
2487 next unless defined $funkyftp;
2488 next if $funkyftp =~ /^\s*$/;
2489 my($asl_ungz, $asl_gz);
2490 ($asl_ungz = $aslocal) =~ s/\.gz//;
2491 $asl_gz = "$asl_ungz.gz";
2492 my($src_switch) = "";
2494 $src_switch = " -source";
2495 } elsif ($f eq "ncftp"){
2496 $src_switch = " -c";
2497 } elsif ($f eq "wget"){
2498 $src_switch = " -O -";
2501 my($stdout_redir) = " > $asl_ungz";
2502 if ($f eq "ncftpget"){
2503 $chdir = "cd $aslocal_dir && ";
2506 $CPAN::Frontend->myprint(
2508 Trying with "$funkyftp$src_switch" to get
2512 "$chdir$funkyftp$src_switch '$url' $devnull$stdout_redir";
2513 $self->debug("system[$system]") if $CPAN::DEBUG;
2515 if (($wstatus = system($system)) == 0
2518 -s $asl_ungz # lynx returns 0 when it fails somewhere
2524 } elsif ($asl_ungz ne $aslocal) {
2525 # test gzip integrity
2526 if (CPAN::Tarzip->gtest($asl_ungz)) {
2527 # e.g. foo.tar is gzipped --> foo.tar.gz
2528 rename $asl_ungz, $aslocal;
2530 CPAN::Tarzip->gzip($asl_ungz,$asl_gz);
2535 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2537 -f $asl_ungz && -s _ == 0;
2538 my $gz = "$aslocal.gz";
2539 my $gzurl = "$url.gz";
2540 $CPAN::Frontend->myprint(
2542 Trying with "$funkyftp$src_switch" to get
2545 my($system) = "$funkyftp$src_switch '$url.gz' $devnull > $asl_gz";
2546 $self->debug("system[$system]") if $CPAN::DEBUG;
2548 if (($wstatus = system($system)) == 0
2552 # test gzip integrity
2553 if (CPAN::Tarzip->gtest($asl_gz)) {
2554 CPAN::Tarzip->gunzip($asl_gz,$aslocal);
2556 # somebody uncompressed file for us?
2557 rename $asl_ungz, $aslocal;
2562 unlink $asl_gz if -f $asl_gz;
2565 my $estatus = $wstatus >> 8;
2566 my $size = -f $aslocal ?
2567 ", left\n$aslocal with size ".-s _ :
2568 "\nWarning: expected file [$aslocal] doesn't exist";
2569 $CPAN::Frontend->myprint(qq{
2570 System call "$system"
2571 returned status $estatus (wstat $wstatus)$size
2574 return if $CPAN::Signal;
2575 } # lynx,ncftpget,ncftp
2580 my($self,$host_seq,$file,$aslocal) = @_;
2583 my($aslocal_dir) = File::Basename::dirname($aslocal);
2584 File::Path::mkpath($aslocal_dir);
2585 HOSTHARDEST: for $i (@$host_seq) {
2586 unless (length $CPAN::Config->{'ftp'}) {
2587 $CPAN::Frontend->myprint("No external ftp command available\n\n");
2590 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2591 $url .= "/" unless substr($url,-1) eq "/";
2593 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
2594 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2597 my($host,$dir,$getfile) = ($1,$2,$3);
2599 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
2600 $ctime,$blksize,$blocks) = stat($aslocal);
2601 $timestamp = $mtime ||= 0;
2602 my($netrc) = CPAN::FTP::netrc->new;
2603 my($netrcfile) = $netrc->netrc;
2604 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
2605 my $targetfile = File::Basename::basename($aslocal);
2611 map("cd $_", split "/", $dir), # RFC 1738
2613 "get $getfile $targetfile",
2617 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
2618 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
2619 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
2621 $netrc->contains($host))) if $CPAN::DEBUG;
2622 if ($netrc->protected) {
2623 $CPAN::Frontend->myprint(qq{
2624 Trying with external ftp to get
2626 As this requires some features that are not thoroughly tested, we\'re
2627 not sure, that we get it right....
2631 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose $host",
2633 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2634 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2636 if ($mtime > $timestamp) {
2637 $CPAN::Frontend->myprint("GOT $aslocal\n");
2641 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
2643 return if $CPAN::Signal;
2645 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
2646 qq{correctly protected.\n});
2649 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
2650 nor does it have a default entry\n");
2653 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
2654 # then and login manually to host, using e-mail as
2656 $CPAN::Frontend->myprint(qq{Issuing "$CPAN::Config->{'ftp'}$verbose -n"\n});
2660 "user anonymous $Config::Config{'cf_email'}"
2662 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose -n", @dialog);
2663 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2664 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2666 if ($mtime > $timestamp) {
2667 $CPAN::Frontend->myprint("GOT $aslocal\n");
2671 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
2673 return if $CPAN::Signal;
2674 $CPAN::Frontend->myprint("Can't access URL $url.\n\n");
2680 my($self,$command,@dialog) = @_;
2681 my $fh = FileHandle->new;
2682 $fh->open("|$command") or die "Couldn't open ftp: $!";
2683 foreach (@dialog) { $fh->print("$_\n") }
2684 $fh->close; # Wait for process to complete
2686 my $estatus = $wstatus >> 8;
2687 $CPAN::Frontend->myprint(qq{
2688 Subprocess "|$command"
2689 returned status $estatus (wstat $wstatus)
2693 # find2perl needs modularization, too, all the following is stolen
2697 my($self,$name) = @_;
2698 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
2699 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
2701 my($perms,%user,%group);
2705 $blocks = int(($blocks + 1) / 2);
2708 $blocks = int(($sizemm + 1023) / 1024);
2711 if (-f _) { $perms = '-'; }
2712 elsif (-d _) { $perms = 'd'; }
2713 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
2714 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
2715 elsif (-p _) { $perms = 'p'; }
2716 elsif (-S _) { $perms = 's'; }
2717 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
2719 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
2720 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
2721 my $tmpmode = $mode;
2722 my $tmp = $rwx[$tmpmode & 7];
2724 $tmp = $rwx[$tmpmode & 7] . $tmp;
2726 $tmp = $rwx[$tmpmode & 7] . $tmp;
2727 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
2728 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
2729 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
2732 my $user = $user{$uid} || $uid; # too lazy to implement lookup
2733 my $group = $group{$gid} || $gid;
2735 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
2737 my($moname) = $moname[$mon];
2738 if (-M _ > 365.25 / 2) {
2739 $timeyear = $year + 1900;
2742 $timeyear = sprintf("%02d:%02d", $hour, $min);
2745 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
2759 package CPAN::FTP::netrc;
2763 my $file = File::Spec->catfile($ENV{HOME},".netrc");
2765 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2766 $atime,$mtime,$ctime,$blksize,$blocks)
2771 my($fh,@machines,$hasdefault);
2773 $fh = FileHandle->new or die "Could not create a filehandle";
2775 if($fh->open($file)){
2776 $protected = ($mode & 077) == 0;
2778 NETRC: while (<$fh>) {
2779 my(@tokens) = split " ", $_;
2780 TOKEN: while (@tokens) {
2781 my($t) = shift @tokens;
2782 if ($t eq "default"){
2786 last TOKEN if $t eq "macdef";
2787 if ($t eq "machine") {
2788 push @machines, shift @tokens;
2793 $file = $hasdefault = $protected = "";
2797 'mach' => [@machines],
2799 'hasdefault' => $hasdefault,
2800 'protected' => $protected,
2804 # CPAN::FTP::hasdefault;
2805 sub hasdefault { shift->{'hasdefault'} }
2806 sub netrc { shift->{'netrc'} }
2807 sub protected { shift->{'protected'} }
2809 my($self,$mach) = @_;
2810 for ( @{$self->{'mach'}} ) {
2811 return 1 if $_ eq $mach;
2816 package CPAN::Complete;
2819 my($text, $line, $start, $end) = @_;
2820 my(@perlret) = cpl($text, $line, $start);
2821 # find longest common match. Can anybody show me how to peruse
2822 # T::R::Gnu to have this done automatically? Seems expensive.
2823 return () unless @perlret;
2824 my($newtext) = $text;
2825 for (my $i = length($text)+1;;$i++) {
2826 last unless length($perlret[0]) && length($perlret[0]) >= $i;
2827 my $try = substr($perlret[0],0,$i);
2828 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
2829 # warn "try[$try]tries[@tries]";
2830 if (@tries == @perlret) {
2836 ($newtext,@perlret);
2839 #-> sub CPAN::Complete::cpl ;
2841 my($word,$line,$pos) = @_;
2845 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2847 if ($line =~ s/^(force\s*)//) {
2852 @return = grep /^$word/, @CPAN::Complete::COMMANDS;
2853 } elsif ( $line !~ /^[\!abcdghimorutl]/ ) {
2855 } elsif ($line =~ /^(a|ls)\s/) {
2856 @return = cplx('CPAN::Author',uc($word));
2857 } elsif ($line =~ /^b\s/) {
2858 CPAN::Shell->local_bundles;
2859 @return = cplx('CPAN::Bundle',$word);
2860 } elsif ($line =~ /^d\s/) {
2861 @return = cplx('CPAN::Distribution',$word);
2862 } elsif ($line =~ m/^(
2863 [mru]|make|clean|dump|get|test|install|readme|look|cvs_import
2865 if ($word =~ /^Bundle::/) {
2866 CPAN::Shell->local_bundles;
2868 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
2869 } elsif ($line =~ /^i\s/) {
2870 @return = cpl_any($word);
2871 } elsif ($line =~ /^reload\s/) {
2872 @return = cpl_reload($word,$line,$pos);
2873 } elsif ($line =~ /^o\s/) {
2874 @return = cpl_option($word,$line,$pos);
2875 } elsif ($line =~ m/^\S+\s/ ) {
2876 # fallback for future commands and what we have forgotten above
2877 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
2884 #-> sub CPAN::Complete::cplx ;
2886 my($class, $word) = @_;
2887 # I believed for many years that this was sorted, today I
2888 # realized, it wasn't sorted anymore. Now (rev 1.301 / v 1.55) I
2889 # make it sorted again. Maybe sort was dropped when GNU-readline
2890 # support came in? The RCS file is difficult to read on that:-(
2891 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
2894 #-> sub CPAN::Complete::cpl_any ;
2898 cplx('CPAN::Author',$word),
2899 cplx('CPAN::Bundle',$word),
2900 cplx('CPAN::Distribution',$word),
2901 cplx('CPAN::Module',$word),
2905 #-> sub CPAN::Complete::cpl_reload ;
2907 my($word,$line,$pos) = @_;
2909 my(@words) = split " ", $line;
2910 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2911 my(@ok) = qw(cpan index);
2912 return @ok if @words == 1;
2913 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
2916 #-> sub CPAN::Complete::cpl_option ;
2918 my($word,$line,$pos) = @_;
2920 my(@words) = split " ", $line;
2921 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2922 my(@ok) = qw(conf debug);
2923 return @ok if @words == 1;
2924 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
2926 } elsif ($words[1] eq 'index') {
2928 } elsif ($words[1] eq 'conf') {
2929 return CPAN::Config::cpl(@_);
2930 } elsif ($words[1] eq 'debug') {
2931 return sort grep /^\Q$word\E/, sort keys %CPAN::DEBUG, 'all';
2935 package CPAN::Index;
2937 #-> sub CPAN::Index::force_reload ;
2940 $CPAN::Index::LAST_TIME = 0;
2944 #-> sub CPAN::Index::reload ;
2946 my($cl,$force) = @_;
2949 # XXX check if a newer one is available. (We currently read it
2950 # from time to time)
2951 for ($CPAN::Config->{index_expire}) {
2952 $_ = 0.001 unless $_ && $_ > 0.001;
2954 unless (1 || $CPAN::Have_warned->{readmetadatacache}++) {
2955 # debug here when CPAN doesn't seem to read the Metadata
2957 Carp::cluck("META-PROTOCOL[$CPAN::META->{PROTOCOL}]");
2959 unless ($CPAN::META->{PROTOCOL}) {
2960 $cl->read_metadata_cache;
2961 $CPAN::META->{PROTOCOL} ||= "1.0";
2963 if ( $CPAN::META->{PROTOCOL} < PROTOCOL ) {
2964 # warn "Setting last_time to 0";
2965 $LAST_TIME = 0; # No warning necessary
2967 return if $LAST_TIME + $CPAN::Config->{index_expire}*86400 > $time
2970 # IFF we are developing, it helps to wipe out the memory
2971 # between reloads, otherwise it is not what a user expects.
2972 undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
2973 $CPAN::META = CPAN->new;
2977 local $LAST_TIME = $time;
2978 local $CPAN::META->{PROTOCOL} = PROTOCOL;
2980 my $needshort = $^O eq "dos";
2982 $cl->rd_authindex($cl
2984 "authors/01mailrc.txt.gz",
2986 File::Spec->catfile('authors', '01mailrc.gz') :
2987 File::Spec->catfile('authors', '01mailrc.txt.gz'),
2990 $debug = "timing reading 01[".($t2 - $time)."]";
2992 return if $CPAN::Signal; # this is sometimes lengthy
2993 $cl->rd_modpacks($cl
2995 "modules/02packages.details.txt.gz",
2997 File::Spec->catfile('modules', '02packag.gz') :
2998 File::Spec->catfile('modules', '02packages.details.txt.gz'),
3001 $debug .= "02[".($t2 - $time)."]";
3003 return if $CPAN::Signal; # this is sometimes lengthy
3006 "modules/03modlist.data.gz",
3008 File::Spec->catfile('modules', '03mlist.gz') :
3009 File::Spec->catfile('modules', '03modlist.data.gz'),
3011 $cl->write_metadata_cache;
3013 $debug .= "03[".($t2 - $time)."]";
3015 CPAN->debug($debug) if $CPAN::DEBUG;
3018 $CPAN::META->{PROTOCOL} = PROTOCOL;
3021 #-> sub CPAN::Index::reload_x ;
3023 my($cl,$wanted,$localname,$force) = @_;
3024 $force |= 2; # means we're dealing with an index here
3025 CPAN::Config->load; # we should guarantee loading wherever we rely
3027 $localname ||= $wanted;
3028 my $abs_wanted = File::Spec->catfile($CPAN::Config->{'keep_source_where'},
3032 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
3035 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
3036 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
3037 qq{day$s. I\'ll use that.});
3040 $force |= 1; # means we're quite serious about it.
3042 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
3045 #-> sub CPAN::Index::rd_authindex ;
3047 my($cl, $index_target) = @_;
3049 return unless defined $index_target;
3050 $CPAN::Frontend->myprint("Going to read $index_target\n");
3052 tie *FH, CPAN::Tarzip, $index_target;
3054 push @lines, split /\012/ while <FH>;
3056 my($userid,$fullname,$email) =
3057 m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
3058 next unless $userid && $fullname && $email;
3060 # instantiate an author object
3061 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
3062 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
3063 return if $CPAN::Signal;
3068 my($self,$dist) = @_;
3069 $dist = $self->{'id'} unless defined $dist;
3070 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
3074 #-> sub CPAN::Index::rd_modpacks ;
3076 my($self, $index_target) = @_;
3078 return unless defined $index_target;
3079 $CPAN::Frontend->myprint("Going to read $index_target\n");
3080 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3082 while ($_ = $fh->READLINE) {
3084 my @ls = map {"$_\n"} split /\n/, $_;
3085 unshift @ls, "\n" x length($1) if /^(\n+)/;
3089 my($line_count,$last_updated);
3091 my $shift = shift(@lines);
3092 last if $shift =~ /^\s*$/;
3093 $shift =~ /^Line-Count:\s+(\d+)/ and $line_count = $1;
3094 $shift =~ /^Last-Updated:\s+(.+)/ and $last_updated = $1;
3096 if (not defined $line_count) {
3098 warn qq{Warning: Your $index_target does not contain a Line-Count header.
3099 Please check the validity of the index file by comparing it to more
3100 than one CPAN mirror. I'll continue but problems seem likely to
3105 } elsif ($line_count != scalar @lines) {
3107 warn sprintf qq{Warning: Your %s
3108 contains a Line-Count header of %d but I see %d lines there. Please
3109 check the validity of the index file by comparing it to more than one
3110 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
3111 $index_target, $line_count, scalar(@lines);
3114 if (not defined $last_updated) {
3116 warn qq{Warning: Your $index_target does not contain a Last-Updated header.
3117 Please check the validity of the index file by comparing it to more
3118 than one CPAN mirror. I'll continue but problems seem likely to
3126 ->myprint(sprintf qq{ Database was generated on %s\n},
3128 $DATE_OF_02 = $last_updated;
3130 if ($CPAN::META->has_inst(HTTP::Date)) {
3132 my($age) = (time - HTTP::Date::str2time($last_updated))/3600/24;
3137 qq{Warning: This index file is %d days old.
3138 Please check the host you chose as your CPAN mirror for staleness.
3139 I'll continue but problems seem likely to happen.\a\n},
3144 $CPAN::Frontend->myprint(" HTTP::Date not available\n");
3149 # A necessity since we have metadata_cache: delete what isn't
3151 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
3152 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
3156 # before 1.56 we split into 3 and discarded the rest. From
3157 # 1.57 we assign remaining text to $comment thus allowing to
3158 # influence isa_perl
3159 my($mod,$version,$dist,$comment) = split " ", $_, 4;
3160 my($bundle,$id,$userid);
3162 if ($mod eq 'CPAN' &&
3164 CPAN::Queue->exists('Bundle::CPAN') ||
3165 CPAN::Queue->exists('CPAN')
3169 if ($version > $CPAN::VERSION){
3170 $CPAN::Frontend->myprint(qq{
3171 There's a new CPAN.pm version (v$version) available!
3172 [Current version is v$CPAN::VERSION]
3173 You might want to try
3174 install Bundle::CPAN
3176 without quitting the current session. It should be a seamless upgrade
3177 while we are running...
3180 $CPAN::Frontend->myprint(qq{\n});
3182 last if $CPAN::Signal;
3183 } elsif ($mod =~ /^Bundle::(.*)/) {
3188 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
3189 # Let's make it a module too, because bundles have so much
3190 # in common with modules.
3192 # Changed in 1.57_63: seems like memory bloat now without
3193 # any value, so commented out
3195 # $CPAN::META->instance('CPAN::Module',$mod);
3199 # instantiate a module object
3200 $id = $CPAN::META->instance('CPAN::Module',$mod);
3204 if ($id->cpan_file ne $dist){ # update only if file is
3205 # different. CPAN prohibits same
3206 # name with different version
3207 $userid = $self->userid($dist);
3209 'CPAN_USERID' => $userid,
3210 'CPAN_VERSION' => $version,
3211 'CPAN_FILE' => $dist,
3215 # instantiate a distribution object
3216 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
3217 # we do not need CONTAINSMODS unless we do something with
3218 # this dist, so we better produce it on demand.
3220 ## my $obj = $CPAN::META->instance(
3221 ## 'CPAN::Distribution' => $dist
3223 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
3225 $CPAN::META->instance(
3226 'CPAN::Distribution' => $dist
3228 'CPAN_USERID' => $userid,
3229 'CPAN_COMMENT' => $comment,
3233 for my $name ($mod,$dist) {
3234 CPAN->debug("exists name[$name]") if $CPAN::DEBUG;
3235 $exists{$name} = undef;
3238 return if $CPAN::Signal;
3242 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
3243 for my $o ($CPAN::META->all_objects($class)) {
3244 next if exists $exists{$o->{ID}};
3245 $CPAN::META->delete($class,$o->{ID});
3246 CPAN->debug("deleting ID[$o->{ID}] in class[$class]")
3253 #-> sub CPAN::Index::rd_modlist ;
3255 my($cl,$index_target) = @_;
3256 return unless defined $index_target;
3257 $CPAN::Frontend->myprint("Going to read $index_target\n");
3258 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3261 while ($_ = $fh->READLINE) {
3263 my @ls = map {"$_\n"} split /\n/, $_;
3264 unshift @ls, "\n" x length($1) if /^(\n+)/;
3268 my $shift = shift(@eval);
3269 if ($shift =~ /^Date:\s+(.*)/){
3270 return if $DATE_OF_03 eq $1;
3273 last if $shift =~ /^\s*$/;
3276 push @eval, q{CPAN::Modulelist->data;};
3278 my($comp) = Safe->new("CPAN::Safe1");
3279 my($eval) = join("", @eval);
3280 my $ret = $comp->reval($eval);
3281 Carp::confess($@) if $@;
3282 return if $CPAN::Signal;
3284 my $obj = $CPAN::META->instance("CPAN::Module",$_);
3285 delete $ret->{$_}{modid}; # not needed here, maybe elsewhere
3286 $obj->set(%{$ret->{$_}});
3287 return if $CPAN::Signal;
3291 #-> sub CPAN::Index::write_metadata_cache ;
3292 sub write_metadata_cache {
3294 return unless $CPAN::Config->{'cache_metadata'};
3295 return unless $CPAN::META->has_usable("Storable");
3297 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
3298 CPAN::Distribution)) {
3299 $cache->{$k} = $CPAN::META->{readonly}{$k}; # unsafe meta access, ok
3301 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3302 $cache->{last_time} = $LAST_TIME;
3303 $cache->{DATE_OF_02} = $DATE_OF_02;
3304 $cache->{PROTOCOL} = PROTOCOL;
3305 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
3306 eval { Storable::nstore($cache, $metadata_file) };
3307 $CPAN::Frontend->mywarn($@) if $@;
3310 #-> sub CPAN::Index::read_metadata_cache ;
3311 sub read_metadata_cache {
3313 return unless $CPAN::Config->{'cache_metadata'};
3314 return unless $CPAN::META->has_usable("Storable");
3315 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3316 return unless -r $metadata_file and -f $metadata_file;
3317 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
3319 eval { $cache = Storable::retrieve($metadata_file) };
3320 $CPAN::Frontend->mywarn($@) if $@;
3321 if (!$cache || ref $cache ne 'HASH'){
3325 if (exists $cache->{PROTOCOL}) {
3326 if (PROTOCOL > $cache->{PROTOCOL}) {
3327 $CPAN::Frontend->mywarn(sprintf("Ignoring Metadata cache written ".
3328 "with protocol v%s, requiring v%s",
3335 $CPAN::Frontend->mywarn("Ignoring Metadata cache written ".
3336 "with protocol v1.0");
3341 while(my($class,$v) = each %$cache) {
3342 next unless $class =~ /^CPAN::/;
3343 $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok
3344 while (my($id,$ro) = each %$v) {
3345 $CPAN::META->{readwrite}{$class}{$id} ||=
3346 $class->new(ID=>$id, RO=>$ro);
3351 unless ($clcnt) { # sanity check
3352 $CPAN::Frontend->myprint("Warning: Found no data in $metadata_file\n");
3355 if ($idcnt < 1000) {
3356 $CPAN::Frontend->myprint("Warning: Found only $idcnt objects ".
3357 "in $metadata_file\n");
3360 $CPAN::META->{PROTOCOL} ||=
3361 $cache->{PROTOCOL}; # reading does not up or downgrade, but it
3362 # does initialize to some protocol
3363 $LAST_TIME = $cache->{last_time};
3364 $DATE_OF_02 = $cache->{DATE_OF_02};
3365 $CPAN::Frontend->myprint(" Database was generated on $DATE_OF_02\n")
3366 if defined $DATE_OF_02; # An old cache may not contain DATE_OF_02
3370 package CPAN::InfoObj;
3373 sub cpan_userid { shift->{RO}{CPAN_USERID} }
3374 sub id { shift->{ID}; }
3376 #-> sub CPAN::InfoObj::new ;
3378 my $this = bless {}, shift;
3383 # The set method may only be used by code that reads index data or
3384 # otherwise "objective" data from the outside world. All session
3385 # related material may do anything else with instance variables but
3386 # must not touch the hash under the RO attribute. The reason is that
3387 # the RO hash gets written to Metadata file and is thus persistent.
3389 #-> sub CPAN::InfoObj::set ;
3391 my($self,%att) = @_;
3392 my $class = ref $self;
3394 # This must be ||=, not ||, because only if we write an empty
3395 # reference, only then the set method will write into the readonly
3396 # area. But for Distributions that spring into existence, maybe
3397 # because of a typo, we do not like it that they are written into
3398 # the readonly area and made permanent (at least for a while) and
3399 # that is why we do not "allow" other places to call ->set.
3400 unless ($self->id) {
3401 CPAN->debug("Bug? Empty ID, rejecting");
3404 my $ro = $self->{RO} =
3405 $CPAN::META->{readonly}{$class}{$self->id} ||= {};
3407 while (my($k,$v) = each %att) {
3412 #-> sub CPAN::InfoObj::as_glimpse ;
3416 my $class = ref($self);
3417 $class =~ s/^CPAN:://;
3418 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
3422 #-> sub CPAN::InfoObj::as_string ;
3426 my $class = ref($self);
3427 $class =~ s/^CPAN:://;
3428 push @m, $class, " id = $self->{ID}\n";
3429 for (sort keys %{$self->{RO}}) {
3430 # next if m/^(ID|RO)$/;
3432 if ($_ eq "CPAN_USERID") {
3433 $extra .= " (".$self->author;
3434 my $email; # old perls!
3435 if ($email = $CPAN::META->instance("CPAN::Author",
3438 $extra .= " <$email>";
3440 $extra .= " <no email>";
3443 } elsif ($_ eq "FULLNAME") { # potential UTF-8 conversion
3444 push @m, sprintf " %-12s %s\n", $_, $self->fullname;
3447 next unless defined $self->{RO}{$_};
3448 push @m, sprintf " %-12s %s%s\n", $_, $self->{RO}{$_}, $extra;
3450 for (sort keys %$self) {
3451 next if m/^(ID|RO)$/;
3452 if (ref($self->{$_}) eq "ARRAY") {
3453 push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
3454 } elsif (ref($self->{$_}) eq "HASH") {
3458 join(" ",keys %{$self->{$_}}),
3461 push @m, sprintf " %-12s %s\n", $_, $self->{$_};
3467 #-> sub CPAN::InfoObj::author ;
3470 $CPAN::META->instance("CPAN::Author",$self->cpan_userid)->fullname;
3473 #-> sub CPAN::InfoObj::dump ;
3476 require Data::Dumper;
3477 print Data::Dumper::Dumper($self);
3480 package CPAN::Author;
3482 #-> sub CPAN::Author::id
3485 my $id = $self->{ID};
3486 $CPAN::Frontend->mydie("Illegal author id[$id]") unless $id =~ /^[A-Z]/;
3490 #-> sub CPAN::Author::as_glimpse ;
3494 my $class = ref($self);
3495 $class =~ s/^CPAN:://;
3496 push @m, sprintf(qq{%-15s %s ("%s" <%s>)\n},
3504 #-> sub CPAN::Author::fullname ;
3506 shift->{RO}{FULLNAME};
3510 #-> sub CPAN::Author::email ;
3511 sub email { shift->{RO}{EMAIL}; }
3513 #-> sub CPAN::Author::ls ;
3518 # adapted from CPAN::Distribution::verifyMD5 ;
3519 my(@csf); # chksumfile
3520 @csf = $self->id =~ /(.)(.)(.*)/;
3521 $csf[1] = join "", @csf[0,1];
3522 $csf[2] = join "", @csf[1,2];
3524 @dl = $self->dir_listing([$csf[0],"CHECKSUMS"], 0);
3525 unless (grep {$_->[2] eq $csf[1]} @dl) {
3526 $CPAN::Frontend->myprint("No files in the directory of $id\n");
3529 @dl = $self->dir_listing([@csf[0,1],"CHECKSUMS"], 0);
3530 unless (grep {$_->[2] eq $csf[2]} @dl) {
3531 $CPAN::Frontend->myprint("No files in the directory of $id\n");
3534 @dl = $self->dir_listing([@csf,"CHECKSUMS"], 1);
3535 $CPAN::Frontend->myprint(join "", map {
3536 sprintf("%8d %10s %s/%s\n", $_->[0], $_->[1], $id, $_->[2])
3537 } sort { $a->[2] cmp $b->[2] } @dl);
3540 # returns an array of arrays, the latter contain (size,mtime,filename)
3541 #-> sub CPAN::Author::dir_listing ;
3544 my $chksumfile = shift;
3545 my $recursive = shift;
3547 File::Spec->catfile($CPAN::Config->{keep_source_where},
3548 "authors", "id", @$chksumfile);
3550 # connect "force" argument with "index_expire".
3552 if (my @stat = stat $lc_want) {
3553 $force = $stat[9] + $CPAN::Config->{index_expire}*86400 <= time;
3555 my $lc_file = CPAN::FTP->localize("authors/id/@$chksumfile",
3558 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
3559 $chksumfile->[-1] .= ".gz";
3560 $lc_file = CPAN::FTP->localize("authors/id/@$chksumfile",
3563 $lc_file =~ s{\.gz(?!\n)\Z}{}; #};
3564 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
3570 # adapted from CPAN::Distribution::MD5_check_file ;
3571 my $fh = FileHandle->new;
3573 if (open $fh, $lc_file){
3576 $eval =~ s/\015?\012/\n/g;
3578 my($comp) = Safe->new();
3579 $cksum = $comp->reval($eval);
3581 rename $lc_file, "$lc_file.bad";
3582 Carp::confess($@) if $@;
3585 Carp::carp "Could not open $lc_file for reading";
3588 for $f (sort keys %$cksum) {
3589 if (exists $cksum->{$f}{isdir}) {
3591 my(@dir) = @$chksumfile;
3593 push @dir, $f, "CHECKSUMS";
3595 [$_->[0], $_->[1], "$f/$_->[2]"]
3596 } $self->dir_listing(\@dir,1);
3598 push @result, [ 0, "-", $f ];
3602 ($cksum->{$f}{"size"}||0),
3603 $cksum->{$f}{"mtime"}||"---",
3611 package CPAN::Distribution;
3614 sub cpan_comment { shift->{RO}{CPAN_COMMENT} }
3618 delete $self->{later};
3621 # CPAN::Distribution::normalize
3624 $s = $self->id unless defined $s;
3628 $s !~ m|[A-Z]/[A-Z-]{2}/[A-Z-]{2,}/|
3630 return $s if $s =~ m:^N/A|^Contact Author: ;
3631 $s =~ s|^(.)(.)([^/]*/)(.+)$|$1/$1$2/$1$2$3$4| or
3632 $CPAN::Frontend->mywarn("Strange distribution name [$s]");
3633 CPAN->debug("s[$s]") if $CPAN::DEBUG;
3638 #-> sub CPAN::Distribution::color_cmd_tmps ;
3639 sub color_cmd_tmps {
3641 my($depth) = shift || 0;
3642 my($color) = shift || 0;
3643 # a distribution needs to recurse into its prereq_pms
3645 return if exists $self->{incommandcolor}
3646 && $self->{incommandcolor}==$color;
3647 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
3648 "color_cmd_tmps depth[%s] self[%s] id[%s]",
3653 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
3654 my $prereq_pm = $self->prereq_pm;
3655 if (defined $prereq_pm) {
3656 for my $pre (keys %$prereq_pm) {
3657 my $premo = CPAN::Shell->expand("Module",$pre);
3658 $premo->color_cmd_tmps($depth+1,$color);
3662 delete $self->{sponsored_mods};
3663 delete $self->{badtestcnt};
3665 $self->{incommandcolor} = $color;
3668 #-> sub CPAN::Distribution::as_string ;
3671 $self->containsmods;
3672 $self->SUPER::as_string(@_);
3675 #-> sub CPAN::Distribution::containsmods ;
3678 return keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
3679 my $dist_id = $self->{ID};
3680 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
3681 my $mod_file = $mod->cpan_file or next;
3682 my $mod_id = $mod->{ID} or next;
3683 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
3685 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
3687 keys %{$self->{CONTAINSMODS}};
3690 #-> sub CPAN::Distribution::uptodate ;
3694 foreach $c ($self->containsmods) {
3695 my $obj = CPAN::Shell->expandany($c);
3696 return 0 unless $obj->uptodate;
3701 #-> sub CPAN::Distribution::called_for ;
3704 $self->{CALLED_FOR} = $id if defined $id;
3705 return $self->{CALLED_FOR};
3708 #-> sub CPAN::Distribution::safe_chdir ;
3710 my($self,$todir) = @_;
3711 # we die if we cannot chdir and we are debuggable
3712 Carp::confess("safe_chdir called without todir argument")
3713 unless defined $todir and length $todir;
3715 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
3718 my $cwd = CPAN::anycwd();
3719 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
3720 qq{to todir[$todir]: $!});
3724 #-> sub CPAN::Distribution::get ;
3729 exists $self->{'build_dir'} and push @e,
3730 "Is already unwrapped into directory $self->{'build_dir'}";
3731 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3733 my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
3736 # Get the file on local disk
3741 File::Spec->catfile(
3742 $CPAN::Config->{keep_source_where},
3745 split("/",$self->id)
3748 $self->debug("Doing localize") if $CPAN::DEBUG;
3749 unless ($local_file =
3750 CPAN::FTP->localize("authors/id/$self->{ID}",
3753 if ($CPAN::Index::DATE_OF_02) {
3754 $note = "Note: Current database in memory was generated ".
3755 "on $CPAN::Index::DATE_OF_02\n";
3757 $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n$note");
3759 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
3760 $self->{localfile} = $local_file;
3761 return if $CPAN::Signal;
3766 if ($CPAN::META->has_inst("Digest::MD5")) {
3767 $self->debug("Digest::MD5 is installed, verifying");
3770 $self->debug("Digest::MD5 is NOT installed");
3772 return if $CPAN::Signal;
3775 # Create a clean room and go there
3777 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
3778 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
3779 $self->safe_chdir($builddir);
3780 $self->debug("Removing tmp") if $CPAN::DEBUG;
3781 File::Path::rmtree("tmp");
3782 mkdir "tmp", 0755 or Carp::croak "Couldn't mkdir tmp: $!";
3784 $self->safe_chdir($sub_wd);
3787 $self->safe_chdir("tmp");
3792 if ($local_file =~ /(\.tar\.(gz|Z)|\.tgz)(?!\n)\Z/i){
3793 $self->{was_uncompressed}++ unless CPAN::Tarzip->gtest($local_file);
3794 $self->untar_me($local_file);
3795 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
3796 $self->unzip_me($local_file);
3797 } elsif ( $local_file =~ /\.pm\.(gz|Z)(?!\n)\Z/) {
3798 $self->{was_uncompressed}++ unless CPAN::Tarzip->gtest($local_file);
3799 $self->pm2dir_me($local_file);
3801 $self->{archived} = "NO";
3802 $self->safe_chdir($sub_wd);
3806 # we are still in the tmp directory!
3807 # Let's check if the package has its own directory.
3808 my $dh = DirHandle->new(File::Spec->curdir)
3809 or Carp::croak("Couldn't opendir .: $!");
3810 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
3812 my ($distdir,$packagedir);
3813 if (@readdir == 1 && -d $readdir[0]) {
3814 $distdir = $readdir[0];
3815 $packagedir = File::Spec->catdir($builddir,$distdir);
3816 $self->debug("packagedir[$packagedir]builddir[$builddir]distdir[$distdir]")
3818 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
3820 File::Path::rmtree($packagedir);
3821 rename($distdir,$packagedir) or
3822 Carp::confess("Couldn't rename $distdir to $packagedir: $!");
3823 $self->debug(sprintf("renamed distdir[%s] to packagedir[%s] -e[%s]-d[%s]",
3830 my $userid = $self->cpan_userid;
3832 CPAN->debug("no userid? self[$self]");
3835 my $pragmatic_dir = $userid . '000';
3836 $pragmatic_dir =~ s/\W_//g;
3837 $pragmatic_dir++ while -d "../$pragmatic_dir";
3838 $packagedir = File::Spec->catdir($builddir,$pragmatic_dir);
3839 $self->debug("packagedir[$packagedir]") if $CPAN::DEBUG;
3840 File::Path::mkpath($packagedir);
3842 for $f (@readdir) { # is already without "." and ".."
3843 my $to = File::Spec->catdir($packagedir,$f);
3844 rename($f,$to) or Carp::confess("Couldn't rename $f to $to: $!");
3848 $self->safe_chdir($sub_wd);
3852 $self->{'build_dir'} = $packagedir;
3853 $self->safe_chdir(File::Spec->updir);
3854 File::Path::rmtree("tmp");
3856 my($mpl) = File::Spec->catfile($packagedir,"Makefile.PL");
3857 my($mpl_exists) = -f $mpl;
3858 unless ($mpl_exists) {
3859 # NFS has been reported to have racing problems after the
3860 # renaming of a directory in some environments.
3863 my $mpldh = DirHandle->new($packagedir)
3864 or Carp::croak("Couldn't opendir $packagedir: $!");
3865 $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read;
3868 unless ($mpl_exists) {
3869 $self->debug(sprintf("makefilepl[%s]anycwd[%s]",
3873 my($configure) = File::Spec->catfile($packagedir,"Configure");
3874 if (-f $configure) {
3875 # do we have anything to do?
3876 $self->{'configure'} = $configure;
3877 } elsif (-f File::Spec->catfile($packagedir,"Makefile")) {
3878 $CPAN::Frontend->myprint(qq{
3879 Package comes with a Makefile and without a Makefile.PL.
3880 We\'ll try to build it with that Makefile then.
3882 $self->{writemakefile} = "YES";
3885 my $cf = $self->called_for || "unknown";
3890 $cf =~ s|[/\\:]||g; # risk of filesystem damage
3891 $cf = "unknown" unless length($cf);
3892 $CPAN::Frontend->myprint(qq{Package seems to come without Makefile.PL.
3893 (The test -f "$mpl" returned false.)
3894 Writing one on our own (setting NAME to $cf)\a\n});
3895 $self->{had_no_makefile_pl}++;
3898 # Writing our own Makefile.PL
3900 my $fh = FileHandle->new;
3902 or Carp::croak("Could not open >$mpl: $!");
3904 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
3905 # because there was no Makefile.PL supplied.
3906 # Autogenerated on: }.scalar localtime().qq{
3908 use ExtUtils::MakeMaker;
3909 WriteMakefile(NAME => q[$cf]);
3919 # CPAN::Distribution::untar_me ;
3921 my($self,$local_file) = @_;
3922 $self->{archived} = "tar";
3923 if (CPAN::Tarzip->untar($local_file)) {
3924 $self->{unwrapped} = "YES";
3926 $self->{unwrapped} = "NO";
3930 # CPAN::Distribution::unzip_me ;
3932 my($self,$local_file) = @_;
3933 $self->{archived} = "zip";
3934 if (CPAN::Tarzip->unzip($local_file)) {
3935 $self->{unwrapped} = "YES";
3937 $self->{unwrapped} = "NO";
3943 my($self,$local_file) = @_;
3944 $self->{archived} = "pm";
3945 my $to = File::Basename::basename($local_file);
3946 $to =~ s/\.(gz|Z)(?!\n)\Z//;
3947 if (CPAN::Tarzip->gunzip($local_file,$to)) {
3948 $self->{unwrapped} = "YES";
3950 $self->{unwrapped} = "NO";
3954 #-> sub CPAN::Distribution::new ;
3956 my($class,%att) = @_;
3958 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
3960 my $this = { %att };
3961 return bless $this, $class;
3964 #-> sub CPAN::Distribution::look ;
3968 if ($^O eq 'MacOS') {
3969 $self->Mac::BuildTools::look;
3973 if ( $CPAN::Config->{'shell'} ) {
3974 $CPAN::Frontend->myprint(qq{
3975 Trying to open a subshell in the build directory...
3978 $CPAN::Frontend->myprint(qq{
3979 Your configuration does not define a value for subshells.
3980 Please define it with "o conf shell <your shell>"
3984 my $dist = $self->id;
3986 unless ($dir = $self->dir) {
3989 unless ($dir ||= $self->dir) {
3990 $CPAN::Frontend->mywarn(qq{
3991 Could not determine which directory to use for looking at $dist.
3995 my $pwd = CPAN::anycwd();
3996 $self->safe_chdir($dir);
3997 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
3998 system($CPAN::Config->{'shell'}) == 0
3999 or $CPAN::Frontend->mydie("Subprocess shell error");
4000 $self->safe_chdir($pwd);
4003 # CPAN::Distribution::cvs_import ;
4007 my $dir = $self->dir;
4009 my $package = $self->called_for;
4010 my $module = $CPAN::META->instance('CPAN::Module', $package);
4011 my $version = $module->cpan_version;
4013 my $userid = $self->cpan_userid;
4015 my $cvs_dir = (split '/', $dir)[-1];
4016 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
4018 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
4020 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
4021 if ($cvs_site_perl) {
4022 $cvs_dir = "$cvs_site_perl/$cvs_dir";
4024 my $cvs_log = qq{"imported $package $version sources"};
4025 $version =~ s/\./_/g;
4026 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
4027 "$cvs_dir", $userid, "v$version");
4029 my $pwd = CPAN::anycwd();
4030 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
4032 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
4034 $CPAN::Frontend->myprint(qq{@cmd\n});
4035 system(@cmd) == 0 or
4036 $CPAN::Frontend->mydie("cvs import failed");
4037 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
4040 #-> sub CPAN::Distribution::readme ;
4043 my($dist) = $self->id;
4044 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
4045 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
4048 File::Spec->catfile(
4049 $CPAN::Config->{keep_source_where},
4052 split("/","$sans.readme"),
4054 $self->debug("Doing localize") if $CPAN::DEBUG;
4055 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
4057 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
4059 if ($^O eq 'MacOS') {
4060 Mac::BuildTools::launch_file($local_file);
4064 my $fh_pager = FileHandle->new;
4065 local($SIG{PIPE}) = "IGNORE";
4066 $fh_pager->open("|$CPAN::Config->{'pager'}")
4067 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
4068 my $fh_readme = FileHandle->new;
4069 $fh_readme->open($local_file)
4070 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
4071 $CPAN::Frontend->myprint(qq{
4074 with pager "$CPAN::Config->{'pager'}"
4077 $fh_pager->print(<$fh_readme>);
4080 #-> sub CPAN::Distribution::verifyMD5 ;
4085 $self->{MD5_STATUS} ||= "";
4086 $self->{MD5_STATUS} eq "OK" and push @e, "MD5 Checksum was ok";
4087 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4089 my($lc_want,$lc_file,@local,$basename);
4090 @local = split("/",$self->id);
4092 push @local, "CHECKSUMS";
4094 File::Spec->catfile($CPAN::Config->{keep_source_where},
4095 "authors", "id", @local);
4100 $self->MD5_check_file($lc_want)
4102 return $self->{MD5_STATUS} = "OK";
4104 $lc_file = CPAN::FTP->localize("authors/id/@local",
4107 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
4108 $local[-1] .= ".gz";
4109 $lc_file = CPAN::FTP->localize("authors/id/@local",
4112 $lc_file =~ s/\.gz(?!\n)\Z//;
4113 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
4118 $self->MD5_check_file($lc_file);
4121 #-> sub CPAN::Distribution::MD5_check_file ;
4122 sub MD5_check_file {
4123 my($self,$chk_file) = @_;
4124 my($cksum,$file,$basename);
4125 $file = $self->{localfile};
4126 $basename = File::Basename::basename($file);
4127 my $fh = FileHandle->new;
4128 if (open $fh, $chk_file){
4131 $eval =~ s/\015?\012/\n/g;
4133 my($comp) = Safe->new();
4134 $cksum = $comp->reval($eval);
4136 rename $chk_file, "$chk_file.bad";
4137 Carp::confess($@) if $@;
4140 Carp::carp "Could not open $chk_file for reading";
4143 if (exists $cksum->{$basename}{md5}) {
4144 $self->debug("Found checksum for $basename:" .
4145 "$cksum->{$basename}{md5}\n") if $CPAN::DEBUG;
4149 my $eq = $self->eq_MD5($fh,$cksum->{$basename}{'md5'});
4151 $fh = CPAN::Tarzip->TIEHANDLE($file);
4154 # had to inline it, when I tied it, the tiedness got lost on
4155 # the call to eq_MD5. (Jan 1998)
4156 my $md5 = Digest::MD5->new;
4159 while ($fh->READ($ref, 4096) > 0){
4162 my $hexdigest = $md5->hexdigest;
4163 $eq += $hexdigest eq $cksum->{$basename}{'md5-ungz'};
4167 $CPAN::Frontend->myprint("Checksum for $file ok\n");
4168 return $self->{MD5_STATUS} = "OK";
4170 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
4171 qq{distribution file. }.
4172 qq{Please investigate.\n\n}.
4174 $CPAN::META->instance(
4179 my $wrap = qq{I\'d recommend removing $file. Its MD5
4180 checksum is incorrect. Maybe you have configured your 'urllist' with
4181 a bad URL. Please check this array with 'o conf urllist', and
4184 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
4186 # former versions just returned here but this seems a
4187 # serious threat that deserves a die
4189 # $CPAN::Frontend->myprint("\n\n");
4193 # close $fh if fileno($fh);
4195 $self->{MD5_STATUS} ||= "";
4196 if ($self->{MD5_STATUS} eq "NIL") {
4197 $CPAN::Frontend->mywarn(qq{
4198 Warning: No md5 checksum for $basename in $chk_file.
4200 The cause for this may be that the file is very new and the checksum
4201 has not yet been calculated, but it may also be that something is
4202 going awry right now.
4204 my $answer = ExtUtils::MakeMaker::prompt("Proceed?", "yes");
4205 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.");
4207 $self->{MD5_STATUS} = "NIL";
4212 #-> sub CPAN::Distribution::eq_MD5 ;
4214 my($self,$fh,$expectMD5) = @_;
4215 my $md5 = Digest::MD5->new;
4217 while (read($fh, $data, 4096)){
4220 # $md5->addfile($fh);
4221 my $hexdigest = $md5->hexdigest;
4222 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
4223 $hexdigest eq $expectMD5;
4226 #-> sub CPAN::Distribution::force ;
4228 # Both modules and distributions know if "force" is in effect by
4229 # autoinspection, not by inspecting a global variable. One of the
4230 # reason why this was chosen to work that way was the treatment of
4231 # dependencies. They should not autpomatically inherit the force
4232 # status. But this has the downside that ^C and die() will return to
4233 # the prompt but will not be able to reset the force_update
4234 # attributes. We try to correct for it currently in the read_metadata
4235 # routine, and immediately before we check for a Signal. I hope this
4236 # works out in one of v1.57_53ff
4239 my($self, $method) = @_;
4241 MD5_STATUS archived build_dir localfile make install unwrapped
4244 delete $self->{$att};
4246 if ($method && $method eq "install") {
4247 $self->{"force_update"}++; # name should probably have been force_install
4251 #-> sub CPAN::Distribution::unforce ;
4254 delete $self->{'force_update'};
4257 #-> sub CPAN::Distribution::isa_perl ;
4260 my $file = File::Basename::basename($self->id);
4261 if ($file =~ m{ ^ perl
4274 } elsif ($self->cpan_comment
4276 $self->cpan_comment =~ /isa_perl\(.+?\)/){
4281 #-> sub CPAN::Distribution::perl ;
4284 my($perl) = File::Spec->file_name_is_absolute($^X) ? $^X : "";
4285 my $pwd = CPAN::anycwd();
4286 my $candidate = File::Spec->catfile($pwd,$^X);
4287 $perl ||= $candidate if MM->maybe_command($candidate);
4289 my ($component,$perl_name);
4290 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
4291 PATH_COMPONENT: foreach $component (File::Spec->path(),
4292 $Config::Config{'binexp'}) {
4293 next unless defined($component) && $component;
4294 my($abs) = File::Spec->catfile($component,$perl_name);
4295 if (MM->maybe_command($abs)) {
4305 #-> sub CPAN::Distribution::make ;
4308 $CPAN::Frontend->myprint(sprintf "Running make for %s\n", $self->id);
4309 # Emergency brake if they said install Pippi and get newest perl
4310 if ($self->isa_perl) {
4312 $self->called_for ne $self->id &&
4313 ! $self->{force_update}
4315 # if we die here, we break bundles
4316 $CPAN::Frontend->mywarn(sprintf qq{
4317 The most recent version "%s" of the module "%s"
4318 comes with the current version of perl (%s).
4319 I\'ll build that only if you ask for something like
4324 $CPAN::META->instance(
4338 $self->{archived} eq "NO" and push @e,
4339 "Is neither a tar nor a zip archive.";
4341 $self->{unwrapped} eq "NO" and push @e,
4342 "had problems unarchiving. Please build manually";
4344 exists $self->{writemakefile} &&
4345 $self->{writemakefile} =~ m/ ^ NO\s* ( .* ) /sx and push @e,
4346 $1 || "Had some problem writing Makefile";
4348 defined $self->{'make'} and push @e,
4349 "Has already been processed within this session";
4351 exists $self->{later} and length($self->{later}) and
4352 push @e, $self->{later};
4354 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4356 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
4357 my $builddir = $self->dir;
4358 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
4359 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
4361 if ($^O eq 'MacOS') {
4362 Mac::BuildTools::make($self);
4367 if ($self->{'configure'}) {
4368 $system = $self->{'configure'};
4370 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
4372 # This needs a handler that can be turned on or off:
4373 # $switch = "-MExtUtils::MakeMaker ".
4374 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
4376 $system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}";
4378 unless (exists $self->{writemakefile}) {
4379 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
4382 if ($CPAN::Config->{inactivity_timeout}) {
4384 alarm $CPAN::Config->{inactivity_timeout};
4385 local $SIG{CHLD}; # = sub { wait };
4386 if (defined($pid = fork)) {
4391 # note, this exec isn't necessary if
4392 # inactivity_timeout is 0. On the Mac I'd
4393 # suggest, we set it always to 0.
4397 $CPAN::Frontend->myprint("Cannot fork: $!");
4405 $CPAN::Frontend->myprint($@);
4406 $self->{writemakefile} = "NO $@";
4411 $ret = system($system);
4413 $self->{writemakefile} = "NO Makefile.PL returned status $ret";
4417 if (-f "Makefile") {
4418 $self->{writemakefile} = "YES";
4419 delete $self->{make_clean}; # if cleaned before, enable next
4421 $self->{writemakefile} =
4422 qq{NO Makefile.PL refused to write a Makefile.};
4423 # It's probably worth it to record the reason, so let's retry
4425 # my $fh = IO::File->new("$system |"); # STDERR? STDIN?
4426 # $self->{writemakefile} .= <$fh>;
4430 delete $self->{force_update};
4433 if (my @prereq = $self->unsat_prereq){
4434 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4436 $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
4437 if (system($system) == 0) {
4438 $CPAN::Frontend->myprint(" $system -- OK\n");
4439 $self->{'make'} = "YES";
4441 $self->{writemakefile} ||= "YES";
4442 $self->{'make'} = "NO";
4443 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4447 sub follow_prereqs {
4451 $CPAN::Frontend->myprint("---- Unsatisfied dependencies detected ".
4452 "during [$id] -----\n");
4454 for my $p (@prereq) {
4455 $CPAN::Frontend->myprint(" $p\n");
4458 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
4460 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
4461 require ExtUtils::MakeMaker;
4462 my $answer = ExtUtils::MakeMaker::prompt(
4463 "Shall I follow them and prepend them to the queue
4464 of modules we are processing right now?", "yes");
4465 $follow = $answer =~ /^\s*y/i;
4469 myprint(" Ignoring dependencies on modules @prereq\n");
4472 # color them as dirty
4473 for my $p (@prereq) {
4474 CPAN::Shell->expandany($p)->color_cmd_tmps(0,1);
4476 CPAN::Queue->jumpqueue(@prereq,$id); # queue them and requeue yourself
4477 $self->{later} = "Delayed until after prerequisites";
4478 return 1; # signal success to the queuerunner
4482 #-> sub CPAN::Distribution::unsat_prereq ;
4485 my $prereq_pm = $self->prereq_pm or return;
4487 NEED: while (my($need_module, $need_version) = each %$prereq_pm) {
4488 my $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
4489 # we were too demanding:
4490 next if $nmo->uptodate;
4492 # if they have not specified a version, we accept any installed one
4493 if (not defined $need_version or
4494 $need_version == 0 or
4495 $need_version eq "undef") {
4496 next if defined $nmo->inst_file;
4499 # We only want to install prereqs if either they're not installed
4500 # or if the installed version is too old. We cannot omit this
4501 # check, because if 'force' is in effect, nobody else will check.
4505 defined $nmo->inst_file &&
4506 ! CPAN::Version->vgt($need_version, $nmo->inst_version)
4508 CPAN->debug(sprintf "id[%s]inst_file[%s]inst_version[%s]need_version[%s]",
4512 CPAN::Version->readable($need_version)
4518 if ($self->{sponsored_mods}{$need_module}++){
4519 # We have already sponsored it and for some reason it's still
4520 # not available. So we do nothing. Or what should we do?
4521 # if we push it again, we have a potential infinite loop
4524 push @need, $need_module;
4529 #-> sub CPAN::Distribution::prereq_pm ;
4532 return $self->{prereq_pm} if
4533 exists $self->{prereq_pm_detected} && $self->{prereq_pm_detected};
4534 return unless $self->{writemakefile}; # no need to have succeeded
4535 # but we must have run it
4536 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
4537 my $makefile = File::Spec->catfile($build_dir,"Makefile");
4542 $fh = FileHandle->new("<$makefile\0")) {
4546 # A.Speer @p -> %p, where %p is $p{Module::Name}=Required_Version
4548 last if /MakeMaker post_initialize section/;
4550 \s+PREREQ_PM\s+=>\s+(.+)
4553 # warn "Found prereq expr[$p]";
4555 # Regexp modified by A.Speer to remember actual version of file
4556 # PREREQ_PM hash key wants, then add to
4557 while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
4558 # In case a prereq is mentioned twice, complain.
4559 if ( defined $p{$1} ) {
4560 warn "Warning: PREREQ_PM mentions $1 more than once, last mention wins";
4567 $self->{prereq_pm_detected}++;
4568 return $self->{prereq_pm} = \%p;
4571 #-> sub CPAN::Distribution::test ;
4576 delete $self->{force_update};
4579 $CPAN::Frontend->myprint("Running make test\n");
4580 if (my @prereq = $self->unsat_prereq){
4581 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4585 exists $self->{make} or exists $self->{later} or push @e,
4586 "Make had some problems, maybe interrupted? Won't test";
4588 exists $self->{'make'} and
4589 $self->{'make'} eq 'NO' and
4590 push @e, "Can't test without successful make";
4592 exists $self->{build_dir} or push @e, "Has no own directory";
4593 $self->{badtestcnt} ||= 0;
4594 $self->{badtestcnt} > 0 and
4595 push @e, "Won't repeat unsuccessful test during this command";
4597 exists $self->{later} and length($self->{later}) and
4598 push @e, $self->{later};
4600 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4602 chdir $self->{'build_dir'} or
4603 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4604 $self->debug("Changed directory to $self->{'build_dir'}")
4607 if ($^O eq 'MacOS') {
4608 Mac::BuildTools::make_test($self);
4612 my $system = join " ", $CPAN::Config->{'make'}, "test";
4613 if (system($system) == 0) {
4614 $CPAN::Frontend->myprint(" $system -- OK\n");
4615 $self->{make_test} = "YES";
4617 $self->{make_test} = "NO";
4618 $self->{badtestcnt}++;
4619 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4623 #-> sub CPAN::Distribution::clean ;
4626 $CPAN::Frontend->myprint("Running make clean\n");
4629 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
4630 push @e, "make clean already called once";
4631 exists $self->{build_dir} or push @e, "Has no own directory";
4632 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4634 chdir $self->{'build_dir'} or
4635 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4636 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
4638 if ($^O eq 'MacOS') {
4639 Mac::BuildTools::make_clean($self);
4643 my $system = join " ", $CPAN::Config->{'make'}, "clean";
4644 if (system($system) == 0) {
4645 $CPAN::Frontend->myprint(" $system -- OK\n");
4649 # Jost Krieger pointed out that this "force" was wrong because
4650 # it has the effect that the next "install" on this distribution
4651 # will untar everything again. Instead we should bring the
4652 # object's state back to where it is after untarring.
4654 delete $self->{force_update};
4655 delete $self->{install};
4656 delete $self->{writemakefile};
4657 delete $self->{make};
4658 delete $self->{make_test}; # no matter if yes or no, tests must be redone
4659 $self->{make_clean} = "YES";
4662 # Hmmm, what to do if make clean failed?
4664 $CPAN::Frontend->myprint(qq{ $system -- NOT OK
4666 make clean did not succeed, marking directory as unusable for further work.
4668 $self->force("make"); # so that this directory won't be used again
4673 #-> sub CPAN::Distribution::install ;
4678 delete $self->{force_update};
4681 $CPAN::Frontend->myprint("Running make install\n");
4684 exists $self->{build_dir} or push @e, "Has no own directory";
4686 exists $self->{make} or exists $self->{later} or push @e,
4687 "Make had some problems, maybe interrupted? Won't install";
4689 exists $self->{'make'} and
4690 $self->{'make'} eq 'NO' and
4691 push @e, "make had returned bad status, install seems impossible";
4693 push @e, "make test had returned bad status, ".
4694 "won't install without force"
4695 if exists $self->{'make_test'} and
4696 $self->{'make_test'} eq 'NO' and
4697 ! $self->{'force_update'};
4699 exists $self->{'install'} and push @e,
4700 $self->{'install'} eq "YES" ?
4701 "Already done" : "Already tried without success";
4703 exists $self->{later} and length($self->{later}) and
4704 push @e, $self->{later};
4706 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4708 chdir $self->{'build_dir'} or
4709 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4710 $self->debug("Changed directory to $self->{'build_dir'}")
4713 if ($^O eq 'MacOS') {
4714 Mac::BuildTools::make_install($self);
4718 my $system = join(" ", $CPAN::Config->{'make'},
4719 "install", $CPAN::Config->{make_install_arg});
4720 my($stderr) = $^O =~ /Win/i ? "" : " 2>&1 ";
4721 my($pipe) = FileHandle->new("$system $stderr |");
4724 $CPAN::Frontend->myprint($_);
4729 $CPAN::Frontend->myprint(" $system -- OK\n");
4730 return $self->{'install'} = "YES";
4732 $self->{'install'} = "NO";
4733 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4734 if ($makeout =~ /permission/s && $> > 0) {
4735 $CPAN::Frontend->myprint(qq{ You may have to su }.
4736 qq{to root to install the package\n});
4739 delete $self->{force_update};
4742 #-> sub CPAN::Distribution::dir ;
4744 shift->{'build_dir'};
4747 package CPAN::Bundle;
4751 delete $self->{later};
4752 for my $c ( $self->contains ) {
4753 my $obj = CPAN::Shell->expandany($c) or next;
4758 #-> sub CPAN::Bundle::color_cmd_tmps ;
4759 sub color_cmd_tmps {
4761 my($depth) = shift || 0;
4762 my($color) = shift || 0;
4763 # a module needs to recurse to its cpan_file, a distribution needs
4764 # to recurse into its prereq_pms, a bundle needs to recurse into its modules
4766 return if exists $self->{incommandcolor}
4767 && $self->{incommandcolor}==$color;
4768 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
4769 "color_cmd_tmps depth[%s] self[%s] id[%s]",
4774 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
4776 for my $c ( $self->contains ) {
4777 my $obj = CPAN::Shell->expandany($c) or next;
4778 CPAN->debug("c[$c]obj[$obj]") if $CPAN::DEBUG;
4779 $obj->color_cmd_tmps($depth+1,$color);
4782 delete $self->{badtestcnt};
4784 $self->{incommandcolor} = $color;
4787 #-> sub CPAN::Bundle::as_string ;
4791 # following line must be "=", not "||=" because we have a moving target
4792 $self->{INST_VERSION} = $self->inst_version;
4793 return $self->SUPER::as_string;
4796 #-> sub CPAN::Bundle::contains ;
4799 my($inst_file) = $self->inst_file || "";
4800 my($id) = $self->id;
4801 $self->debug("inst_file[$inst_file]id[$id]") if $CPAN::DEBUG;
4802 unless ($inst_file) {
4803 # Try to get at it in the cpan directory
4804 $self->debug("no inst_file") if $CPAN::DEBUG;
4806 $CPAN::Frontend->mydie("I don't know a bundle with ID $id\n") unless
4807 $cpan_file = $self->cpan_file;
4808 if ($cpan_file eq "N/A") {
4809 $CPAN::Frontend->mydie("Bundle $id not found on disk and not on CPAN.
4810 Maybe stale symlink? Maybe removed during session? Giving up.\n");
4812 my $dist = $CPAN::META->instance('CPAN::Distribution',
4815 $self->debug($dist->as_string) if $CPAN::DEBUG;
4816 my($todir) = $CPAN::Config->{'cpan_home'};
4817 my(@me,$from,$to,$me);
4818 @me = split /::/, $self->id;
4820 $me = File::Spec->catfile(@me);
4821 $from = $self->find_bundle_file($dist->{'build_dir'},$me);
4822 $to = File::Spec->catfile($todir,$me);
4823 File::Path::mkpath(File::Basename::dirname($to));
4824 File::Copy::copy($from, $to)
4825 or Carp::confess("Couldn't copy $from to $to: $!");
4829 my $fh = FileHandle->new;
4831 open($fh,$inst_file) or die "Could not open '$inst_file': $!";
4833 $self->debug("inst_file[$inst_file]") if $CPAN::DEBUG;
4835 $in_cont = m/^=(?!head1\s+CONTENTS)/ ? 0 :
4836 m/^=head1\s+CONTENTS/ ? 1 : $in_cont;
4837 next unless $in_cont;
4842 push @result, (split " ", $_, 2)[0];
4845 delete $self->{STATUS};
4846 $self->{CONTAINS} = \@result;
4847 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
4849 $CPAN::Frontend->mywarn(qq{
4850 The bundle file "$inst_file" may be a broken
4851 bundlefile. It seems not to contain any bundle definition.
4852 Please check the file and if it is bogus, please delete it.
4853 Sorry for the inconvenience.
4859 #-> sub CPAN::Bundle::find_bundle_file
4860 sub find_bundle_file {
4861 my($self,$where,$what) = @_;
4862 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
4863 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
4864 ### my $bu = File::Spec->catfile($where,$what);
4865 ### return $bu if -f $bu;
4866 my $manifest = File::Spec->catfile($where,"MANIFEST");
4867 unless (-f $manifest) {
4868 require ExtUtils::Manifest;
4869 my $cwd = CPAN::anycwd();
4870 chdir $where or $CPAN::Frontend->mydie(qq{Could not chdir to "$where": $!});
4871 ExtUtils::Manifest::mkmanifest();
4872 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
4874 my $fh = FileHandle->new($manifest)
4875 or Carp::croak("Couldn't open $manifest: $!");
4878 if ($^O eq 'MacOS') {
4881 $what2 =~ s/:Bundle://;
4884 $what2 =~ s|Bundle[/\\]||;
4889 my($file) = /(\S+)/;
4890 if ($file =~ m|\Q$what\E$|) {
4892 # return File::Spec->catfile($where,$bu); # bad
4895 # retry if she managed to
4896 # have no Bundle directory
4897 $bu = $file if $file =~ m|\Q$what2\E$|;
4899 $bu =~ tr|/|:| if $^O eq 'MacOS';
4900 return File::Spec->catfile($where, $bu) if $bu;
4901 Carp::croak("Couldn't find a Bundle file in $where");
4904 # needs to work quite differently from Module::inst_file because of
4905 # cpan_home/Bundle/ directory and the possibility that we have
4906 # shadowing effect. As it makes no sense to take the first in @INC for
4907 # Bundles, we parse them all for $VERSION and take the newest.
4909 #-> sub CPAN::Bundle::inst_file ;
4914 @me = split /::/, $self->id;
4917 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
4918 my $bfile = File::Spec->catfile($incdir, @me);
4919 CPAN->debug("bfile[$bfile]") if $CPAN::DEBUG;
4920 next unless -f $bfile;
4921 my $foundv = MM->parse_version($bfile);
4922 if (!$bestv || CPAN::Version->vgt($foundv,$bestv)) {
4923 $self->{INST_FILE} = $bfile;
4924 $self->{INST_VERSION} = $bestv = $foundv;
4930 #-> sub CPAN::Bundle::inst_version ;
4933 $self->inst_file; # finds INST_VERSION as side effect
4934 $self->{INST_VERSION};
4937 #-> sub CPAN::Bundle::rematein ;
4939 my($self,$meth) = @_;
4940 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
4941 my($id) = $self->id;
4942 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
4943 unless $self->inst_file || $self->cpan_file;
4945 for $s ($self->contains) {
4946 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
4947 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
4948 if ($type eq 'CPAN::Distribution') {
4949 $CPAN::Frontend->mywarn(qq{
4950 The Bundle }.$self->id.qq{ contains
4951 explicitly a file $s.
4955 # possibly noisy action:
4956 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
4957 my $obj = $CPAN::META->instance($type,$s);
4959 if ($obj->isa(CPAN::Bundle)
4961 exists $obj->{install_failed}
4963 ref($obj->{install_failed}) eq "HASH"
4965 for (keys %{$obj->{install_failed}}) {
4966 $self->{install_failed}{$_} = undef; # propagate faiure up
4969 $fail{$s} = 1; # the bundle itself may have succeeded but
4974 $success = $obj->can("uptodate") ? $obj->uptodate : 0;
4975 $success ||= $obj->{'install'} && $obj->{'install'} eq "YES";
4977 delete $self->{install_failed}{$s};
4984 # recap with less noise
4985 if ( $meth eq "install" ) {
4988 my $raw = sprintf(qq{Bundle summary:
4989 The following items in bundle %s had installation problems:},
4992 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
4993 $CPAN::Frontend->myprint("\n");
4996 for $s ($self->contains) {
4998 $paragraph .= "$s ";
4999 $self->{install_failed}{$s} = undef;
5000 $reported{$s} = undef;
5003 my $report_propagated;
5004 for $s (sort keys %{$self->{install_failed}}) {
5005 next if exists $reported{$s};
5006 $paragraph .= "and the following items had problems
5007 during recursive bundle calls: " unless $report_propagated++;
5008 $paragraph .= "$s ";
5010 $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
5011 $CPAN::Frontend->myprint("\n");
5013 $self->{'install'} = 'YES';
5018 #sub CPAN::Bundle::xs_file
5020 # If a bundle contains another that contains an xs_file we have
5021 # here, we just don't bother I suppose
5025 #-> sub CPAN::Bundle::force ;
5026 sub force { shift->rematein('force',@_); }
5027 #-> sub CPAN::Bundle::get ;
5028 sub get { shift->rematein('get',@_); }
5029 #-> sub CPAN::Bundle::make ;
5030 sub make { shift->rematein('make',@_); }
5031 #-> sub CPAN::Bundle::test ;
5034 $self->{badtestcnt} ||= 0;
5035 $self->rematein('test',@_);
5037 #-> sub CPAN::Bundle::install ;
5040 $self->rematein('install',@_);
5042 #-> sub CPAN::Bundle::clean ;
5043 sub clean { shift->rematein('clean',@_); }
5045 #-> sub CPAN::Bundle::uptodate ;
5048 return 0 unless $self->SUPER::uptodate; # we mut have the current Bundle def
5050 foreach $c ($self->contains) {
5051 my $obj = CPAN::Shell->expandany($c);
5052 return 0 unless $obj->uptodate;
5057 #-> sub CPAN::Bundle::readme ;
5060 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
5061 No File found for bundle } . $self->id . qq{\n}), return;
5062 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
5063 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
5066 package CPAN::Module;
5069 # sub cpan_userid { shift->{RO}{CPAN_USERID} }
5072 return unless exists $self->{RO}; # should never happen
5073 return $self->{RO}{CPAN_USERID} || $self->{RO}{userid};
5075 sub description { shift->{RO}{description} }
5079 delete $self->{later};
5080 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
5085 #-> sub CPAN::Module::color_cmd_tmps ;
5086 sub color_cmd_tmps {
5088 my($depth) = shift || 0;
5089 my($color) = shift || 0;
5090 # a module needs to recurse to its cpan_file
5092 return if exists $self->{incommandcolor}
5093 && $self->{incommandcolor}==$color;
5094 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
5095 "color_cmd_tmps depth[%s] self[%s] id[%s]",
5100 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
5102 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
5103 $dist->color_cmd_tmps($depth+1,$color);
5106 delete $self->{badtestcnt};
5108 $self->{incommandcolor} = $color;
5111 #-> sub CPAN::Module::as_glimpse ;
5115 my $class = ref($self);
5116 $class =~ s/^CPAN:://;
5120 $CPAN::Shell::COLOR_REGISTERED
5122 $CPAN::META->has_inst("Term::ANSIColor")
5124 $self->{RO}{description}
5126 $color_on = Term::ANSIColor::color("green");
5127 $color_off = Term::ANSIColor::color("reset");
5129 push @m, sprintf("%-15s %s%-15s%s (%s)\n",
5138 #-> sub CPAN::Module::as_string ;
5142 CPAN->debug($self) if $CPAN::DEBUG;
5143 my $class = ref($self);
5144 $class =~ s/^CPAN:://;
5146 push @m, $class, " id = $self->{ID}\n";
5147 my $sprintf = " %-12s %s\n";
5148 push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
5149 if $self->description;
5150 my $sprintf2 = " %-12s %s (%s)\n";
5152 if ($userid = $self->cpan_userid || $self->userid){
5154 if ($author = CPAN::Shell->expand('Author',$userid)) {
5157 if ($m = $author->email) {
5164 $author->fullname . $email
5168 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
5169 if $self->cpan_version;
5170 push @m, sprintf($sprintf, 'CPAN_FILE', $self->cpan_file)
5171 if $self->cpan_file;
5172 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
5173 my(%statd,%stats,%statl,%stati);
5174 @statd{qw,? i c a b R M S,} = qw,unknown idea
5175 pre-alpha alpha beta released mature standard,;
5176 @stats{qw,? m d u n,} = qw,unknown mailing-list
5177 developer comp.lang.perl.* none,;
5178 @statl{qw,? p c + o h,} = qw,unknown perl C C++ other hybrid,;
5179 @stati{qw,? f r O h,} = qw,unknown functions
5180 references+ties object-oriented hybrid,;
5181 $statd{' '} = 'unknown';
5182 $stats{' '} = 'unknown';
5183 $statl{' '} = 'unknown';
5184 $stati{' '} = 'unknown';
5192 $statd{$self->{RO}{statd}},
5193 $stats{$self->{RO}{stats}},
5194 $statl{$self->{RO}{statl}},
5195 $stati{$self->{RO}{stati}}
5196 ) if $self->{RO}{statd};
5197 my $local_file = $self->inst_file;
5198 unless ($self->{MANPAGE}) {
5200 $self->{MANPAGE} = $self->manpage_headline($local_file);
5202 # If we have already untarred it, we should look there
5203 my $dist = $CPAN::META->instance('CPAN::Distribution',
5205 # warn "dist[$dist]";
5206 # mff=manifest file; mfh=manifest handle
5211 (-f ($mff = File::Spec->catfile($dist->{build_dir}, "MANIFEST")))
5213 $mfh = FileHandle->new($mff)
5215 CPAN->debug("mff[$mff]") if $CPAN::DEBUG;
5216 my $lfre = $self->id; # local file RE
5219 my($lfl); # local file file
5221 my(@mflines) = <$mfh>;
5226 while (length($lfre)>5 and !$lfl) {
5227 ($lfl) = grep /$lfre/, @mflines;
5228 CPAN->debug("lfl[$lfl]lfre[$lfre]") if $CPAN::DEBUG;
5231 $lfl =~ s/\s.*//; # remove comments
5232 $lfl =~ s/\s+//g; # chomp would maybe be too system-specific
5233 my $lfl_abs = File::Spec->catfile($dist->{build_dir},$lfl);
5234 # warn "lfl_abs[$lfl_abs]";
5236 $self->{MANPAGE} = $self->manpage_headline($lfl_abs);
5242 for $item (qw/MANPAGE/) {
5243 push @m, sprintf($sprintf, $item, $self->{$item})
5244 if exists $self->{$item};
5246 for $item (qw/CONTAINS/) {
5247 push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
5248 if exists $self->{$item} && @{$self->{$item}};
5250 push @m, sprintf($sprintf, 'INST_FILE',
5251 $local_file || "(not installed)");
5252 push @m, sprintf($sprintf, 'INST_VERSION',
5253 $self->inst_version) if $local_file;
5257 sub manpage_headline {
5258 my($self,$local_file) = @_;
5259 my(@local_file) = $local_file;
5260 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
5261 push @local_file, $local_file;
5263 for $locf (@local_file) {
5264 next unless -f $locf;
5265 my $fh = FileHandle->new($locf)
5266 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
5270 $inpod = m/^=(?!head1\s+NAME)/ ? 0 :
5271 m/^=head1\s+NAME/ ? 1 : $inpod;
5284 #-> sub CPAN::Module::cpan_file ;
5285 # Note: also inherited by CPAN::Bundle
5288 CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
5289 unless (defined $self->{RO}{CPAN_FILE}) {
5290 CPAN::Index->reload;
5292 if (exists $self->{RO}{CPAN_FILE} && defined $self->{RO}{CPAN_FILE}){
5293 return $self->{RO}{CPAN_FILE};
5295 my $userid = $self->userid;
5297 if ($CPAN::META->exists("CPAN::Author",$userid)) {
5298 my $author = $CPAN::META->instance("CPAN::Author",
5300 my $fullname = $author->fullname;
5301 my $email = $author->email;
5302 unless (defined $fullname && defined $email) {
5303 return sprintf("Contact Author %s",
5307 return "Contact Author $fullname <$email>";
5309 return "UserID $userid";
5317 #-> sub CPAN::Module::cpan_version ;
5321 $self->{RO}{CPAN_VERSION} = 'undef'
5322 unless defined $self->{RO}{CPAN_VERSION};
5323 # I believe this is always a bug in the index and should be reported
5324 # as such, but usually I find out such an error and do not want to
5325 # provoke too many bugreports
5327 $self->{RO}{CPAN_VERSION};
5330 #-> sub CPAN::Module::force ;
5333 $self->{'force_update'}++;
5336 #-> sub CPAN::Module::rematein ;
5338 my($self,$meth) = @_;
5339 $CPAN::Frontend->myprint(sprintf("Running %s for module %s\n",
5342 my $cpan_file = $self->cpan_file;
5343 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
5344 $CPAN::Frontend->mywarn(sprintf qq{
5345 The module %s isn\'t available on CPAN.
5347 Either the module has not yet been uploaded to CPAN, or it is
5348 temporary unavailable. Please contact the author to find out
5349 more about the status. Try 'i %s'.
5356 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
5357 $pack->called_for($self->id);
5358 $pack->force($meth) if exists $self->{'force_update'};
5360 $pack->unforce if $pack->can("unforce") && exists $self->{'force_update'};
5361 delete $self->{'force_update'};
5364 #-> sub CPAN::Module::readme ;
5365 sub readme { shift->rematein('readme') }
5366 #-> sub CPAN::Module::look ;
5367 sub look { shift->rematein('look') }
5368 #-> sub CPAN::Module::cvs_import ;
5369 sub cvs_import { shift->rematein('cvs_import') }
5370 #-> sub CPAN::Module::get ;
5371 sub get { shift->rematein('get',@_); }
5372 #-> sub CPAN::Module::make ;
5375 $self->rematein('make');
5377 #-> sub CPAN::Module::test ;
5380 $self->{badtestcnt} ||= 0;
5381 $self->rematein('test',@_);
5383 #-> sub CPAN::Module::uptodate ;
5386 my($latest) = $self->cpan_version;
5388 my($inst_file) = $self->inst_file;
5390 if (defined $inst_file) {
5391 $have = $self->inst_version;
5396 ! CPAN::Version->vgt($latest, $have)
5398 CPAN->debug("returning uptodate. inst_file[$inst_file] ".
5399 "latest[$latest] have[$have]") if $CPAN::DEBUG;
5404 #-> sub CPAN::Module::install ;
5410 not exists $self->{'force_update'}
5412 $CPAN::Frontend->myprint( $self->id. " is up to date.\n");
5416 $self->rematein('install') if $doit;
5418 #-> sub CPAN::Module::clean ;
5419 sub clean { shift->rematein('clean') }
5421 #-> sub CPAN::Module::inst_file ;
5425 @packpath = split /::/, $self->{ID};
5426 $packpath[-1] .= ".pm";
5427 foreach $dir (@INC) {
5428 my $pmfile = File::Spec->catfile($dir,@packpath);
5436 #-> sub CPAN::Module::xs_file ;
5440 @packpath = split /::/, $self->{ID};
5441 push @packpath, $packpath[-1];
5442 $packpath[-1] .= "." . $Config::Config{'dlext'};
5443 foreach $dir (@INC) {
5444 my $xsfile = File::Spec->catfile($dir,'auto',@packpath);
5452 #-> sub CPAN::Module::inst_version ;
5455 my $parsefile = $self->inst_file or return;
5456 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
5459 # there was a bug in 5.6.0 that let lots of unini warnings out of
5460 # parse_version. Fixed shortly after 5.6.0 by PMQS. We can remove
5461 # the following workaround after 5.6.1 is out.
5462 local($SIG{__WARN__}) = sub { my $w = shift;
5463 return if $w =~ /uninitialized/i;
5467 $have = MM->parse_version($parsefile) || "undef";
5468 $have =~ s/^ //; # since the %vd hack these two lines here are needed
5469 $have =~ s/ $//; # trailing whitespace happens all the time
5471 # My thoughts about why %vd processing should happen here
5473 # Alt1 maintain it as string with leading v:
5474 # read index files do nothing
5475 # compare it use utility for compare
5476 # print it do nothing
5478 # Alt2 maintain it as what it is
5479 # read index files convert
5480 # compare it use utility because there's still a ">" vs "gt" issue
5481 # print it use CPAN::Version for print
5483 # Seems cleaner to hold it in memory as a string starting with a "v"
5485 # If the author of this module made a mistake and wrote a quoted
5486 # "v1.13" instead of v1.13, we simply leave it at that with the
5487 # effect that *we* will treat it like a v-tring while the rest of
5488 # perl won't. Seems sensible when we consider that any action we
5489 # could take now would just add complexity.
5491 $have = CPAN::Version->readable($have);
5493 $have =~ s/\s*//g; # stringify to float around floating point issues
5494 $have; # no stringify needed, \s* above matches always
5497 package CPAN::Tarzip;
5499 # CPAN::Tarzip::gzip
5501 my($class,$read,$write) = @_;
5502 if ($CPAN::META->has_inst("Compress::Zlib")) {
5504 $fhw = FileHandle->new($read)
5505 or $CPAN::Frontend->mydie("Could not open $read: $!");
5506 my $gz = Compress::Zlib::gzopen($write, "wb")
5507 or $CPAN::Frontend->mydie("Cannot gzopen $write: $!\n");
5508 $gz->gzwrite($buffer)
5509 while read($fhw,$buffer,4096) > 0 ;
5514 system("$CPAN::Config->{gzip} -c $read > $write")==0;
5519 # CPAN::Tarzip::gunzip
5521 my($class,$read,$write) = @_;
5522 if ($CPAN::META->has_inst("Compress::Zlib")) {
5524 $fhw = FileHandle->new(">$write")
5525 or $CPAN::Frontend->mydie("Could not open >$write: $!");
5526 my $gz = Compress::Zlib::gzopen($read, "rb")
5527 or $CPAN::Frontend->mydie("Cannot gzopen $read: $!\n");
5528 $fhw->print($buffer)
5529 while $gz->gzread($buffer) > 0 ;
5530 $CPAN::Frontend->mydie("Error reading from $read: $!\n")
5531 if $gz->gzerror != Compress::Zlib::Z_STREAM_END();
5536 system("$CPAN::Config->{gzip} -dc $read > $write")==0;
5541 # CPAN::Tarzip::gtest
5543 my($class,$read) = @_;
5544 # After I had reread the documentation in zlib.h, I discovered that
5545 # uncompressed files do not lead to an gzerror (anymore?).
5546 if ( $CPAN::META->has_inst("Compress::Zlib") ) {
5549 my $gz = Compress::Zlib::gzopen($read, "rb")
5550 or $CPAN::Frontend->mydie(sprintf("Cannot gzopen %s: %s\n",
5552 $Compress::Zlib::gzerrno));
5553 while ($gz->gzread($buffer) > 0 ){
5554 $len += length($buffer);
5557 my $err = $gz->gzerror;
5558 my $success = ! $err || $err == Compress::Zlib::Z_STREAM_END();
5559 if ($len == -s $read){
5561 CPAN->debug("hit an uncompressed file") if $CPAN::DEBUG;
5564 CPAN->debug("err[$err]success[$success]") if $CPAN::DEBUG;
5567 return system("$CPAN::Config->{gzip} -dt $read")==0;
5572 # CPAN::Tarzip::TIEHANDLE
5574 my($class,$file) = @_;
5576 $class->debug("file[$file]");
5577 if ($CPAN::META->has_inst("Compress::Zlib")) {
5578 my $gz = Compress::Zlib::gzopen($file,"rb") or
5579 die "Could not gzopen $file";
5580 $ret = bless {GZ => $gz}, $class;
5582 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $file |";
5583 my $fh = FileHandle->new($pipe) or die "Could not pipe[$pipe]: $!";
5585 $ret = bless {FH => $fh}, $class;
5591 # CPAN::Tarzip::READLINE
5594 if (exists $self->{GZ}) {
5595 my $gz = $self->{GZ};
5596 my($line,$bytesread);
5597 $bytesread = $gz->gzreadline($line);
5598 return undef if $bytesread <= 0;
5601 my $fh = $self->{FH};
5602 return scalar <$fh>;
5607 # CPAN::Tarzip::READ
5609 my($self,$ref,$length,$offset) = @_;
5610 die "read with offset not implemented" if defined $offset;
5611 if (exists $self->{GZ}) {
5612 my $gz = $self->{GZ};
5613 my $byteread = $gz->gzread($$ref,$length);# 30eaf79e8b446ef52464b5422da328a8
5616 my $fh = $self->{FH};
5617 return read($fh,$$ref,$length);
5622 # CPAN::Tarzip::DESTROY
5625 if (exists $self->{GZ}) {
5626 my $gz = $self->{GZ};
5627 $gz->gzclose() if defined $gz; # hard to say if it is allowed
5628 # to be undef ever. AK, 2000-09
5630 my $fh = $self->{FH};
5631 $fh->close if defined $fh;
5637 # CPAN::Tarzip::untar
5639 my($class,$file) = @_;
5642 if (0) { # makes changing order easier
5643 } elsif ($BUGHUNTING){
5645 } elsif (MM->maybe_command($CPAN::Config->{gzip})
5647 MM->maybe_command($CPAN::Config->{'tar'})) {
5648 # should be default until Archive::Tar is fixed
5651 $CPAN::META->has_inst("Archive::Tar")
5653 $CPAN::META->has_inst("Compress::Zlib") ) {
5656 $CPAN::Frontend->mydie(qq{
5657 CPAN.pm needs either both external programs tar and gzip installed or
5658 both the modules Archive::Tar and Compress::Zlib. Neither prerequisite
5659 is available. Can\'t continue.
5662 if ($prefer==1) { # 1 => external gzip+tar
5664 my $is_compressed = $class->gtest($file);
5665 if ($is_compressed) {
5666 $system = "$CPAN::Config->{gzip} --decompress --stdout " .
5667 "< $file | $CPAN::Config->{tar} xvf -";
5669 $system = "$CPAN::Config->{tar} xvf $file";
5671 if (system($system) != 0) {
5672 # people find the most curious tar binaries that cannot handle
5674 if ($is_compressed) {
5675 (my $ungzf = $file) =~ s/\.gz(?!\n)\Z//;
5676 if (CPAN::Tarzip->gunzip($file, $ungzf)) {
5677 $CPAN::Frontend->myprint(qq{Uncompressed $file successfully\n});
5679 $CPAN::Frontend->mydie(qq{Couldn\'t uncompress $file\n});
5683 $system = "$CPAN::Config->{tar} xvf $file";
5684 $CPAN::Frontend->myprint(qq{Using Tar:$system:\n});
5685 if (system($system)==0) {
5686 $CPAN::Frontend->myprint(qq{Untarred $file successfully\n});
5688 $CPAN::Frontend->mydie(qq{Couldn\'t untar $file\n});
5694 } elsif ($prefer==2) { # 2 => modules
5695 my $tar = Archive::Tar->new($file,1);
5696 my $af; # archive file
5699 # RCS 1.337 had this code, it turned out unacceptable slow but
5700 # it revealed a bug in Archive::Tar. Code is only here to hunt
5701 # the bug again. It should never be enabled in published code.
5702 # GDGraph3d-0.53 was an interesting case according to Larry
5704 warn(">>>Bughunting code enabled<<< " x 20);
5705 for $af ($tar->list_files) {
5706 if ($af =~ m!^(/|\.\./)!) {
5707 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5708 "illegal member [$af]");
5710 $CPAN::Frontend->myprint("$af\n");
5711 $tar->extract($af); # slow but effective for finding the bug
5712 return if $CPAN::Signal;
5715 for $af ($tar->list_files) {
5716 if ($af =~ m!^(/|\.\./)!) {
5717 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5718 "illegal member [$af]");
5720 $CPAN::Frontend->myprint("$af\n");
5722 return if $CPAN::Signal;
5727 Mac::BuildTools::convert_files([$tar->list_files], 1)
5728 if ($^O eq 'MacOS');
5735 my($class,$file) = @_;
5736 if ($CPAN::META->has_inst("Archive::Zip")) {
5737 # blueprint of the code from Archive::Zip::Tree::extractTree();
5738 my $zip = Archive::Zip->new();
5740 $status = $zip->read($file);
5741 die "Read of file[$file] failed\n" if $status != Archive::Zip::AZ_OK();
5742 $CPAN::META->debug("Successfully read file[$file]") if $CPAN::DEBUG;
5743 my @members = $zip->members();
5744 for my $member ( @members ) {
5745 my $af = $member->fileName();
5746 if ($af =~ m!^(/|\.\./)!) {
5747 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5748 "illegal member [$af]");
5750 my $status = $member->extractToFileNamed( $af );
5751 $CPAN::META->debug("af[$af]status[$status]") if $CPAN::DEBUG;
5752 die "Extracting of file[$af] from zipfile[$file] failed\n" if
5753 $status != Archive::Zip::AZ_OK();
5754 return if $CPAN::Signal;
5758 my $unzip = $CPAN::Config->{unzip} or
5759 $CPAN::Frontend->mydie("Cannot unzip, no unzip program available");
5760 my @system = ($unzip, $file);
5761 return system(@system) == 0;
5766 package CPAN::Version;
5767 # CPAN::Version::vcmp courtesy Jost Krieger
5769 my($self,$l,$r) = @_;
5771 CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG;
5773 return 0 if $l eq $r; # short circuit for quicker success
5775 if ($l=~/^v/ <=> $r=~/^v/) {
5778 $_ = $self->float2vv($_);
5783 ($l ne "undef") <=> ($r ne "undef") ||
5787 $self->vstring($l) cmp $self->vstring($r)) ||
5793 my($self,$l,$r) = @_;
5794 $self->vcmp($l,$r) > 0;
5799 $n =~ s/^v// or die "CPAN::Version::vstring() called with invalid arg [$n]";
5800 pack "U*", split /\./, $n;
5803 # vv => visible vstring
5808 my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits to limit
5809 # architecture influence
5811 $mantissa .= "0" while length($mantissa)%3;
5812 my $ret = "v" . $rev;
5814 $mantissa =~ s/(\d{1,3})// or
5815 die "Panic: length>0 but not a digit? mantissa[$mantissa]";
5816 $ret .= ".".int($1);
5818 # warn "n[$n]ret[$ret]";
5824 $n =~ /^([\w\-\+\.]+)/;
5826 return $1 if defined $1 && length($1)>0;
5827 # if the first user reaches version v43, he will be treated as "+".
5828 # We'll have to decide about a new rule here then, depending on what
5829 # will be the prevailing versioning behavior then.
5831 if ($] < 5.006) { # or whenever v-strings were introduced
5832 # we get them wrong anyway, whatever we do, because 5.005 will
5833 # have already interpreted 0.2.4 to be "0.24". So even if he
5834 # indexer sends us something like "v0.2.4" we compare wrongly.
5836 # And if they say v1.2, then the old perl takes it as "v12"
5838 $CPAN::Frontend->mywarn("Suspicious version string seen [$n]");
5841 my $better = sprintf "v%vd", $n;
5842 CPAN->debug("n[$n] better[$better]") if $CPAN::DEBUG;
5854 CPAN - query, download and build perl modules from CPAN sites
5860 perl -MCPAN -e shell;
5866 autobundle, clean, install, make, recompile, test
5870 The CPAN module is designed to automate the make and install of perl
5871 modules and extensions. It includes some searching capabilities and
5872 knows how to use Net::FTP or LWP (or lynx or an external ftp client)
5873 to fetch the raw data from the net.
5875 Modules are fetched from one or more of the mirrored CPAN
5876 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
5879 The CPAN module also supports the concept of named and versioned
5880 I<bundles> of modules. Bundles simplify the handling of sets of
5881 related modules. See Bundles below.
5883 The package contains a session manager and a cache manager. There is
5884 no status retained between sessions. The session manager keeps track
5885 of what has been fetched, built and installed in the current
5886 session. The cache manager keeps track of the disk space occupied by
5887 the make processes and deletes excess space according to a simple FIFO
5890 For extended searching capabilities there's a plugin for CPAN available,
5891 L<C<CPAN::WAIT>|CPAN::WAIT>. C<CPAN::WAIT> is a full-text search engine
5892 that indexes all documents available in CPAN authors directories. If
5893 C<CPAN::WAIT> is installed on your system, the interactive shell of
5894 CPAN.pm will enable the C<wq>, C<wr>, C<wd>, C<wl>, and C<wh> commands
5895 which send queries to the WAIT server that has been configured for your
5898 All other methods provided are accessible in a programmer style and in an
5899 interactive shell style.
5901 =head2 Interactive Mode
5903 The interactive mode is entered by running
5905 perl -MCPAN -e shell
5907 which puts you into a readline interface. You will have the most fun if
5908 you install Term::ReadKey and Term::ReadLine to enjoy both history and
5911 Once you are on the command line, type 'h' and the rest should be
5914 The function call C<shell> takes two optional arguments, one is the
5915 prompt, the second is the default initial command line (the latter
5916 only works if a real ReadLine interface module is installed).
5918 The most common uses of the interactive modes are
5922 =item Searching for authors, bundles, distribution files and modules
5924 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
5925 for each of the four categories and another, C<i> for any of the
5926 mentioned four. Each of the four entities is implemented as a class
5927 with slightly differing methods for displaying an object.
5929 Arguments you pass to these commands are either strings exactly matching
5930 the identification string of an object or regular expressions that are
5931 then matched case-insensitively against various attributes of the
5932 objects. The parser recognizes a regular expression only if you
5933 enclose it between two slashes.
5935 The principle is that the number of found objects influences how an
5936 item is displayed. If the search finds one item, the result is
5937 displayed with the rather verbose method C<as_string>, but if we find
5938 more than one, we display each object with the terse method
5941 =item make, test, install, clean modules or distributions
5943 These commands take any number of arguments and investigate what is
5944 necessary to perform the action. If the argument is a distribution
5945 file name (recognized by embedded slashes), it is processed. If it is
5946 a module, CPAN determines the distribution file in which this module
5947 is included and processes that, following any dependencies named in
5948 the module's Makefile.PL (this behavior is controlled by
5949 I<prerequisites_policy>.)
5951 Any C<make> or C<test> are run unconditionally. An
5953 install <distribution_file>
5955 also is run unconditionally. But for
5959 CPAN checks if an install is actually needed for it and prints
5960 I<module up to date> in the case that the distribution file containing
5961 the module doesn't need to be updated.
5963 CPAN also keeps track of what it has done within the current session
5964 and doesn't try to build a package a second time regardless if it
5965 succeeded or not. The C<force> command takes as a first argument the
5966 method to invoke (currently: C<make>, C<test>, or C<install>) and executes the
5967 command from scratch.
5971 cpan> install OpenGL
5972 OpenGL is up to date.
5973 cpan> force install OpenGL
5976 OpenGL-0.4/COPYRIGHT
5979 A C<clean> command results in a
5983 being executed within the distribution file's working directory.
5985 =item get, readme, look module or distribution
5987 C<get> downloads a distribution file without further action. C<readme>
5988 displays the README file of the associated distribution. C<Look> gets
5989 and untars (if not yet done) the distribution file, changes to the
5990 appropriate directory and opens a subshell process in that directory.
5994 C<ls> lists all distribution files in and below an author's CPAN
5995 directory. Only those files that contain modules are listed and if
5996 there is more than one for any given module, only the most recent one
6001 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
6002 in the cpan-shell it is intended that you can press C<^C> anytime and
6003 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
6004 to clean up and leave the shell loop. You can emulate the effect of a
6005 SIGTERM by sending two consecutive SIGINTs, which usually means by
6006 pressing C<^C> twice.
6008 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
6009 SIGALRM is used during the run of the C<perl Makefile.PL> subprocess.
6015 The commands that are available in the shell interface are methods in
6016 the package CPAN::Shell. If you enter the shell command, all your
6017 input is split by the Text::ParseWords::shellwords() routine which
6018 acts like most shells do. The first word is being interpreted as the
6019 method to be called and the rest of the words are treated as arguments
6020 to this method. Continuation lines are supported if a line ends with a
6025 C<autobundle> writes a bundle file into the
6026 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
6027 a list of all modules that are both available from CPAN and currently
6028 installed within @INC. The name of the bundle file is based on the
6029 current date and a counter.
6033 recompile() is a very special command in that it takes no argument and
6034 runs the make/test/install cycle with brute force over all installed
6035 dynamically loadable extensions (aka XS modules) with 'force' in
6036 effect. The primary purpose of this command is to finish a network
6037 installation. Imagine, you have a common source tree for two different
6038 architectures. You decide to do a completely independent fresh
6039 installation. You start on one architecture with the help of a Bundle
6040 file produced earlier. CPAN installs the whole Bundle for you, but
6041 when you try to repeat the job on the second architecture, CPAN
6042 responds with a C<"Foo up to date"> message for all modules. So you
6043 invoke CPAN's recompile on the second architecture and you're done.
6045 Another popular use for C<recompile> is to act as a rescue in case your
6046 perl breaks binary compatibility. If one of the modules that CPAN uses
6047 is in turn depending on binary compatibility (so you cannot run CPAN
6048 commands), then you should try the CPAN::Nox module for recovery.
6050 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
6052 Although it may be considered internal, the class hierarchy does matter
6053 for both users and programmer. CPAN.pm deals with above mentioned four
6054 classes, and all those classes share a set of methods. A classical
6055 single polymorphism is in effect. A metaclass object registers all
6056 objects of all kinds and indexes them with a string. The strings
6057 referencing objects have a separated namespace (well, not completely
6062 words containing a "/" (slash) Distribution
6063 words starting with Bundle:: Bundle
6064 everything else Module or Author
6066 Modules know their associated Distribution objects. They always refer
6067 to the most recent official release. Developers may mark their releases
6068 as unstable development versions (by inserting an underbar into the
6069 module version number which will also be reflected in the distribution
6070 name when you run 'make dist'), so the really hottest and newest
6071 distribution is not always the default. If a module Foo circulates
6072 on CPAN in both version 1.23 and 1.23_90, CPAN.pm offers a convenient
6073 way to install version 1.23 by saying
6077 This would install the complete distribution file (say
6078 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
6079 like to install version 1.23_90, you need to know where the
6080 distribution file resides on CPAN relative to the authors/id/
6081 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
6082 so you would have to say
6084 install BAR/Foo-1.23_90.tar.gz
6086 The first example will be driven by an object of the class
6087 CPAN::Module, the second by an object of class CPAN::Distribution.
6089 =head2 Programmer's interface
6091 If you do not enter the shell, the available shell commands are both
6092 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
6093 functions in the calling package (C<install(...)>).
6095 There's currently only one class that has a stable interface -
6096 CPAN::Shell. All commands that are available in the CPAN shell are
6097 methods of the class CPAN::Shell. Each of the commands that produce
6098 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
6099 the IDs of all modules within the list.
6103 =item expand($type,@things)
6105 The IDs of all objects available within a program are strings that can
6106 be expanded to the corresponding real objects with the
6107 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
6108 list of CPAN::Module objects according to the C<@things> arguments
6109 given. In scalar context it only returns the first element of the
6112 =item expandany(@things)
6114 Like expand, but returns objects of the appropriate type, i.e.
6115 CPAN::Bundle objects for bundles, CPAN::Module objects for modules and
6116 CPAN::Distribution objects fro distributions.
6118 =item Programming Examples
6120 This enables the programmer to do operations that combine
6121 functionalities that are available in the shell.
6123 # install everything that is outdated on my disk:
6124 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
6126 # install my favorite programs if necessary:
6127 for $mod (qw(Net::FTP Digest::MD5 Data::Dumper)){
6128 my $obj = CPAN::Shell->expand('Module',$mod);
6132 # list all modules on my disk that have no VERSION number
6133 for $mod (CPAN::Shell->expand("Module","/./")){
6134 next unless $mod->inst_file;
6135 # MakeMaker convention for undefined $VERSION:
6136 next unless $mod->inst_version eq "undef";
6137 print "No VERSION in ", $mod->id, "\n";
6140 # find out which distribution on CPAN contains a module:
6141 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
6143 Or if you want to write a cronjob to watch The CPAN, you could list
6144 all modules that need updating. First a quick and dirty way:
6146 perl -e 'use CPAN; CPAN::Shell->r;'
6148 If you don't want to get any output in the case that all modules are
6149 up to date, you can parse the output of above command for the regular
6150 expression //modules are up to date// and decide to mail the output
6151 only if it doesn't match. Ick?
6153 If you prefer to do it more in a programmer style in one single
6154 process, maybe something like this suits you better:
6156 # list all modules on my disk that have newer versions on CPAN
6157 for $mod (CPAN::Shell->expand("Module","/./")){
6158 next unless $mod->inst_file;
6159 next if $mod->uptodate;
6160 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
6161 $mod->id, $mod->inst_version, $mod->cpan_version;
6164 If that gives you too much output every day, you maybe only want to
6165 watch for three modules. You can write
6167 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")){
6169 as the first line instead. Or you can combine some of the above
6172 # watch only for a new mod_perl module
6173 $mod = CPAN::Shell->expand("Module","mod_perl");
6174 exit if $mod->uptodate;
6175 # new mod_perl arrived, let me know all update recommendations
6180 =head2 Methods in the other Classes
6182 The programming interface for the classes CPAN::Module,
6183 CPAN::Distribution, CPAN::Bundle, and CPAN::Author is still considered
6184 beta and partially even alpha. In the following paragraphs only those
6185 methods are documented that have proven useful over a longer time and
6186 thus are unlikely to change.
6190 =item CPAN::Author::as_glimpse()
6192 Returns a one-line description of the author
6194 =item CPAN::Author::as_string()
6196 Returns a multi-line description of the author
6198 =item CPAN::Author::email()
6200 Returns the author's email address
6202 =item CPAN::Author::fullname()
6204 Returns the author's name
6206 =item CPAN::Author::name()
6208 An alias for fullname
6210 =item CPAN::Bundle::as_glimpse()
6212 Returns a one-line description of the bundle
6214 =item CPAN::Bundle::as_string()
6216 Returns a multi-line description of the bundle
6218 =item CPAN::Bundle::clean()
6220 Recursively runs the C<clean> method on all items contained in the bundle.
6222 =item CPAN::Bundle::contains()
6224 Returns a list of objects' IDs contained in a bundle. The associated
6225 objects may be bundles, modules or distributions.
6227 =item CPAN::Bundle::force($method,@args)
6229 Forces CPAN to perform a task that normally would have failed. Force
6230 takes as arguments a method name to be called and any number of
6231 additional arguments that should be passed to the called method. The
6232 internals of the object get the needed changes so that CPAN.pm does
6233 not refuse to take the action. The C<force> is passed recursively to
6234 all contained objects.
6236 =item CPAN::Bundle::get()
6238 Recursively runs the C<get> method on all items contained in the bundle
6240 =item CPAN::Bundle::inst_file()
6242 Returns the highest installed version of the bundle in either @INC or
6243 C<$CPAN::Config->{cpan_home}>. Note that this is different from
6244 CPAN::Module::inst_file.
6246 =item CPAN::Bundle::inst_version()
6248 Like CPAN::Bundle::inst_file, but returns the $VERSION
6250 =item CPAN::Bundle::uptodate()
6252 Returns 1 if the bundle itself and all its members are uptodate.
6254 =item CPAN::Bundle::install()
6256 Recursively runs the C<install> method on all items contained in the bundle
6258 =item CPAN::Bundle::make()
6260 Recursively runs the C<make> method on all items contained in the bundle
6262 =item CPAN::Bundle::readme()
6264 Recursively runs the C<readme> method on all items contained in the bundle
6266 =item CPAN::Bundle::test()
6268 Recursively runs the C<test> method on all items contained in the bundle
6270 =item CPAN::Distribution::as_glimpse()
6272 Returns a one-line description of the distribution
6274 =item CPAN::Distribution::as_string()
6276 Returns a multi-line description of the distribution
6278 =item CPAN::Distribution::clean()
6280 Changes to the directory where the distribution has been unpacked and
6281 runs C<make clean> there.
6283 =item CPAN::Distribution::containsmods()
6285 Returns a list of IDs of modules contained in a distribution file.
6286 Only works for distributions listed in the 02packages.details.txt.gz
6287 file. This typically means that only the most recent version of a
6288 distribution is covered.
6290 =item CPAN::Distribution::cvs_import()
6292 Changes to the directory where the distribution has been unpacked and
6295 cvs -d $cvs_root import -m $cvs_log $cvs_dir $userid v$version
6299 =item CPAN::Distribution::dir()
6301 Returns the directory into which this distribution has been unpacked.
6303 =item CPAN::Distribution::force($method,@args)
6305 Forces CPAN to perform a task that normally would have failed. Force
6306 takes as arguments a method name to be called and any number of
6307 additional arguments that should be passed to the called method. The
6308 internals of the object get the needed changes so that CPAN.pm does
6309 not refuse to take the action.
6311 =item CPAN::Distribution::get()
6313 Downloads the distribution from CPAN and unpacks it. Does nothing if
6314 the distribution has already been downloaded and unpacked within the
6317 =item CPAN::Distribution::install()
6319 Changes to the directory where the distribution has been unpacked and
6320 runs the external command C<make install> there. If C<make> has not
6321 yet been run, it will be run first. A C<make test> will be issued in
6322 any case and if this fails, the install will be canceled. The
6323 cancellation can be avoided by letting C<force> run the C<install> for
6326 =item CPAN::Distribution::isa_perl()
6328 Returns 1 if this distribution file seems to be a perl distribution.
6329 Normally this is derived from the file name only, but the index from
6330 CPAN can contain a hint to achieve a return value of true for other
6333 =item CPAN::Distribution::look()
6335 Changes to the directory where the distribution has been unpacked and
6336 opens a subshell there. Exiting the subshell returns.
6338 =item CPAN::Distribution::make()
6340 First runs the C<get> method to make sure the distribution is
6341 downloaded and unpacked. Changes to the directory where the
6342 distribution has been unpacked and runs the external commands C<perl
6343 Makefile.PL> and C<make> there.
6345 =item CPAN::Distribution::prereq_pm()
6347 Returns the hash reference that has been announced by a distribution
6348 as the PREREQ_PM hash in the Makefile.PL. Note: works only after an
6349 attempt has been made to C<make> the distribution. Returns undef
6352 =item CPAN::Distribution::readme()
6354 Downloads the README file associated with a distribution and runs it
6355 through the pager specified in C<$CPAN::Config->{pager}>.
6357 =item CPAN::Distribution::test()
6359 Changes to the directory where the distribution has been unpacked and
6360 runs C<make test> there.
6362 =item CPAN::Distribution::uptodate()
6364 Returns 1 if all the modules contained in the distribution are
6365 uptodate. Relies on containsmods.
6367 =item CPAN::Index::force_reload()
6369 Forces a reload of all indices.
6371 =item CPAN::Index::reload()
6373 Reloads all indices if they have been read more than
6374 C<$CPAN::Config->{index_expire}> days.
6376 =item CPAN::InfoObj::dump()
6378 CPAN::Author, CPAN::Bundle, CPAN::Module, and CPAN::Distribution
6379 inherit this method. It prints the data structure associated with an
6380 object. Useful for debugging. Note: the data structure is considered
6381 internal and thus subject to change without notice.
6383 =item CPAN::Module::as_glimpse()
6385 Returns a one-line description of the module
6387 =item CPAN::Module::as_string()
6389 Returns a multi-line description of the module
6391 =item CPAN::Module::clean()
6393 Runs a clean on the distribution associated with this module.
6395 =item CPAN::Module::cpan_file()
6397 Returns the filename on CPAN that is associated with the module.
6399 =item CPAN::Module::cpan_version()
6401 Returns the latest version of this module available on CPAN.
6403 =item CPAN::Module::cvs_import()
6405 Runs a cvs_import on the distribution associated with this module.
6407 =item CPAN::Module::description()
6409 Returns a 44 character description of this module. Only available for
6410 modules listed in The Module List (CPAN/modules/00modlist.long.html
6411 or 00modlist.long.txt.gz)
6413 =item CPAN::Module::force($method,@args)
6415 Forces CPAN to perform a task that normally would have failed. Force
6416 takes as arguments a method name to be called and any number of
6417 additional arguments that should be passed to the called method. The
6418 internals of the object get the needed changes so that CPAN.pm does
6419 not refuse to take the action.
6421 =item CPAN::Module::get()
6423 Runs a get on the distribution associated with this module.
6425 =item CPAN::Module::inst_file()
6427 Returns the filename of the module found in @INC. The first file found
6428 is reported just like perl itself stops searching @INC when it finds a
6431 =item CPAN::Module::inst_version()
6433 Returns the version number of the module in readable format.
6435 =item CPAN::Module::install()
6437 Runs an C<install> on the distribution associated with this module.
6439 =item CPAN::Module::look()
6441 Changes to the directory where the distribution associated with this
6442 module has been unpacked and opens a subshell there. Exiting the
6445 =item CPAN::Module::make()
6447 Runs a C<make> on the distribution associated with this module.
6449 =item CPAN::Module::manpage_headline()
6451 If module is installed, peeks into the module's manpage, reads the
6452 headline and returns it. Moreover, if the module has been downloaded
6453 within this session, does the equivalent on the downloaded module even
6454 if it is not installed.
6456 =item CPAN::Module::readme()
6458 Runs a C<readme> on the distribution associated with this module.
6460 =item CPAN::Module::test()
6462 Runs a C<test> on the distribution associated with this module.
6464 =item CPAN::Module::uptodate()
6466 Returns 1 if the module is installed and up-to-date.
6468 =item CPAN::Module::userid()
6470 Returns the author's ID of the module.
6474 =head2 Cache Manager
6476 Currently the cache manager only keeps track of the build directory
6477 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
6478 deletes complete directories below C<build_dir> as soon as the size of
6479 all directories there gets bigger than $CPAN::Config->{build_cache}
6480 (in MB). The contents of this cache may be used for later
6481 re-installations that you intend to do manually, but will never be
6482 trusted by CPAN itself. This is due to the fact that the user might
6483 use these directories for building modules on different architectures.
6485 There is another directory ($CPAN::Config->{keep_source_where}) where
6486 the original distribution files are kept. This directory is not
6487 covered by the cache manager and must be controlled by the user. If
6488 you choose to have the same directory as build_dir and as
6489 keep_source_where directory, then your sources will be deleted with
6490 the same fifo mechanism.
6494 A bundle is just a perl module in the namespace Bundle:: that does not
6495 define any functions or methods. It usually only contains documentation.
6497 It starts like a perl module with a package declaration and a $VERSION
6498 variable. After that the pod section looks like any other pod with the
6499 only difference being that I<one special pod section> exists starting with
6504 In this pod section each line obeys the format
6506 Module_Name [Version_String] [- optional text]
6508 The only required part is the first field, the name of a module
6509 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
6510 of the line is optional. The comment part is delimited by a dash just
6511 as in the man page header.
6513 The distribution of a bundle should follow the same convention as
6514 other distributions.
6516 Bundles are treated specially in the CPAN package. If you say 'install
6517 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
6518 the modules in the CONTENTS section of the pod. You can install your
6519 own Bundles locally by placing a conformant Bundle file somewhere into
6520 your @INC path. The autobundle() command which is available in the
6521 shell interface does that for you by including all currently installed
6522 modules in a snapshot bundle file.
6524 =head2 Prerequisites
6526 If you have a local mirror of CPAN and can access all files with
6527 "file:" URLs, then you only need a perl better than perl5.003 to run
6528 this module. Otherwise Net::FTP is strongly recommended. LWP may be
6529 required for non-UNIX systems or if your nearest CPAN site is
6530 associated with a URL that is not C<ftp:>.
6532 If you have neither Net::FTP nor LWP, there is a fallback mechanism
6533 implemented for an external ftp command or for an external lynx
6536 =head2 Finding packages and VERSION
6538 This module presumes that all packages on CPAN
6544 declare their $VERSION variable in an easy to parse manner. This
6545 prerequisite can hardly be relaxed because it consumes far too much
6546 memory to load all packages into the running program just to determine
6547 the $VERSION variable. Currently all programs that are dealing with
6548 version use something like this
6550 perl -MExtUtils::MakeMaker -le \
6551 'print MM->parse_version(shift)' filename
6553 If you are author of a package and wonder if your $VERSION can be
6554 parsed, please try the above method.
6558 come as compressed or gzipped tarfiles or as zip files and contain a
6559 Makefile.PL (well, we try to handle a bit more, but without much
6566 The debugging of this module is a bit complex, because we have
6567 interferences of the software producing the indices on CPAN, of the
6568 mirroring process on CPAN, of packaging, of configuration, of
6569 synchronicity, and of bugs within CPAN.pm.
6571 For code debugging in interactive mode you can try "o debug" which
6572 will list options for debugging the various parts of the code. You
6573 should know that "o debug" has built-in completion support.
6575 For data debugging there is the C<dump> command which takes the same
6576 arguments as make/test/install and outputs the object's Data::Dumper
6579 =head2 Floppy, Zip, Offline Mode
6581 CPAN.pm works nicely without network too. If you maintain machines
6582 that are not networked at all, you should consider working with file:
6583 URLs. Of course, you have to collect your modules somewhere first. So
6584 you might use CPAN.pm to put together all you need on a networked
6585 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
6586 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
6587 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
6588 with this floppy. See also below the paragraph about CD-ROM support.
6590 =head1 CONFIGURATION
6592 When the CPAN module is installed, a site wide configuration file is
6593 created as CPAN/Config.pm. The default values defined there can be
6594 overridden in another configuration file: CPAN/MyConfig.pm. You can
6595 store this file in $HOME/.cpan/CPAN/MyConfig.pm if you want, because
6596 $HOME/.cpan is added to the search path of the CPAN module before the
6597 use() or require() statements.
6599 Currently the following keys in the hash reference $CPAN::Config are
6602 build_cache size of cache for directories to build modules
6603 build_dir locally accessible directory to build modules
6604 index_expire after this many days refetch index files
6605 cache_metadata use serializer to cache metadata
6606 cpan_home local directory reserved for this package
6607 dontload_hash anonymous hash: modules in the keys will not be
6608 loaded by the CPAN::has_inst() routine
6609 gzip location of external program gzip
6610 inactivity_timeout breaks interactive Makefile.PLs after this
6611 many seconds inactivity. Set to 0 to never break.
6612 inhibit_startup_message
6613 if true, does not print the startup message
6614 keep_source_where directory in which to keep the source (if we do)
6615 make location of external make program
6616 make_arg arguments that should always be passed to 'make'
6617 make_install_arg same as make_arg for 'make install'
6618 makepl_arg arguments passed to 'perl Makefile.PL'
6619 pager location of external program more (or any pager)
6620 prerequisites_policy
6621 what to do if you are missing module prerequisites
6622 ('follow' automatically, 'ask' me, or 'ignore')
6623 proxy_user username for accessing an authenticating proxy
6624 proxy_pass password for accessing an authenticating proxy
6625 scan_cache controls scanning of cache ('atstart' or 'never')
6626 tar location of external program tar
6627 term_is_latin if true internal UTF-8 is translated to ISO-8859-1
6628 (and nonsense for characters outside latin range)
6629 unzip location of external program unzip
6630 urllist arrayref to nearby CPAN sites (or equivalent locations)
6631 wait_list arrayref to a wait server to try (See CPAN::WAIT)
6632 ftp_proxy, } the three usual variables for configuring
6633 http_proxy, } proxy requests. Both as CPAN::Config variables
6634 no_proxy } and as environment variables configurable.
6636 You can set and query each of these options interactively in the cpan
6637 shell with the command set defined within the C<o conf> command:
6641 =item C<o conf E<lt>scalar optionE<gt>>
6643 prints the current value of the I<scalar option>
6645 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
6647 Sets the value of the I<scalar option> to I<value>
6649 =item C<o conf E<lt>list optionE<gt>>
6651 prints the current value of the I<list option> in MakeMaker's
6654 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
6656 shifts or pops the array in the I<list option> variable
6658 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
6660 works like the corresponding perl commands.
6664 =head2 Note on urllist parameter's format
6666 urllist parameters are URLs according to RFC 1738. We do a little
6667 guessing if your URL is not compliant, but if you have problems with
6668 file URLs, please try the correct format. Either:
6670 file://localhost/whatever/ftp/pub/CPAN/
6674 file:///home/ftp/pub/CPAN/
6676 =head2 urllist parameter has CD-ROM support
6678 The C<urllist> parameter of the configuration table contains a list of
6679 URLs that are to be used for downloading. If the list contains any
6680 C<file> URLs, CPAN always tries to get files from there first. This
6681 feature is disabled for index files. So the recommendation for the
6682 owner of a CD-ROM with CPAN contents is: include your local, possibly
6683 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
6685 o conf urllist push file://localhost/CDROM/CPAN
6687 CPAN.pm will then fetch the index files from one of the CPAN sites
6688 that come at the beginning of urllist. It will later check for each
6689 module if there is a local copy of the most recent version.
6691 Another peculiarity of urllist is that the site that we could
6692 successfully fetch the last file from automatically gets a preference
6693 token and is tried as the first site for the next request. So if you
6694 add a new site at runtime it may happen that the previously preferred
6695 site will be tried another time. This means that if you want to disallow
6696 a site for the next transfer, it must be explicitly removed from
6701 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
6702 install foreign, unmasked, unsigned code on your machine. We compare
6703 to a checksum that comes from the net just as the distribution file
6704 itself. If somebody has managed to tamper with the distribution file,
6705 they may have as well tampered with the CHECKSUMS file. Future
6706 development will go towards strong authentication.
6710 Most functions in package CPAN are exported per default. The reason
6711 for this is that the primary use is intended for the cpan shell or for
6714 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
6716 Populating a freshly installed perl with my favorite modules is pretty
6717 easy if you maintain a private bundle definition file. To get a useful
6718 blueprint of a bundle definition file, the command autobundle can be used
6719 on the CPAN shell command line. This command writes a bundle definition
6720 file for all modules that are installed for the currently running perl
6721 interpreter. It's recommended to run this command only once and from then
6722 on maintain the file manually under a private name, say
6723 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
6725 cpan> install Bundle::my_bundle
6727 then answer a few questions and then go out for a coffee.
6729 Maintaining a bundle definition file means keeping track of two
6730 things: dependencies and interactivity. CPAN.pm sometimes fails on
6731 calculating dependencies because not all modules define all MakeMaker
6732 attributes correctly, so a bundle definition file should specify
6733 prerequisites as early as possible. On the other hand, it's a bit
6734 annoying that many distributions need some interactive configuring. So
6735 what I try to accomplish in my private bundle file is to have the
6736 packages that need to be configured early in the file and the gentle
6737 ones later, so I can go out after a few minutes and leave CPAN.pm
6740 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
6742 Thanks to Graham Barr for contributing the following paragraphs about
6743 the interaction between perl, and various firewall configurations. For
6744 further informations on firewalls, it is recommended to consult the
6745 documentation that comes with the ncftp program. If you are unable to
6746 go through the firewall with a simple Perl setup, it is very likely
6747 that you can configure ncftp so that it works for your firewall.
6749 =head2 Three basic types of firewalls
6751 Firewalls can be categorized into three basic types.
6757 This is where the firewall machine runs a web server and to access the
6758 outside world you must do it via the web server. If you set environment
6759 variables like http_proxy or ftp_proxy to a values beginning with http://
6760 or in your web browser you have to set proxy information then you know
6761 you are running an http firewall.
6763 To access servers outside these types of firewalls with perl (even for
6764 ftp) you will need to use LWP.
6768 This where the firewall machine runs an ftp server. This kind of
6769 firewall will only let you access ftp servers outside the firewall.
6770 This is usually done by connecting to the firewall with ftp, then
6771 entering a username like "user@outside.host.com"
6773 To access servers outside these type of firewalls with perl you
6774 will need to use Net::FTP.
6776 =item One way visibility
6778 I say one way visibility as these firewalls try to make themselves look
6779 invisible to the users inside the firewall. An FTP data connection is
6780 normally created by sending the remote server your IP address and then
6781 listening for the connection. But the remote server will not be able to
6782 connect to you because of the firewall. So for these types of firewall
6783 FTP connections need to be done in a passive mode.
6785 There are two that I can think off.
6791 If you are using a SOCKS firewall you will need to compile perl and link
6792 it with the SOCKS library, this is what is normally called a 'socksified'
6793 perl. With this executable you will be able to connect to servers outside
6794 the firewall as if it is not there.
6798 This is the firewall implemented in the Linux kernel, it allows you to
6799 hide a complete network behind one IP address. With this firewall no
6800 special compiling is needed as you can access hosts directly.
6806 =head2 Configuring lynx or ncftp for going through a firewall
6808 If you can go through your firewall with e.g. lynx, presumably with a
6811 /usr/local/bin/lynx -pscott:tiger
6813 then you would configure CPAN.pm with the command
6815 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
6817 That's all. Similarly for ncftp or ftp, you would configure something
6820 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
6822 Your mileage may vary...
6830 I installed a new version of module X but CPAN keeps saying,
6831 I have the old version installed
6833 Most probably you B<do> have the old version installed. This can
6834 happen if a module installs itself into a different directory in the
6835 @INC path than it was previously installed. This is not really a
6836 CPAN.pm problem, you would have the same problem when installing the
6837 module manually. The easiest way to prevent this behaviour is to add
6838 the argument C<UNINST=1> to the C<make install> call, and that is why
6839 many people add this argument permanently by configuring
6841 o conf make_install_arg UNINST=1
6845 So why is UNINST=1 not the default?
6847 Because there are people who have their precise expectations about who
6848 may install where in the @INC path and who uses which @INC array. In
6849 fine tuned environments C<UNINST=1> can cause damage.
6853 I want to clean up my mess, and install a new perl along with
6854 all modules I have. How do I go about it?
6856 Run the autobundle command for your old perl and optionally rename the
6857 resulting bundle file (e.g. Bundle/mybundle.pm), install the new perl
6858 with the Configure option prefix, e.g.
6860 ./Configure -Dprefix=/usr/local/perl-5.6.78.9
6862 Install the bundle file you produced in the first step with something like
6864 cpan> install Bundle::mybundle
6870 When I install bundles or multiple modules with one command
6871 there is too much output to keep track of.
6873 You may want to configure something like
6875 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
6876 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
6878 so that STDOUT is captured in a file for later inspection.
6883 I am not root, how can I install a module in a personal directory?
6885 You will most probably like something like this:
6887 o conf makepl_arg "LIB=~/myperl/lib \
6888 INSTALLMAN1DIR=~/myperl/man/man1 \
6889 INSTALLMAN3DIR=~/myperl/man/man3"
6890 install Sybase::Sybperl
6892 You can make this setting permanent like all C<o conf> settings with
6895 You will have to add ~/myperl/man to the MANPATH environment variable
6896 and also tell your perl programs to look into ~/myperl/lib, e.g. by
6899 use lib "$ENV{HOME}/myperl/lib";
6901 or setting the PERL5LIB environment variable.
6903 Another thing you should bear in mind is that the UNINST parameter
6904 should never be set if you are not root.
6908 How to get a package, unwrap it, and make a change before building it?
6910 look Sybase::Sybperl
6914 I installed a Bundle and had a couple of fails. When I
6915 retried, everything resolved nicely. Can this be fixed to work
6918 The reason for this is that CPAN does not know the dependencies of all
6919 modules when it starts out. To decide about the additional items to
6920 install, it just uses data found in the generated Makefile. An
6921 undetected missing piece breaks the process. But it may well be that
6922 your Bundle installs some prerequisite later than some depending item
6923 and thus your second try is able to resolve everything. Please note,
6924 CPAN.pm does not know the dependency tree in advance and cannot sort
6925 the queue of things to install in a topologically correct order. It
6926 resolves perfectly well IFF all modules declare the prerequisites
6927 correctly with the PREREQ_PM attribute to MakeMaker. For bundles which
6928 fail and you need to install often, it is recommended sort the Bundle
6929 definition file manually. It is planned to improve the metadata
6930 situation for dependencies on CPAN in general, but this will still
6935 In our intranet we have many modules for internal use. How
6936 can I integrate these modules with CPAN.pm but without uploading
6937 the modules to CPAN?
6939 Have a look at the CPAN::Site module.
6943 When I run CPAN's shell, I get error msg about line 1 to 4,
6944 setting meta input/output via the /etc/inputrc file.
6946 Some versions of readline are picky about capitalization in the
6947 /etc/inputrc file and specifically RedHat 6.2 comes with a
6948 /etc/inputrc that contains the word C<on> in lowercase. Change the
6949 occurrences of C<on> to C<On> and the bug should disappear.
6953 Some authors have strange characters in their names.
6955 Internally CPAN.pm uses the UTF-8 charset. If your terminal is
6956 expecting ISO-8859-1 charset, a converter can be activated by setting
6957 term_is_latin to a true value in your config file. One way of doing so
6960 cpan> ! $CPAN::Config->{term_is_latin}=1
6962 Extended support for converters will be made available as soon as perl
6963 becomes stable with regard to charset issues.
6969 We should give coverage for B<all> of the CPAN and not just the PAUSE
6970 part, right? In this discussion CPAN and PAUSE have become equal --
6971 but they are not. PAUSE is authors/, modules/ and scripts/. CPAN is
6972 PAUSE plus the clpa/, doc/, misc/, ports/, and src/.
6974 Future development should be directed towards a better integration of
6977 If a Makefile.PL requires special customization of libraries, prompts
6978 the user for special input, etc. then you may find CPAN is not able to
6979 build the distribution. In that case, you should attempt the
6980 traditional method of building a Perl module package from a shell.
6984 Andreas Koenig E<lt>andreas.koenig@anima.deE<gt>
6988 Kawai,Takanori provides a Japanese translation of this manpage at
6989 http://member.nifty.ne.jp/hippo2000/perltips/CPAN.htm
6993 perl(1), CPAN::Nox(3)