1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
3 use vars qw{$Try_autoload
5 $META $Signal $Cwd $End
12 # $Id: CPAN.pm,v 1.324 2000/09/01 12:04:57 k Exp $
14 # only used during development:
16 # $Revision = "[".substr(q$Revision: 1.324 $, 10)."]";
23 use ExtUtils::MakeMaker (); # $SelfLoader::DEBUG=1;
24 use File::Basename ();
30 use Text::ParseWords ();
33 no lib "."; # we need to run chdir all over and we would get at wrong
36 END { $End++; &cleanup; }
58 $CPAN::Frontend ||= "CPAN::Shell";
59 $CPAN::Defaultsite ||= "ftp://ftp.perl.org/pub/CPAN";
62 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $HAS_USABLE $term);
65 @CPAN::ISA = qw(CPAN::Debug Exporter);
68 autobundle bundle expand force get cvs_import
69 install make readme recompile shell test clean
72 #-> sub CPAN::AUTOLOAD ;
77 @EXPORT{@EXPORT} = '';
78 CPAN::Config->load unless $CPAN::Config_loaded++;
79 if (exists $EXPORT{$l}){
82 my $ok = CPAN::Shell->try_dot_al($AUTOLOAD);
86 # $CPAN::Frontend->mywarn("Could not autoload $AUTOLOAD");
88 $CPAN::Frontend->mywarn(qq{Unknown command "$AUTOLOAD". }.
97 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
98 CPAN::Config->load unless $CPAN::Config_loaded++;
100 CPAN::Index->read_metadata_cache;
102 my $prompt = "cpan> ";
104 unless ($Suppress_readline) {
105 require Term::ReadLine;
106 # import Term::ReadLine;
107 $term = Term::ReadLine->new('CPAN Monitor');
108 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
109 my $attribs = $term->Attribs;
110 # $attribs->{completion_entry_function} =
111 # $attribs->{'list_completion_function'};
112 $attribs->{attempted_completion_function} = sub {
113 &CPAN::Complete::gnu_cpl;
115 # $attribs->{completion_word} =
116 # [qw(help me somebody to find out how
117 # to use completion with GNU)];
119 $readline::rl_completion_function =
120 $readline::rl_completion_function = 'CPAN::Complete::cpl';
122 # $term->OUT is autoflushed anyway
123 my $odef = select STDERR;
133 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
134 my $cwd = CPAN->$getcwd();
135 my $try_detect_readline;
136 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
137 my $rl_avail = $Suppress_readline ? "suppressed" :
138 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
139 "available (try 'install Bundle::CPAN')";
141 $CPAN::Frontend->myprint(
143 cpan shell -- CPAN exploration and modules installation (v$CPAN::VERSION$CPAN::Revision)
144 ReadLine support $rl_avail
146 }) unless $CPAN::Config->{'inhibit_startup_message'} ;
147 my($continuation) = "";
149 if ($Suppress_readline) {
151 last unless defined ($_ = <> );
154 last unless defined ($_ = $term->readline($prompt));
156 $_ = "$continuation$_" if $continuation;
159 $_ = 'h' if /^\s*\?/;
160 if (/^(?:q(?:uit)?|bye|exit)$/i) {
170 use vars qw($import_done);
171 CPAN->import(':DEFAULT') unless $import_done++;
172 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
179 if ($] < 5.00322) { # parsewords had a bug until recently
182 eval { @line = Text::ParseWords::shellwords($_) };
183 warn($@), next if $@;
185 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
186 my $command = shift @line;
187 eval { CPAN::Shell->$command(@line) };
189 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
190 $CPAN::Frontend->myprint("\n");
196 CPAN::Queue->nullify_queue;
197 if ($try_detect_readline) {
198 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
200 $CPAN::META->has_inst("Term::ReadLine::Perl")
202 delete $INC{"Term/ReadLine.pm"};
204 local($SIG{__WARN__}) = CPAN::Shell::dotdot_onreload(\$redef);
205 require Term::ReadLine;
206 $CPAN::Frontend->myprint("\n$redef subroutines in ".
207 "Term::ReadLine redefined\n");
214 package CPAN::CacheMgr;
215 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
218 package CPAN::Config;
219 use vars qw(%can $dot_cpan);
222 'commit' => "Commit changes to disk",
223 'defaults' => "Reload defaults from disk",
224 'init' => "Interactive setting of all options",
228 use vars qw($Ua $Thesite $Themethod);
229 @CPAN::FTP::ISA = qw(CPAN::Debug);
231 package CPAN::Complete;
232 @CPAN::Complete::ISA = qw(CPAN::Debug);
235 use vars qw($last_time $date_of_03);
236 @CPAN::Index::ISA = qw(CPAN::Debug);
240 package CPAN::InfoObj;
241 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
243 package CPAN::Author;
244 @CPAN::Author::ISA = qw(CPAN::InfoObj);
246 package CPAN::Distribution;
247 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
249 package CPAN::Bundle;
250 @CPAN::Bundle::ISA = qw(CPAN::Module);
252 package CPAN::Module;
253 @CPAN::Module::ISA = qw(CPAN::InfoObj);
256 use vars qw($AUTOLOAD $redef @ISA);
257 @CPAN::Shell::ISA = qw(CPAN::Debug);
259 #-> sub CPAN::Shell::AUTOLOAD ;
261 my($autoload) = $AUTOLOAD;
262 my $class = shift(@_);
263 # warn "autoload[$autoload] class[$class]";
264 $autoload =~ s/.*:://;
265 if ($autoload =~ /^w/) {
266 if ($CPAN::META->has_inst('CPAN::WAIT')) {
267 CPAN::WAIT->$autoload(@_);
269 $CPAN::Frontend->mywarn(qq{
270 Commands starting with "w" require CPAN::WAIT to be installed.
271 Please consider installing CPAN::WAIT to use the fulltext index.
272 For this you just need to type
277 my $ok = CPAN::Shell->try_dot_al($AUTOLOAD);
281 # $CPAN::Frontend->mywarn("Could not autoload $autoload");
283 $CPAN::Frontend->mywarn(qq{Unknown command '$autoload'. }.
289 #-> CPAN::Shell::try_dot_al
291 my($class,$autoload) = @_;
292 return unless $CPAN::Try_autoload;
293 # I don't see how to re-use that from the AutoLoader...
295 # Braces used to preserve $1 et al.
297 my ($pkg,$func) = $autoload =~ /(.*)::([^:]+)$/;
299 if (defined($name=$INC{"$pkg.pm"}))
301 $name =~ s|^(.*)$pkg\.pm(?!\n)\Z|$1auto/$pkg/$func.al|s;
302 $name = undef unless (-r $name);
304 unless (defined $name)
306 $name = "auto/$autoload.al";
311 eval {local $SIG{__DIE__};require $name};
313 if (substr($autoload,-9) eq '::DESTROY') {
317 if ($name =~ s{(\w{12,})\.al(?!\n)\Z}{substr($1,0,11).".al"}e){
318 eval {local $SIG{__DIE__};require $name};
333 # my $lm = Carp::longmess();
334 # warn "ok[$ok] autoload[$autoload] longmess[$lm]"; # debug
338 #### autoloader is experimental
339 #### to try it we have to set $Try_autoload and uncomment
340 #### the use statement and uncomment the __END__ below
341 #### You also need AutoSplit 1.01 available. MakeMaker will
342 #### then build CPAN with all the AutoLoad stuff.
346 if ($CPAN::Try_autoload) {
349 CPAN::Author CPAN::Bundle CPAN::CacheMgr CPAN::Complete
350 CPAN::Config CPAN::Debug CPAN::Distribution CPAN::FTP
351 CPAN::FTP::netrc CPAN::Index CPAN::InfoObj CPAN::Module
353 *{"$p\::AUTOLOAD"} = \&AutoLoader::AUTOLOAD;
357 package CPAN::Tarzip;
358 use vars qw($AUTOLOAD @ISA);
359 @CPAN::Tarzip::ISA = qw(CPAN::Debug);
363 # One use of the queue is to determine if we should or shouldn't
364 # announce the availability of a new CPAN module
366 # Now we try to use it for dependency tracking. For that to happen
367 # we need to draw a dependency tree and do the leaves first. This can
368 # easily be reached by running CPAN.pm recursively, but we don't want
369 # to waste memory and run into deep recursion. So what we can do is
372 # CPAN::Queue is the package where the queue is maintained. Dependencies
373 # often have high priority and must be brought to the head of the queue,
374 # possibly by jumping the queue if they are already there. My first code
375 # attempt tried to be extremely correct. Whenever a module needed
376 # immediate treatment, I either unshifted it to the front of the queue,
377 # or, if it was already in the queue, I spliced and let it bypass the
378 # others. This became a too correct model that made it impossible to put
379 # an item more than once into the queue. Why would you need that? Well,
380 # you need temporary duplicates as the manager of the queue is a loop
383 # (1) looks at the first item in the queue without shifting it off
385 # (2) cares for the item
387 # (3) removes the item from the queue, *even if its agenda failed and
388 # even if the item isn't the first in the queue anymore* (that way
389 # protecting against never ending queues)
391 # So if an item has prerequisites, the installation fails now, but we
392 # want to retry later. That's easy if we have it twice in the queue.
394 # I also expect insane dependency situations where an item gets more
395 # than two lives in the queue. Simplest example is triggered by 'install
396 # Foo Foo Foo'. People make this kind of mistakes and I don't want to
397 # get in the way. I wanted the queue manager to be a dumb servant, not
398 # one that knows everything.
400 # Who would I tell in this model that the user wants to be asked before
401 # processing? I can't attach that information to the module object,
402 # because not modules are installed but distributions. So I'd have to
403 # tell the distribution object that it should ask the user before
404 # processing. Where would the question be triggered then? Most probably
405 # in CPAN::Distribution::rematein.
406 # Hope that makes sense, my head is a bit off:-) -- AK
411 my($class,$mod) = @_;
412 my $self = bless {mod => $mod}, $class;
414 # my @all = map { $_->{mod} } @All;
415 # warn "Adding Queue object for mod[$mod] all[@all]";
425 my($class,$what) = @_;
427 for my $i (0..$#All) {
428 if ( $All[$i]->{mod} eq $what ) {
439 WHAT: for my $what (reverse @what) {
441 for (my $i=0; $i<$#All;$i++) { #prevent deep recursion
442 if ($All[$i]->{mod} eq $what){
444 if ($jumped > 100) { # one's OK if e.g. just processing now;
445 # more are OK if user typed it several
447 $CPAN::Frontend->mywarn(
448 qq{Object [$what] queued more than 100 times, ignoring}
454 my $obj = bless { mod => $what }, $class;
460 my($self,$what) = @_;
461 my @all = map { $_->{mod} } @All;
462 my $exists = grep { $_->{mod} eq $what } @All;
463 # warn "Checking exists in Queue object for mod[$what] all[@all] exists[$exists]";
469 @All = grep { $_->{mod} ne $mod } @All;
470 # my @all = map { $_->{mod} } @All;
471 # warn "Deleting Queue object for mod[$mod] all[@all]";
482 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
486 # __END__ # uncomment this and AutoSplit version 1.01 will split it
488 #-> sub CPAN::autobundle ;
490 #-> sub CPAN::bundle ;
492 #-> sub CPAN::expand ;
494 #-> sub CPAN::force ;
496 #-> sub CPAN::install ;
500 #-> sub CPAN::clean ;
507 my($mgr,$class) = @_;
508 CPAN::Config->load unless $CPAN::Config_loaded++;
509 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
511 values %{ $META->{$class} };
513 *all = \&all_objects;
515 # Called by shell, not in batch mode. In batch mode I see no risk in
516 # having many processes updating something as installations are
517 # continually checked at runtime. In shell mode I suspect it is
518 # unintentional to open more than one shell at a time
520 #-> sub CPAN::checklock ;
523 my $lockfile = MM->catfile($CPAN::Config->{cpan_home},".lock");
524 if (-f $lockfile && -M _ > 0) {
525 my $fh = FileHandle->new($lockfile);
528 if (defined $other && $other) {
530 return if $$==$other; # should never happen
531 $CPAN::Frontend->mywarn(
533 There seems to be running another CPAN process ($other). Contacting...
535 if (kill 0, $other) {
536 $CPAN::Frontend->mydie(qq{Other job is running.
537 You may want to kill it and delete the lockfile, maybe. On UNIX try:
541 } elsif (-w $lockfile) {
543 ExtUtils::MakeMaker::prompt
544 (qq{Other job not responding. Shall I overwrite }.
545 qq{the lockfile? (Y/N)},"y");
546 $CPAN::Frontend->myexit("Ok, bye\n")
547 unless $ans =~ /^y/i;
550 qq{Lockfile $lockfile not writeable by you. }.
551 qq{Cannot proceed.\n}.
554 qq{ and then rerun us.\n}
559 my $dotcpan = $CPAN::Config->{cpan_home};
560 eval { File::Path::mkpath($dotcpan);};
562 # A special case at least for Jarkko.
567 $symlinkcpan = readlink $dotcpan;
568 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
569 eval { File::Path::mkpath($symlinkcpan); };
573 $CPAN::Frontend->mywarn(qq{
574 Working directory $symlinkcpan created.
578 unless (-d $dotcpan) {
580 Your configuration suggests "$dotcpan" as your
581 CPAN.pm working directory. I could not create this directory due
582 to this error: $firsterror\n};
584 As "$dotcpan" is a symlink to "$symlinkcpan",
585 I tried to create that, but I failed with this error: $seconderror
588 Please make sure the directory exists and is writable.
590 $CPAN::Frontend->mydie($diemess);
594 unless ($fh = FileHandle->new(">$lockfile")) {
595 if ($! =~ /Permission/) {
596 my $incc = $INC{'CPAN/Config.pm'};
597 my $myincc = MM->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
598 $CPAN::Frontend->myprint(qq{
600 Your configuration suggests that CPAN.pm should use a working
602 $CPAN::Config->{cpan_home}
603 Unfortunately we could not create the lock file
605 due to permission problems.
607 Please make sure that the configuration variable
608 \$CPAN::Config->{cpan_home}
609 points to a directory where you can write a .lock file. You can set
610 this variable in either
617 $CPAN::Frontend->mydie("Could not open >$lockfile: $!");
619 $fh->print($$, "\n");
620 $self->{LOCK} = $lockfile;
624 $CPAN::Frontend->mydie("Got SIGTERM, leaving");
629 $CPAN::Frontend->mydie("Got another SIGINT") if $Signal;
630 print "Caught SIGINT\n";
634 # From: Larry Wall <larry@wall.org>
635 # Subject: Re: deprecating SIGDIE
636 # To: perl5-porters@perl.org
637 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
639 # The original intent of __DIE__ was only to allow you to substitute one
640 # kind of death for another on an application-wide basis without respect
641 # to whether you were in an eval or not. As a global backstop, it should
642 # not be used any more lightly (or any more heavily :-) than class
643 # UNIVERSAL. Any attempt to build a general exception model on it should
644 # be politely squashed. Any bug that causes every eval {} to have to be
645 # modified should be not so politely squashed.
647 # Those are my current opinions. It is also my optinion that polite
648 # arguments degenerate to personal arguments far too frequently, and that
649 # when they do, it's because both people wanted it to, or at least didn't
650 # sufficiently want it not to.
654 $SIG{'__DIE__'} = \&cleanup;
655 $self->debug("Signal handler set.") if $CPAN::DEBUG;
658 #-> sub CPAN::DESTROY ;
660 &cleanup; # need an eval?
664 sub cwd {Cwd::cwd();}
666 #-> sub CPAN::getcwd ;
667 sub getcwd {Cwd::getcwd();}
669 #-> sub CPAN::exists ;
671 my($mgr,$class,$id) = @_;
673 ### Carp::croak "exists called without class argument" unless $class;
675 exists $META->{$class}{$id};
678 #-> sub CPAN::delete ;
680 my($mgr,$class,$id) = @_;
681 delete $META->{$class}{$id};
684 #-> sub CPAN::has_usable
685 # has_inst is sometimes too optimistic, we should replace it with this
686 # has_usable whenever a case is given
688 my($self,$mod,$message) = @_;
689 return 1 if $HAS_USABLE->{$mod};
690 my $has_inst = $self->has_inst($mod,$message);
691 return unless $has_inst;
694 LWP => [ # we frequently had "Can't locate object
695 # method "new" via package
696 # "LWP::UserAgent" at (eval 69) line
699 sub {require LWP::UserAgent},
700 sub {require HTTP::Request},
701 sub {require URI::URL},
704 sub {require Net::FTP},
705 sub {require Net::Config},
708 if ($capabilities->{$mod}) {
709 for my $c (0..$#{$capabilities->{$mod}}) {
710 my $code = $capabilities->{$mod}[$c];
711 my $ret = eval { &$code() };
713 warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
718 return $HAS_USABLE->{$mod} = 1;
721 #-> sub CPAN::has_inst
723 my($self,$mod,$message) = @_;
724 Carp::croak("CPAN->has_inst() called without an argument")
726 if (defined $message && $message eq "no"
728 exists $CPAN::META->{dontload_hash}{$mod}
730 exists $CPAN::Config->{dontload_hash}{$mod}
732 $CPAN::META->{dontload_hash}{$mod}||=1;
738 $file =~ s|/|\\|g if $^O eq 'MSWin32';
741 # checking %INC is wrong, because $INC{LWP} may be true
742 # although $INC{"URI/URL.pm"} may have failed. But as
743 # I really want to say "bla loaded OK", I have to somehow
745 ### warn "$file in %INC"; #debug
747 } elsif (eval { require $file }) {
748 # eval is good: if we haven't yet read the database it's
749 # perfect and if we have installed the module in the meantime,
750 # it tries again. The second require is only a NOOP returning
751 # 1 if we had success, otherwise it's retrying
753 $CPAN::Frontend->myprint("CPAN: $mod loaded ok\n");
754 if ($mod eq "CPAN::WAIT") {
755 push @CPAN::Shell::ISA, CPAN::WAIT;
758 } elsif ($mod eq "Net::FTP") {
760 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
762 install Bundle::libnet
766 } elsif ($mod eq "MD5"){
767 $CPAN::Frontend->myprint(qq{
768 CPAN: MD5 security checks disabled because MD5 not installed.
769 Please consider installing the MD5 module.
774 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
779 #-> sub CPAN::instance ;
781 my($mgr,$class,$id) = @_;
784 $META->{$class}{$id} ||= $class->new(ID => $id );
792 #-> sub CPAN::cleanup ;
794 # warn "cleanup called with arg[@_] End[$End] Signal[$Signal]";
795 local $SIG{__DIE__} = '';
800 0 && # disabled, try reload cpan with it
801 $] > 5.004_60 # thereabouts
806 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
808 $subroutine eq '(eval)';
811 return if $ineval && !$End;
812 return unless defined $META->{'LOCK'};
813 return unless -f $META->{'LOCK'};
814 unlink $META->{'LOCK'};
816 # Carp::cluck("DEBUGGING");
817 $CPAN::Frontend->mywarn("Lockfile removed.\n");
820 package CPAN::CacheMgr;
822 #-> sub CPAN::CacheMgr::as_string ;
824 eval { require Data::Dumper };
826 return shift->SUPER::as_string;
828 return Data::Dumper::Dumper(shift);
832 #-> sub CPAN::CacheMgr::cachesize ;
837 #-> sub CPAN::CacheMgr::tidyup ;
840 return unless -d $self->{ID};
841 while ($self->{DU} > $self->{'MAX'} ) {
842 my($toremove) = shift @{$self->{FIFO}};
843 $CPAN::Frontend->myprint(sprintf(
844 "Deleting from cache".
845 ": $toremove (%.1f>%.1f MB)\n",
846 $self->{DU}, $self->{'MAX'})
848 return if $CPAN::Signal;
849 $self->force_clean_cache($toremove);
850 return if $CPAN::Signal;
854 #-> sub CPAN::CacheMgr::dir ;
859 #-> sub CPAN::CacheMgr::entries ;
862 return unless defined $dir;
863 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
864 $dir ||= $self->{ID};
866 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
867 my($cwd) = CPAN->$getcwd();
868 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
869 my $dh = DirHandle->new(File::Spec->curdir)
870 or Carp::croak("Couldn't opendir $dir: $!");
873 next if $_ eq "." || $_ eq "..";
875 push @entries, MM->catfile($dir,$_);
877 push @entries, MM->catdir($dir,$_);
879 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
882 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
883 sort { -M $b <=> -M $a} @entries;
886 #-> sub CPAN::CacheMgr::disk_usage ;
889 return if exists $self->{SIZE}{$dir};
890 return if $CPAN::Signal;
894 $File::Find::prune++ if $CPAN::Signal;
896 if ($^O eq 'MacOS') {
898 my $cat = Mac::Files::FSpGetCatInfo($_);
899 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
906 return if $CPAN::Signal;
907 $self->{SIZE}{$dir} = $Du/1024/1024;
908 push @{$self->{FIFO}}, $dir;
909 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
910 $self->{DU} += $Du/1024/1024;
914 #-> sub CPAN::CacheMgr::force_clean_cache ;
915 sub force_clean_cache {
917 return unless -e $dir;
918 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
920 File::Path::rmtree($dir);
921 $self->{DU} -= $self->{SIZE}{$dir};
922 delete $self->{SIZE}{$dir};
925 #-> sub CPAN::CacheMgr::new ;
932 ID => $CPAN::Config->{'build_dir'},
933 MAX => $CPAN::Config->{'build_cache'},
934 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
937 File::Path::mkpath($self->{ID});
938 my $dh = DirHandle->new($self->{ID});
942 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
944 CPAN->debug($debug) if $CPAN::DEBUG;
948 #-> sub CPAN::CacheMgr::scan_cache ;
951 return if $self->{SCAN} eq 'never';
952 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
953 unless $self->{SCAN} eq 'atstart';
954 $CPAN::Frontend->myprint(
955 sprintf("Scanning cache %s for sizes\n",
958 for $e ($self->entries($self->{ID})) {
959 next if $e eq ".." || $e eq ".";
960 $self->disk_usage($e);
961 return if $CPAN::Signal;
968 #-> sub CPAN::Debug::debug ;
971 my($caller,$func,$line,@rest) = caller(1); # caller(0) eg
972 # Complete, caller(1)
974 ($caller) = caller(0);
976 $arg = "" unless defined $arg;
977 my $rest = join "|", map { defined $_ ? $_ : "UNDEF" } @rest;
978 if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
979 if ($arg and ref $arg) {
980 eval { require Data::Dumper };
982 $CPAN::Frontend->myprint($arg->as_string);
984 $CPAN::Frontend->myprint(Data::Dumper::Dumper($arg));
987 $CPAN::Frontend->myprint("Debug($caller:$func,$line,[$rest]): $arg\n");
992 package CPAN::Config;
994 #-> sub CPAN::Config::edit ;
995 # returns true on successful action
997 my($self,@args) = @_;
999 CPAN->debug("self[$self]args[".join(" | ",@args)."]");
1000 my($o,$str,$func,$args,$key_exists);
1006 CPAN->debug("o[$o]") if $CPAN::DEBUG;
1007 if ($o =~ /list$/) {
1008 $func = shift @args;
1010 CPAN->debug("func[$func]") if $CPAN::DEBUG;
1012 # Let's avoid eval, it's easier to comprehend without.
1013 if ($func eq "push") {
1014 push @{$CPAN::Config->{$o}}, @args;
1016 } elsif ($func eq "pop") {
1017 pop @{$CPAN::Config->{$o}};
1019 } elsif ($func eq "shift") {
1020 shift @{$CPAN::Config->{$o}};
1022 } elsif ($func eq "unshift") {
1023 unshift @{$CPAN::Config->{$o}}, @args;
1025 } elsif ($func eq "splice") {
1026 splice @{$CPAN::Config->{$o}}, @args;
1029 $CPAN::Config->{$o} = [@args];
1032 $self->prettyprint($o);
1034 if ($o eq "urllist" && $changed) {
1035 # reset the cached values
1036 undef $CPAN::FTP::Thesite;
1037 undef $CPAN::FTP::Themethod;
1041 $CPAN::Config->{$o} = $args[0] if defined $args[0];
1042 $self->prettyprint($o);
1049 my $v = $CPAN::Config->{$k};
1051 my(@report) = ref $v eq "ARRAY" ?
1053 map { sprintf(" %-18s => %s\n",
1055 defined $v->{$_} ? $v->{$_} : "UNDEFINED"
1057 $CPAN::Frontend->myprint(
1064 map {"\t$_\n"} @report
1067 } elsif (defined $v) {
1068 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1070 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, "UNDEFINED");
1074 #-> sub CPAN::Config::commit ;
1076 my($self,$configpm) = @_;
1077 unless (defined $configpm){
1078 $configpm ||= $INC{"CPAN/MyConfig.pm"};
1079 $configpm ||= $INC{"CPAN/Config.pm"};
1080 $configpm || Carp::confess(q{
1081 CPAN::Config::commit called without an argument.
1082 Please specify a filename where to save the configuration or try
1083 "o conf init" to have an interactive course through configing.
1088 $mode = (stat $configpm)[2];
1089 if ($mode && ! -w _) {
1090 Carp::confess("$configpm is not writable");
1095 $msg = <<EOF unless $configpm =~ /MyConfig/;
1097 # This is CPAN.pm's systemwide configuration file. This file provides
1098 # defaults for users, and the values can be changed in a per-user
1099 # configuration file. The user-config file is being looked for as
1100 # ~/.cpan/CPAN/MyConfig.pm.
1104 my($fh) = FileHandle->new;
1105 rename $configpm, "$configpm~" if -f $configpm;
1106 open $fh, ">$configpm" or warn "Couldn't open >$configpm: $!";
1107 $fh->print(qq[$msg\$CPAN::Config = \{\n]);
1108 foreach (sort keys %$CPAN::Config) {
1111 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}),
1116 $fh->print("};\n1;\n__END__\n");
1119 #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
1120 #chmod $mode, $configpm;
1121 ###why was that so? $self->defaults;
1122 $CPAN::Frontend->myprint("commit: wrote $configpm\n");
1126 *default = \&defaults;
1127 #-> sub CPAN::Config::defaults ;
1137 undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
1146 #-> sub CPAN::Config::load ;
1151 eval {require CPAN::Config;}; # We eval because of some
1152 # MakeMaker problems
1153 unless ($dot_cpan++){
1154 unshift @INC, MM->catdir($ENV{HOME},".cpan");
1155 eval {require CPAN::MyConfig;}; # where you can override
1156 # system wide settings
1159 return unless @miss = $self->missing_config_data;
1161 require CPAN::FirstTime;
1162 my($configpm,$fh,$redo,$theycalled);
1164 $theycalled++ if @miss==1 && $miss[0] eq 'inhibit_startup_message';
1165 if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
1166 $configpm = $INC{"CPAN/Config.pm"};
1168 } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
1169 $configpm = $INC{"CPAN/MyConfig.pm"};
1172 my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
1173 my($configpmdir) = MM->catdir($path_to_cpan,"CPAN");
1174 my($configpmtest) = MM->catfile($configpmdir,"Config.pm");
1175 if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
1176 if (-w $configpmtest) {
1177 $configpm = $configpmtest;
1178 } elsif (-w $configpmdir) {
1179 #_#_# following code dumped core on me with 5.003_11, a.k.
1180 unlink "$configpmtest.bak" if -f "$configpmtest.bak";
1181 rename $configpmtest, "$configpmtest.bak" if -f $configpmtest;
1182 my $fh = FileHandle->new;
1183 if ($fh->open(">$configpmtest")) {
1185 $configpm = $configpmtest;
1187 # Should never happen
1188 Carp::confess("Cannot open >$configpmtest");
1192 unless ($configpm) {
1193 $configpmdir = MM->catdir($ENV{HOME},".cpan","CPAN");
1194 File::Path::mkpath($configpmdir);
1195 $configpmtest = MM->catfile($configpmdir,"MyConfig.pm");
1196 if (-w $configpmtest) {
1197 $configpm = $configpmtest;
1198 } elsif (-w $configpmdir) {
1199 #_#_# following code dumped core on me with 5.003_11, a.k.
1200 my $fh = FileHandle->new;
1201 if ($fh->open(">$configpmtest")) {
1203 $configpm = $configpmtest;
1205 # Should never happen
1206 Carp::confess("Cannot open >$configpmtest");
1209 Carp::confess(qq{WARNING: CPAN.pm is unable to }.
1210 qq{create a configuration file.});
1215 $CPAN::Frontend->myprint(<<END) if $redo && ! $theycalled;
1216 We have to reconfigure CPAN.pm due to following uninitialized parameters:
1220 $CPAN::Frontend->myprint(qq{
1221 $configpm initialized.
1224 CPAN::FirstTime::init($configpm);
1227 #-> sub CPAN::Config::missing_config_data ;
1228 sub missing_config_data {
1231 "cpan_home", "keep_source_where", "build_dir", "build_cache",
1232 "scan_cache", "index_expire", "gzip", "tar", "unzip", "make", "pager",
1233 "makepl_arg", "make_arg", "make_install_arg", "urllist",
1234 "inhibit_startup_message", "ftp_proxy", "http_proxy", "no_proxy",
1235 "prerequisites_policy",
1237 # "cache_metadata" # not yet stable enough
1240 push @miss, $_ unless defined $CPAN::Config->{$_};
1245 #-> sub CPAN::Config::unload ;
1247 delete $INC{'CPAN/MyConfig.pm'};
1248 delete $INC{'CPAN/Config.pm'};
1251 #-> sub CPAN::Config::help ;
1253 $CPAN::Frontend->myprint(q[
1255 defaults reload default config values from disk
1256 commit commit session changes to disk
1257 init go through a dialog to set all parameters
1259 You may edit key values in the follow fashion (the "o" is a literal
1262 o conf build_cache 15
1264 o conf build_dir "/foo/bar"
1266 o conf urllist shift
1268 o conf urllist unshift ftp://ftp.foo.bar/
1271 undef; #don't reprint CPAN::Config
1274 #-> sub CPAN::Config::cpl ;
1276 my($word,$line,$pos) = @_;
1278 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1279 my(@words) = split " ", substr($line,0,$pos+1);
1284 $words[2] =~ /list$/ && @words == 3
1286 $words[2] =~ /list$/ && @words == 4 && length($word)
1289 return grep /^\Q$word\E/, qw(splice shift unshift pop push);
1290 } elsif (@words >= 4) {
1293 my(@o_conf) = (keys %CPAN::Config::can, keys %$CPAN::Config);
1294 return grep /^\Q$word\E/, @o_conf;
1297 package CPAN::Shell;
1299 #-> sub CPAN::Shell::h ;
1301 my($class,$about) = @_;
1302 if (defined $about) {
1303 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
1305 $CPAN::Frontend->myprint(q{
1308 b string display bundles
1309 d or info distributions
1310 m /regex/ about modules
1311 i or anything of above
1312 r none reinstall recommendations
1313 u uninstalled distributions
1315 Download, Test, Make, Install...
1317 make make (implies get)
1318 test modules, make test (implies make)
1319 install dists, bundles make install (implies test)
1321 look open subshell in these dists' directories
1322 readme display these dists' README files
1325 h,? display this menu ! perl-code eval a perl command
1326 o conf [opt] set and query options q quit the cpan shell
1327 reload cpan load CPAN.pm again reload index load newer indices
1328 autobundle Snapshot force cmd unconditionally do cmd});
1334 #-> sub CPAN::Shell::a ;
1336 my($self,@arg) = @_;
1337 # authors are always UPPERCASE
1341 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1343 #-> sub CPAN::Shell::b ;
1345 my($self,@which) = @_;
1346 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1347 my($incdir,$bdir,$dh);
1348 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1349 $bdir = MM->catdir($incdir,"Bundle");
1350 if ($dh = DirHandle->new($bdir)) { # may fail
1352 for $entry ($dh->read) {
1353 next if -d MM->catdir($bdir,$entry);
1354 next unless $entry =~ s/\.pm(?!\n)\Z//;
1355 $CPAN::META->instance('CPAN::Bundle',"Bundle::$entry");
1359 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1361 #-> sub CPAN::Shell::d ;
1362 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1363 #-> sub CPAN::Shell::m ;
1364 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
1365 $CPAN::Frontend->myprint(shift->format_result('Module',@_));
1368 #-> sub CPAN::Shell::i ;
1373 @type = qw/Author Bundle Distribution Module/;
1374 @args = '/./' unless @args;
1377 push @result, $self->expand($type,@args);
1379 my $result = @result == 1 ?
1380 $result[0]->as_string :
1381 join "", map {$_->as_glimpse} @result;
1382 $result ||= "No objects found of any type for argument @args\n";
1383 $CPAN::Frontend->myprint($result);
1386 #-> sub CPAN::Shell::o ;
1388 # CPAN::Shell::o and CPAN::Config::edit are closely related. I suspect
1389 # some code duplication
1391 my($self,$o_type,@o_what) = @_;
1393 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1394 if ($o_type eq 'conf') {
1395 shift @o_what if @o_what && $o_what[0] eq 'help';
1396 if (!@o_what) { # print all things, "o conf"
1398 $CPAN::Frontend->myprint("CPAN::Config options");
1399 if (exists $INC{'CPAN/Config.pm'}) {
1400 $CPAN::Frontend->myprint(" from $INC{'CPAN/Config.pm'}");
1402 if (exists $INC{'CPAN/MyConfig.pm'}) {
1403 $CPAN::Frontend->myprint(" and $INC{'CPAN/MyConfig.pm'}");
1405 $CPAN::Frontend->myprint(":\n");
1406 for $k (sort keys %CPAN::Config::can) {
1407 $v = $CPAN::Config::can{$k};
1408 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1410 $CPAN::Frontend->myprint("\n");
1411 for $k (sort keys %$CPAN::Config) {
1412 CPAN::Config->prettyprint($k);
1414 $CPAN::Frontend->myprint("\n");
1415 } elsif (!CPAN::Config->edit(@o_what)) {
1416 $CPAN::Frontend->myprint(qq[Type 'o conf' to view configuration edit options\n\n]);
1418 } elsif ($o_type eq 'debug') {
1420 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1423 my($what) = shift @o_what;
1424 if ( exists $CPAN::DEBUG{$what} ) {
1425 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1426 } elsif ($what =~ /^\d/) {
1427 $CPAN::DEBUG = $what;
1428 } elsif (lc $what eq 'all') {
1430 for (values %CPAN::DEBUG) {
1433 $CPAN::DEBUG = $max;
1436 for (keys %CPAN::DEBUG) {
1437 next unless lc($_) eq lc($what);
1438 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1441 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1446 my $raw = "Valid options for debug are ".
1447 join(", ",sort(keys %CPAN::DEBUG), 'all').
1448 qq{ or a number. Completion works on the options. }.
1449 qq{Case is ignored.};
1451 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
1452 $CPAN::Frontend->myprint("\n\n");
1455 $CPAN::Frontend->myprint("Options set for debugging:\n");
1457 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1458 $v = $CPAN::DEBUG{$k};
1459 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
1460 if $v & $CPAN::DEBUG;
1463 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1466 $CPAN::Frontend->myprint(qq{
1468 conf set or get configuration variables
1469 debug set or get debugging options
1474 sub dotdot_onreload {
1477 if ( $_[0] =~ /Subroutine (\w+) redefined/ ) {
1481 # $CPAN::Frontend->myprint(".($subr)");
1482 $CPAN::Frontend->myprint(".");
1489 #-> sub CPAN::Shell::reload ;
1491 my($self,$command,@arg) = @_;
1493 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1494 if ($command =~ /cpan/i) {
1495 CPAN->debug("reloading the whole CPAN.pm") if $CPAN::DEBUG;
1496 my $fh = FileHandle->new($INC{'CPAN.pm'});
1499 local($SIG{__WARN__}) = dotdot_onreload(\$redef);
1502 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1503 } elsif ($command =~ /index/) {
1504 CPAN::Index->force_reload;
1506 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN.pm file
1507 index re-reads the index files\n});
1511 #-> sub CPAN::Shell::_binary_extensions ;
1512 sub _binary_extensions {
1513 my($self) = shift @_;
1514 my(@result,$module,%seen,%need,$headerdone);
1515 for $module ($self->expand('Module','/./')) {
1516 my $file = $module->cpan_file;
1517 next if $file eq "N/A";
1518 next if $file =~ /^Contact Author/;
1519 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
1520 next if $dist->isa_perl;
1521 next unless $module->xs_file;
1523 $CPAN::Frontend->myprint(".");
1524 push @result, $module;
1526 # print join " | ", @result;
1527 $CPAN::Frontend->myprint("\n");
1531 #-> sub CPAN::Shell::recompile ;
1533 my($self) = shift @_;
1534 my($module,@module,$cpan_file,%dist);
1535 @module = $self->_binary_extensions();
1536 for $module (@module){ # we force now and compile later, so we
1538 $cpan_file = $module->cpan_file;
1539 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1541 $dist{$cpan_file}++;
1543 for $cpan_file (sort keys %dist) {
1544 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1545 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1547 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1548 # stop a package from recompiling,
1549 # e.g. IO-1.12 when we have perl5.003_10
1553 #-> sub CPAN::Shell::_u_r_common ;
1555 my($self) = shift @_;
1556 my($what) = shift @_;
1557 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1558 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
1559 $what && $what =~ /^[aru]$/;
1561 @args = '/./' unless @args;
1562 my(@result,$module,%seen,%need,$headerdone,
1563 $version_undefs,$version_zeroes);
1564 $version_undefs = $version_zeroes = 0;
1565 my $sprintf = "%-25s %9s %9s %s\n";
1566 for $module ($self->expand('Module',@args)) {
1567 my $file = $module->cpan_file;
1568 next unless defined $file; # ??
1569 my($latest) = $module->cpan_version; # %vd not needed
1570 my($inst_file) = $module->inst_file;
1572 return if $CPAN::Signal;
1575 $have = $module->inst_version; # %vd already applied
1576 } elsif ($what eq "r") {
1577 $have = $module->inst_version; # %vd already applied
1579 if ($have eq "undef"){
1581 } elsif ($have == 0){
1584 next unless CPAN::Version->vgt($latest, $have);
1585 # to be pedantic we should probably say:
1586 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1587 # to catch the case where CPAN has a version 0 and we have a version undef
1588 } elsif ($what eq "u") {
1594 } elsif ($what eq "r") {
1596 } elsif ($what eq "u") {
1600 return if $CPAN::Signal; # this is sometimes lengthy
1603 push @result, sprintf "%s %s\n", $module->id, $have;
1604 } elsif ($what eq "r") {
1605 push @result, $module->id;
1606 next if $seen{$file}++;
1607 } elsif ($what eq "u") {
1608 push @result, $module->id;
1609 next if $seen{$file}++;
1610 next if $file =~ /^Contact/;
1612 unless ($headerdone++){
1613 $CPAN::Frontend->myprint("\n");
1614 $CPAN::Frontend->myprint(sprintf(
1616 "Package namespace",
1622 $CPAN::Frontend->myprint(sprintf $sprintf,
1627 $need{$module->id}++;
1631 $CPAN::Frontend->myprint("No modules found for @args\n");
1632 } elsif ($what eq "r") {
1633 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1637 if ($version_zeroes) {
1638 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1639 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1640 qq{a version number of 0\n});
1642 if ($version_undefs) {
1643 my $s_has = $version_undefs > 1 ? "s have" : " has";
1644 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1645 qq{parseable version number\n});
1651 #-> sub CPAN::Shell::r ;
1653 shift->_u_r_common("r",@_);
1656 #-> sub CPAN::Shell::u ;
1658 shift->_u_r_common("u",@_);
1661 #-> sub CPAN::Shell::autobundle ;
1664 CPAN::Config->load unless $CPAN::Config_loaded++;
1665 my(@bundle) = $self->_u_r_common("a",@_);
1666 my($todir) = MM->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1667 File::Path::mkpath($todir);
1668 unless (-d $todir) {
1669 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
1672 my($y,$m,$d) = (localtime)[5,4,3];
1676 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1677 my($to) = MM->catfile($todir,"$me.pm");
1679 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1680 $to = MM->catfile($todir,"$me.pm");
1682 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1684 "package Bundle::$me;\n\n",
1685 "\$VERSION = '0.01';\n\n",
1689 "Bundle::$me - Snapshot of installation on ",
1690 $Config::Config{'myhostname'},
1693 "\n\n=head1 SYNOPSIS\n\n",
1694 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1695 "=head1 CONTENTS\n\n",
1696 join("\n", @bundle),
1697 "\n\n=head1 CONFIGURATION\n\n",
1699 "\n\n=head1 AUTHOR\n\n",
1700 "This Bundle has been generated automatically ",
1701 "by the autobundle routine in CPAN.pm.\n",
1704 $CPAN::Frontend->myprint("\nWrote bundle file
1708 #-> sub CPAN::Shell::expand ;
1711 my($type,@args) = @_;
1715 if ($arg =~ m|^/(.*)/$|) {
1718 my $class = "CPAN::$type";
1720 if (defined $regex) {
1724 $CPAN::META->all_objects($class)
1727 # BUG, we got an empty object somewhere
1728 CPAN->debug(sprintf(
1729 "Empty id on obj[%s]%%[%s]",
1736 if $obj->id =~ /$regex/i
1740 $] < 5.00303 ### provide sort of
1741 ### compatibility with 5.003
1746 $obj->name =~ /$regex/i
1751 if ( $type eq 'Bundle' ) {
1752 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
1754 if ($CPAN::META->exists($class,$xarg)) {
1755 $obj = $CPAN::META->instance($class,$xarg);
1756 } elsif ($CPAN::META->exists($class,$arg)) {
1757 $obj = $CPAN::META->instance($class,$arg);
1764 return wantarray ? @m : $m[0];
1767 #-> sub CPAN::Shell::format_result ;
1770 my($type,@args) = @_;
1771 @args = '/./' unless @args;
1772 my(@result) = $self->expand($type,@args);
1773 my $result = @result == 1 ?
1774 $result[0]->as_string :
1775 join "", map {$_->as_glimpse} @result;
1776 $result ||= "No objects of type $type found for argument @args\n";
1780 # The only reason for this method is currently to have a reliable
1781 # debugging utility that reveals which output is going through which
1782 # channel. No, I don't like the colors ;-)
1783 sub print_ornamented {
1784 my($self,$what,$ornament) = @_;
1786 my $ornamenting = 0; # turn the colors on
1789 unless (defined &color) {
1790 if ($CPAN::META->has_inst("Term::ANSIColor")) {
1791 import Term::ANSIColor "color";
1793 *color = sub { return "" };
1797 for $line (split /\n/, $what) {
1798 $longest = length($line) if length($line) > $longest;
1800 my $sprintf = "%-" . $longest . "s";
1802 $what =~ s/(.*\n?)//m;
1805 my($nl) = chomp $line ? "\n" : "";
1806 # print "line[$line]ornament[$ornament]sprintf[$sprintf]\n";
1807 print color($ornament), sprintf($sprintf,$line), color("reset"), $nl;
1815 my($self,$what) = @_;
1816 $self->print_ornamented($what, 'bold blue on_yellow');
1820 my($self,$what) = @_;
1821 $self->myprint($what);
1826 my($self,$what) = @_;
1827 $self->print_ornamented($what, 'bold red on_yellow');
1831 my($self,$what) = @_;
1832 $self->print_ornamented($what, 'bold red on_white');
1833 Carp::confess "died";
1837 my($self,$what) = @_;
1838 $self->print_ornamented($what, 'bold red on_white');
1843 return if -t STDOUT;
1844 my $odef = select STDERR;
1851 #-> sub CPAN::Shell::rematein ;
1852 # RE-adme||MA-ke||TE-st||IN-stall
1855 my($meth,@some) = @_;
1857 if ($meth eq 'force') {
1859 $meth = shift @some;
1862 CPAN->debug("pragma[$pragma]meth[$meth] some[@some]") if $CPAN::DEBUG;
1864 foreach $s (@some) {
1865 CPAN::Queue->new($s);
1867 while ($s = CPAN::Queue->first) {
1871 } elsif ($s =~ m|^/|) { # looks like a regexp
1872 $CPAN::Frontend->mydie("Sorry, $meth with a regular expression is not supported");
1873 } elsif ($s =~ m|/|) { # looks like a file
1874 $obj = $CPAN::META->instance('CPAN::Distribution',$s);
1875 } elsif ($s =~ m|^Bundle::|) {
1876 $obj = $CPAN::META->instance('CPAN::Bundle',$s);
1878 $obj = $CPAN::META->instance('CPAN::Module',$s)
1879 if $CPAN::META->exists('CPAN::Module',$s);
1884 ($] < 5.00303 || $obj->can($pragma))){
1885 ### compatibility with 5.003
1886 $obj->$pragma($meth); # the pragma "force" in
1887 # "CPAN::Distribution" must know
1888 # what we are intending
1890 if ($]>=5.00303 && $obj->can('called_for')) {
1891 $obj->called_for($s);
1894 qq{pragma[$pragma]meth[$meth]obj[$obj]as_string\[}.
1898 CPAN::Queue->delete($s) if $obj->$meth(); # if it is more
1901 } elsif ($CPAN::META->exists('CPAN::Author',$s)) {
1902 $obj = $CPAN::META->instance('CPAN::Author',$s);
1903 $CPAN::Frontend->myprint(
1905 "Don't be silly, you can't $meth ",
1911 ->myprint(qq{Warning: Cannot $meth $s, }.
1912 qq{don\'t know what it is.
1917 to find objects with similar identifiers.
1920 CPAN::Queue->delete_first($s);
1924 #-> sub CPAN::Shell::force ;
1925 sub force { shift->rematein('force',@_); }
1926 #-> sub CPAN::Shell::get ;
1927 sub get { shift->rematein('get',@_); }
1928 #-> sub CPAN::Shell::readme ;
1929 sub readme { shift->rematein('readme',@_); }
1930 #-> sub CPAN::Shell::make ;
1931 sub make { shift->rematein('make',@_); }
1932 #-> sub CPAN::Shell::test ;
1933 sub test { shift->rematein('test',@_); }
1934 #-> sub CPAN::Shell::install ;
1935 sub install { shift->rematein('install',@_); }
1936 #-> sub CPAN::Shell::clean ;
1937 sub clean { shift->rematein('clean',@_); }
1938 #-> sub CPAN::Shell::look ;
1939 sub look { shift->rematein('look',@_); }
1940 #-> sub CPAN::Shell::cvs_import ;
1941 sub cvs_import { shift->rematein('cvs_import',@_); }
1945 #-> sub CPAN::FTP::ftp_get ;
1947 my($class,$host,$dir,$file,$target) = @_;
1949 qq[Going to fetch file [$file] from dir [$dir]
1950 on host [$host] as local [$target]\n]
1952 my $ftp = Net::FTP->new($host);
1953 return 0 unless defined $ftp;
1954 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
1955 $class->debug(qq[Going to ->login("anonymous","$Config::Config{'cf_email'}")\n]);
1956 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
1957 warn "Couldn't login on $host";
1960 unless ( $ftp->cwd($dir) ){
1961 warn "Couldn't cwd $dir";
1965 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
1966 unless ( $ftp->get($file,$target) ){
1967 warn "Couldn't fetch $file from $host\n";
1970 $ftp->quit; # it's ok if this fails
1974 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
1976 # leach,> *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
1977 # leach,> --- /tmp/cp Wed Sep 24 13:26:40 1997
1978 # leach,> ***************
1979 # leach,> *** 1562,1567 ****
1980 # leach,> --- 1562,1580 ----
1981 # leach,> return 1 if substr($url,0,4) eq "file";
1982 # leach,> return 1 unless $url =~ m|://([^/]+)|;
1983 # leach,> my $host = $1;
1984 # leach,> + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
1985 # leach,> + if ($proxy) {
1986 # leach,> + $proxy =~ m|://([^/:]+)|;
1987 # leach,> + $proxy = $1;
1988 # leach,> + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
1989 # leach,> + if ($noproxy) {
1990 # leach,> + if ($host !~ /$noproxy$/) {
1991 # leach,> + $host = $proxy;
1993 # leach,> + } else {
1994 # leach,> + $host = $proxy;
1997 # leach,> require Net::Ping;
1998 # leach,> return 1 unless $Net::Ping::VERSION >= 2;
2002 # this is quite optimistic and returns one on several occasions where
2003 # inappropriate. But this does no harm. It would do harm if we were
2004 # too pessimistic (as I was before the http_proxy
2006 my($self,$url) = @_;
2007 return 1; # we can't simply roll our own, firewalls may break ping
2008 return 0 unless $url;
2009 return 1 if substr($url,0,4) eq "file";
2010 return 1 unless $url =~ m|^(\w+)://([^/]+)|;
2011 my $proxytype = $1 . "_proxy"; # ftp_proxy or http_proxy
2013 return 1 if $CPAN::Config->{$proxytype} || $ENV{$proxytype};
2015 return 1 unless $Net::Ping::VERSION >= 2;
2017 # 1.3101 had it different: only if the first eval raised an
2018 # exception we tried it with TCP. Now we are happy if icmp wins
2019 # the order and return, we don't even check for $@. Thanks to
2020 # thayer@uis.edu for the suggestion.
2021 eval {$p = Net::Ping->new("icmp");};
2022 return 1 if $p && ref($p) && $p->ping($host, 10);
2023 eval {$p = Net::Ping->new("tcp");};
2024 $CPAN::Frontend->mydie($@) if $@;
2025 return $p->ping($host, 10);
2028 #-> sub CPAN::FTP::localize ;
2030 my($self,$file,$aslocal,$force) = @_;
2032 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
2033 unless defined $aslocal;
2034 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
2037 if ($^O eq 'MacOS') {
2038 my($name, $path) = File::Basename::fileparse($aslocal, '');
2039 if (length($name) > 31) {
2040 $name =~ s/(\.(readme(\.(gz|Z))?|(tar\.)?(gz|Z)|tgz|zip|pm\.(gz|Z)))$//;
2042 my $size = 31 - length($suf);
2043 while (length($name) > $size) {
2047 $aslocal = File::Spec->catfile($path, $name);
2051 return $aslocal if -f $aslocal && -r _ && !($force & 1);
2054 rename $aslocal, "$aslocal.bak";
2058 my($aslocal_dir) = File::Basename::dirname($aslocal);
2059 File::Path::mkpath($aslocal_dir);
2060 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
2061 qq{directory "$aslocal_dir".
2062 I\'ll continue, but if you encounter problems, they may be due
2063 to insufficient permissions.\n}) unless -w $aslocal_dir;
2065 # Inheritance is not easier to manage than a few if/else branches
2066 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2068 $Ua = LWP::UserAgent->new;
2070 $Ua->proxy('ftp', $var)
2071 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
2072 $Ua->proxy('http', $var)
2073 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
2075 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
2078 $ENV{ftp_proxy} = $CPAN::Config->{ftp_proxy} if $CPAN::Config->{ftp_proxy};
2079 $ENV{http_proxy} = $CPAN::Config->{http_proxy} if $CPAN::Config->{http_proxy};
2080 $ENV{no_proxy} = $CPAN::Config->{no_proxy} if $CPAN::Config->{no_proxy};
2082 # Try the list of urls for each single object. We keep a record
2083 # where we did get a file from
2084 my(@reordered,$last);
2085 $CPAN::Config->{urllist} ||= [];
2086 $last = $#{$CPAN::Config->{urllist}};
2087 if ($force & 2) { # local cpans probably out of date, don't reorder
2088 @reordered = (0..$last);
2092 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
2094 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
2105 @levels = ($Themethod, grep {$_ ne $Themethod} qw/easy hard hardest/);
2107 @levels = qw/easy hard hardest/;
2109 @levels = qw/easy/ if $^O eq 'MacOS';
2111 for $levelno (0..$#levels) {
2112 my $level = $levels[$levelno];
2113 my $method = "host$level";
2114 my @host_seq = $level eq "easy" ?
2115 @reordered : 0..$last; # reordered has CDROM up front
2116 @host_seq = (0) unless @host_seq;
2117 my $ret = $self->$method(\@host_seq,$file,$aslocal);
2119 $Themethod = $level;
2121 # utime $now, $now, $aslocal; # too bad, if we do that, we
2122 # might alter a local mirror
2123 $self->debug("level[$level]") if $CPAN::DEBUG;
2127 last if $CPAN::Signal; # need to cleanup
2130 unless ($CPAN::Signal) {
2133 qq{Please check, if the URLs I found in your configuration file \(}.
2134 join(", ", @{$CPAN::Config->{urllist}}).
2135 qq{\) are valid. The urllist can be edited.},
2136 qq{E.g. with 'o conf urllist push ftp://myurl/'};
2137 $CPAN::Frontend->myprint(Text::Wrap::wrap("","",@mess). "\n\n");
2139 $CPAN::Frontend->myprint("Cannot fetch $file\n\n");
2142 rename "$aslocal.bak", $aslocal;
2143 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
2144 $self->ls($aslocal));
2151 my($self,$host_seq,$file,$aslocal) = @_;
2153 HOSTEASY: for $i (@$host_seq) {
2154 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2155 unless ($self->is_reachable($url)) {
2156 $CPAN::Frontend->myprint("Skipping $url (seems to be not reachable)\n");
2160 $url .= "/" unless substr($url,-1) eq "/";
2162 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
2163 if ($url =~ /^file:/) {
2165 if ($CPAN::META->has_inst('URI::URL')) {
2166 my $u = URI::URL->new($url);
2168 } else { # works only on Unix, is poorly constructed, but
2169 # hopefully better than nothing.
2170 # RFC 1738 says fileurl BNF is
2171 # fileurl = "file://" [ host | "localhost" ] "/" fpath
2172 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
2174 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
2175 $l =~ s|^file:||; # assume they
2178 $l =~ s|^/||s unless -f $l; # e.g. /P:
2180 if ( -f $l && -r _) {
2184 # Maybe mirror has compressed it?
2186 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
2187 CPAN::Tarzip->gunzip("$l.gz", $aslocal);
2194 if ($CPAN::META->has_usable('LWP')) {
2195 $CPAN::Frontend->myprint("Fetching with LWP:
2199 require LWP::UserAgent;
2200 $Ua = LWP::UserAgent->new;
2202 my $res = $Ua->mirror($url, $aslocal);
2203 if ($res->is_success) {
2206 utime $now, $now, $aslocal; # download time is more
2207 # important than upload time
2209 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2210 my $gzurl = "$url.gz";
2211 $CPAN::Frontend->myprint("Fetching with LWP:
2214 $res = $Ua->mirror($gzurl, "$aslocal.gz");
2215 if ($res->is_success &&
2216 CPAN::Tarzip->gunzip("$aslocal.gz",$aslocal)
2222 # Alan Burlison informed me that in firewall environments
2223 # Net::FTP can still succeed where LWP fails. So we do not
2224 # skip Net::FTP anymore when LWP is available.
2227 $self->debug("LWP not installed") if $CPAN::DEBUG;
2229 return if $CPAN::Signal;
2230 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2231 # that's the nice and easy way thanks to Graham
2232 my($host,$dir,$getfile) = ($1,$2,$3);
2233 if ($CPAN::META->has_usable('Net::FTP')) {
2235 $CPAN::Frontend->myprint("Fetching with Net::FTP:
2238 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
2239 "aslocal[$aslocal]") if $CPAN::DEBUG;
2240 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
2244 if ($aslocal !~ /\.gz(?!\n)\Z/) {
2245 my $gz = "$aslocal.gz";
2246 $CPAN::Frontend->myprint("Fetching with Net::FTP
2249 if (CPAN::FTP->ftp_get($host,
2253 CPAN::Tarzip->gunzip($gz,$aslocal)
2262 return if $CPAN::Signal;
2267 my($self,$host_seq,$file,$aslocal) = @_;
2269 # Came back if Net::FTP couldn't establish connection (or
2270 # failed otherwise) Maybe they are behind a firewall, but they
2271 # gave us a socksified (or other) ftp program...
2274 my($devnull) = $CPAN::Config->{devnull} || "";
2276 my($aslocal_dir) = File::Basename::dirname($aslocal);
2277 File::Path::mkpath($aslocal_dir);
2278 HOSTHARD: for $i (@$host_seq) {
2279 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2280 unless ($self->is_reachable($url)) {
2281 $CPAN::Frontend->myprint("Skipping $url (not reachable)\n");
2284 $url .= "/" unless substr($url,-1) eq "/";
2286 my($proto,$host,$dir,$getfile);
2288 # Courtesy Mark Conty mark_conty@cargill.com change from
2289 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2291 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
2292 # proto not yet used
2293 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
2295 next HOSTHARD; # who said, we could ftp anything except ftp?
2298 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
2300 for $f ('lynx','ncftpget','ncftp') {
2301 next unless exists $CPAN::Config->{$f};
2302 $funkyftp = $CPAN::Config->{$f};
2303 next unless defined $funkyftp;
2304 next if $funkyftp =~ /^\s*$/;
2305 my($asl_ungz, $asl_gz);
2306 ($asl_ungz = $aslocal) =~ s/\.gz//;
2307 $asl_gz = "$asl_ungz.gz";
2308 my($src_switch) = "";
2310 $src_switch = " -source";
2311 } elsif ($f eq "ncftp"){
2312 $src_switch = " -c";
2315 my($stdout_redir) = " > $asl_ungz";
2316 if ($f eq "ncftpget"){
2317 $chdir = "cd $aslocal_dir && ";
2320 $CPAN::Frontend->myprint(
2322 Trying with "$funkyftp$src_switch" to get
2326 "$chdir$funkyftp$src_switch '$url' $devnull$stdout_redir";
2327 $self->debug("system[$system]") if $CPAN::DEBUG;
2329 if (($wstatus = system($system)) == 0
2332 -s $asl_ungz # lynx returns 0 on my
2333 # system even if it fails
2339 } elsif ($asl_ungz ne $aslocal) {
2340 # test gzip integrity
2342 CPAN::Tarzip->gtest($asl_ungz)
2344 rename $asl_ungz, $aslocal;
2346 CPAN::Tarzip->gzip($asl_ungz,$asl_gz);
2351 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2353 -f $asl_ungz && -s _ == 0;
2354 my $gz = "$aslocal.gz";
2355 my $gzurl = "$url.gz";
2356 $CPAN::Frontend->myprint(
2358 Trying with "$funkyftp$src_switch" to get
2361 my($system) = "$funkyftp$src_switch '$url.gz' $devnull > $asl_gz";
2362 $self->debug("system[$system]") if $CPAN::DEBUG;
2364 if (($wstatus = system($system)) == 0
2368 # test gzip integrity
2369 if (CPAN::Tarzip->gtest($asl_gz)) {
2370 CPAN::Tarzip->gunzip($asl_gz,$aslocal);
2372 rename $asl_ungz, $aslocal;
2377 unlink $asl_gz if -f $asl_gz;
2380 my $estatus = $wstatus >> 8;
2381 my $size = -f $aslocal ?
2382 ", left\n$aslocal with size ".-s _ :
2383 "\nWarning: expected file [$aslocal] doesn't exist";
2384 $CPAN::Frontend->myprint(qq{
2385 System call "$system"
2386 returned status $estatus (wstat $wstatus)$size
2389 return if $CPAN::Signal;
2390 } # lynx,ncftpget,ncftp
2395 my($self,$host_seq,$file,$aslocal) = @_;
2398 my($aslocal_dir) = File::Basename::dirname($aslocal);
2399 File::Path::mkpath($aslocal_dir);
2400 HOSTHARDEST: for $i (@$host_seq) {
2401 unless (length $CPAN::Config->{'ftp'}) {
2402 $CPAN::Frontend->myprint("No external ftp command available\n\n");
2405 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2406 unless ($self->is_reachable($url)) {
2407 $CPAN::Frontend->myprint("Skipping $url (not reachable)\n");
2410 $url .= "/" unless substr($url,-1) eq "/";
2412 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
2413 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2416 my($host,$dir,$getfile) = ($1,$2,$3);
2418 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
2419 $ctime,$blksize,$blocks) = stat($aslocal);
2420 $timestamp = $mtime ||= 0;
2421 my($netrc) = CPAN::FTP::netrc->new;
2422 my($netrcfile) = $netrc->netrc;
2423 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
2424 my $targetfile = File::Basename::basename($aslocal);
2430 map("cd $_", split "/", $dir), # RFC 1738
2432 "get $getfile $targetfile",
2436 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
2437 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
2438 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
2440 $netrc->contains($host))) if $CPAN::DEBUG;
2441 if ($netrc->protected) {
2442 $CPAN::Frontend->myprint(qq{
2443 Trying with external ftp to get
2445 As this requires some features that are not thoroughly tested, we\'re
2446 not sure, that we get it right....
2450 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose $host",
2452 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2453 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2455 if ($mtime > $timestamp) {
2456 $CPAN::Frontend->myprint("GOT $aslocal\n");
2460 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
2462 return if $CPAN::Signal;
2464 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
2465 qq{correctly protected.\n});
2468 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
2469 nor does it have a default entry\n");
2472 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
2473 # then and login manually to host, using e-mail as
2475 $CPAN::Frontend->myprint(qq{Issuing "$CPAN::Config->{'ftp'}$verbose -n"\n});
2479 "user anonymous $Config::Config{'cf_email'}"
2481 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose -n", @dialog);
2482 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2483 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2485 if ($mtime > $timestamp) {
2486 $CPAN::Frontend->myprint("GOT $aslocal\n");
2490 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
2492 return if $CPAN::Signal;
2493 $CPAN::Frontend->myprint("Can't access URL $url.\n\n");
2499 my($self,$command,@dialog) = @_;
2500 my $fh = FileHandle->new;
2501 $fh->open("|$command") or die "Couldn't open ftp: $!";
2502 foreach (@dialog) { $fh->print("$_\n") }
2503 $fh->close; # Wait for process to complete
2505 my $estatus = $wstatus >> 8;
2506 $CPAN::Frontend->myprint(qq{
2507 Subprocess "|$command"
2508 returned status $estatus (wstat $wstatus)
2512 # find2perl needs modularization, too, all the following is stolen
2516 my($self,$name) = @_;
2517 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
2518 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
2520 my($perms,%user,%group);
2524 $blocks = int(($blocks + 1) / 2);
2527 $blocks = int(($sizemm + 1023) / 1024);
2530 if (-f _) { $perms = '-'; }
2531 elsif (-d _) { $perms = 'd'; }
2532 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
2533 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
2534 elsif (-p _) { $perms = 'p'; }
2535 elsif (-S _) { $perms = 's'; }
2536 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
2538 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
2539 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
2540 my $tmpmode = $mode;
2541 my $tmp = $rwx[$tmpmode & 7];
2543 $tmp = $rwx[$tmpmode & 7] . $tmp;
2545 $tmp = $rwx[$tmpmode & 7] . $tmp;
2546 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
2547 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
2548 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
2551 my $user = $user{$uid} || $uid; # too lazy to implement lookup
2552 my $group = $group{$gid} || $gid;
2554 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
2556 my($moname) = $moname[$mon];
2557 if (-M _ > 365.25 / 2) {
2558 $timeyear = $year + 1900;
2561 $timeyear = sprintf("%02d:%02d", $hour, $min);
2564 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
2578 package CPAN::FTP::netrc;
2582 my $file = MM->catfile($ENV{HOME},".netrc");
2584 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2585 $atime,$mtime,$ctime,$blksize,$blocks)
2590 my($fh,@machines,$hasdefault);
2592 $fh = FileHandle->new or die "Could not create a filehandle";
2594 if($fh->open($file)){
2595 $protected = ($mode & 077) == 0;
2597 NETRC: while (<$fh>) {
2598 my(@tokens) = split " ", $_;
2599 TOKEN: while (@tokens) {
2600 my($t) = shift @tokens;
2601 if ($t eq "default"){
2605 last TOKEN if $t eq "macdef";
2606 if ($t eq "machine") {
2607 push @machines, shift @tokens;
2612 $file = $hasdefault = $protected = "";
2616 'mach' => [@machines],
2618 'hasdefault' => $hasdefault,
2619 'protected' => $protected,
2623 sub hasdefault { shift->{'hasdefault'} }
2624 sub netrc { shift->{'netrc'} }
2625 sub protected { shift->{'protected'} }
2627 my($self,$mach) = @_;
2628 for ( @{$self->{'mach'}} ) {
2629 return 1 if $_ eq $mach;
2634 package CPAN::Complete;
2637 my($text, $line, $start, $end) = @_;
2638 my(@perlret) = cpl($text, $line, $start);
2639 # find longest common match. Can anybody show me how to peruse
2640 # T::R::Gnu to have this done automatically? Seems expensive.
2641 return () unless @perlret;
2642 my($newtext) = $text;
2643 for (my $i = length($text)+1;;$i++) {
2644 last unless length($perlret[0]) && length($perlret[0]) >= $i;
2645 my $try = substr($perlret[0],0,$i);
2646 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
2647 # warn "try[$try]tries[@tries]";
2648 if (@tries == @perlret) {
2654 ($newtext,@perlret);
2657 #-> sub CPAN::Complete::cpl ;
2659 my($word,$line,$pos) = @_;
2663 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2665 if ($line =~ s/^(force\s*)//) {
2673 ! a b d h i m o q r u autobundle clean
2674 make test install force reload look cvs_import
2677 } elsif ( $line !~ /^[\!abcdhimorutl]/ ) {
2679 } elsif ($line =~ /^a\s/) {
2680 @return = cplx('CPAN::Author',$word);
2681 } elsif ($line =~ /^b\s/) {
2682 @return = cplx('CPAN::Bundle',$word);
2683 } elsif ($line =~ /^d\s/) {
2684 @return = cplx('CPAN::Distribution',$word);
2685 } elsif ($line =~ /^([mru]|make|clean|test|install|readme|look|cvs_import)\s/ ) {
2686 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
2687 } elsif ($line =~ /^i\s/) {
2688 @return = cpl_any($word);
2689 } elsif ($line =~ /^reload\s/) {
2690 @return = cpl_reload($word,$line,$pos);
2691 } elsif ($line =~ /^o\s/) {
2692 @return = cpl_option($word,$line,$pos);
2699 #-> sub CPAN::Complete::cplx ;
2701 my($class, $word) = @_;
2702 # I believed for many years that this was sorted, today I
2703 # realized, it wasn't sorted anymore. Now (rev 1.301 / v 1.55) I
2704 # make it sorted again. Maybe sort was dropped when GNU-readline
2705 # support came in? The RCS file is difficult to read on that:-(
2706 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
2709 #-> sub CPAN::Complete::cpl_any ;
2713 cplx('CPAN::Author',$word),
2714 cplx('CPAN::Bundle',$word),
2715 cplx('CPAN::Distribution',$word),
2716 cplx('CPAN::Module',$word),
2720 #-> sub CPAN::Complete::cpl_reload ;
2722 my($word,$line,$pos) = @_;
2724 my(@words) = split " ", $line;
2725 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2726 my(@ok) = qw(cpan index);
2727 return @ok if @words == 1;
2728 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
2731 #-> sub CPAN::Complete::cpl_option ;
2733 my($word,$line,$pos) = @_;
2735 my(@words) = split " ", $line;
2736 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2737 my(@ok) = qw(conf debug);
2738 return @ok if @words == 1;
2739 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
2741 } elsif ($words[1] eq 'index') {
2743 } elsif ($words[1] eq 'conf') {
2744 return CPAN::Config::cpl(@_);
2745 } elsif ($words[1] eq 'debug') {
2746 return sort grep /^\Q$word\E/, sort keys %CPAN::DEBUG, 'all';
2750 package CPAN::Index;
2752 #-> sub CPAN::Index::force_reload ;
2755 $CPAN::Index::last_time = 0;
2759 #-> sub CPAN::Index::reload ;
2761 my($cl,$force) = @_;
2764 # XXX check if a newer one is available. (We currently read it
2765 # from time to time)
2766 for ($CPAN::Config->{index_expire}) {
2767 $_ = 0.001 unless $_ && $_ > 0.001;
2769 return if $last_time + $CPAN::Config->{index_expire}*86400 > $time
2771 ## IFF we are developing, it helps to wipe out the memory between
2772 ## reloads, otherwise it is not what a user expects.
2774 ## undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
2775 ## $CPAN::META = CPAN->new;
2779 my $needshort = $^O eq "dos";
2781 $cl->rd_authindex($cl
2783 "authors/01mailrc.txt.gz",
2785 File::Spec->catfile('authors', '01mailrc.gz') :
2786 File::Spec->catfile('authors', '01mailrc.txt.gz'),
2789 $debug = "timing reading 01[".($t2 - $time)."]";
2791 return if $CPAN::Signal; # this is sometimes lengthy
2792 $cl->rd_modpacks($cl
2794 "modules/02packages.details.txt.gz",
2796 File::Spec->catfile('modules', '02packag.gz') :
2797 File::Spec->catfile('modules', '02packages.details.txt.gz'),
2800 $debug .= "02[".($t2 - $time)."]";
2802 return if $CPAN::Signal; # this is sometimes lengthy
2805 "modules/03modlist.data.gz",
2807 File::Spec->catfile('modules', '03mlist.gz') :
2808 File::Spec->catfile('modules', '03modlist.data.gz'),
2810 $cl->write_metadata_cache;
2812 $debug .= "03[".($t2 - $time)."]";
2814 CPAN->debug($debug) if $CPAN::DEBUG;
2817 #-> sub CPAN::Index::reload_x ;
2819 my($cl,$wanted,$localname,$force) = @_;
2820 $force |= 2; # means we're dealing with an index here
2821 CPAN::Config->load; # we should guarantee loading wherever we rely
2823 $localname ||= $wanted;
2824 my $abs_wanted = MM->catfile($CPAN::Config->{'keep_source_where'},
2828 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
2831 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
2832 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
2833 qq{day$s. I\'ll use that.});
2836 $force |= 1; # means we're quite serious about it.
2838 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
2841 #-> sub CPAN::Index::rd_authindex ;
2843 my($cl, $index_target) = @_;
2845 return unless defined $index_target;
2846 $CPAN::Frontend->myprint("Going to read $index_target\n");
2847 # my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
2848 # while ($_ = $fh->READLINE) {
2851 tie *FH, CPAN::Tarzip, $index_target;
2853 push @lines, split /\012/ while <FH>;
2855 my($userid,$fullname,$email) =
2856 m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
2857 next unless $userid && $fullname && $email;
2859 # instantiate an author object
2860 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
2861 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
2862 return if $CPAN::Signal;
2867 my($self,$dist) = @_;
2868 $dist = $self->{'id'} unless defined $dist;
2869 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
2873 #-> sub CPAN::Index::rd_modpacks ;
2875 my($self, $index_target) = @_;
2877 return unless defined $index_target;
2878 $CPAN::Frontend->myprint("Going to read $index_target\n");
2879 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
2881 while ($_ = $fh->READLINE) {
2883 my @ls = map {"$_\n"} split /\n/, $_;
2884 unshift @ls, "\n" x length($1) if /^(\n+)/;
2890 my $shift = shift(@lines);
2891 $shift =~ /^Line-Count:\s+(\d+)/;
2892 $line_count = $1 if $1;
2893 last if $shift =~ /^\s*$/;
2895 if (not defined $line_count) {
2897 warn qq{Warning: Your $index_target does not contain a Line-Count header.
2898 Please check the validity of the index file by comparing it to more
2899 than one CPAN mirror. I'll continue but problems seem likely to
2904 } elsif ($line_count != scalar @lines) {
2906 warn sprintf qq{Warning: Your %s
2907 contains a Line-Count header of %d but I see %d lines there. Please
2908 check the validity of the index file by comparing it to more than one
2909 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
2910 $index_target, $line_count, scalar(@lines);
2913 # A necessity since we have metadata_cache: delete what isn't
2915 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
2916 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
2920 # before 1.56 we split into 3 and discarded the rest. From
2921 # 1.57 we assign remaining text to $comment thus allowing to
2922 # influence isa_perl
2923 my($mod,$version,$dist,$comment) = split " ", $_, 4;
2924 my($bundle,$id,$userid);
2926 if ($mod eq 'CPAN' &&
2928 CPAN::Queue->exists('Bundle::CPAN') ||
2929 CPAN::Queue->exists('CPAN')
2933 if ($version > $CPAN::VERSION){
2934 $CPAN::Frontend->myprint(qq{
2935 There's a new CPAN.pm version (v$version) available!
2936 [Current version is v$CPAN::VERSION]
2937 You might want to try
2938 install Bundle::CPAN
2940 without quitting the current session. It should be a seamless upgrade
2941 while we are running...
2944 $CPAN::Frontend->myprint(qq{\n});
2946 last if $CPAN::Signal;
2947 } elsif ($mod =~ /^Bundle::(.*)/) {
2952 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
2953 # Let's make it a module too, because bundles have so much
2954 # in common with modules
2955 $CPAN::META->instance('CPAN::Module',$mod);
2959 # instantiate a module object
2960 $id = $CPAN::META->instance('CPAN::Module',$mod);
2964 if ($id->cpan_file ne $dist){ # update only if file is
2965 # different. CPAN prohibits same
2966 # name with different version
2967 $userid = $self->userid($dist);
2969 'CPAN_USERID' => $userid,
2970 'CPAN_VERSION' => $version, # %vd not needed
2971 'CPAN_FILE' => $dist,
2972 'CPAN_COMMENT' => $comment,
2976 # instantiate a distribution object
2977 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
2978 # we do not need CONTAINSMODS unless we do something with
2979 # this dist, so we better produce it on demand.
2981 ## my $obj = $CPAN::META->instance(
2982 ## 'CPAN::Distribution' => $dist
2984 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
2986 $CPAN::META->instance(
2987 'CPAN::Distribution' => $dist
2989 'CPAN_USERID' => $userid
2993 for my $name ($mod,$dist) {
2994 # CPAN->debug("confirm existence of name[$name]") if $CPAN::DEBUG;
2995 $exists{$name} = undef;
2998 return if $CPAN::Signal;
3002 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
3003 for my $o ($CPAN::META->all_objects($class)) {
3004 next if exists $exists{$o->{ID}};
3005 $CPAN::META->delete($class,$o->{ID});
3006 CPAN->debug("deleting ID[$o->{ID}] in class[$class]") if $CPAN::DEBUG;
3012 #-> sub CPAN::Index::rd_modlist ;
3014 my($cl,$index_target) = @_;
3015 return unless defined $index_target;
3016 $CPAN::Frontend->myprint("Going to read $index_target\n");
3017 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3020 while ($_ = $fh->READLINE) {
3022 my @ls = map {"$_\n"} split /\n/, $_;
3023 unshift @ls, "\n" x length($1) if /^(\n+)/;
3027 my $shift = shift(@eval);
3028 if ($shift =~ /^Date:\s+(.*)/){
3029 return if $date_of_03 eq $1;
3032 last if $shift =~ /^\s*$/;
3035 push @eval, q{CPAN::Modulelist->data;};
3037 my($comp) = Safe->new("CPAN::Safe1");
3038 my($eval) = join("", @eval);
3039 my $ret = $comp->reval($eval);
3040 Carp::confess($@) if $@;
3041 return if $CPAN::Signal;
3043 my $obj = $CPAN::META->instance(CPAN::Module,$_);
3044 $obj->set(%{$ret->{$_}});
3045 return if $CPAN::Signal;
3049 #-> sub CPAN::Index::write_metadata_cache ;
3050 sub write_metadata_cache {
3052 return unless $CPAN::Config->{'cache_metadata'};
3053 return unless $CPAN::META->has_usable("Storable");
3055 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
3056 CPAN::Distribution)) {
3057 $cache->{$k} = $CPAN::META->{$k};
3059 my $metadata_file = MM->catfile($CPAN::Config->{cpan_home},"Metadata");
3060 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
3061 $cache->{last_time} = $last_time;
3062 eval { Storable::nstore($cache, $metadata_file) };
3063 $CPAN::Frontent->mywarn($@) if $@;
3066 #-> sub CPAN::Index::read_metadata_cache ;
3067 sub read_metadata_cache {
3069 return unless $CPAN::Config->{'cache_metadata'};
3070 return unless $CPAN::META->has_usable("Storable");
3071 my $metadata_file = MM->catfile($CPAN::Config->{cpan_home},"Metadata");
3072 return unless -r $metadata_file and -f $metadata_file;
3073 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
3075 eval { $cache = Storable::retrieve($metadata_file) };
3076 $CPAN::Frontend->mywarn($@) if $@;
3077 return if (!$cache || ref $cache ne 'HASH');
3078 while(my($k,$v) = each %$cache) {
3079 next unless $k =~ /^CPAN::/;
3080 for my $k2 (keys %$v) {
3081 delete $v->{$k2}{force_update}; # if a buggy CPAN.pm left
3082 # over such a mess, it's
3083 # high time to correct now
3085 $CPAN::META->{$k} = $v;
3087 $last_time = $cache->{last_time};
3090 package CPAN::InfoObj;
3092 #-> sub CPAN::InfoObj::new ;
3093 sub new { my $this = bless {}, shift; %$this = @_; $this }
3095 #-> sub CPAN::InfoObj::set ;
3097 my($self,%att) = @_;
3098 my(%oldatt) = %$self;
3099 %$self = (%oldatt, %att);
3102 #-> sub CPAN::InfoObj::id ;
3103 sub id { shift->{'ID'} }
3105 #-> sub CPAN::InfoObj::as_glimpse ;
3109 my $class = ref($self);
3110 $class =~ s/^CPAN:://;
3111 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
3115 #-> sub CPAN::InfoObj::as_string ;
3119 my $class = ref($self);
3120 $class =~ s/^CPAN:://;
3121 push @m, $class, " id = $self->{ID}\n";
3122 for (sort keys %$self) {
3125 if ($_ eq "CPAN_USERID") {
3126 $extra .= " (".$self->author;
3127 my $email; # old perls!
3128 if ($email = $CPAN::META->instance(CPAN::Author,
3131 $extra .= " <$email>";
3133 $extra .= " <no email>";
3137 if (ref($self->{$_}) eq "ARRAY") { # language interface? XXX
3138 push @m, sprintf " %-12s %s%s\n", $_, "@{$self->{$_}}", $extra;
3139 } elsif (ref($self->{$_}) eq "HASH") {
3143 join(" ",keys %{$self->{$_}}),
3146 push @m, sprintf " %-12s %s%s\n", $_, $self->{$_}, $extra;
3152 #-> sub CPAN::InfoObj::author ;
3155 $CPAN::META->instance(CPAN::Author,$self->{CPAN_USERID})->fullname;
3160 require Data::Dumper;
3161 Data::Dumper::Dumper($self);
3164 package CPAN::Author;
3166 #-> sub CPAN::Author::as_glimpse ;
3170 my $class = ref($self);
3171 $class =~ s/^CPAN:://;
3172 push @m, sprintf "%-15s %s (%s)\n", $class, $self->{ID}, $self->fullname;
3176 #-> sub CPAN::Author::fullname ;
3177 sub fullname { shift->{'FULLNAME'} }
3180 #-> sub CPAN::Author::email ;
3181 sub email { shift->{'EMAIL'} }
3183 package CPAN::Distribution;
3185 #-> sub CPAN::Distribution::as_string ;
3188 $self->containsmods;
3189 $self->SUPER::as_string(@_);
3192 #-> sub CPAN::Distribution::containsmods ;
3195 return if exists $self->{CONTAINSMODS};
3196 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
3197 my $mod_file = $mod->{CPAN_FILE} or next;
3198 my $dist_id = $self->{ID} or next;
3199 my $mod_id = $mod->{ID} or next;
3200 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
3204 #-> sub CPAN::Distribution::called_for ;
3207 $self->{'CALLED_FOR'} = $id if defined $id;
3208 return $self->{'CALLED_FOR'};
3211 #-> sub CPAN::Distribution::get ;
3216 exists $self->{'build_dir'} and push @e,
3217 "Is already unwrapped into directory $self->{'build_dir'}";
3218 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3223 $CPAN::Config->{keep_source_where},
3226 split("/",$self->{ID})
3229 $self->debug("Doing localize") if $CPAN::DEBUG;
3231 CPAN::FTP->localize("authors/id/$self->{ID}", $local_wanted)
3232 or $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n");
3233 return if $CPAN::Signal;
3234 $self->{localfile} = $local_file;
3235 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
3236 my $builddir = $CPAN::META->{cachemgr}->dir;
3237 $self->debug("doing chdir $builddir") if $CPAN::DEBUG;
3238 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
3241 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
3242 if ($CPAN::META->has_inst('MD5')) {
3243 $self->debug("MD5 is installed, verifying");
3246 $self->debug("MD5 is NOT installed");
3248 $self->debug("Removing tmp") if $CPAN::DEBUG;
3249 File::Path::rmtree("tmp");
3250 mkdir "tmp", 0755 or Carp::croak "Couldn't mkdir tmp: $!";
3251 chdir "tmp" or $CPAN::Frontend->mydie(qq{Could not chdir to "tmp": $!});;
3252 $self->debug("Changed directory to tmp") if $CPAN::DEBUG;
3253 return if $CPAN::Signal;
3254 if (! $local_file) {
3255 Carp::croak "bad download, can't do anything :-(\n";
3256 } elsif ($local_file =~ /(\.tar\.(gz|Z)|\.tgz)(?!\n)\Z/i){
3257 $self->untar_me($local_file);
3258 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
3259 $self->unzip_me($local_file);
3260 } elsif ( $local_file =~ /\.pm\.(gz|Z)(?!\n)\Z/) {
3261 $self->pm2dir_me($local_file);
3263 $self->{archived} = "NO";
3265 my $cwd = File::Spec->updir;
3266 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "": $!});
3267 if ($self->{archived} ne 'NO') {
3268 $cwd = File::Spec->catdir(File::Spec->curdir, "tmp");
3269 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
3270 # Let's check if the package has its own directory.
3271 my $dh = DirHandle->new(File::Spec->curdir)
3272 or Carp::croak("Couldn't opendir .: $!");
3273 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
3275 my ($distdir,$packagedir);
3276 if (@readdir == 1 && -d $readdir[0]) {
3277 $distdir = $readdir[0];
3278 $packagedir = MM->catdir($builddir,$distdir);
3279 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used $packagedir\n");
3280 File::Path::rmtree($packagedir);
3281 rename($distdir,$packagedir) or Carp::confess("Couldn't rename $distdir to $packagedir: $!");
3283 my $pragmatic_dir = $self->{'CPAN_USERID'} . '000';
3284 $pragmatic_dir =~ s/\W_//g;
3285 $pragmatic_dir++ while -d "../$pragmatic_dir";
3286 $packagedir = MM->catdir($builddir,$pragmatic_dir);
3287 File::Path::mkpath($packagedir);
3289 for $f (@readdir) { # is already without "." and ".."
3290 my $to = MM->catdir($packagedir,$f);
3291 rename($f,$to) or Carp::confess("Couldn't rename $f to $to: $!");
3294 $self->{'build_dir'} = $packagedir;
3295 $cwd = File::Spec->updir;
3296 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
3298 $self->debug("Changed directory to .. (self is $self [".$self->as_string."])")
3300 File::Path::rmtree("tmp");
3301 if ($CPAN::Config->{keep_source_where} =~ /^no/i ){
3302 $CPAN::Frontend->myprint("Going to unlink $local_file\n");
3303 unlink $local_file or Carp::carp "Couldn't unlink $local_file";
3305 my($makefilepl) = MM->catfile($packagedir,"Makefile.PL");
3306 unless (-f $makefilepl) {
3307 my($configure) = MM->catfile($packagedir,"Configure");
3308 if (-f $configure) {
3309 # do we have anything to do?
3310 $self->{'configure'} = $configure;
3311 } elsif (-f MM->catfile($packagedir,"Makefile")) {
3312 $CPAN::Frontend->myprint(qq{
3313 Package comes with a Makefile and without a Makefile.PL.
3314 We\'ll try to build it with that Makefile then.
3316 $self->{writemakefile} = "YES";
3319 my $fh = FileHandle->new(">$makefilepl")
3320 or Carp::croak("Could not open >$makefilepl");
3321 my $cf = $self->called_for || "unknown";
3323 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
3324 # because there was no Makefile.PL supplied.
3325 # Autogenerated on: }.scalar localtime().qq{
3327 use ExtUtils::MakeMaker;
3328 WriteMakefile(NAME => q[$cf]);
3331 $CPAN::Frontend->myprint(qq{Package comes without Makefile.PL.
3332 Writing one on our own (calling it $cf)\n});
3340 my($self,$local_file) = @_;
3341 $self->{archived} = "tar";
3342 if (CPAN::Tarzip->untar($local_file)) {
3343 $self->{unwrapped} = "YES";
3345 $self->{unwrapped} = "NO";
3350 my($self,$local_file) = @_;
3351 $self->{archived} = "zip";
3352 if (CPAN::Tarzip->unzip($local_file)) {
3353 $self->{unwrapped} = "YES";
3355 $self->{unwrapped} = "NO";
3361 my($self,$local_file) = @_;
3362 $self->{archived} = "pm";
3363 my $to = File::Basename::basename($local_file);
3364 $to =~ s/\.(gz|Z)(?!\n)\Z//;
3365 if (CPAN::Tarzip->gunzip($local_file,$to)) {
3366 $self->{unwrapped} = "YES";
3368 $self->{unwrapped} = "NO";
3372 #-> sub CPAN::Distribution::new ;
3374 my($class,%att) = @_;
3376 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
3378 my $this = { %att };
3379 return bless $this, $class;
3382 #-> sub CPAN::Distribution::look ;
3386 if ($^O eq 'MacOS') {
3387 $self->ExtUtils::MM_MacOS::look;
3391 if ( $CPAN::Config->{'shell'} ) {
3392 $CPAN::Frontend->myprint(qq{
3393 Trying to open a subshell in the build directory...
3396 $CPAN::Frontend->myprint(qq{
3397 Your configuration does not define a value for subshells.
3398 Please define it with "o conf shell <your shell>"
3402 my $dist = $self->id;
3403 my $dir = $self->dir or $self->get;
3406 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
3407 my $pwd = CPAN->$getcwd();
3408 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
3409 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
3410 system($CPAN::Config->{'shell'}) == 0
3411 or $CPAN::Frontend->mydie("Subprocess shell error");
3412 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
3418 my $dir = $self->dir;
3420 my $package = $self->called_for;
3421 my $module = $CPAN::META->instance('CPAN::Module', $package);
3422 my $version = $module->cpan_version; # %vd not needed
3424 my $userid = $self->{CPAN_USERID};
3426 my $cvs_dir = (split '/', $dir)[-1];
3427 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
3429 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
3431 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
3432 if ($cvs_site_perl) {
3433 $cvs_dir = "$cvs_site_perl/$cvs_dir";
3435 my $cvs_log = qq{"imported $package $version sources"};
3436 $version =~ s/\./_/g;
3437 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
3438 "$cvs_dir", $userid, "v$version");
3441 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
3442 my $pwd = CPAN->$getcwd();
3443 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
3445 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
3447 $CPAN::Frontend->myprint(qq{@cmd\n});
3448 system(@cmd) == 0 or
3449 $CPAN::Frontend->mydie("cvs import failed");
3450 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
3453 #-> sub CPAN::Distribution::readme ;
3456 my($dist) = $self->id;
3457 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
3458 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
3462 $CPAN::Config->{keep_source_where},
3465 split("/","$sans.readme"),
3467 $self->debug("Doing localize") if $CPAN::DEBUG;
3468 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
3470 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
3472 if ($^O eq 'MacOS') {
3473 ExtUtils::MM_MacOS::launch_file($local_file);
3477 my $fh_pager = FileHandle->new;
3478 local($SIG{PIPE}) = "IGNORE";
3479 $fh_pager->open("|$CPAN::Config->{'pager'}")
3480 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
3481 my $fh_readme = FileHandle->new;
3482 $fh_readme->open($local_file)
3483 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
3484 $CPAN::Frontend->myprint(qq{
3487 with pager "$CPAN::Config->{'pager'}"
3490 $fh_pager->print(<$fh_readme>);
3493 #-> sub CPAN::Distribution::verifyMD5 ;
3498 $self->{MD5_STATUS} ||= "";
3499 $self->{MD5_STATUS} eq "OK" and push @e, "MD5 Checksum was ok";
3500 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3502 my($lc_want,$lc_file,@local,$basename);
3503 @local = split("/",$self->{ID});
3505 push @local, "CHECKSUMS";
3507 MM->catfile($CPAN::Config->{keep_source_where},
3508 "authors", "id", @local);
3513 $self->MD5_check_file($lc_want)
3515 return $self->{MD5_STATUS} = "OK";
3517 $lc_file = CPAN::FTP->localize("authors/id/@local",
3520 $local[-1] .= ".gz";
3521 $lc_file = CPAN::FTP->localize("authors/id/@local",
3524 $lc_file =~ s/\.gz(?!\n)\Z//;
3525 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
3530 $self->MD5_check_file($lc_file);
3533 #-> sub CPAN::Distribution::MD5_check_file ;
3534 sub MD5_check_file {
3535 my($self,$chk_file) = @_;
3536 my($cksum,$file,$basename);
3537 $file = $self->{localfile};
3538 $basename = File::Basename::basename($file);
3539 my $fh = FileHandle->new;
3540 if (open $fh, $chk_file){
3543 $eval =~ s/\015?\012/\n/g;
3545 my($comp) = Safe->new();
3546 $cksum = $comp->reval($eval);
3548 rename $chk_file, "$chk_file.bad";
3549 Carp::confess($@) if $@;
3552 Carp::carp "Could not open $chk_file for reading";
3555 if (exists $cksum->{$basename}{md5}) {
3556 $self->debug("Found checksum for $basename:" .
3557 "$cksum->{$basename}{md5}\n") if $CPAN::DEBUG;
3561 my $eq = $self->eq_MD5($fh,$cksum->{$basename}{'md5'});
3563 $fh = CPAN::Tarzip->TIEHANDLE($file);
3566 # had to inline it, when I tied it, the tiedness got lost on
3567 # the call to eq_MD5. (Jan 1998)
3571 while ($fh->READ($ref, 4096) > 0){
3574 my $hexdigest = $md5->hexdigest;
3575 $eq += $hexdigest eq $cksum->{$basename}{'md5-ungz'};
3579 $CPAN::Frontend->myprint("Checksum for $file ok\n");
3580 return $self->{MD5_STATUS} = "OK";
3582 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
3583 qq{distribution file. }.
3584 qq{Please investigate.\n\n}.
3586 $CPAN::META->instance(
3588 $self->{CPAN_USERID}
3591 my $wrap = qq{I\'d recommend removing $file. Its MD5
3592 checksum is incorrect. Maybe you have configured your 'urllist' with
3593 a bad URL. Please check this array with 'o conf urllist', and
3596 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
3598 # former versions just returned here but this seems a
3599 # serious threat that deserves a die
3601 # $CPAN::Frontend->myprint("\n\n");
3605 # close $fh if fileno($fh);
3607 $self->{MD5_STATUS} ||= "";
3608 if ($self->{MD5_STATUS} eq "NIL") {
3609 $CPAN::Frontend->myprint(qq{
3610 No md5 checksum for $basename in local $chk_file.
3613 unlink $chk_file or $CPAN::Frontend->myprint("Could not unlink: $!");
3616 $self->{MD5_STATUS} = "NIL";
3621 #-> sub CPAN::Distribution::eq_MD5 ;
3623 my($self,$fh,$expectMD5) = @_;
3626 while (read($fh, $data, 4096)){
3629 # $md5->addfile($fh);
3630 my $hexdigest = $md5->hexdigest;
3631 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
3632 $hexdigest eq $expectMD5;
3635 #-> sub CPAN::Distribution::force ;
3637 # Both modules and distributions know if "force" is in effect by
3638 # autoinspection, not by inspecting a global variable. One of the
3639 # reason why this was chosen to work that way was the treatment of
3640 # dependencies. They should not autpomatically inherit the force
3641 # status. But this has the downside that ^C and die() will return to
3642 # the prompt but will not be able to reset the force_update
3643 # attributes. We try to correct for it currently in the read_metadata
3644 # routine, and immediately before we check for a Signal. I hope this
3645 # works out in one of v1.57_53ff
3648 my($self, $method) = @_;
3650 MD5_STATUS archived build_dir localfile make install unwrapped
3653 delete $self->{$att};
3655 if ($method && $method eq "install") {
3656 $self->{"force_update"}++; # name should probably have been force_install
3660 #-> sub CPAN::Distribution::unforce ;
3663 delete $self->{'force_update'};
3666 #-> sub CPAN::Distribution::isa_perl ;
3669 my $file = File::Basename::basename($self->id);
3670 if ($file =~ m{ ^ perl
3683 } elsif ($self->{'CPAN_COMMENT'} && $self->{'CPAN_COMMENT'} =~ /isa_perl\(.+?\)/){
3688 #-> sub CPAN::Distribution::perl ;
3691 my($perl) = MM->file_name_is_absolute($^X) ? $^X : "";
3692 my $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
3693 my $pwd = CPAN->$getcwd();
3694 my $candidate = MM->catfile($pwd,$^X);
3695 $perl ||= $candidate if MM->maybe_command($candidate);
3697 my ($component,$perl_name);
3698 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
3699 PATH_COMPONENT: foreach $component (MM->path(),
3700 $Config::Config{'binexp'}) {
3701 next unless defined($component) && $component;
3702 my($abs) = MM->catfile($component,$perl_name);
3703 if (MM->maybe_command($abs)) {
3713 #-> sub CPAN::Distribution::make ;
3716 $CPAN::Frontend->myprint(sprintf "Running make for %s\n", $self->id);
3717 # Emergency brake if they said install Pippi and get newest perl
3718 if ($self->isa_perl) {
3720 $self->called_for ne $self->id &&
3721 ! $self->{force_update}
3723 # if we die here, we break bundles
3724 $CPAN::Frontend->mywarn(sprintf qq{
3725 The most recent version "%s" of the module "%s"
3726 comes with the current version of perl (%s).
3727 I\'ll build that only if you ask for something like
3732 $CPAN::META->instance(
3735 )->cpan_version, # %vd not needed
3746 $self->{archived} eq "NO" and push @e,
3747 "Is neither a tar nor a zip archive.";
3749 $self->{unwrapped} eq "NO" and push @e,
3750 "had problems unarchiving. Please build manually";
3752 exists $self->{writemakefile} &&
3753 $self->{writemakefile} =~ m/ ^ NO\s* ( .* ) /sx and push @e,
3754 $1 || "Had some problem writing Makefile";
3756 defined $self->{'make'} and push @e,
3757 "Has already been processed within this session";
3759 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3761 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
3762 my $builddir = $self->dir;
3763 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
3764 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
3766 if ($^O eq 'MacOS') {
3767 ExtUtils::MM_MacOS::make($self);
3772 if ($self->{'configure'}) {
3773 $system = $self->{'configure'};
3775 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
3777 # This needs a handler that can be turned on or off:
3778 # $switch = "-MExtUtils::MakeMaker ".
3779 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
3781 $system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}";
3783 unless (exists $self->{writemakefile}) {
3784 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
3787 if ($CPAN::Config->{inactivity_timeout}) {
3789 alarm $CPAN::Config->{inactivity_timeout};
3790 local $SIG{CHLD}; # = sub { wait };
3791 if (defined($pid = fork)) {
3796 # note, this exec isn't necessary if
3797 # inactivity_timeout is 0. On the Mac I'd
3798 # suggest, we set it always to 0.
3802 $CPAN::Frontend->myprint("Cannot fork: $!");
3810 $CPAN::Frontend->myprint($@);
3811 $self->{writemakefile} = "NO $@";
3816 $ret = system($system);
3818 $self->{writemakefile} = "NO Makefile.PL returned status $ret";
3822 if (-f "Makefile") {
3823 $self->{writemakefile} = "YES";
3824 delete $self->{make_clean}; # if cleaned before, enable next
3826 $self->{writemakefile} =
3827 qq{NO Makefile.PL refused to write a Makefile.};
3828 # It's probably worth to record the reason, so let's retry
3830 # my $fh = IO::File->new("$system |"); # STDERR? STDIN?
3831 # $self->{writemakefile} .= <$fh>;
3835 delete $self->{force_update};
3838 if (my @prereq = $self->needs_prereq){
3840 $CPAN::Frontend->myprint("---- Dependencies detected ".
3841 "during [$id] -----\n");
3843 for my $p (@prereq) {
3844 $CPAN::Frontend->myprint(" $p\n");
3847 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
3849 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
3850 require ExtUtils::MakeMaker;
3851 my $answer = ExtUtils::MakeMaker::prompt(
3852 "Shall I follow them and prepend them to the queue
3853 of modules we are processing right now?", "yes");
3854 $follow = $answer =~ /^\s*y/i;
3858 myprint(" Ignoring dependencies on modules @prereq\n");
3861 CPAN::Queue->jumpqueue(@prereq,$id); # requeue yourself
3865 $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
3866 if (system($system) == 0) {
3867 $CPAN::Frontend->myprint(" $system -- OK\n");
3868 $self->{'make'} = "YES";
3870 $self->{writemakefile} ||= "YES";
3871 $self->{'make'} = "NO";
3872 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
3876 #-> sub CPAN::Distribution::needs_prereq ;
3879 return unless -f "Makefile"; # we cannot say much
3880 my $fh = FileHandle->new("<Makefile") or
3881 $CPAN::Frontend->mydie("Couldn't open Makefile: $!");
3884 # A.Speer @p -> %p, where %p is $p{Module::Name}=Required_Version
3888 last if /MakeMaker post_initialize section/;
3890 \s+PREREQ_PM\s+=>\s+(.+)
3893 # warn "Found prereq expr[$p]";
3895 # Regexp modified by A.Speer to remember actual version of file
3896 # PREREQ_PM hash key wants, then add to
3897 while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
3898 # In case a prereq is mentioned twice, complain.
3899 if ( defined $p{$1} ) {
3900 warn "Warning: PREREQ_PM mentions $1 more than once, last mention wins";
3906 NEED: while (my($module, $need_version) = each %p) {
3907 my $mo = $CPAN::META->instance("CPAN::Module",$module);
3908 # we were too demanding:
3909 # next if $mo->uptodate;
3911 # We only want to install prereqs if either they're not installed
3912 # or if the installed version is too old. We cannot omit this
3913 # check, because if 'force' is in effect, nobody else will check.
3917 defined $mo->inst_file &&
3918 ! CPAN::Version->vgt($need_version, $mo->inst_version)
3920 CPAN->debug(sprintf "inst_file[%s]inst_version[%s]need_version[%s]",
3923 CPAN::Version->readable($need_version)
3929 if ($self->{have_sponsored}{$module}++){
3930 # We have already sponsored it and for some reason it's still
3931 # not available. So we do nothing. Or what should we do?
3932 # if we push it again, we have a potential infinite loop
3935 push @need, $module;
3940 #-> sub CPAN::Distribution::test ;
3945 delete $self->{force_update};
3948 $CPAN::Frontend->myprint("Running make test\n");
3951 exists $self->{'make'} or push @e,
3952 "Make had some problems, maybe interrupted? Won't test";
3954 exists $self->{'make'} and
3955 $self->{'make'} eq 'NO' and
3956 push @e, "Can't test without successful make";
3958 exists $self->{'build_dir'} or push @e, "Has no own directory";
3959 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3961 chdir $self->{'build_dir'} or
3962 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
3963 $self->debug("Changed directory to $self->{'build_dir'}")
3966 if ($^O eq 'MacOS') {
3967 ExtUtils::MM_MacOS::make_test($self);
3971 my $system = join " ", $CPAN::Config->{'make'}, "test";
3972 if (system($system) == 0) {
3973 $CPAN::Frontend->myprint(" $system -- OK\n");
3974 $self->{'make_test'} = "YES";
3976 $self->{'make_test'} = "NO";
3977 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
3981 #-> sub CPAN::Distribution::clean ;
3984 $CPAN::Frontend->myprint("Running make clean\n");
3987 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
3988 push @e, "make clean already called once";
3989 exists $self->{build_dir} or push @e, "Has no own directory";
3990 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3992 chdir $self->{'build_dir'} or
3993 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
3994 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
3996 if ($^O eq 'MacOS') {
3997 ExtUtils::MM_MacOS::make_clean($self);
4001 my $system = join " ", $CPAN::Config->{'make'}, "clean";
4002 if (system($system) == 0) {
4003 $CPAN::Frontend->myprint(" $system -- OK\n");
4007 # Jost Krieger pointed out that this "force" was wrong because
4008 # it has the effect that the next "install" on this distribution
4009 # will untar everything again. Instead we should bring the
4010 # object's state back to where it is after untarring.
4012 delete $self->{force_update};
4013 delete $self->{install};
4014 delete $self->{writemakefile};
4015 delete $self->{make};
4016 delete $self->{make_test}; # no matter if yes or no, tests must be redone
4017 $self->{make_clean} = "YES";
4020 # Hmmm, what to do if make clean failed?
4022 $CPAN::Frontend->myprint(qq{ $system -- NOT OK
4024 make clean did not succeed, marking directory as unusable for further work.
4026 $self->force("make"); # so that this directory won't be used again
4031 #-> sub CPAN::Distribution::install ;
4036 delete $self->{force_update};
4039 $CPAN::Frontend->myprint("Running make install\n");
4042 exists $self->{'build_dir'} or push @e, "Has no own directory";
4044 exists $self->{'make'} or push @e,
4045 "Make had some problems, maybe interrupted? Won't install";
4047 exists $self->{'make'} and
4048 $self->{'make'} eq 'NO' and
4049 push @e, "make had returned bad status, won't install without force";
4051 push @e, "make test had returned bad status, ".
4052 "won't install without force"
4053 if exists $self->{'make_test'} and
4054 $self->{'make_test'} eq 'NO' and
4055 ! $self->{'force_update'};
4057 exists $self->{'install'} and push @e,
4058 $self->{'install'} eq "YES" ?
4059 "Already done" : "Already tried without success";
4061 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4063 chdir $self->{'build_dir'} or
4064 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4065 $self->debug("Changed directory to $self->{'build_dir'}")
4068 if ($^O eq 'MacOS') {
4069 ExtUtils::MM_MacOS::make_install($self);
4073 my $system = join(" ", $CPAN::Config->{'make'},
4074 "install", $CPAN::Config->{make_install_arg});
4075 my($stderr) = $^O =~ /Win/i ? "" : " 2>&1 ";
4076 my($pipe) = FileHandle->new("$system $stderr |");
4079 $CPAN::Frontend->myprint($_);
4084 $CPAN::Frontend->myprint(" $system -- OK\n");
4085 return $self->{'install'} = "YES";
4087 $self->{'install'} = "NO";
4088 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4089 if ($makeout =~ /permission/s && $> > 0) {
4090 $CPAN::Frontend->myprint(qq{ You may have to su }.
4091 qq{to root to install the package\n});
4094 delete $self->{force_update};
4097 #-> sub CPAN::Distribution::dir ;
4099 shift->{'build_dir'};
4102 package CPAN::Bundle;
4104 #-> sub CPAN::Bundle::as_string ;
4108 # following line must be "=", not "||=" because we have a moving target
4109 $self->{INST_VERSION} = $self->inst_version; # %vd already applied
4110 return $self->SUPER::as_string;
4113 #-> sub CPAN::Bundle::contains ;
4116 my($parsefile) = $self->inst_file;
4117 my($id) = $self->id;
4118 $self->debug("parsefile[$parsefile]id[$id]") if $CPAN::DEBUG;
4119 unless ($parsefile) {
4120 # Try to get at it in the cpan directory
4121 $self->debug("no parsefile") if $CPAN::DEBUG;
4122 Carp::confess "I don't know a $id" unless $self->{CPAN_FILE};
4123 my $dist = $CPAN::META->instance('CPAN::Distribution',
4124 $self->{CPAN_FILE});
4126 $self->debug($dist->as_string) if $CPAN::DEBUG;
4127 my($todir) = $CPAN::Config->{'cpan_home'};
4128 my(@me,$from,$to,$me);
4129 @me = split /::/, $self->id;
4131 $me = MM->catfile(@me);
4132 $from = $self->find_bundle_file($dist->{'build_dir'},$me);
4133 $to = MM->catfile($todir,$me);
4134 File::Path::mkpath(File::Basename::dirname($to));
4135 File::Copy::copy($from, $to)
4136 or Carp::confess("Couldn't copy $from to $to: $!");
4140 my $fh = FileHandle->new;
4142 open($fh,$parsefile) or die "Could not open '$parsefile': $!";
4144 $self->debug("parsefile[$parsefile]") if $CPAN::DEBUG;
4146 $in_cont = m/^=(?!head1\s+CONTENTS)/ ? 0 :
4147 m/^=head1\s+CONTENTS/ ? 1 : $in_cont;
4148 next unless $in_cont;
4153 push @result, (split " ", $_, 2)[0];
4156 delete $self->{STATUS};
4157 $self->{CONTAINS} = join ", ", @result;
4158 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
4160 $CPAN::Frontend->mywarn(qq{
4161 The bundle file "$parsefile" may be a broken
4162 bundlefile. It seems not to contain any bundle definition.
4163 Please check the file and if it is bogus, please delete it.
4164 Sorry for the inconvenience.
4170 #-> sub CPAN::Bundle::find_bundle_file
4171 sub find_bundle_file {
4172 my($self,$where,$what) = @_;
4173 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
4174 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
4175 ### my $bu = MM->catfile($where,$what);
4176 ### return $bu if -f $bu;
4177 my $manifest = MM->catfile($where,"MANIFEST");
4178 unless (-f $manifest) {
4179 require ExtUtils::Manifest;
4180 my $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
4181 my $cwd = CPAN->$getcwd();
4182 chdir $where or $CPAN::Frontend->mydie(qq{Could not chdir to "$where": $!});
4183 ExtUtils::Manifest::mkmanifest();
4184 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
4186 my $fh = FileHandle->new($manifest)
4187 or Carp::croak("Couldn't open $manifest: $!");
4190 if ($^O eq 'MacOS') {
4193 $what2 =~ s/:Bundle://;
4196 $what2 =~ s|Bundle[/\\]||;
4201 my($file) = /(\S+)/;
4202 if ($file =~ m|\Q$what\E$|) {
4204 # return MM->catfile($where,$bu); # bad
4207 # retry if she managed to
4208 # have no Bundle directory
4209 $bu = $file if $file =~ m|\Q$what2\E$|;
4211 $bu =~ tr|/|:| if $^O eq 'MacOS';
4212 return MM->catfile($where, $bu) if $bu;
4213 Carp::croak("Couldn't find a Bundle file in $where");
4216 #-> sub CPAN::Bundle::inst_file ;
4220 ($me = $self->id) =~ s/.*://;
4221 ## my(@me,$inst_file);
4222 ## @me = split /::/, $self->id;
4223 ## $me[-1] .= ".pm";
4224 $inst_file = MM->catfile($CPAN::Config->{'cpan_home'},
4225 "Bundle", "$me.pm");
4227 return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
4229 $self->SUPER::inst_file;
4230 # return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
4231 # return $self->{'INST_FILE'}; # even if undefined?
4234 #-> sub CPAN::Bundle::rematein ;
4236 my($self,$meth) = @_;
4237 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
4238 my($id) = $self->id;
4239 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
4240 unless $self->inst_file || $self->{CPAN_FILE};
4242 for $s ($self->contains) {
4243 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
4244 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
4245 if ($type eq 'CPAN::Distribution') {
4246 $CPAN::Frontend->mywarn(qq{
4247 The Bundle }.$self->id.qq{ contains
4248 explicitly a file $s.
4252 # possibly noisy action:
4253 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
4254 my $obj = $CPAN::META->instance($type,$s);
4256 if ($obj->isa(CPAN::Bundle)
4258 exists $obj->{install_failed}
4260 ref($obj->{install_failed}) eq "HASH"
4262 for (keys %{$obj->{install_failed}}) {
4263 $self->{install_failed}{$_} = undef; # propagate faiure up
4266 $fail{$s} = 1; # the bundle itself may have succeeded but
4271 $success = $obj->can("uptodate") ? $obj->uptodate : 0;
4272 $success ||= $obj->{'install'} && $obj->{'install'} eq "YES";
4274 delete $self->{install_failed}{$s};
4281 # recap with less noise
4282 if ( $meth eq "install" ) {
4285 my $raw = sprintf(qq{Bundle summary:
4286 The following items in bundle %s had installation problems:},
4289 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
4290 $CPAN::Frontend->myprint("\n");
4293 for $s ($self->contains) {
4295 $paragraph .= "$s ";
4296 $self->{install_failed}{$s} = undef;
4297 $reported{$s} = undef;
4300 my $report_propagated;
4301 for $s (sort keys %{$self->{install_failed}}) {
4302 next if exists $reported{$s};
4303 $paragraph .= "and the following items had problems
4304 during recursive bundle calls: " unless $report_propagated++;
4305 $paragraph .= "$s ";
4307 $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
4308 $CPAN::Frontend->myprint("\n");
4310 $self->{'install'} = 'YES';
4315 #sub CPAN::Bundle::xs_file
4317 # If a bundle contains another that contains an xs_file we have
4318 # here, we just don't bother I suppose
4322 #-> sub CPAN::Bundle::force ;
4323 sub force { shift->rematein('force',@_); }
4324 #-> sub CPAN::Bundle::get ;
4325 sub get { shift->rematein('get',@_); }
4326 #-> sub CPAN::Bundle::make ;
4327 sub make { shift->rematein('make',@_); }
4328 #-> sub CPAN::Bundle::test ;
4329 sub test { shift->rematein('test',@_); }
4330 #-> sub CPAN::Bundle::install ;
4333 $self->rematein('install',@_);
4335 #-> sub CPAN::Bundle::clean ;
4336 sub clean { shift->rematein('clean',@_); }
4338 #-> sub CPAN::Bundle::readme ;
4341 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
4342 No File found for bundle } . $self->id . qq{\n}), return;
4343 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
4344 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
4347 package CPAN::Module;
4349 #-> sub CPAN::Module::as_glimpse ;
4353 my $class = ref($self);
4354 $class =~ s/^CPAN:://;
4355 push @m, sprintf("%-15s %-15s (%s)\n", $class, $self->{ID},
4360 #-> sub CPAN::Module::as_string ;
4364 CPAN->debug($self) if $CPAN::DEBUG;
4365 my $class = ref($self);
4366 $class =~ s/^CPAN:://;
4368 push @m, $class, " id = $self->{ID}\n";
4369 my $sprintf = " %-12s %s\n";
4370 push @m, sprintf($sprintf, 'DESCRIPTION', $self->{description})
4371 if $self->{description};
4372 my $sprintf2 = " %-12s %s (%s)\n";
4374 if ($userid = $self->{'CPAN_USERID'} || $self->{'userid'}){
4376 if ($author = CPAN::Shell->expand('Author',$userid)) {
4379 if ($m = $author->email) {
4386 $author->fullname . $email
4390 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->{CPAN_VERSION}) # %vd not needed
4391 if $self->{CPAN_VERSION}; # %vd not needed
4392 push @m, sprintf($sprintf, 'CPAN_FILE', $self->{CPAN_FILE})
4393 if $self->{CPAN_FILE};
4394 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
4395 my(%statd,%stats,%statl,%stati);
4396 @statd{qw,? i c a b R M S,} = qw,unknown idea
4397 pre-alpha alpha beta released mature standard,;
4398 @stats{qw,? m d u n,} = qw,unknown mailing-list
4399 developer comp.lang.perl.* none,;
4400 @statl{qw,? p c + o h,} = qw,unknown perl C C++ other hybrid,;
4401 @stati{qw,? f r O h,} = qw,unknown functions
4402 references+ties object-oriented hybrid,;
4403 $statd{' '} = 'unknown';
4404 $stats{' '} = 'unknown';
4405 $statl{' '} = 'unknown';
4406 $stati{' '} = 'unknown';
4414 $statd{$self->{statd}},
4415 $stats{$self->{stats}},
4416 $statl{$self->{statl}},
4417 $stati{$self->{stati}}
4418 ) if $self->{statd};
4419 my $local_file = $self->inst_file;
4421 $self->{MANPAGE} ||= $self->manpage_headline($local_file);
4424 for $item (qw/MANPAGE CONTAINS/) {
4425 push @m, sprintf($sprintf, $item, $self->{$item})
4426 if exists $self->{$item};
4428 push @m, sprintf($sprintf, 'INST_FILE',
4429 $local_file || "(not installed)");
4430 push @m, sprintf($sprintf, 'INST_VERSION',
4431 $self->inst_version) if $local_file; #%vd already applied
4435 sub manpage_headline {
4436 my($self,$local_file) = @_;
4437 my(@local_file) = $local_file;
4438 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
4439 push @local_file, $local_file;
4441 for $locf (@local_file) {
4442 next unless -f $locf;
4443 my $fh = FileHandle->new($locf)
4444 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
4448 $inpod = m/^=(?!head1\s+NAME)/ ? 0 :
4449 m/^=head1\s+NAME/ ? 1 : $inpod;
4462 #-> sub CPAN::Module::cpan_file ;
4465 CPAN->debug($self->id) if $CPAN::DEBUG;
4466 unless (defined $self->{'CPAN_FILE'}) {
4467 CPAN::Index->reload;
4469 if (exists $self->{'CPAN_FILE'} && defined $self->{'CPAN_FILE'}){
4470 return $self->{'CPAN_FILE'};
4471 } elsif (exists $self->{'userid'} && defined $self->{'userid'}) {
4472 my $fullname = $CPAN::META->instance(CPAN::Author,
4473 $self->{'userid'})->fullname;
4474 my $email = $CPAN::META->instance(CPAN::Author,
4475 $self->{'userid'})->email;
4476 unless (defined $fullname && defined $email) {
4477 return "Contact Author $self->{userid} (Try 'a $self->{userid}')";
4479 return "Contact Author $fullname <$email>";
4485 *name = \&cpan_file;
4487 #-> sub CPAN::Module::cpan_version ;
4490 $self->{'CPAN_VERSION'} = 'undef'
4491 unless defined $self->{'CPAN_VERSION'}; # I believe this is
4492 # always a bug in the
4493 # index and should be
4495 # but usually I find
4497 # and do not want to
4500 $self->{'CPAN_VERSION'}; # %vd not needed
4503 #-> sub CPAN::Module::force ;
4506 $self->{'force_update'}++;
4509 #-> sub CPAN::Module::rematein ;
4511 my($self,$meth) = @_;
4512 $self->debug($self->id) if $CPAN::DEBUG;
4513 my $cpan_file = $self->cpan_file;
4514 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
4515 $CPAN::Frontend->mywarn(sprintf qq{
4516 The module %s isn\'t available on CPAN.
4518 Either the module has not yet been uploaded to CPAN, or it is
4519 temporary unavailable. Please contact the author to find out
4520 more about the status. Try 'i %s'.
4527 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
4528 $pack->called_for($self->id);
4529 $pack->force($meth) if exists $self->{'force_update'};
4531 $pack->unforce if $pack->can("unforce") && exists $self->{'force_update'};
4532 delete $self->{'force_update'};
4535 #-> sub CPAN::Module::readme ;
4536 sub readme { shift->rematein('readme') }
4537 #-> sub CPAN::Module::look ;
4538 sub look { shift->rematein('look') }
4539 #-> sub CPAN::Module::cvs_import ;
4540 sub cvs_import { shift->rematein('cvs_import') }
4541 #-> sub CPAN::Module::get ;
4542 sub get { shift->rematein('get',@_); }
4543 #-> sub CPAN::Module::make ;
4544 sub make { shift->rematein('make') }
4545 #-> sub CPAN::Module::test ;
4546 sub test { shift->rematein('test') }
4547 #-> sub CPAN::Module::uptodate ;
4550 my($latest) = $self->cpan_version; # %vd not needed
4552 my($inst_file) = $self->inst_file;
4554 if (defined $inst_file) {
4555 $have = $self->inst_version; # %vd already applied
4560 ! CPAN::Version->vgt($latest, $have)
4566 #-> sub CPAN::Module::install ;
4572 not exists $self->{'force_update'}
4574 $CPAN::Frontend->myprint( $self->id. " is up to date.\n");
4578 $self->rematein('install') if $doit;
4580 #-> sub CPAN::Module::clean ;
4581 sub clean { shift->rematein('clean') }
4583 #-> sub CPAN::Module::inst_file ;
4587 @packpath = split /::/, $self->{ID};
4588 $packpath[-1] .= ".pm";
4589 foreach $dir (@INC) {
4590 my $pmfile = MM->catfile($dir,@packpath);
4598 #-> sub CPAN::Module::xs_file ;
4602 @packpath = split /::/, $self->{ID};
4603 push @packpath, $packpath[-1];
4604 $packpath[-1] .= "." . $Config::Config{'dlext'};
4605 foreach $dir (@INC) {
4606 my $xsfile = MM->catfile($dir,'auto',@packpath);
4614 #-> sub CPAN::Module::inst_version ;
4617 my $parsefile = $self->inst_file or return;
4618 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
4620 # local($SIG{__WARN__}) = sub { warn "1. have[$have]"; };
4622 # there was a bug in 5.6.0 that let lots of unini warnings out of
4623 # parse_version. Fixed shortly after 5.6.0 by PMQS. We can remove
4624 # the following workaround after 5.6.1 is out.
4625 local($SIG{__WARN__}) = sub { my $w = shift;
4626 return if $w =~ /uninitialized/i;
4630 $have = MM->parse_version($parsefile) || "undef";
4631 $have =~ s/^ //; # since the %vd hack these two lines here are needed
4632 $have =~ s/ $//; # trailing whitespace happens all the time
4634 # local($SIG{__WARN__}) = sub { warn "2. have[$have]"; };
4636 # My thoughts about why %vd processing should happen here
4638 # Alt1 maintain it as string with leading v:
4639 # read index files do nothing
4640 # compare it use utility for compare
4641 # print it do nothing
4643 # Alt2 maintain it as what is is
4644 # read index files convert
4645 # compare it use utility because there's still a ">" vs "gt" issue
4646 # print it use CPAN::Version for print
4648 # Seems cleaner to hold it in memory as a string starting with a "v"
4650 # If the author of this module made a mistake and wrote a quoted
4651 # "v1.13" instead of v1.13, we simply leave it at that with the
4652 # effect that *we* will treat it like a v-tring while the rest of
4653 # perl won't. Seems sensible when we consider that any action we
4654 # could take now would just add complexity.
4656 $have = CPAN::Version->readable($have);
4658 $have =~ s/\s*//g; # stringify to float around floating point issues
4659 $have; # no stringify needed, \s* above matches always
4662 package CPAN::Tarzip;
4664 # CPAN::Tarzip::gzip
4666 my($class,$read,$write) = @_;
4667 if ($CPAN::META->has_inst("Compress::Zlib")) {
4669 $fhw = FileHandle->new($read)
4670 or $CPAN::Frontend->mydie("Could not open $read: $!");
4671 my $gz = Compress::Zlib::gzopen($write, "wb")
4672 or $CPAN::Frontend->mydie("Cannot gzopen $write: $!\n");
4673 $gz->gzwrite($buffer)
4674 while read($fhw,$buffer,4096) > 0 ;
4679 system("$CPAN::Config->{'gzip'} -c $read > $write")==0;
4684 # CPAN::Tarzip::gunzip
4686 my($class,$read,$write) = @_;
4687 if ($CPAN::META->has_inst("Compress::Zlib")) {
4689 $fhw = FileHandle->new(">$write")
4690 or $CPAN::Frontend->mydie("Could not open >$write: $!");
4691 my $gz = Compress::Zlib::gzopen($read, "rb")
4692 or $CPAN::Frontend->mydie("Cannot gzopen $read: $!\n");
4693 $fhw->print($buffer)
4694 while $gz->gzread($buffer) > 0 ;
4695 $CPAN::Frontend->mydie("Error reading from $read: $!\n")
4696 if $gz->gzerror != Compress::Zlib::Z_STREAM_END();
4701 system("$CPAN::Config->{'gzip'} -dc $read > $write")==0;
4706 # CPAN::Tarzip::gtest
4708 my($class,$read) = @_;
4709 if ($CPAN::META->has_inst("Compress::Zlib")) {
4711 my $gz = Compress::Zlib::gzopen($read, "rb")
4712 or $CPAN::Frontend->mydie("Cannot open $read: $!\n");
4713 1 while $gz->gzread($buffer) > 0 ;
4714 my $err = $gz->gzerror;
4715 my $success = ! $err || $err == Compress::Zlib::Z_STREAM_END();
4717 $class->debug("err[$err]success[$success]") if $CPAN::DEBUG;
4720 return system("$CPAN::Config->{'gzip'} -dt $read")==0;
4725 # CPAN::Tarzip::TIEHANDLE
4727 my($class,$file) = @_;
4729 $class->debug("file[$file]");
4730 if ($CPAN::META->has_inst("Compress::Zlib")) {
4731 my $gz = Compress::Zlib::gzopen($file,"rb") or
4732 die "Could not gzopen $file";
4733 $ret = bless {GZ => $gz}, $class;
4735 my $pipe = "$CPAN::Config->{'gzip'} --decompress --stdout $file |";
4736 my $fh = FileHandle->new($pipe) or die "Could pipe[$pipe]: $!";
4738 $ret = bless {FH => $fh}, $class;
4744 # CPAN::Tarzip::READLINE
4747 if (exists $self->{GZ}) {
4748 my $gz = $self->{GZ};
4749 my($line,$bytesread);
4750 $bytesread = $gz->gzreadline($line);
4751 return undef if $bytesread <= 0;
4754 my $fh = $self->{FH};
4755 return scalar <$fh>;
4760 # CPAN::Tarzip::READ
4762 my($self,$ref,$length,$offset) = @_;
4763 die "read with offset not implemented" if defined $offset;
4764 if (exists $self->{GZ}) {
4765 my $gz = $self->{GZ};
4766 my $byteread = $gz->gzread($$ref,$length);# 30eaf79e8b446ef52464b5422da328a8
4769 my $fh = $self->{FH};
4770 return read($fh,$$ref,$length);
4775 # CPAN::Tarzip::DESTROY
4778 if (exists $self->{GZ}) {
4779 my $gz = $self->{GZ};
4782 my $fh = $self->{FH};
4783 $fh->close if defined $fh;
4789 # CPAN::Tarzip::untar
4791 my($class,$file) = @_;
4792 if (0) { # makes changing order easier
4793 } elsif ($CPAN::META->has_inst("Archive::Tar")
4795 $CPAN::META->has_inst("Compress::Zlib") ) {
4796 my $tar = Archive::Tar->new($file,1);
4797 my $af; # archive file
4798 for $af ($tar->list_files) {
4799 if ($af =~ m!^(/|\.\./)!) {
4800 $CPAN::Frontend->mydie("ALERT: Archive contains illegal member [$af]");
4802 $CPAN::Frontend->myprint("$af\n");
4804 return if $CPAN::Signal;
4807 ExtUtils::MM_MacOS::convert_files([$tar->list_files], 1)
4808 if ($^O eq 'MacOS');
4811 } elsif (MM->maybe_command($CPAN::Config->{'gzip'})
4813 MM->maybe_command($CPAN::Config->{'tar'})) {
4814 my $system = "$CPAN::Config->{'gzip'} --decompress --stdout " .
4815 "< $file | $CPAN::Config->{tar} xvf -";
4816 if (system($system) != 0) {
4817 # people find the most curious tar binaries that cannot handle
4819 my $system = "$CPAN::Config->{'gzip'} --decompress $file";
4820 if (system($system)==0) {
4821 $CPAN::Frontend->myprint(qq{Uncompressed $file successfully\n});
4823 $CPAN::Frontend->mydie(
4824 qq{Couldn\'t uncompress $file\n}
4827 $file =~ s/\.gz(?!\n)\Z//;
4828 $system = "$CPAN::Config->{tar} xvf $file";
4829 $CPAN::Frontend->myprint(qq{Using Tar:$system:\n});
4830 if (system($system)==0) {
4831 $CPAN::Frontend->myprint(qq{Untarred $file successfully\n});
4833 $CPAN::Frontend->mydie(qq{Couldn\'t untar $file\n});
4840 $CPAN::Frontend->mydie(qq{
4841 CPAN.pm needs either both external programs tar and gzip installed or
4842 both the modules Archive::Tar and Compress::Zlib. Neither prerequisite
4843 is available. Can\'t continue.
4849 my($class,$file) = @_;
4850 if ($CPAN::META->has_inst("Archive::Zip")) {
4851 # blueprint of the code from Archive::Zip::Tree::extractTree();
4852 my $zip = Archive::Zip->new();
4854 $status = $zip->read($file);
4855 die "Read of file[$file] failed\n" if $status != Archive::Zip::AZ_OK();
4856 $CPAN::META->debug("Successfully read file[$file]") if $CPAN::DEBUG;
4857 my @members = $zip->members();
4858 for my $member ( @members ) {
4859 my $af = $member->fileName();
4860 if ($af =~ m!^(/|\.\./)!) {
4861 $CPAN::Frontend->mydie("ALERT: Archive contains illegal member [$af]");
4863 my $status = $member->extractToFileNamed( $af );
4864 $CPAN::META->debug("af[$af]status[$status]") if $CPAN::DEBUG;
4865 die "Extracting of file[$af] from zipfile[$file] failed\n" if
4866 $status != Archive::Zip::AZ_OK();
4867 return if $CPAN::Signal;
4871 my $unzip = $CPAN::Config->{unzip} or
4872 $CPAN::Frontend->mydie("Cannot unzip, no unzip program available");
4873 my @system = ($unzip, $file);
4874 return system(@system) == 0;
4879 package CPAN::Version;
4880 # CPAN::Version::vcmp courtesy Jost Krieger
4882 my($self,$l,$r) = @_;
4884 CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG;
4886 return 0 if $l eq $r; # short circuit for quicker success
4888 if ($l=~/^v/ <=> $r=~/^v/) {
4891 $_ = $self->float2vv($_);
4896 ($l ne "undef") <=> ($r ne "undef") ||
4900 $self->vstring($l) cmp $self->vstring($r)) ||
4906 my($self,$l,$r) = @_;
4907 $self->vcmp($l,$r) > 0;
4912 $n =~ s/^v// or die "CPAN::Version::vstring() called with invalid argument [$n]";
4913 pack "U*", split /\./, $n;
4916 # vv => visible vstring
4921 my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits so that
4922 # architecture cannot
4925 $mantissa .= "0" while length($mantissa)%3;
4926 my $ret = "v" . $rev;
4928 $mantissa =~ s/(\d{1,3})// or
4929 die "Panic: length>0 but not a digit? mantissa[$mantissa]";
4930 $ret .= ".".int($1);
4932 # warn "n[$n]ret[$ret]";
4938 $n =~ /^([\w\-\+\.]+)/;
4940 return $1 if defined $1 && length($1)>0;
4941 # if the first user reaches version v43, he will be treated as "+".
4942 # We'll have to decide about a new rule here then, depending on what
4943 # will be the prevailing versioning behavior then.
4945 if ($] < 5.006) { # or whenever v-strings were introduced
4946 # we get them wrong anyway, whatever we do, because 5.005 will
4947 # have already interpreted 0.2.4 to be "0.24". So even if he
4948 # indexer sends us something like "v0.2.4" we compare wrongly.
4950 # And if they say v1.2, then the old perl takes it as "v12"
4952 $CPAN::Frontend->mywarn("Suspicious version string seen [$n]");
4955 my $better = sprintf "v%vd", $n;
4956 CPAN->debug("n[$n] better[$better]") if $CPAN::DEBUG;
4968 CPAN - query, download and build perl modules from CPAN sites
4974 perl -MCPAN -e shell;
4980 autobundle, clean, install, make, recompile, test
4984 The CPAN module is designed to automate the make and install of perl
4985 modules and extensions. It includes some searching capabilities and
4986 knows how to use Net::FTP or LWP (or lynx or an external ftp client)
4987 to fetch the raw data from the net.
4989 Modules are fetched from one or more of the mirrored CPAN
4990 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
4993 The CPAN module also supports the concept of named and versioned
4994 I<bundles> of modules. Bundles simplify the handling of sets of
4995 related modules. See Bundles below.
4997 The package contains a session manager and a cache manager. There is
4998 no status retained between sessions. The session manager keeps track
4999 of what has been fetched, built and installed in the current
5000 session. The cache manager keeps track of the disk space occupied by
5001 the make processes and deletes excess space according to a simple FIFO
5004 For extended searching capabilities there's a plugin for CPAN available,
5005 L<CPAN::WAIT>. C<CPAN::WAIT> is a full-text search engine that indexes
5006 all documents available in CPAN authors directories. If C<CPAN::WAIT>
5007 is installed on your system, the interactive shell of <CPAN.pm> will
5008 enable the C<wq>, C<wr>, C<wd>, C<wl>, and C<wh> commands which send
5009 queries to the WAIT server that has been configured for your
5012 All other methods provided are accessible in a programmer style and in an
5013 interactive shell style.
5015 =head2 Interactive Mode
5017 The interactive mode is entered by running
5019 perl -MCPAN -e shell
5021 which puts you into a readline interface. You will have the most fun if
5022 you install Term::ReadKey and Term::ReadLine to enjoy both history and
5025 Once you are on the command line, type 'h' and the rest should be
5028 The most common uses of the interactive modes are
5032 =item Searching for authors, bundles, distribution files and modules
5034 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
5035 for each of the four categories and another, C<i> for any of the
5036 mentioned four. Each of the four entities is implemented as a class
5037 with slightly differing methods for displaying an object.
5039 Arguments you pass to these commands are either strings exactly matching
5040 the identification string of an object or regular expressions that are
5041 then matched case-insensitively against various attributes of the
5042 objects. The parser recognizes a regular expression only if you
5043 enclose it between two slashes.
5045 The principle is that the number of found objects influences how an
5046 item is displayed. If the search finds one item, the result is
5047 displayed with the rather verbose method C<as_string>, but if we find
5048 more than one, we display each object with the terse method
5051 =item make, test, install, clean modules or distributions
5053 These commands take any number of arguments and investigate what is
5054 necessary to perform the action. If the argument is a distribution
5055 file name (recognized by embedded slashes), it is processed. If it is
5056 a module, CPAN determines the distribution file in which this module
5057 is included and processes that, following any dependencies named in
5058 the module's Makefile.PL (this behavior is controlled by
5059 I<prerequisites_policy>.)
5061 Any C<make> or C<test> are run unconditionally. An
5063 install <distribution_file>
5065 also is run unconditionally. But for
5069 CPAN checks if an install is actually needed for it and prints
5070 I<module up to date> in the case that the distribution file containing
5071 the module doesn't need to be updated.
5073 CPAN also keeps track of what it has done within the current session
5074 and doesn't try to build a package a second time regardless if it
5075 succeeded or not. The C<force> command takes as a first argument the
5076 method to invoke (currently: C<make>, C<test>, or C<install>) and executes the
5077 command from scratch.
5081 cpan> install OpenGL
5082 OpenGL is up to date.
5083 cpan> force install OpenGL
5086 OpenGL-0.4/COPYRIGHT
5089 A C<clean> command results in a
5093 being executed within the distribution file's working directory.
5095 =item get, readme, look module or distribution
5097 C<get> downloads a distribution file without further action. C<readme>
5098 displays the README file of the associated distribution. C<Look> gets
5099 and untars (if not yet done) the distribution file, changes to the
5100 appropriate directory and opens a subshell process in that directory.
5104 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
5105 in the cpan-shell it is intended that you can press C<^C> anytime and
5106 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
5107 to clean up and leave the shell loop. You can emulate the effect of a
5108 SIGTERM by sending two consecutive SIGINTs, which usually means by
5109 pressing C<^C> twice.
5111 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
5112 SIGALRM is used during the run of the C<perl Makefile.PL> subprocess.
5118 The commands that are available in the shell interface are methods in
5119 the package CPAN::Shell. If you enter the shell command, all your
5120 input is split by the Text::ParseWords::shellwords() routine which
5121 acts like most shells do. The first word is being interpreted as the
5122 method to be called and the rest of the words are treated as arguments
5123 to this method. Continuation lines are supported if a line ends with a
5128 C<autobundle> writes a bundle file into the
5129 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
5130 a list of all modules that are both available from CPAN and currently
5131 installed within @INC. The name of the bundle file is based on the
5132 current date and a counter.
5136 recompile() is a very special command in that it takes no argument and
5137 runs the make/test/install cycle with brute force over all installed
5138 dynamically loadable extensions (aka XS modules) with 'force' in
5139 effect. The primary purpose of this command is to finish a network
5140 installation. Imagine, you have a common source tree for two different
5141 architectures. You decide to do a completely independent fresh
5142 installation. You start on one architecture with the help of a Bundle
5143 file produced earlier. CPAN installs the whole Bundle for you, but
5144 when you try to repeat the job on the second architecture, CPAN
5145 responds with a C<"Foo up to date"> message for all modules. So you
5146 invoke CPAN's recompile on the second architecture and you're done.
5148 Another popular use for C<recompile> is to act as a rescue in case your
5149 perl breaks binary compatibility. If one of the modules that CPAN uses
5150 is in turn depending on binary compatibility (so you cannot run CPAN
5151 commands), then you should try the CPAN::Nox module for recovery.
5153 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
5155 Although it may be considered internal, the class hierarchy does matter
5156 for both users and programmer. CPAN.pm deals with above mentioned four
5157 classes, and all those classes share a set of methods. A classical
5158 single polymorphism is in effect. A metaclass object registers all
5159 objects of all kinds and indexes them with a string. The strings
5160 referencing objects have a separated namespace (well, not completely
5165 words containing a "/" (slash) Distribution
5166 words starting with Bundle:: Bundle
5167 everything else Module or Author
5169 Modules know their associated Distribution objects. They always refer
5170 to the most recent official release. Developers may mark their releases
5171 as unstable development versions (by inserting an underbar into the
5172 visible version number), so the really hottest and newest distribution
5173 file is not always the default. If a module Foo circulates on CPAN in
5174 both version 1.23 and 1.23_90, CPAN.pm offers a convenient way to
5175 install version 1.23 by saying
5179 This would install the complete distribution file (say
5180 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
5181 like to install version 1.23_90, you need to know where the
5182 distribution file resides on CPAN relative to the authors/id/
5183 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
5184 so you would have to say
5186 install BAR/Foo-1.23_90.tar.gz
5188 The first example will be driven by an object of the class
5189 CPAN::Module, the second by an object of class CPAN::Distribution.
5191 =head2 Programmer's interface
5193 If you do not enter the shell, the available shell commands are both
5194 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
5195 functions in the calling package (C<install(...)>).
5197 There's currently only one class that has a stable interface -
5198 CPAN::Shell. All commands that are available in the CPAN shell are
5199 methods of the class CPAN::Shell. Each of the commands that produce
5200 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
5201 the IDs of all modules within the list.
5205 =item expand($type,@things)
5207 The IDs of all objects available within a program are strings that can
5208 be expanded to the corresponding real objects with the
5209 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
5210 list of CPAN::Module objects according to the C<@things> arguments
5211 given. In scalar context it only returns the first element of the
5214 =item Programming Examples
5216 This enables the programmer to do operations that combine
5217 functionalities that are available in the shell.
5219 # install everything that is outdated on my disk:
5220 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
5222 # install my favorite programs if necessary:
5223 for $mod (qw(Net::FTP MD5 Data::Dumper)){
5224 my $obj = CPAN::Shell->expand('Module',$mod);
5228 # list all modules on my disk that have no VERSION number
5229 for $mod (CPAN::Shell->expand("Module","/./")){
5230 next unless $mod->inst_file;
5231 # MakeMaker convention for undefined $VERSION:
5232 next unless $mod->inst_version eq "undef";
5233 print "No VERSION in ", $mod->id, "\n";
5236 # find out which distribution on CPAN contains a module:
5237 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
5239 Or if you want to write a cronjob to watch The CPAN, you could list
5240 all modules that need updating. First a quick and dirty way:
5242 perl -e 'use CPAN; CPAN::Shell->r;'
5244 If you don't want to get any output if all modules are up to date, you
5245 can parse the output of above command for the regular expression
5246 //modules are up to date// and decide to mail the output only if it
5249 If you prefer to do it more in a programmer style in one single
5250 process, maybe something like this suites you better:
5252 # list all modules on my disk that have newer versions on CPAN
5253 for $mod (CPAN::Shell->expand("Module","/./")){
5254 next unless $mod->inst_file;
5255 next if $mod->uptodate;
5256 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
5257 $mod->id, $mod->inst_version, $mod->cpan_version;
5260 If that gives you too much output every day, you maybe only want to
5261 watch for three modules. You can write
5263 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")){
5265 as the first line instead. Or you can combine some of the above
5268 # watch only for a new mod_perl module
5269 $mod = CPAN::Shell->expand("Module","mod_perl");
5270 exit if $mod->uptodate;
5271 # new mod_perl arrived, let me know all update recommendations
5276 =head2 Methods in the four Classes
5278 =head2 Cache Manager
5280 Currently the cache manager only keeps track of the build directory
5281 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
5282 deletes complete directories below C<build_dir> as soon as the size of
5283 all directories there gets bigger than $CPAN::Config->{build_cache}
5284 (in MB). The contents of this cache may be used for later
5285 re-installations that you intend to do manually, but will never be
5286 trusted by CPAN itself. This is due to the fact that the user might
5287 use these directories for building modules on different architectures.
5289 There is another directory ($CPAN::Config->{keep_source_where}) where
5290 the original distribution files are kept. This directory is not
5291 covered by the cache manager and must be controlled by the user. If
5292 you choose to have the same directory as build_dir and as
5293 keep_source_where directory, then your sources will be deleted with
5294 the same fifo mechanism.
5298 A bundle is just a perl module in the namespace Bundle:: that does not
5299 define any functions or methods. It usually only contains documentation.
5301 It starts like a perl module with a package declaration and a $VERSION
5302 variable. After that the pod section looks like any other pod with the
5303 only difference being that I<one special pod section> exists starting with
5308 In this pod section each line obeys the format
5310 Module_Name [Version_String] [- optional text]
5312 The only required part is the first field, the name of a module
5313 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
5314 of the line is optional. The comment part is delimited by a dash just
5315 as in the man page header.
5317 The distribution of a bundle should follow the same convention as
5318 other distributions.
5320 Bundles are treated specially in the CPAN package. If you say 'install
5321 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
5322 the modules in the CONTENTS section of the pod. You can install your
5323 own Bundles locally by placing a conformant Bundle file somewhere into
5324 your @INC path. The autobundle() command which is available in the
5325 shell interface does that for you by including all currently installed
5326 modules in a snapshot bundle file.
5328 =head2 Prerequisites
5330 If you have a local mirror of CPAN and can access all files with
5331 "file:" URLs, then you only need a perl better than perl5.003 to run
5332 this module. Otherwise Net::FTP is strongly recommended. LWP may be
5333 required for non-UNIX systems or if your nearest CPAN site is
5334 associated with an URL that is not C<ftp:>.
5336 If you have neither Net::FTP nor LWP, there is a fallback mechanism
5337 implemented for an external ftp command or for an external lynx
5340 =head2 Finding packages and VERSION
5342 This module presumes that all packages on CPAN
5348 declare their $VERSION variable in an easy to parse manner. This
5349 prerequisite can hardly be relaxed because it consumes far too much
5350 memory to load all packages into the running program just to determine
5351 the $VERSION variable. Currently all programs that are dealing with
5352 version use something like this
5354 perl -MExtUtils::MakeMaker -le \
5355 'print MM->parse_version(shift)' filename
5357 If you are author of a package and wonder if your $VERSION can be
5358 parsed, please try the above method.
5362 come as compressed or gzipped tarfiles or as zip files and contain a
5363 Makefile.PL (well, we try to handle a bit more, but without much
5370 The debugging of this module is pretty difficult, because we have
5371 interferences of the software producing the indices on CPAN, of the
5372 mirroring process on CPAN, of packaging, of configuration, of
5373 synchronicity, and of bugs within CPAN.pm.
5375 In interactive mode you can try "o debug" which will list options for
5376 debugging the various parts of the package. The output may not be very
5377 useful for you as it's just a by-product of my own testing, but if you
5378 have an idea which part of the package may have a bug, it's sometimes
5379 worth to give it a try and send me more specific output. You should
5380 know that "o debug" has built-in completion support.
5382 =head2 Floppy, Zip, Offline Mode
5384 CPAN.pm works nicely without network too. If you maintain machines
5385 that are not networked at all, you should consider working with file:
5386 URLs. Of course, you have to collect your modules somewhere first. So
5387 you might use CPAN.pm to put together all you need on a networked
5388 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
5389 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
5390 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
5391 with this floppy. See also below the paragraph about CD-ROM support.
5393 =head1 CONFIGURATION
5395 When the CPAN module is installed, a site wide configuration file is
5396 created as CPAN/Config.pm. The default values defined there can be
5397 overridden in another configuration file: CPAN/MyConfig.pm. You can
5398 store this file in $HOME/.cpan/CPAN/MyConfig.pm if you want, because
5399 $HOME/.cpan is added to the search path of the CPAN module before the
5400 use() or require() statements.
5402 Currently the following keys in the hash reference $CPAN::Config are
5405 build_cache size of cache for directories to build modules
5406 build_dir locally accessible directory to build modules
5407 index_expire after this many days refetch index files
5408 cache_metadata use serializer to cache metadata
5409 cpan_home local directory reserved for this package
5410 dontload_hash anonymous hash: modules in the keys will not be
5411 loaded by the CPAN::has_inst() routine
5412 gzip location of external program gzip
5413 inactivity_timeout breaks interactive Makefile.PLs after this
5414 many seconds inactivity. Set to 0 to never break.
5415 inhibit_startup_message
5416 if true, does not print the startup message
5417 keep_source_where directory in which to keep the source (if we do)
5418 make location of external make program
5419 make_arg arguments that should always be passed to 'make'
5420 make_install_arg same as make_arg for 'make install'
5421 makepl_arg arguments passed to 'perl Makefile.PL'
5422 pager location of external program more (or any pager)
5423 prerequisites_policy
5424 what to do if you are missing module prerequisites
5425 ('follow' automatically, 'ask' me, or 'ignore')
5426 scan_cache controls scanning of cache ('atstart' or 'never')
5427 tar location of external program tar
5428 unzip location of external program unzip
5429 urllist arrayref to nearby CPAN sites (or equivalent locations)
5430 wait_list arrayref to a wait server to try (See CPAN::WAIT)
5431 ftp_proxy, } the three usual variables for configuring
5432 http_proxy, } proxy requests. Both as CPAN::Config variables
5433 no_proxy } and as environment variables configurable.
5435 You can set and query each of these options interactively in the cpan
5436 shell with the command set defined within the C<o conf> command:
5440 =item C<o conf E<lt>scalar optionE<gt>>
5442 prints the current value of the I<scalar option>
5444 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
5446 Sets the value of the I<scalar option> to I<value>
5448 =item C<o conf E<lt>list optionE<gt>>
5450 prints the current value of the I<list option> in MakeMaker's
5453 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
5455 shifts or pops the array in the I<list option> variable
5457 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
5459 works like the corresponding perl commands.
5463 =head2 Note on urllist parameter's format
5465 urllist parameters are URLs according to RFC 1738. We do a little
5466 guessing if your URL is not compliant, but if you have problems with
5467 file URLs, please try the correct format. Either:
5469 file://localhost/whatever/ftp/pub/CPAN/
5473 file:///home/ftp/pub/CPAN/
5475 =head2 urllist parameter has CD-ROM support
5477 The C<urllist> parameter of the configuration table contains a list of
5478 URLs that are to be used for downloading. If the list contains any
5479 C<file> URLs, CPAN always tries to get files from there first. This
5480 feature is disabled for index files. So the recommendation for the
5481 owner of a CD-ROM with CPAN contents is: include your local, possibly
5482 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
5484 o conf urllist push file://localhost/CDROM/CPAN
5486 CPAN.pm will then fetch the index files from one of the CPAN sites
5487 that come at the beginning of urllist. It will later check for each
5488 module if there is a local copy of the most recent version.
5490 Another peculiarity of urllist is that the site that we could
5491 successfully fetch the last file from automatically gets a preference
5492 token and is tried as the first site for the next request. So if you
5493 add a new site at runtime it may happen that the previously preferred
5494 site will be tried another time. This means that if you want to disallow
5495 a site for the next transfer, it must be explicitly removed from
5500 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
5501 install foreign, unmasked, unsigned code on your machine. We compare
5502 to a checksum that comes from the net just as the distribution file
5503 itself. If somebody has managed to tamper with the distribution file,
5504 they may have as well tampered with the CHECKSUMS file. Future
5505 development will go towards strong authentication.
5509 Most functions in package CPAN are exported per default. The reason
5510 for this is that the primary use is intended for the cpan shell or for
5513 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
5515 To populate a freshly installed perl with my favorite modules is pretty
5516 easiest by maintaining a private bundle definition file. To get a useful
5517 blueprint of a bundle definition file, the command autobundle can be used
5518 on the CPAN shell command line. This command writes a bundle definition
5519 file for all modules that are installed for the currently running perl
5520 interpreter. It's recommended to run this command only once and from then
5521 on maintain the file manually under a private name, say
5522 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
5524 cpan> install Bundle::my_bundle
5526 then answer a few questions and then go out for a coffee.
5528 Maintaining a bundle definition file means to keep track of two
5529 things: dependencies and interactivity. CPAN.pm sometimes fails on
5530 calculating dependencies because not all modules define all MakeMaker
5531 attributes correctly, so a bundle definition file should specify
5532 prerequisites as early as possible. On the other hand, it's a bit
5533 annoying that many distributions need some interactive configuring. So
5534 what I try to accomplish in my private bundle file is to have the
5535 packages that need to be configured early in the file and the gentle
5536 ones later, so I can go out after a few minutes and leave CPAN.pm
5539 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
5541 Thanks to Graham Barr for contributing the following paragraphs about
5542 the interaction between perl, and various firewall configurations. For
5543 further informations on firewalls, it is recommended to consult the
5544 documentation that comes with the ncftp program. If you are unable to
5545 go through the firewall with a simple Perl setup, it is very likely
5546 that you can configure ncftp so that it works for your firewall.
5548 =head2 Three basic types of firewalls
5550 Firewalls can be categorized into three basic types.
5556 This is where the firewall machine runs a web server and to access the
5557 outside world you must do it via the web server. If you set environment
5558 variables like http_proxy or ftp_proxy to a values beginning with http://
5559 or in your web browser you have to set proxy information then you know
5560 you are running a http firewall.
5562 To access servers outside these types of firewalls with perl (even for
5563 ftp) you will need to use LWP.
5567 This where the firewall machine runs a ftp server. This kind of
5568 firewall will only let you access ftp servers outside the firewall.
5569 This is usually done by connecting to the firewall with ftp, then
5570 entering a username like "user@outside.host.com"
5572 To access servers outside these type of firewalls with perl you
5573 will need to use Net::FTP.
5575 =item One way visibility
5577 I say one way visibility as these firewalls try to make themselve look
5578 invisible to the users inside the firewall. An FTP data connection is
5579 normally created by sending the remote server your IP address and then
5580 listening for the connection. But the remote server will not be able to
5581 connect to you because of the firewall. So for these types of firewall
5582 FTP connections need to be done in a passive mode.
5584 There are two that I can think off.
5590 If you are using a SOCKS firewall you will need to compile perl and link
5591 it with the SOCKS library, this is what is normally called a 'socksified'
5592 perl. With this executable you will be able to connect to servers outside
5593 the firewall as if it is not there.
5597 This is the firewall implemented in the Linux kernel, it allows you to
5598 hide a complete network behind one IP address. With this firewall no
5599 special compiling is need as you can access hosts directly.
5605 =head2 Configuring lynx or ncftp for going through a firewall
5607 If you can go through your firewall with e.g. lynx, presumably with a
5610 /usr/local/bin/lynx -pscott:tiger
5612 then you would configure CPAN.pm with the command
5614 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
5616 That's all. Similarly for ncftp or ftp, you would configure something
5619 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
5621 Your milage may vary...
5627 =item I installed a new version of module X but CPAN keeps saying, I
5628 have the old version installed
5630 Most probably you B<do> have the old version installed. This can
5631 happen if a module installs itself into a different directory in the
5632 @INC path than it was previously installed. This is not really a
5633 CPAN.pm problem, you would have the same problem when installing the
5634 module manually. The easiest way to prevent this behaviour is to add
5635 the argument C<UNINST=1> to the C<make install> call, and that is why
5636 many people add this argument permanently by configuring
5638 o conf make_install_arg UNINST=1
5640 =item So why is UNINST=1 not the default?
5642 Because there are people who have their precise expectations about who
5643 may install where in the @INC path and who uses which @INC array. In
5644 fine tuned environments C<UNINST=1> can cause damage.
5646 =item When I install bundles or multiple modules with one command
5647 there is too much output to keep track of
5649 You may want to configure something like
5651 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
5652 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
5654 so that STDOUT is captured in a file for later inspection.
5657 =item I am not root, how can I install a module in a personal directory?
5659 You will most probably like something like this:
5661 o conf makepl_arg "LIB=~/myperl/lib \
5662 INSTALLMAN1DIR=~/myperl/man/man1 \
5663 INSTALLMAN3DIR=~/myperl/man/man3"
5664 install Sybase::Sybperl
5666 You can make this setting permanent like all C<o conf> settings with
5669 You will have to add ~/myperl/man to the MANPATH environment variable
5670 and also tell your perl programs to look into ~/myperl/lib, e.g. by
5673 use lib "$ENV{HOME}/myperl/lib";
5675 or setting the PERL5LIB environment variable.
5677 Another thing you should bear in mind is that the UNINST parameter
5678 should never be set if you are not root.
5680 =item How to get a package, unwrap it, and make a change before building it?
5682 look Sybase::Sybperl
5684 =item I installed a Bundle and had a couple of fails. When I retried,
5685 everything resolved nicely. Can this be fixed to work on first
5688 The reason for this is that CPAN does not know the dependencies of all
5689 modules when it starts out. To decide about the additional items to
5690 install, it just uses data found in the generated Makefile. An
5691 undetected missing piece breaks the process. But it may well be that
5692 your Bundle installs some prerequisite later than some depending item
5693 and thus your second try is able to resolve everything. Please note,
5694 CPAN.pm does not know the dependency tree in advance and cannot sort
5695 the queue of things to install in a topologically correct sequence.
5696 For bundles which you need to install often, it is recommended to do
5697 the sorting manually. It is planned to improve the metadata situation
5698 for dependencies on CPAN in general, but this will still take some
5705 We should give coverage for B<all> of the CPAN and not just the PAUSE
5706 part, right? In this discussion CPAN and PAUSE have become equal --
5707 but they are not. PAUSE is authors/, modules/ and scripts/. CPAN is
5708 PAUSE plus the clpa/, doc/, misc/, ports/, and src/.
5710 Future development should be directed towards a better integration of
5713 If a Makefile.PL requires special customization of libraries, prompts
5714 the user for special input, etc. then you may find CPAN is not able to
5715 build the distribution. In that case, you should attempt the
5716 traditional method of building a Perl module package from a shell.
5720 Andreas Koenig E<lt>andreas.koenig@anima.deE<gt>
5724 perl(1), CPAN::Nox(3)