1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
5 # $Id: CPAN.pm,v 1.366 2000/10/27 07:45:49 k Exp $
7 # only used during development:
9 # $Revision = "[".substr(q$Revision: 1.366 $, 10)."]";
16 use ExtUtils::MakeMaker (); # $SelfLoader::DEBUG=1;
17 use File::Basename ();
23 use Text::ParseWords ();
26 no lib "."; # we need to run chdir all over and we would get at wrong
29 END { $End++; &cleanup; }
52 $CPAN::Frontend ||= "CPAN::Shell";
53 $CPAN::Defaultsite ||= "ftp://ftp.perl.org/pub/CPAN";
58 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $HAS_USABLE $term
59 $Revision $Signal $End $Suppress_readline $Frontend
60 $Defaultsite $Have_warned);
62 @CPAN::ISA = qw(CPAN::Debug Exporter);
65 autobundle bundle expand force get cvs_import
66 install make readme recompile shell test clean
69 #-> sub CPAN::AUTOLOAD ;
74 @EXPORT{@EXPORT} = '';
75 CPAN::Config->load unless $CPAN::Config_loaded++;
76 if (exists $EXPORT{$l}){
79 $CPAN::Frontend->mywarn(qq{Unknown command "$AUTOLOAD". }.
88 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
89 CPAN::Config->load unless $CPAN::Config_loaded++;
91 my $oprompt = shift || "cpan> ";
92 my $prompt = $oprompt;
93 my $commandline = shift || "";
96 unless ($Suppress_readline) {
97 require Term::ReadLine;
100 $term->ReadLine eq "Term::ReadLine::Stub"
102 $term = Term::ReadLine->new('CPAN Monitor');
104 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
105 my $attribs = $term->Attribs;
106 $attribs->{attempted_completion_function} = sub {
107 &CPAN::Complete::gnu_cpl;
110 $readline::rl_completion_function =
111 $readline::rl_completion_function = 'CPAN::Complete::cpl';
113 # $term->OUT is autoflushed anyway
114 my $odef = select STDERR;
121 # no strict; # I do not recall why no strict was here (2000-09-03)
123 my $cwd = CPAN::anycwd();
124 my $try_detect_readline;
125 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
126 my $rl_avail = $Suppress_readline ? "suppressed" :
127 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
128 "available (try 'install Bundle::CPAN')";
130 $CPAN::Frontend->myprint(
132 cpan shell -- CPAN exploration and modules installation (v%s%s)
140 unless $CPAN::Config->{'inhibit_startup_message'} ;
141 my($continuation) = "";
143 if ($Suppress_readline) {
145 last unless defined ($_ = <> );
148 last unless defined ($_ = $term->readline($prompt, $commandline));
150 $_ = "$continuation$_" if $continuation;
153 $_ = 'h' if /^\s*\?/;
154 if (/^(?:q(?:uit)?|bye|exit)$/i) {
164 use vars qw($import_done);
165 CPAN->import(':DEFAULT') unless $import_done++;
166 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
173 if ($] < 5.00322) { # parsewords had a bug until recently
176 eval { @line = Text::ParseWords::shellwords($_) };
177 warn($@), next if $@;
179 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
180 my $command = shift @line;
181 eval { CPAN::Shell->$command(@line) };
183 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
184 $CPAN::Frontend->myprint("\n");
189 $commandline = ""; # I do want to be able to pass a default to
190 # shell, but on the second command I see no
193 CPAN::Queue->nullify_queue;
194 if ($try_detect_readline) {
195 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
197 $CPAN::META->has_inst("Term::ReadLine::Perl")
199 delete $INC{"Term/ReadLine.pm"};
201 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
202 require Term::ReadLine;
203 $CPAN::Frontend->myprint("\n$redef subroutines in ".
204 "Term::ReadLine redefined\n");
210 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
213 package CPAN::CacheMgr;
214 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
217 package CPAN::Config;
218 use vars qw(%can $dot_cpan);
221 'commit' => "Commit changes to disk",
222 'defaults' => "Reload defaults from disk",
223 'init' => "Interactive setting of all options",
227 use vars qw($Ua $Thesite $Themethod);
228 @CPAN::FTP::ISA = qw(CPAN::Debug);
230 package CPAN::Complete;
231 @CPAN::Complete::ISA = qw(CPAN::Debug);
232 @CPAN::Complete::COMMANDS = sort qw(
233 ! a b d h i m o q r u autobundle clean dump
234 make test install force readme reload look cvs_import
235 ) unless @CPAN::Complete::COMMANDS;
238 use vars qw($last_time $date_of_03);
239 @CPAN::Index::ISA = qw(CPAN::Debug);
242 # use constant PROTOCOL => "2.0"; # outcommented to avoid warning on upgrade from 1.57
245 package CPAN::InfoObj;
246 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
248 package CPAN::Author;
249 @CPAN::Author::ISA = qw(CPAN::InfoObj);
251 package CPAN::Distribution;
252 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
254 package CPAN::Bundle;
255 @CPAN::Bundle::ISA = qw(CPAN::Module);
257 package CPAN::Module;
258 @CPAN::Module::ISA = qw(CPAN::InfoObj);
261 use vars qw($AUTOLOAD @ISA $COLOR_REGISTERED);
262 @CPAN::Shell::ISA = qw(CPAN::Debug);
263 $COLOR_REGISTERED ||= 0;
265 #-> sub CPAN::Shell::AUTOLOAD ;
267 my($autoload) = $AUTOLOAD;
268 my $class = shift(@_);
269 # warn "autoload[$autoload] class[$class]";
270 $autoload =~ s/.*:://;
271 if ($autoload =~ /^w/) {
272 if ($CPAN::META->has_inst('CPAN::WAIT')) {
273 CPAN::WAIT->$autoload(@_);
275 $CPAN::Frontend->mywarn(qq{
276 Commands starting with "w" require CPAN::WAIT to be installed.
277 Please consider installing CPAN::WAIT to use the fulltext index.
278 For this you just need to type
283 $CPAN::Frontend->mywarn(qq{Unknown command '$autoload'. }.
289 package CPAN::Tarzip;
290 use vars qw($AUTOLOAD @ISA);
291 @CPAN::Tarzip::ISA = qw(CPAN::Debug);
295 # One use of the queue is to determine if we should or shouldn't
296 # announce the availability of a new CPAN module
298 # Now we try to use it for dependency tracking. For that to happen
299 # we need to draw a dependency tree and do the leaves first. This can
300 # easily be reached by running CPAN.pm recursively, but we don't want
301 # to waste memory and run into deep recursion. So what we can do is
304 # CPAN::Queue is the package where the queue is maintained. Dependencies
305 # often have high priority and must be brought to the head of the queue,
306 # possibly by jumping the queue if they are already there. My first code
307 # attempt tried to be extremely correct. Whenever a module needed
308 # immediate treatment, I either unshifted it to the front of the queue,
309 # or, if it was already in the queue, I spliced and let it bypass the
310 # others. This became a too correct model that made it impossible to put
311 # an item more than once into the queue. Why would you need that? Well,
312 # you need temporary duplicates as the manager of the queue is a loop
315 # (1) looks at the first item in the queue without shifting it off
317 # (2) cares for the item
319 # (3) removes the item from the queue, *even if its agenda failed and
320 # even if the item isn't the first in the queue anymore* (that way
321 # protecting against never ending queues)
323 # So if an item has prerequisites, the installation fails now, but we
324 # want to retry later. That's easy if we have it twice in the queue.
326 # I also expect insane dependency situations where an item gets more
327 # than two lives in the queue. Simplest example is triggered by 'install
328 # Foo Foo Foo'. People make this kind of mistakes and I don't want to
329 # get in the way. I wanted the queue manager to be a dumb servant, not
330 # one that knows everything.
332 # Who would I tell in this model that the user wants to be asked before
333 # processing? I can't attach that information to the module object,
334 # because not modules are installed but distributions. So I'd have to
335 # tell the distribution object that it should ask the user before
336 # processing. Where would the question be triggered then? Most probably
337 # in CPAN::Distribution::rematein.
338 # Hope that makes sense, my head is a bit off:-) -- AK
345 my $self = bless { qmod => $s }, $class;
350 # CPAN::Queue::first ;
356 # CPAN::Queue::delete_first ;
358 my($class,$what) = @_;
360 for my $i (0..$#All) {
361 if ( $All[$i]->{qmod} eq $what ) {
368 # CPAN::Queue::jumpqueue ;
372 CPAN->debug(sprintf("before jumpqueue All[%s] what[%s]",
373 join(",",map {$_->{qmod}} @All),
376 WHAT: for my $what (reverse @what) {
378 for (my $i=0; $i<$#All;$i++) { #prevent deep recursion
379 CPAN->debug("i[$All[$i]]what[$what]") if $CPAN::DEBUG;
380 if ($All[$i]->{qmod} eq $what){
382 if ($jumped > 100) { # one's OK if e.g. just
383 # processing now; more are OK if
384 # user typed it several times
385 $CPAN::Frontend->mywarn(
386 qq{Object [$what] queued more than 100 times, ignoring}
392 my $obj = bless { qmod => $what }, $class;
395 CPAN->debug(sprintf("after jumpqueue All[%s] what[%s]",
396 join(",",map {$_->{qmod}} @All),
401 # CPAN::Queue::exists ;
403 my($self,$what) = @_;
404 my @all = map { $_->{qmod} } @All;
405 my $exists = grep { $_->{qmod} eq $what } @All;
406 # warn "in exists what[$what] all[@all] exists[$exists]";
410 # CPAN::Queue::delete ;
413 @All = grep { $_->{qmod} ne $mod } @All;
416 # CPAN::Queue::nullify_queue ;
425 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
427 # from here on only subs.
428 ################################################################################
430 #-> sub CPAN::all_objects ;
432 my($mgr,$class) = @_;
433 CPAN::Config->load unless $CPAN::Config_loaded++;
434 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
436 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
438 *all = \&all_objects;
440 # Called by shell, not in batch mode. In batch mode I see no risk in
441 # having many processes updating something as installations are
442 # continually checked at runtime. In shell mode I suspect it is
443 # unintentional to open more than one shell at a time
445 #-> sub CPAN::checklock ;
448 my $lockfile = MM->catfile($CPAN::Config->{cpan_home},".lock");
449 if (-f $lockfile && -M _ > 0) {
450 my $fh = FileHandle->new($lockfile) or
451 $CPAN::Frontend->mydie("Could not open $lockfile: $!");
454 if (defined $other && $other) {
456 return if $$==$other; # should never happen
457 $CPAN::Frontend->mywarn(
459 There seems to be running another CPAN process ($other). Contacting...
461 if (kill 0, $other) {
462 $CPAN::Frontend->mydie(qq{Other job is running.
463 You may want to kill it and delete the lockfile, maybe. On UNIX try:
467 } elsif (-w $lockfile) {
469 ExtUtils::MakeMaker::prompt
470 (qq{Other job not responding. Shall I overwrite }.
471 qq{the lockfile? (Y/N)},"y");
472 $CPAN::Frontend->myexit("Ok, bye\n")
473 unless $ans =~ /^y/i;
476 qq{Lockfile $lockfile not writeable by you. }.
477 qq{Cannot proceed.\n}.
480 qq{ and then rerun us.\n}
484 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile $lockfile ".
485 "reports other process with ID ".
486 "$other. Cannot proceed.\n"));
489 my $dotcpan = $CPAN::Config->{cpan_home};
490 eval { File::Path::mkpath($dotcpan);};
492 # A special case at least for Jarkko.
497 $symlinkcpan = readlink $dotcpan;
498 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
499 eval { File::Path::mkpath($symlinkcpan); };
503 $CPAN::Frontend->mywarn(qq{
504 Working directory $symlinkcpan created.
508 unless (-d $dotcpan) {
510 Your configuration suggests "$dotcpan" as your
511 CPAN.pm working directory. I could not create this directory due
512 to this error: $firsterror\n};
514 As "$dotcpan" is a symlink to "$symlinkcpan",
515 I tried to create that, but I failed with this error: $seconderror
518 Please make sure the directory exists and is writable.
520 $CPAN::Frontend->mydie($diemess);
524 unless ($fh = FileHandle->new(">$lockfile")) {
525 if ($! =~ /Permission/) {
526 my $incc = $INC{'CPAN/Config.pm'};
527 my $myincc = MM->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
528 $CPAN::Frontend->myprint(qq{
530 Your configuration suggests that CPAN.pm should use a working
532 $CPAN::Config->{cpan_home}
533 Unfortunately we could not create the lock file
535 due to permission problems.
537 Please make sure that the configuration variable
538 \$CPAN::Config->{cpan_home}
539 points to a directory where you can write a .lock file. You can set
540 this variable in either
547 $CPAN::Frontend->mydie("Could not open >$lockfile: $!");
549 $fh->print($$, "\n");
550 $self->{LOCK} = $lockfile;
554 $CPAN::Frontend->mydie("Got SIGTERM, leaving");
559 $CPAN::Frontend->mydie("Got another SIGINT") if $Signal;
560 print "Caught SIGINT\n";
564 # From: Larry Wall <larry@wall.org>
565 # Subject: Re: deprecating SIGDIE
566 # To: perl5-porters@perl.org
567 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
569 # The original intent of __DIE__ was only to allow you to substitute one
570 # kind of death for another on an application-wide basis without respect
571 # to whether you were in an eval or not. As a global backstop, it should
572 # not be used any more lightly (or any more heavily :-) than class
573 # UNIVERSAL. Any attempt to build a general exception model on it should
574 # be politely squashed. Any bug that causes every eval {} to have to be
575 # modified should be not so politely squashed.
577 # Those are my current opinions. It is also my optinion that polite
578 # arguments degenerate to personal arguments far too frequently, and that
579 # when they do, it's because both people wanted it to, or at least didn't
580 # sufficiently want it not to.
584 # global backstop to cleanup if we should really die
585 $SIG{__DIE__} = \&cleanup;
586 $self->debug("Signal handler set.") if $CPAN::DEBUG;
589 #-> sub CPAN::DESTROY ;
591 &cleanup; # need an eval?
594 #-> sub CPAN::anycwd ;
597 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
602 sub cwd {Cwd::cwd();}
604 #-> sub CPAN::getcwd ;
605 sub getcwd {Cwd::getcwd();}
607 #-> sub CPAN::exists ;
609 my($mgr,$class,$id) = @_;
610 CPAN::Config->load unless $CPAN::Config_loaded++;
612 ### Carp::croak "exists called without class argument" unless $class;
614 exists $META->{readonly}{$class}{$id} or
615 exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
618 #-> sub CPAN::delete ;
620 my($mgr,$class,$id) = @_;
621 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
622 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
625 #-> sub CPAN::has_usable
626 # has_inst is sometimes too optimistic, we should replace it with this
627 # has_usable whenever a case is given
629 my($self,$mod,$message) = @_;
630 return 1 if $HAS_USABLE->{$mod};
631 my $has_inst = $self->has_inst($mod,$message);
632 return unless $has_inst;
635 LWP => [ # we frequently had "Can't locate object
636 # method "new" via package "LWP::UserAgent" at
637 # (eval 69) line 2006
639 sub {require LWP::UserAgent},
640 sub {require HTTP::Request},
641 sub {require URI::URL},
644 sub {require Net::FTP},
645 sub {require Net::Config},
648 if ($usable->{$mod}) {
649 for my $c (0..$#{$usable->{$mod}}) {
650 my $code = $usable->{$mod}[$c];
651 my $ret = eval { &$code() };
653 warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
658 return $HAS_USABLE->{$mod} = 1;
661 #-> sub CPAN::has_inst
663 my($self,$mod,$message) = @_;
664 Carp::croak("CPAN->has_inst() called without an argument")
666 if (defined $message && $message eq "no"
668 exists $CPAN::META->{dontload_hash}{$mod} # unsafe meta access, ok
670 exists $CPAN::Config->{dontload_hash}{$mod}
672 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
678 $file =~ s|/|\\|g if $^O eq 'MSWin32';
681 # checking %INC is wrong, because $INC{LWP} may be true
682 # although $INC{"URI/URL.pm"} may have failed. But as
683 # I really want to say "bla loaded OK", I have to somehow
685 ### warn "$file in %INC"; #debug
687 } elsif (eval { require $file }) {
688 # eval is good: if we haven't yet read the database it's
689 # perfect and if we have installed the module in the meantime,
690 # it tries again. The second require is only a NOOP returning
691 # 1 if we had success, otherwise it's retrying
693 $CPAN::Frontend->myprint("CPAN: $mod loaded ok\n");
694 if ($mod eq "CPAN::WAIT") {
695 push @CPAN::Shell::ISA, CPAN::WAIT;
698 } elsif ($mod eq "Net::FTP") {
699 $CPAN::Frontend->mywarn(qq{
700 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
702 install Bundle::libnet
704 }) unless $Have_warned->{"Net::FTP"}++;
706 } elsif ($mod eq "MD5"){
707 $CPAN::Frontend->myprint(qq{
708 CPAN: MD5 security checks disabled because MD5 not installed.
709 Please consider installing the MD5 module.
714 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
719 #-> sub CPAN::instance ;
721 my($mgr,$class,$id) = @_;
724 # unsafe meta access, ok?
725 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
726 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
734 #-> sub CPAN::cleanup ;
736 # warn "cleanup called with arg[@_] End[$End] Signal[$Signal]";
737 local $SIG{__DIE__} = '';
742 0 && # disabled, try reload cpan with it
743 $] > 5.004_60 # thereabouts
748 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
750 $subroutine eq '(eval)';
753 return if $ineval && !$End;
754 return unless defined $META->{LOCK}; # unsafe meta access, ok
755 return unless -f $META->{LOCK}; # unsafe meta access, ok
756 unlink $META->{LOCK}; # unsafe meta access, ok
758 # Carp::cluck("DEBUGGING");
759 $CPAN::Frontend->mywarn("Lockfile removed.\n");
762 package CPAN::CacheMgr;
764 #-> sub CPAN::CacheMgr::as_string ;
766 eval { require Data::Dumper };
768 return shift->SUPER::as_string;
770 return Data::Dumper::Dumper(shift);
774 #-> sub CPAN::CacheMgr::cachesize ;
779 #-> sub CPAN::CacheMgr::tidyup ;
782 return unless -d $self->{ID};
783 while ($self->{DU} > $self->{'MAX'} ) {
784 my($toremove) = shift @{$self->{FIFO}};
785 $CPAN::Frontend->myprint(sprintf(
786 "Deleting from cache".
787 ": $toremove (%.1f>%.1f MB)\n",
788 $self->{DU}, $self->{'MAX'})
790 return if $CPAN::Signal;
791 $self->force_clean_cache($toremove);
792 return if $CPAN::Signal;
796 #-> sub CPAN::CacheMgr::dir ;
801 #-> sub CPAN::CacheMgr::entries ;
804 return unless defined $dir;
805 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
806 $dir ||= $self->{ID};
807 my($cwd) = CPAN::anycwd();
808 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
809 my $dh = DirHandle->new(File::Spec->curdir)
810 or Carp::croak("Couldn't opendir $dir: $!");
813 next if $_ eq "." || $_ eq "..";
815 push @entries, MM->catfile($dir,$_);
817 push @entries, MM->catdir($dir,$_);
819 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
822 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
823 sort { -M $b <=> -M $a} @entries;
826 #-> sub CPAN::CacheMgr::disk_usage ;
829 return if exists $self->{SIZE}{$dir};
830 return if $CPAN::Signal;
834 $File::Find::prune++ if $CPAN::Signal;
836 if ($^O eq 'MacOS') {
838 my $cat = Mac::Files::FSpGetCatInfo($_);
839 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
846 return if $CPAN::Signal;
847 $self->{SIZE}{$dir} = $Du/1024/1024;
848 push @{$self->{FIFO}}, $dir;
849 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
850 $self->{DU} += $Du/1024/1024;
854 #-> sub CPAN::CacheMgr::force_clean_cache ;
855 sub force_clean_cache {
857 return unless -e $dir;
858 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
860 File::Path::rmtree($dir);
861 $self->{DU} -= $self->{SIZE}{$dir};
862 delete $self->{SIZE}{$dir};
865 #-> sub CPAN::CacheMgr::new ;
872 ID => $CPAN::Config->{'build_dir'},
873 MAX => $CPAN::Config->{'build_cache'},
874 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
877 File::Path::mkpath($self->{ID});
878 my $dh = DirHandle->new($self->{ID});
882 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
884 CPAN->debug($debug) if $CPAN::DEBUG;
888 #-> sub CPAN::CacheMgr::scan_cache ;
891 return if $self->{SCAN} eq 'never';
892 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
893 unless $self->{SCAN} eq 'atstart';
894 $CPAN::Frontend->myprint(
895 sprintf("Scanning cache %s for sizes\n",
898 for $e ($self->entries($self->{ID})) {
899 next if $e eq ".." || $e eq ".";
900 $self->disk_usage($e);
901 return if $CPAN::Signal;
908 #-> sub CPAN::Debug::debug ;
911 my($caller,$func,$line,@rest) = caller(1); # caller(0) eg
912 # Complete, caller(1)
914 ($caller) = caller(0);
916 $arg = "" unless defined $arg;
917 my $rest = join "|", map { defined $_ ? $_ : "UNDEF" } @rest;
918 if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
919 if ($arg and ref $arg) {
920 eval { require Data::Dumper };
922 $CPAN::Frontend->myprint($arg->as_string);
924 $CPAN::Frontend->myprint(Data::Dumper::Dumper($arg));
927 $CPAN::Frontend->myprint("Debug($caller:$func,$line,[$rest]): $arg\n");
932 package CPAN::Config;
934 #-> sub CPAN::Config::edit ;
935 # returns true on successful action
937 my($self,@args) = @_;
939 CPAN->debug("self[$self]args[".join(" | ",@args)."]");
940 my($o,$str,$func,$args,$key_exists);
946 CPAN->debug("o[$o]") if $CPAN::DEBUG;
950 CPAN->debug("func[$func]") if $CPAN::DEBUG;
952 # Let's avoid eval, it's easier to comprehend without.
953 if ($func eq "push") {
954 push @{$CPAN::Config->{$o}}, @args;
956 } elsif ($func eq "pop") {
957 pop @{$CPAN::Config->{$o}};
959 } elsif ($func eq "shift") {
960 shift @{$CPAN::Config->{$o}};
962 } elsif ($func eq "unshift") {
963 unshift @{$CPAN::Config->{$o}}, @args;
965 } elsif ($func eq "splice") {
966 splice @{$CPAN::Config->{$o}}, @args;
969 $CPAN::Config->{$o} = [@args];
972 $self->prettyprint($o);
974 if ($o eq "urllist" && $changed) {
975 # reset the cached values
976 undef $CPAN::FTP::Thesite;
977 undef $CPAN::FTP::Themethod;
981 $CPAN::Config->{$o} = $args[0] if defined $args[0];
982 $self->prettyprint($o);
989 my $v = $CPAN::Config->{$k};
991 my(@report) = ref $v eq "ARRAY" ?
993 map { sprintf(" %-18s => %s\n",
995 defined $v->{$_} ? $v->{$_} : "UNDEFINED"
997 $CPAN::Frontend->myprint(
1004 map {"\t$_\n"} @report
1007 } elsif (defined $v) {
1008 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1010 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, "UNDEFINED");
1014 #-> sub CPAN::Config::commit ;
1016 my($self,$configpm) = @_;
1017 unless (defined $configpm){
1018 $configpm ||= $INC{"CPAN/MyConfig.pm"};
1019 $configpm ||= $INC{"CPAN/Config.pm"};
1020 $configpm || Carp::confess(q{
1021 CPAN::Config::commit called without an argument.
1022 Please specify a filename where to save the configuration or try
1023 "o conf init" to have an interactive course through configing.
1028 $mode = (stat $configpm)[2];
1029 if ($mode && ! -w _) {
1030 Carp::confess("$configpm is not writable");
1035 $msg = <<EOF unless $configpm =~ /MyConfig/;
1037 # This is CPAN.pm's systemwide configuration file. This file provides
1038 # defaults for users, and the values can be changed in a per-user
1039 # configuration file. The user-config file is being looked for as
1040 # ~/.cpan/CPAN/MyConfig.pm.
1044 my($fh) = FileHandle->new;
1045 rename $configpm, "$configpm~" if -f $configpm;
1046 open $fh, ">$configpm" or
1047 $CPAN::Frontend->mydie("Couldn't open >$configpm: $!");
1048 $fh->print(qq[$msg\$CPAN::Config = \{\n]);
1049 foreach (sort keys %$CPAN::Config) {
1052 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}),
1057 $fh->print("};\n1;\n__END__\n");
1060 #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
1061 #chmod $mode, $configpm;
1062 ###why was that so? $self->defaults;
1063 $CPAN::Frontend->myprint("commit: wrote $configpm\n");
1067 *default = \&defaults;
1068 #-> sub CPAN::Config::defaults ;
1078 undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
1087 #-> sub CPAN::Config::load ;
1092 eval {require CPAN::Config;}; # We eval because of some
1093 # MakeMaker problems
1094 unless ($dot_cpan++){
1095 unshift @INC, MM->catdir($ENV{HOME},".cpan");
1096 eval {require CPAN::MyConfig;}; # where you can override
1097 # system wide settings
1100 return unless @miss = $self->missing_config_data;
1102 require CPAN::FirstTime;
1103 my($configpm,$fh,$redo,$theycalled);
1105 $theycalled++ if @miss==1 && $miss[0] eq 'inhibit_startup_message';
1106 if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
1107 $configpm = $INC{"CPAN/Config.pm"};
1109 } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
1110 $configpm = $INC{"CPAN/MyConfig.pm"};
1113 my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
1114 my($configpmdir) = MM->catdir($path_to_cpan,"CPAN");
1115 my($configpmtest) = MM->catfile($configpmdir,"Config.pm");
1116 if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
1117 if (-w $configpmtest) {
1118 $configpm = $configpmtest;
1119 } elsif (-w $configpmdir) {
1120 #_#_# following code dumped core on me with 5.003_11, a.k.
1121 unlink "$configpmtest.bak" if -f "$configpmtest.bak";
1122 rename $configpmtest, "$configpmtest.bak" if -f $configpmtest;
1123 my $fh = FileHandle->new;
1124 if ($fh->open(">$configpmtest")) {
1126 $configpm = $configpmtest;
1128 # Should never happen
1129 Carp::confess("Cannot open >$configpmtest");
1133 unless ($configpm) {
1134 $configpmdir = MM->catdir($ENV{HOME},".cpan","CPAN");
1135 File::Path::mkpath($configpmdir);
1136 $configpmtest = MM->catfile($configpmdir,"MyConfig.pm");
1137 if (-w $configpmtest) {
1138 $configpm = $configpmtest;
1139 } elsif (-w $configpmdir) {
1140 #_#_# following code dumped core on me with 5.003_11, a.k.
1141 my $fh = FileHandle->new;
1142 if ($fh->open(">$configpmtest")) {
1144 $configpm = $configpmtest;
1146 # Should never happen
1147 Carp::confess("Cannot open >$configpmtest");
1150 Carp::confess(qq{WARNING: CPAN.pm is unable to }.
1151 qq{create a configuration file.});
1156 $CPAN::Frontend->myprint(<<END) if $redo && ! $theycalled;
1157 We have to reconfigure CPAN.pm due to following uninitialized parameters:
1161 $CPAN::Frontend->myprint(qq{
1162 $configpm initialized.
1165 CPAN::FirstTime::init($configpm);
1168 #-> sub CPAN::Config::missing_config_data ;
1169 sub missing_config_data {
1172 "cpan_home", "keep_source_where", "build_dir", "build_cache",
1173 "scan_cache", "index_expire", "gzip", "tar", "unzip", "make",
1175 "makepl_arg", "make_arg", "make_install_arg", "urllist",
1176 "inhibit_startup_message", "ftp_proxy", "http_proxy", "no_proxy",
1177 "prerequisites_policy",
1180 push @miss, $_ unless defined $CPAN::Config->{$_};
1185 #-> sub CPAN::Config::unload ;
1187 delete $INC{'CPAN/MyConfig.pm'};
1188 delete $INC{'CPAN/Config.pm'};
1191 #-> sub CPAN::Config::help ;
1193 $CPAN::Frontend->myprint(q[
1195 defaults reload default config values from disk
1196 commit commit session changes to disk
1197 init go through a dialog to set all parameters
1199 You may edit key values in the follow fashion (the "o" is a literal
1202 o conf build_cache 15
1204 o conf build_dir "/foo/bar"
1206 o conf urllist shift
1208 o conf urllist unshift ftp://ftp.foo.bar/
1211 undef; #don't reprint CPAN::Config
1214 #-> sub CPAN::Config::cpl ;
1216 my($word,$line,$pos) = @_;
1218 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1219 my(@words) = split " ", substr($line,0,$pos+1);
1224 $words[2] =~ /list$/ && @words == 3
1226 $words[2] =~ /list$/ && @words == 4 && length($word)
1229 return grep /^\Q$word\E/, qw(splice shift unshift pop push);
1230 } elsif (@words >= 4) {
1233 my(@o_conf) = (keys %CPAN::Config::can, keys %$CPAN::Config);
1234 return grep /^\Q$word\E/, @o_conf;
1237 package CPAN::Shell;
1239 #-> sub CPAN::Shell::h ;
1241 my($class,$about) = @_;
1242 if (defined $about) {
1243 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
1245 $CPAN::Frontend->myprint(q{
1248 b string display bundles
1249 d or info distributions
1250 m /regex/ about modules
1251 i or anything of above
1252 r none reinstall recommendations
1253 u uninstalled distributions
1255 Download, Test, Make, Install...
1257 make make (implies get)
1258 test modules, make test (implies make)
1259 install dists, bundles make install (implies test)
1261 look open subshell in these dists' directories
1262 readme display these dists' README files
1265 h,? display this menu ! perl-code eval a perl command
1266 o conf [opt] set and query options q quit the cpan shell
1267 reload cpan load CPAN.pm again reload index load newer indices
1268 autobundle Snapshot force cmd unconditionally do cmd});
1274 #-> sub CPAN::Shell::a ;
1276 my($self,@arg) = @_;
1277 # authors are always UPPERCASE
1281 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1284 #-> sub CPAN::Shell::local_bundles ;
1287 my($self,@which) = @_;
1288 my($incdir,$bdir,$dh);
1289 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1290 $bdir = MM->catdir($incdir,"Bundle");
1291 if ($dh = DirHandle->new($bdir)) { # may fail
1293 for $entry ($dh->read) {
1294 next if -d MM->catdir($bdir,$entry);
1295 next unless $entry =~ s/\.pm(?!\n)\Z//;
1296 $CPAN::META->instance('CPAN::Bundle',"Bundle::$entry");
1302 #-> sub CPAN::Shell::b ;
1304 my($self,@which) = @_;
1305 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1306 $self->local_bundles;
1307 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1310 #-> sub CPAN::Shell::d ;
1311 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1313 #-> sub CPAN::Shell::m ;
1314 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
1315 $CPAN::Frontend->myprint(shift->format_result('Module',@_));
1318 #-> sub CPAN::Shell::i ;
1323 @type = qw/Author Bundle Distribution Module/;
1324 @args = '/./' unless @args;
1327 push @result, $self->expand($type,@args);
1329 my $result = @result == 1 ?
1330 $result[0]->as_string :
1331 join "", map {$_->as_glimpse} @result;
1332 $result ||= "No objects found of any type for argument @args\n";
1333 $CPAN::Frontend->myprint($result);
1336 #-> sub CPAN::Shell::o ;
1338 # CPAN::Shell::o and CPAN::Config::edit are closely related. 'o conf'
1339 # should have been called set and 'o debug' maybe 'set debug'
1341 my($self,$o_type,@o_what) = @_;
1343 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1344 if ($o_type eq 'conf') {
1345 shift @o_what if @o_what && $o_what[0] eq 'help';
1346 if (!@o_what) { # print all things, "o conf"
1348 $CPAN::Frontend->myprint("CPAN::Config options");
1349 if (exists $INC{'CPAN/Config.pm'}) {
1350 $CPAN::Frontend->myprint(" from $INC{'CPAN/Config.pm'}");
1352 if (exists $INC{'CPAN/MyConfig.pm'}) {
1353 $CPAN::Frontend->myprint(" and $INC{'CPAN/MyConfig.pm'}");
1355 $CPAN::Frontend->myprint(":\n");
1356 for $k (sort keys %CPAN::Config::can) {
1357 $v = $CPAN::Config::can{$k};
1358 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1360 $CPAN::Frontend->myprint("\n");
1361 for $k (sort keys %$CPAN::Config) {
1362 CPAN::Config->prettyprint($k);
1364 $CPAN::Frontend->myprint("\n");
1365 } elsif (!CPAN::Config->edit(@o_what)) {
1366 $CPAN::Frontend->myprint(qq{Type 'o conf' to view configuration }.
1367 qq{edit options\n\n});
1369 } elsif ($o_type eq 'debug') {
1371 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1374 my($what) = shift @o_what;
1375 if ( exists $CPAN::DEBUG{$what} ) {
1376 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1377 } elsif ($what =~ /^\d/) {
1378 $CPAN::DEBUG = $what;
1379 } elsif (lc $what eq 'all') {
1381 for (values %CPAN::DEBUG) {
1384 $CPAN::DEBUG = $max;
1387 for (keys %CPAN::DEBUG) {
1388 next unless lc($_) eq lc($what);
1389 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1392 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1397 my $raw = "Valid options for debug are ".
1398 join(", ",sort(keys %CPAN::DEBUG), 'all').
1399 qq{ or a number. Completion works on the options. }.
1400 qq{Case is ignored.};
1402 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
1403 $CPAN::Frontend->myprint("\n\n");
1406 $CPAN::Frontend->myprint("Options set for debugging:\n");
1408 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1409 $v = $CPAN::DEBUG{$k};
1410 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
1411 if $v & $CPAN::DEBUG;
1414 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1417 $CPAN::Frontend->myprint(qq{
1419 conf set or get configuration variables
1420 debug set or get debugging options
1425 sub paintdots_onreload {
1428 if ( $_[0] =~ /[Ss]ubroutine (\w+) redefined/ ) {
1432 # $CPAN::Frontend->myprint(".($subr)");
1433 $CPAN::Frontend->myprint(".");
1440 #-> sub CPAN::Shell::reload ;
1442 my($self,$command,@arg) = @_;
1444 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1445 if ($command =~ /cpan/i) {
1446 CPAN->debug("reloading the whole CPAN.pm") if $CPAN::DEBUG;
1447 my $fh = FileHandle->new($INC{'CPAN.pm'});
1450 local($SIG{__WARN__}) = paintdots_onreload(\$redef);
1453 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1454 } elsif ($command =~ /index/) {
1455 CPAN::Index->force_reload;
1457 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN.pm file
1458 index re-reads the index files\n});
1462 #-> sub CPAN::Shell::_binary_extensions ;
1463 sub _binary_extensions {
1464 my($self) = shift @_;
1465 my(@result,$module,%seen,%need,$headerdone);
1466 for $module ($self->expand('Module','/./')) {
1467 my $file = $module->cpan_file;
1468 next if $file eq "N/A";
1469 next if $file =~ /^Contact Author/;
1470 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
1471 next if $dist->isa_perl;
1472 next unless $module->xs_file;
1474 $CPAN::Frontend->myprint(".");
1475 push @result, $module;
1477 # print join " | ", @result;
1478 $CPAN::Frontend->myprint("\n");
1482 #-> sub CPAN::Shell::recompile ;
1484 my($self) = shift @_;
1485 my($module,@module,$cpan_file,%dist);
1486 @module = $self->_binary_extensions();
1487 for $module (@module){ # we force now and compile later, so we
1489 $cpan_file = $module->cpan_file;
1490 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1492 $dist{$cpan_file}++;
1494 for $cpan_file (sort keys %dist) {
1495 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1496 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1498 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1499 # stop a package from recompiling,
1500 # e.g. IO-1.12 when we have perl5.003_10
1504 #-> sub CPAN::Shell::_u_r_common ;
1506 my($self) = shift @_;
1507 my($what) = shift @_;
1508 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1509 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
1510 $what && $what =~ /^[aru]$/;
1512 @args = '/./' unless @args;
1513 my(@result,$module,%seen,%need,$headerdone,
1514 $version_undefs,$version_zeroes);
1515 $version_undefs = $version_zeroes = 0;
1516 my $sprintf = "%s%-25s%s %9s %9s %s\n";
1517 my @expand = $self->expand('Module',@args);
1518 my $expand = scalar @expand;
1519 if (0) { # Looks like noise to me, was very useful for debugging
1520 # for metadata cache
1521 $CPAN::Frontend->myprint(sprintf "%d matches in the database\n", $expand);
1523 for $module (@expand) {
1524 my $file = $module->cpan_file;
1525 next unless defined $file; # ??
1526 my($latest) = $module->cpan_version;
1527 my($inst_file) = $module->inst_file;
1529 return if $CPAN::Signal;
1532 $have = $module->inst_version;
1533 } elsif ($what eq "r") {
1534 $have = $module->inst_version;
1536 if ($have eq "undef"){
1538 } elsif ($have == 0){
1541 next unless CPAN::Version->vgt($latest, $have);
1542 # to be pedantic we should probably say:
1543 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1544 # to catch the case where CPAN has a version 0 and we have a version undef
1545 } elsif ($what eq "u") {
1551 } elsif ($what eq "r") {
1553 } elsif ($what eq "u") {
1557 return if $CPAN::Signal; # this is sometimes lengthy
1560 push @result, sprintf "%s %s\n", $module->id, $have;
1561 } elsif ($what eq "r") {
1562 push @result, $module->id;
1563 next if $seen{$file}++;
1564 } elsif ($what eq "u") {
1565 push @result, $module->id;
1566 next if $seen{$file}++;
1567 next if $file =~ /^Contact/;
1569 unless ($headerdone++){
1570 $CPAN::Frontend->myprint("\n");
1571 $CPAN::Frontend->myprint(sprintf(
1574 "Package namespace",
1586 $CPAN::META->has_inst("Term::ANSIColor")
1588 $module->{RO}{description}
1590 $color_on = Term::ANSIColor::color("green");
1591 $color_off = Term::ANSIColor::color("reset");
1593 $CPAN::Frontend->myprint(sprintf $sprintf,
1600 $need{$module->id}++;
1604 $CPAN::Frontend->myprint("No modules found for @args\n");
1605 } elsif ($what eq "r") {
1606 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1610 if ($version_zeroes) {
1611 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1612 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1613 qq{a version number of 0\n});
1615 if ($version_undefs) {
1616 my $s_has = $version_undefs > 1 ? "s have" : " has";
1617 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1618 qq{parseable version number\n});
1624 #-> sub CPAN::Shell::r ;
1626 shift->_u_r_common("r",@_);
1629 #-> sub CPAN::Shell::u ;
1631 shift->_u_r_common("u",@_);
1634 #-> sub CPAN::Shell::autobundle ;
1637 CPAN::Config->load unless $CPAN::Config_loaded++;
1638 my(@bundle) = $self->_u_r_common("a",@_);
1639 my($todir) = MM->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1640 File::Path::mkpath($todir);
1641 unless (-d $todir) {
1642 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
1645 my($y,$m,$d) = (localtime)[5,4,3];
1649 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1650 my($to) = MM->catfile($todir,"$me.pm");
1652 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1653 $to = MM->catfile($todir,"$me.pm");
1655 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1657 "package Bundle::$me;\n\n",
1658 "\$VERSION = '0.01';\n\n",
1662 "Bundle::$me - Snapshot of installation on ",
1663 $Config::Config{'myhostname'},
1666 "\n\n=head1 SYNOPSIS\n\n",
1667 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1668 "=head1 CONTENTS\n\n",
1669 join("\n", @bundle),
1670 "\n\n=head1 CONFIGURATION\n\n",
1672 "\n\n=head1 AUTHOR\n\n",
1673 "This Bundle has been generated automatically ",
1674 "by the autobundle routine in CPAN.pm.\n",
1677 $CPAN::Frontend->myprint("\nWrote bundle file
1681 #-> sub CPAN::Shell::expandany ;
1684 CPAN->debug("s[$s]") if $CPAN::DEBUG;
1685 if ($s =~ m|/|) { # looks like a file
1686 return $CPAN::META->instance('CPAN::Distribution',$s);
1687 # Distributions spring into existence, not expand
1688 } elsif ($s =~ m|^Bundle::|) {
1689 $self->local_bundles; # scanning so late for bundles seems
1690 # both attractive and crumpy: always
1691 # current state but easy to forget
1693 return $self->expand('Bundle',$s);
1695 return $self->expand('Module',$s)
1696 if $CPAN::META->exists('CPAN::Module',$s);
1701 #-> sub CPAN::Shell::expand ;
1704 my($type,@args) = @_;
1707 my($regex,$command);
1708 if ($arg =~ m|^/(.*)/$|) {
1710 } elsif ($arg =~ m/^=/) {
1711 $command = substr($arg,1);
1713 my $class = "CPAN::$type";
1715 if (defined $regex) {
1719 $CPAN::META->all_objects($class)
1722 # BUG, we got an empty object somewhere
1723 CPAN->debug(sprintf(
1724 "Empty id on obj[%s]%%[%s]",
1731 if $obj->id =~ /$regex/i
1735 $] < 5.00303 ### provide sort of
1736 ### compatibility with 5.003
1741 $obj->name =~ /$regex/i
1744 } elsif ($command) {
1745 die "leading equal sign in command disabled, ".
1746 "please edit CPAN.pm to enable eval() or ".
1747 "do not use = on argument list";
1751 $CPAN::META->all_objects($class)
1753 push @m, $self if eval $command;
1757 if ( $type eq 'Bundle' ) {
1758 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
1760 if ($CPAN::META->exists($class,$xarg)) {
1761 $obj = $CPAN::META->instance($class,$xarg);
1762 } elsif ($CPAN::META->exists($class,$arg)) {
1763 $obj = $CPAN::META->instance($class,$arg);
1770 return wantarray ? @m : $m[0];
1773 #-> sub CPAN::Shell::format_result ;
1776 my($type,@args) = @_;
1777 @args = '/./' unless @args;
1778 my(@result) = $self->expand($type,@args);
1779 my $result = @result == 1 ?
1780 $result[0]->as_string :
1781 join "", map {$_->as_glimpse} @result;
1782 $result ||= "No objects of type $type found for argument @args\n";
1786 # The only reason for this method is currently to have a reliable
1787 # debugging utility that reveals which output is going through which
1788 # channel. No, I don't like the colors ;-)
1789 sub print_ornamented {
1790 my($self,$what,$ornament) = @_;
1792 my $ornamenting = 0; # turn the colors on
1795 unless (defined &color) {
1796 if ($CPAN::META->has_inst("Term::ANSIColor")) {
1797 import Term::ANSIColor "color";
1799 *color = sub { return "" };
1803 for $line (split /\n/, $what) {
1804 $longest = length($line) if length($line) > $longest;
1806 my $sprintf = "%-" . $longest . "s";
1808 $what =~ s/(.*\n?)//m;
1811 my($nl) = chomp $line ? "\n" : "";
1812 # print "line[$line]ornament[$ornament]sprintf[$sprintf]\n";
1813 print color($ornament), sprintf($sprintf,$line), color("reset"), $nl;
1821 my($self,$what) = @_;
1822 $self->print_ornamented($what, 'bold blue on_yellow');
1826 my($self,$what) = @_;
1827 $self->myprint($what);
1832 my($self,$what) = @_;
1833 $self->print_ornamented($what, 'bold red on_yellow');
1837 my($self,$what) = @_;
1838 $self->print_ornamented($what, 'bold red on_white');
1839 Carp::confess "died";
1843 my($self,$what) = @_;
1844 $self->print_ornamented($what, 'bold red on_white');
1849 return if -t STDOUT;
1850 my $odef = select STDERR;
1857 #-> sub CPAN::Shell::rematein ;
1858 # RE-adme||MA-ke||TE-st||IN-stall
1861 my($meth,@some) = @_;
1863 if ($meth eq 'force') {
1865 $meth = shift @some;
1868 CPAN->debug("pragma[$pragma]meth[$meth] some[@some]") if $CPAN::DEBUG;
1870 # Here is the place to set "test_count" on all involved parties to
1871 # 0. We then can pass this counter on to the involved
1872 # distributions and those can refuse to test if test_count > X. In
1873 # the first stab at it we could use a 1 for "X".
1875 # But when do I reset the distributions to start with 0 again?
1876 # Jost suggested to have a random or cycling interaction ID that
1877 # we pass through. But the ID is something that is just left lying
1878 # around in addition to the counter, so I'd prefer to set the
1879 # counter to 0 now, and repeat at the end of the loop. But what
1880 # about dependencies? They appear later and are not reset, they
1881 # enter the queue but not its copy. How do they get a sensible
1884 # construct the queue
1886 foreach $s (@some) {
1889 CPAN->debug("s is an object[$s]") if $CPAN::DEBUG;
1891 } elsif ($s =~ m|^/|) { # looks like a regexp
1892 $CPAN::Frontend->mywarn("Sorry, $meth with a regular expression is ".
1897 CPAN->debug("calling expandany [$s]") if $CPAN::DEBUG;
1898 $obj = CPAN::Shell->expandany($s);
1901 $obj->color_cmd_tmps(0,1);
1902 CPAN::Queue->new($s);
1904 } elsif ($CPAN::META->exists('CPAN::Author',$s)) {
1905 $obj = $CPAN::META->instance('CPAN::Author',$s);
1906 $CPAN::Frontend->myprint(
1908 "Don't be silly, you can't $meth ",
1915 ->myprint(qq{Warning: Cannot $meth $s, }.
1916 qq{don\'t know what it is.
1921 to find objects with matching identifiers.
1927 # queuerunner (please be warned: when I started to change the
1928 # queue to hold objects instead of names, I made one or two
1929 # mistakes and never found which. I reverted back instead)
1930 while ($s = CPAN::Queue->first) {
1933 $obj = $s; # I do not believe, we would survive if this happened
1935 $obj = CPAN::Shell->expandany($s);
1939 ($] < 5.00303 || $obj->can($pragma))){
1940 ### compatibility with 5.003
1941 $obj->$pragma($meth); # the pragma "force" in
1942 # "CPAN::Distribution" must know
1943 # what we are intending
1945 if ($]>=5.00303 && $obj->can('called_for')) {
1946 $obj->called_for($s);
1949 qq{pragma[$pragma]meth[$meth]obj[$obj]as_string\[}.
1955 CPAN::Queue->delete($s);
1957 CPAN->debug("failed");
1961 CPAN::Queue->delete_first($s);
1963 for my $obj (@qcopy) {
1964 $obj->color_cmd_tmps(0,0);
1968 #-> sub CPAN::Shell::dump ;
1969 sub dump { shift->rematein('dump',@_); }
1970 #-> sub CPAN::Shell::force ;
1971 sub force { shift->rematein('force',@_); }
1972 #-> sub CPAN::Shell::get ;
1973 sub get { shift->rematein('get',@_); }
1974 #-> sub CPAN::Shell::readme ;
1975 sub readme { shift->rematein('readme',@_); }
1976 #-> sub CPAN::Shell::make ;
1977 sub make { shift->rematein('make',@_); }
1978 #-> sub CPAN::Shell::test ;
1979 sub test { shift->rematein('test',@_); }
1980 #-> sub CPAN::Shell::install ;
1981 sub install { shift->rematein('install',@_); }
1982 #-> sub CPAN::Shell::clean ;
1983 sub clean { shift->rematein('clean',@_); }
1984 #-> sub CPAN::Shell::look ;
1985 sub look { shift->rematein('look',@_); }
1986 #-> sub CPAN::Shell::cvs_import ;
1987 sub cvs_import { shift->rematein('cvs_import',@_); }
1991 #-> sub CPAN::FTP::ftp_get ;
1993 my($class,$host,$dir,$file,$target) = @_;
1995 qq[Going to fetch file [$file] from dir [$dir]
1996 on host [$host] as local [$target]\n]
1998 my $ftp = Net::FTP->new($host);
1999 return 0 unless defined $ftp;
2000 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
2001 $class->debug(qq[Going to login("anonymous","$Config::Config{cf_email}")]);
2002 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
2003 warn "Couldn't login on $host";
2006 unless ( $ftp->cwd($dir) ){
2007 warn "Couldn't cwd $dir";
2011 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
2012 unless ( $ftp->get($file,$target) ){
2013 warn "Couldn't fetch $file from $host\n";
2016 $ftp->quit; # it's ok if this fails
2020 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
2022 # > *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
2023 # > --- /tmp/cp Wed Sep 24 13:26:40 1997
2025 # > *** 1562,1567 ****
2026 # > --- 1562,1580 ----
2027 # > return 1 if substr($url,0,4) eq "file";
2028 # > return 1 unless $url =~ m|://([^/]+)|;
2030 # > + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
2032 # > + $proxy =~ m|://([^/:]+)|;
2034 # > + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
2035 # > + if ($noproxy) {
2036 # > + if ($host !~ /$noproxy$/) {
2037 # > + $host = $proxy;
2040 # > + $host = $proxy;
2043 # > require Net::Ping;
2044 # > return 1 unless $Net::Ping::VERSION >= 2;
2048 #-> sub CPAN::FTP::localize ;
2050 my($self,$file,$aslocal,$force) = @_;
2052 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
2053 unless defined $aslocal;
2054 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
2057 if ($^O eq 'MacOS') {
2058 # Comment by AK on 2000-09-03: Uniq short filenames would be
2059 # available in CHECKSUMS file
2060 my($name, $path) = File::Basename::fileparse($aslocal, '');
2061 if (length($name) > 31) {
2072 my $size = 31 - length($suf);
2073 while (length($name) > $size) {
2077 $aslocal = File::Spec->catfile($path, $name);
2081 return $aslocal if -f $aslocal && -r _ && !($force & 1);
2084 rename $aslocal, "$aslocal.bak";
2088 my($aslocal_dir) = File::Basename::dirname($aslocal);
2089 File::Path::mkpath($aslocal_dir);
2090 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
2091 qq{directory "$aslocal_dir".
2092 I\'ll continue, but if you encounter problems, they may be due
2093 to insufficient permissions.\n}) unless -w $aslocal_dir;
2095 # Inheritance is not easier to manage than a few if/else branches
2096 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2098 $Ua = LWP::UserAgent->new;
2100 $Ua->proxy('ftp', $var)
2101 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
2102 $Ua->proxy('http', $var)
2103 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
2105 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
2108 $ENV{ftp_proxy} = $CPAN::Config->{ftp_proxy} if $CPAN::Config->{ftp_proxy};
2109 $ENV{http_proxy} = $CPAN::Config->{http_proxy}
2110 if $CPAN::Config->{http_proxy};
2111 $ENV{no_proxy} = $CPAN::Config->{no_proxy} if $CPAN::Config->{no_proxy};
2113 # Try the list of urls for each single object. We keep a record
2114 # where we did get a file from
2115 my(@reordered,$last);
2116 $CPAN::Config->{urllist} ||= [];
2117 $last = $#{$CPAN::Config->{urllist}};
2118 if ($force & 2) { # local cpans probably out of date, don't reorder
2119 @reordered = (0..$last);
2123 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
2125 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
2136 @levels = ($Themethod, grep {$_ ne $Themethod} qw/easy hard hardest/);
2138 @levels = qw/easy hard hardest/;
2140 @levels = qw/easy/ if $^O eq 'MacOS';
2142 for $levelno (0..$#levels) {
2143 my $level = $levels[$levelno];
2144 my $method = "host$level";
2145 my @host_seq = $level eq "easy" ?
2146 @reordered : 0..$last; # reordered has CDROM up front
2147 @host_seq = (0) unless @host_seq;
2148 my $ret = $self->$method(\@host_seq,$file,$aslocal);
2150 $Themethod = $level;
2152 # utime $now, $now, $aslocal; # too bad, if we do that, we
2153 # might alter a local mirror
2154 $self->debug("level[$level]") if $CPAN::DEBUG;
2158 last if $CPAN::Signal; # need to cleanup
2161 unless ($CPAN::Signal) {
2164 qq{Please check, if the URLs I found in your configuration file \(}.
2165 join(", ", @{$CPAN::Config->{urllist}}).
2166 qq{\) are valid. The urllist can be edited.},
2167 qq{E.g. with 'o conf urllist push ftp://myurl/'};
2168 $CPAN::Frontend->myprint(Text::Wrap::wrap("","",@mess). "\n\n");
2170 $CPAN::Frontend->myprint("Cannot fetch $file\n\n");
2173 rename "$aslocal.bak", $aslocal;
2174 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
2175 $self->ls($aslocal));
2182 my($self,$host_seq,$file,$aslocal) = @_;
2184 HOSTEASY: for $i (@$host_seq) {
2185 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2186 $url .= "/" unless substr($url,-1) eq "/";
2188 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
2189 if ($url =~ /^file:/) {
2191 if ($CPAN::META->has_inst('URI::URL')) {
2192 my $u = URI::URL->new($url);
2194 } else { # works only on Unix, is poorly constructed, but
2195 # hopefully better than nothing.
2196 # RFC 1738 says fileurl BNF is
2197 # fileurl = "file://" [ host | "localhost" ] "/" fpath
2198 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
2200 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
2201 $l =~ s|^file:||; # assume they
2204 $l =~ s|^/||s unless -f $l; # e.g. /P:
2206 if ( -f $l && -r _) {
2210 # Maybe mirror has compressed it?
2212 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
2213 CPAN::Tarzip->gunzip("$l.gz", $aslocal);
2220 if ($CPAN::META->has_usable('LWP')) {
2221 $CPAN::Frontend->myprint("Fetching with LWP:
2225 require LWP::UserAgent;
2226 $Ua = LWP::UserAgent->new;
2228 my $res = $Ua->mirror($url, $aslocal);
2229 if ($res->is_success) {
2232 utime $now, $now, $aslocal; # download time is more
2233 # important than upload time
2235 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2236 my $gzurl = "$url.gz";
2237 $CPAN::Frontend->myprint("Fetching with LWP:
2240 $res = $Ua->mirror($gzurl, "$aslocal.gz");
2241 if ($res->is_success &&
2242 CPAN::Tarzip->gunzip("$aslocal.gz",$aslocal)
2248 # Alan Burlison informed me that in firewall environments
2249 # Net::FTP can still succeed where LWP fails. So we do not
2250 # skip Net::FTP anymore when LWP is available.
2253 $self->debug("LWP not installed") if $CPAN::DEBUG;
2255 return if $CPAN::Signal;
2256 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2257 # that's the nice and easy way thanks to Graham
2258 my($host,$dir,$getfile) = ($1,$2,$3);
2259 if ($CPAN::META->has_usable('Net::FTP')) {
2261 $CPAN::Frontend->myprint("Fetching with Net::FTP:
2264 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
2265 "aslocal[$aslocal]") if $CPAN::DEBUG;
2266 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
2270 if ($aslocal !~ /\.gz(?!\n)\Z/) {
2271 my $gz = "$aslocal.gz";
2272 $CPAN::Frontend->myprint("Fetching with Net::FTP
2275 if (CPAN::FTP->ftp_get($host,
2279 CPAN::Tarzip->gunzip($gz,$aslocal)
2288 return if $CPAN::Signal;
2293 my($self,$host_seq,$file,$aslocal) = @_;
2295 # Came back if Net::FTP couldn't establish connection (or
2296 # failed otherwise) Maybe they are behind a firewall, but they
2297 # gave us a socksified (or other) ftp program...
2300 my($devnull) = $CPAN::Config->{devnull} || "";
2302 my($aslocal_dir) = File::Basename::dirname($aslocal);
2303 File::Path::mkpath($aslocal_dir);
2304 HOSTHARD: for $i (@$host_seq) {
2305 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2306 $url .= "/" unless substr($url,-1) eq "/";
2308 my($proto,$host,$dir,$getfile);
2310 # Courtesy Mark Conty mark_conty@cargill.com change from
2311 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2313 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
2314 # proto not yet used
2315 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
2317 next HOSTHARD; # who said, we could ftp anything except ftp?
2319 next HOSTHARD if $proto eq "file"; # file URLs would have had
2320 # success above. Likely a bogus URL
2322 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
2324 for $f ('lynx','ncftpget','ncftp','wget') {
2325 next unless exists $CPAN::Config->{$f};
2326 $funkyftp = $CPAN::Config->{$f};
2327 next unless defined $funkyftp;
2328 next if $funkyftp =~ /^\s*$/;
2329 my($asl_ungz, $asl_gz);
2330 ($asl_ungz = $aslocal) =~ s/\.gz//;
2331 $asl_gz = "$asl_ungz.gz";
2332 my($src_switch) = "";
2334 $src_switch = " -source";
2335 } elsif ($f eq "ncftp"){
2336 $src_switch = " -c";
2337 } elsif ($f eq "wget"){
2338 $src_switch = " -O -";
2341 my($stdout_redir) = " > $asl_ungz";
2342 if ($f eq "ncftpget"){
2343 $chdir = "cd $aslocal_dir && ";
2346 $CPAN::Frontend->myprint(
2348 Trying with "$funkyftp$src_switch" to get
2352 "$chdir$funkyftp$src_switch '$url' $devnull$stdout_redir";
2353 $self->debug("system[$system]") if $CPAN::DEBUG;
2355 if (($wstatus = system($system)) == 0
2358 -s $asl_ungz # lynx returns 0 when it fails somewhere
2364 } elsif ($asl_ungz ne $aslocal) {
2365 # test gzip integrity
2366 if (CPAN::Tarzip->gtest($asl_ungz)) {
2367 # e.g. foo.tar is gzipped --> foo.tar.gz
2368 rename $asl_ungz, $aslocal;
2370 CPAN::Tarzip->gzip($asl_ungz,$asl_gz);
2375 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2377 -f $asl_ungz && -s _ == 0;
2378 my $gz = "$aslocal.gz";
2379 my $gzurl = "$url.gz";
2380 $CPAN::Frontend->myprint(
2382 Trying with "$funkyftp$src_switch" to get
2385 my($system) = "$funkyftp$src_switch '$url.gz' $devnull > $asl_gz";
2386 $self->debug("system[$system]") if $CPAN::DEBUG;
2388 if (($wstatus = system($system)) == 0
2392 # test gzip integrity
2393 if (CPAN::Tarzip->gtest($asl_gz)) {
2394 CPAN::Tarzip->gunzip($asl_gz,$aslocal);
2396 # somebody uncompressed file for us?
2397 rename $asl_ungz, $aslocal;
2402 unlink $asl_gz if -f $asl_gz;
2405 my $estatus = $wstatus >> 8;
2406 my $size = -f $aslocal ?
2407 ", left\n$aslocal with size ".-s _ :
2408 "\nWarning: expected file [$aslocal] doesn't exist";
2409 $CPAN::Frontend->myprint(qq{
2410 System call "$system"
2411 returned status $estatus (wstat $wstatus)$size
2414 return if $CPAN::Signal;
2415 } # lynx,ncftpget,ncftp
2420 my($self,$host_seq,$file,$aslocal) = @_;
2423 my($aslocal_dir) = File::Basename::dirname($aslocal);
2424 File::Path::mkpath($aslocal_dir);
2425 HOSTHARDEST: for $i (@$host_seq) {
2426 unless (length $CPAN::Config->{'ftp'}) {
2427 $CPAN::Frontend->myprint("No external ftp command available\n\n");
2430 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2431 $url .= "/" unless substr($url,-1) eq "/";
2433 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
2434 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2437 my($host,$dir,$getfile) = ($1,$2,$3);
2439 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
2440 $ctime,$blksize,$blocks) = stat($aslocal);
2441 $timestamp = $mtime ||= 0;
2442 my($netrc) = CPAN::FTP::netrc->new;
2443 my($netrcfile) = $netrc->netrc;
2444 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
2445 my $targetfile = File::Basename::basename($aslocal);
2451 map("cd $_", split "/", $dir), # RFC 1738
2453 "get $getfile $targetfile",
2457 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
2458 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
2459 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
2461 $netrc->contains($host))) if $CPAN::DEBUG;
2462 if ($netrc->protected) {
2463 $CPAN::Frontend->myprint(qq{
2464 Trying with external ftp to get
2466 As this requires some features that are not thoroughly tested, we\'re
2467 not sure, that we get it right....
2471 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose $host",
2473 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2474 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2476 if ($mtime > $timestamp) {
2477 $CPAN::Frontend->myprint("GOT $aslocal\n");
2481 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
2483 return if $CPAN::Signal;
2485 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
2486 qq{correctly protected.\n});
2489 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
2490 nor does it have a default entry\n");
2493 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
2494 # then and login manually to host, using e-mail as
2496 $CPAN::Frontend->myprint(qq{Issuing "$CPAN::Config->{'ftp'}$verbose -n"\n});
2500 "user anonymous $Config::Config{'cf_email'}"
2502 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose -n", @dialog);
2503 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2504 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2506 if ($mtime > $timestamp) {
2507 $CPAN::Frontend->myprint("GOT $aslocal\n");
2511 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
2513 return if $CPAN::Signal;
2514 $CPAN::Frontend->myprint("Can't access URL $url.\n\n");
2520 my($self,$command,@dialog) = @_;
2521 my $fh = FileHandle->new;
2522 $fh->open("|$command") or die "Couldn't open ftp: $!";
2523 foreach (@dialog) { $fh->print("$_\n") }
2524 $fh->close; # Wait for process to complete
2526 my $estatus = $wstatus >> 8;
2527 $CPAN::Frontend->myprint(qq{
2528 Subprocess "|$command"
2529 returned status $estatus (wstat $wstatus)
2533 # find2perl needs modularization, too, all the following is stolen
2537 my($self,$name) = @_;
2538 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
2539 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
2541 my($perms,%user,%group);
2545 $blocks = int(($blocks + 1) / 2);
2548 $blocks = int(($sizemm + 1023) / 1024);
2551 if (-f _) { $perms = '-'; }
2552 elsif (-d _) { $perms = 'd'; }
2553 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
2554 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
2555 elsif (-p _) { $perms = 'p'; }
2556 elsif (-S _) { $perms = 's'; }
2557 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
2559 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
2560 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
2561 my $tmpmode = $mode;
2562 my $tmp = $rwx[$tmpmode & 7];
2564 $tmp = $rwx[$tmpmode & 7] . $tmp;
2566 $tmp = $rwx[$tmpmode & 7] . $tmp;
2567 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
2568 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
2569 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
2572 my $user = $user{$uid} || $uid; # too lazy to implement lookup
2573 my $group = $group{$gid} || $gid;
2575 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
2577 my($moname) = $moname[$mon];
2578 if (-M _ > 365.25 / 2) {
2579 $timeyear = $year + 1900;
2582 $timeyear = sprintf("%02d:%02d", $hour, $min);
2585 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
2599 package CPAN::FTP::netrc;
2603 my $file = MM->catfile($ENV{HOME},".netrc");
2605 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2606 $atime,$mtime,$ctime,$blksize,$blocks)
2611 my($fh,@machines,$hasdefault);
2613 $fh = FileHandle->new or die "Could not create a filehandle";
2615 if($fh->open($file)){
2616 $protected = ($mode & 077) == 0;
2618 NETRC: while (<$fh>) {
2619 my(@tokens) = split " ", $_;
2620 TOKEN: while (@tokens) {
2621 my($t) = shift @tokens;
2622 if ($t eq "default"){
2626 last TOKEN if $t eq "macdef";
2627 if ($t eq "machine") {
2628 push @machines, shift @tokens;
2633 $file = $hasdefault = $protected = "";
2637 'mach' => [@machines],
2639 'hasdefault' => $hasdefault,
2640 'protected' => $protected,
2644 # CPAN::FTP::hasdefault;
2645 sub hasdefault { shift->{'hasdefault'} }
2646 sub netrc { shift->{'netrc'} }
2647 sub protected { shift->{'protected'} }
2649 my($self,$mach) = @_;
2650 for ( @{$self->{'mach'}} ) {
2651 return 1 if $_ eq $mach;
2656 package CPAN::Complete;
2659 my($text, $line, $start, $end) = @_;
2660 my(@perlret) = cpl($text, $line, $start);
2661 # find longest common match. Can anybody show me how to peruse
2662 # T::R::Gnu to have this done automatically? Seems expensive.
2663 return () unless @perlret;
2664 my($newtext) = $text;
2665 for (my $i = length($text)+1;;$i++) {
2666 last unless length($perlret[0]) && length($perlret[0]) >= $i;
2667 my $try = substr($perlret[0],0,$i);
2668 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
2669 # warn "try[$try]tries[@tries]";
2670 if (@tries == @perlret) {
2676 ($newtext,@perlret);
2679 #-> sub CPAN::Complete::cpl ;
2681 my($word,$line,$pos) = @_;
2685 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2687 if ($line =~ s/^(force\s*)//) {
2692 @return = grep /^$word/, @CPAN::Complete::COMMANDS;
2693 } elsif ( $line !~ /^[\!abcdhimorutl]/ ) {
2695 } elsif ($line =~ /^a\s/) {
2696 @return = cplx('CPAN::Author',$word);
2697 } elsif ($line =~ /^b\s/) {
2698 @return = cplx('CPAN::Bundle',$word);
2699 } elsif ($line =~ /^d\s/) {
2700 @return = cplx('CPAN::Distribution',$word);
2701 } elsif ($line =~ m/^(
2702 [mru]|make|clean|dump|test|install|readme|look|cvs_import
2704 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
2705 } elsif ($line =~ /^i\s/) {
2706 @return = cpl_any($word);
2707 } elsif ($line =~ /^reload\s/) {
2708 @return = cpl_reload($word,$line,$pos);
2709 } elsif ($line =~ /^o\s/) {
2710 @return = cpl_option($word,$line,$pos);
2711 } elsif ($line =~ m/^\S+\s/ ) {
2712 # fallback for future commands and what we have forgotten above
2713 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
2720 #-> sub CPAN::Complete::cplx ;
2722 my($class, $word) = @_;
2723 # I believed for many years that this was sorted, today I
2724 # realized, it wasn't sorted anymore. Now (rev 1.301 / v 1.55) I
2725 # make it sorted again. Maybe sort was dropped when GNU-readline
2726 # support came in? The RCS file is difficult to read on that:-(
2727 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
2730 #-> sub CPAN::Complete::cpl_any ;
2734 cplx('CPAN::Author',$word),
2735 cplx('CPAN::Bundle',$word),
2736 cplx('CPAN::Distribution',$word),
2737 cplx('CPAN::Module',$word),
2741 #-> sub CPAN::Complete::cpl_reload ;
2743 my($word,$line,$pos) = @_;
2745 my(@words) = split " ", $line;
2746 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2747 my(@ok) = qw(cpan index);
2748 return @ok if @words == 1;
2749 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
2752 #-> sub CPAN::Complete::cpl_option ;
2754 my($word,$line,$pos) = @_;
2756 my(@words) = split " ", $line;
2757 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2758 my(@ok) = qw(conf debug);
2759 return @ok if @words == 1;
2760 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
2762 } elsif ($words[1] eq 'index') {
2764 } elsif ($words[1] eq 'conf') {
2765 return CPAN::Config::cpl(@_);
2766 } elsif ($words[1] eq 'debug') {
2767 return sort grep /^\Q$word\E/, sort keys %CPAN::DEBUG, 'all';
2771 package CPAN::Index;
2773 #-> sub CPAN::Index::force_reload ;
2776 $CPAN::Index::last_time = 0;
2780 #-> sub CPAN::Index::reload ;
2782 my($cl,$force) = @_;
2785 # XXX check if a newer one is available. (We currently read it
2786 # from time to time)
2787 for ($CPAN::Config->{index_expire}) {
2788 $_ = 0.001 unless $_ && $_ > 0.001;
2790 unless (1 || $CPAN::Have_warned->{readmetadatacache}++) {
2791 # debug here when CPAN doesn't seem to read the Metadata
2793 Carp::cluck("META-PROTOCOL[$CPAN::META->{PROTOCOL}]");
2795 unless ($CPAN::META->{PROTOCOL}) {
2796 $cl->read_metadata_cache;
2797 $CPAN::META->{PROTOCOL} ||= "1.0";
2799 if ( $CPAN::META->{PROTOCOL} < PROTOCOL ) {
2800 # warn "Setting last_time to 0";
2801 $last_time = 0; # No warning necessary
2803 return if $last_time + $CPAN::Config->{index_expire}*86400 > $time
2806 # IFF we are developing, it helps to wipe out the memory
2807 # between reloads, otherwise it is not what a user expects.
2808 undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
2809 $CPAN::META = CPAN->new;
2813 local $last_time = $time;
2814 local $CPAN::META->{PROTOCOL} = PROTOCOL;
2816 my $needshort = $^O eq "dos";
2818 $cl->rd_authindex($cl
2820 "authors/01mailrc.txt.gz",
2822 File::Spec->catfile('authors', '01mailrc.gz') :
2823 File::Spec->catfile('authors', '01mailrc.txt.gz'),
2826 $debug = "timing reading 01[".($t2 - $time)."]";
2828 return if $CPAN::Signal; # this is sometimes lengthy
2829 $cl->rd_modpacks($cl
2831 "modules/02packages.details.txt.gz",
2833 File::Spec->catfile('modules', '02packag.gz') :
2834 File::Spec->catfile('modules', '02packages.details.txt.gz'),
2837 $debug .= "02[".($t2 - $time)."]";
2839 return if $CPAN::Signal; # this is sometimes lengthy
2842 "modules/03modlist.data.gz",
2844 File::Spec->catfile('modules', '03mlist.gz') :
2845 File::Spec->catfile('modules', '03modlist.data.gz'),
2847 $cl->write_metadata_cache;
2849 $debug .= "03[".($t2 - $time)."]";
2851 CPAN->debug($debug) if $CPAN::DEBUG;
2854 $CPAN::META->{PROTOCOL} = PROTOCOL;
2857 #-> sub CPAN::Index::reload_x ;
2859 my($cl,$wanted,$localname,$force) = @_;
2860 $force |= 2; # means we're dealing with an index here
2861 CPAN::Config->load; # we should guarantee loading wherever we rely
2863 $localname ||= $wanted;
2864 my $abs_wanted = MM->catfile($CPAN::Config->{'keep_source_where'},
2868 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
2871 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
2872 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
2873 qq{day$s. I\'ll use that.});
2876 $force |= 1; # means we're quite serious about it.
2878 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
2881 #-> sub CPAN::Index::rd_authindex ;
2883 my($cl, $index_target) = @_;
2885 return unless defined $index_target;
2886 $CPAN::Frontend->myprint("Going to read $index_target\n");
2887 # my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
2888 # while ($_ = $fh->READLINE) {
2891 tie *FH, CPAN::Tarzip, $index_target;
2893 push @lines, split /\012/ while <FH>;
2895 my($userid,$fullname,$email) =
2896 m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
2897 next unless $userid && $fullname && $email;
2899 # instantiate an author object
2900 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
2901 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
2902 return if $CPAN::Signal;
2907 my($self,$dist) = @_;
2908 $dist = $self->{'id'} unless defined $dist;
2909 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
2913 #-> sub CPAN::Index::rd_modpacks ;
2915 my($self, $index_target) = @_;
2917 return unless defined $index_target;
2918 $CPAN::Frontend->myprint("Going to read $index_target\n");
2919 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
2921 while ($_ = $fh->READLINE) {
2923 my @ls = map {"$_\n"} split /\n/, $_;
2924 unshift @ls, "\n" x length($1) if /^(\n+)/;
2930 my $shift = shift(@lines);
2931 $shift =~ /^Line-Count:\s+(\d+)/;
2932 $line_count = $1 if $1;
2933 last if $shift =~ /^\s*$/;
2935 if (not defined $line_count) {
2937 warn qq{Warning: Your $index_target does not contain a Line-Count header.
2938 Please check the validity of the index file by comparing it to more
2939 than one CPAN mirror. I'll continue but problems seem likely to
2944 } elsif ($line_count != scalar @lines) {
2946 warn sprintf qq{Warning: Your %s
2947 contains a Line-Count header of %d but I see %d lines there. Please
2948 check the validity of the index file by comparing it to more than one
2949 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
2950 $index_target, $line_count, scalar(@lines);
2953 # A necessity since we have metadata_cache: delete what isn't
2955 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
2956 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
2960 # before 1.56 we split into 3 and discarded the rest. From
2961 # 1.57 we assign remaining text to $comment thus allowing to
2962 # influence isa_perl
2963 my($mod,$version,$dist,$comment) = split " ", $_, 4;
2964 my($bundle,$id,$userid);
2966 if ($mod eq 'CPAN' &&
2968 CPAN::Queue->exists('Bundle::CPAN') ||
2969 CPAN::Queue->exists('CPAN')
2973 if ($version > $CPAN::VERSION){
2974 $CPAN::Frontend->myprint(qq{
2975 There's a new CPAN.pm version (v$version) available!
2976 [Current version is v$CPAN::VERSION]
2977 You might want to try
2978 install Bundle::CPAN
2980 without quitting the current session. It should be a seamless upgrade
2981 while we are running...
2984 $CPAN::Frontend->myprint(qq{\n});
2986 last if $CPAN::Signal;
2987 } elsif ($mod =~ /^Bundle::(.*)/) {
2992 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
2993 # Let's make it a module too, because bundles have so much
2994 # in common with modules.
2996 # Changed in 1.57_63: seems like memory bloat now without
2997 # any value, so commented out
2999 # $CPAN::META->instance('CPAN::Module',$mod);
3003 # instantiate a module object
3004 $id = $CPAN::META->instance('CPAN::Module',$mod);
3008 if ($id->cpan_file ne $dist){ # update only if file is
3009 # different. CPAN prohibits same
3010 # name with different version
3011 $userid = $self->userid($dist);
3013 'CPAN_USERID' => $userid,
3014 'CPAN_VERSION' => $version,
3015 'CPAN_FILE' => $dist,
3019 # instantiate a distribution object
3020 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
3021 # we do not need CONTAINSMODS unless we do something with
3022 # this dist, so we better produce it on demand.
3024 ## my $obj = $CPAN::META->instance(
3025 ## 'CPAN::Distribution' => $dist
3027 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
3029 $CPAN::META->instance(
3030 'CPAN::Distribution' => $dist
3032 'CPAN_USERID' => $userid,
3033 'CPAN_COMMENT' => $comment,
3037 for my $name ($mod,$dist) {
3038 CPAN->debug("exists name[$name]") if $CPAN::DEBUG;
3039 $exists{$name} = undef;
3042 return if $CPAN::Signal;
3046 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
3047 for my $o ($CPAN::META->all_objects($class)) {
3048 next if exists $exists{$o->{ID}};
3049 $CPAN::META->delete($class,$o->{ID});
3050 CPAN->debug("deleting ID[$o->{ID}] in class[$class]")
3057 #-> sub CPAN::Index::rd_modlist ;
3059 my($cl,$index_target) = @_;
3060 return unless defined $index_target;
3061 $CPAN::Frontend->myprint("Going to read $index_target\n");
3062 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3065 while ($_ = $fh->READLINE) {
3067 my @ls = map {"$_\n"} split /\n/, $_;
3068 unshift @ls, "\n" x length($1) if /^(\n+)/;
3072 my $shift = shift(@eval);
3073 if ($shift =~ /^Date:\s+(.*)/){
3074 return if $date_of_03 eq $1;
3077 last if $shift =~ /^\s*$/;
3080 push @eval, q{CPAN::Modulelist->data;};
3082 my($comp) = Safe->new("CPAN::Safe1");
3083 my($eval) = join("", @eval);
3084 my $ret = $comp->reval($eval);
3085 Carp::confess($@) if $@;
3086 return if $CPAN::Signal;
3088 my $obj = $CPAN::META->instance("CPAN::Module",$_);
3089 delete $ret->{$_}{modid}; # not needed here, maybe elsewhere
3090 $obj->set(%{$ret->{$_}});
3091 return if $CPAN::Signal;
3095 #-> sub CPAN::Index::write_metadata_cache ;
3096 sub write_metadata_cache {
3098 return unless $CPAN::Config->{'cache_metadata'};
3099 return unless $CPAN::META->has_usable("Storable");
3101 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
3102 CPAN::Distribution)) {
3103 $cache->{$k} = $CPAN::META->{readonly}{$k}; # unsafe meta access, ok
3105 my $metadata_file = MM->catfile($CPAN::Config->{cpan_home},"Metadata");
3106 $cache->{last_time} = $last_time;
3107 $cache->{PROTOCOL} = PROTOCOL;
3108 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
3109 eval { Storable::nstore($cache, $metadata_file) };
3110 $CPAN::Frontend->mywarn($@) if $@;
3113 #-> sub CPAN::Index::read_metadata_cache ;
3114 sub read_metadata_cache {
3116 return unless $CPAN::Config->{'cache_metadata'};
3117 return unless $CPAN::META->has_usable("Storable");
3118 my $metadata_file = MM->catfile($CPAN::Config->{cpan_home},"Metadata");
3119 return unless -r $metadata_file and -f $metadata_file;
3120 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
3122 eval { $cache = Storable::retrieve($metadata_file) };
3123 $CPAN::Frontend->mywarn($@) if $@;
3124 if (!$cache || ref $cache ne 'HASH'){
3128 if (exists $cache->{PROTOCOL}) {
3129 if (PROTOCOL > $cache->{PROTOCOL}) {
3130 $CPAN::Frontend->mywarn(sprintf("Ignoring Metadata cache written ".
3131 "with protocol v%s, requiring v%s",
3138 $CPAN::Frontend->mywarn("Ignoring Metadata cache written ".
3139 "with protocol v1.0");
3144 while(my($class,$v) = each %$cache) {
3145 next unless $class =~ /^CPAN::/;
3146 $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok
3147 while (my($id,$ro) = each %$v) {
3148 $CPAN::META->{readwrite}{$class}{$id} ||=
3149 $class->new(ID=>$id, RO=>$ro);
3154 unless ($clcnt) { # sanity check
3155 $CPAN::Frontend->myprint("Warning: Found no data in $metadata_file\n");
3158 if ($idcnt < 1000) {
3159 $CPAN::Frontend->myprint("Warning: Found only $idcnt objects ".
3160 "in $metadata_file\n");
3163 $CPAN::META->{PROTOCOL} ||=
3164 $cache->{PROTOCOL}; # reading does not up or downgrade, but it
3165 # does initialize to some protocol
3166 $last_time = $cache->{last_time};
3169 package CPAN::InfoObj;
3172 sub cpan_userid { shift->{RO}{CPAN_USERID} }
3173 sub id { shift->{ID} }
3175 #-> sub CPAN::InfoObj::new ;
3177 my $this = bless {}, shift;
3182 # The set method may only be used by code that reads index data or
3183 # otherwise "objective" data from the outside world. All session
3184 # related material may do anything else with instance variables but
3185 # must not touch the hash under the RO attribute. The reason is that
3186 # the RO hash gets written to Metadata file and is thus persistent.
3188 #-> sub CPAN::InfoObj::set ;
3190 my($self,%att) = @_;
3191 my $class = ref $self;
3193 # This must be ||=, not ||, because only if we write an empty
3194 # reference, only then the set method will write into the readonly
3195 # area. But for Distributions that spring into existence, maybe
3196 # because of a typo, we do not like it that they are written into
3197 # the readonly area and made permanent (at least for a while) and
3198 # that is why we do not "allow" other places to call ->set.
3199 my $ro = $self->{RO} =
3200 $CPAN::META->{readonly}{$class}{$self->id} ||= {};
3202 while (my($k,$v) = each %att) {
3207 #-> sub CPAN::InfoObj::as_glimpse ;
3211 my $class = ref($self);
3212 $class =~ s/^CPAN:://;
3213 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
3217 #-> sub CPAN::InfoObj::as_string ;
3221 my $class = ref($self);
3222 $class =~ s/^CPAN:://;
3223 push @m, $class, " id = $self->{ID}\n";
3224 for (sort keys %{$self->{RO}}) {
3225 # next if m/^(ID|RO)$/;
3227 if ($_ eq "CPAN_USERID") {
3228 $extra .= " (".$self->author;
3229 my $email; # old perls!
3230 if ($email = $CPAN::META->instance("CPAN::Author",
3233 $extra .= " <$email>";
3235 $extra .= " <no email>";
3238 } elsif ($_ eq "FULLNAME") { # potential UTF-8 conversion
3239 push @m, sprintf " %-12s %s\n", $_, $self->fullname;
3242 next unless defined $self->{RO}{$_};
3243 push @m, sprintf " %-12s %s%s\n", $_, $self->{RO}{$_}, $extra;
3245 for (sort keys %$self) {
3246 next if m/^(ID|RO)$/;
3247 if (ref($self->{$_}) eq "ARRAY") {
3248 push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
3249 } elsif (ref($self->{$_}) eq "HASH") {
3253 join(" ",keys %{$self->{$_}}),
3256 push @m, sprintf " %-12s %s\n", $_, $self->{$_};
3262 #-> sub CPAN::InfoObj::author ;
3265 $CPAN::META->instance("CPAN::Author",$self->cpan_userid)->fullname;
3268 #-> sub CPAN::InfoObj::dump ;
3271 require Data::Dumper;
3272 print Data::Dumper::Dumper($self);
3275 package CPAN::Author;
3277 #-> sub CPAN::Author::as_glimpse ;
3281 my $class = ref($self);
3282 $class =~ s/^CPAN:://;
3283 push @m, sprintf "%-15s %s (%s)\n", $class, $self->{ID}, $self->fullname;
3287 #-> sub CPAN::Author::fullname ;
3289 my $fullname = shift->{RO}{FULLNAME};
3290 return $fullname unless $CPAN::Config->{term_is_latin};
3292 $fullname =~ s/([\xC0-\xDF])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;
3297 #-> sub CPAN::Author::email ;
3298 sub email { shift->{RO}{EMAIL} }
3300 package CPAN::Distribution;
3303 sub cpan_comment { shift->{RO}{CPAN_COMMENT} }
3307 delete $self->{later};
3310 #-> sub CPAN::Distribution::color_cmd_tmps ;
3311 sub color_cmd_tmps {
3313 my($depth) = shift || 0;
3314 my($color) = shift || 0;
3315 # a distribution needs to recurse into its prereq_pms
3317 return if exists $self->{incommandcolor}
3318 && $self->{incommandcolor}==$color;
3319 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
3320 "color_cmd_tmps depth[%s] self[%s] id[%s]",
3325 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
3326 my $prereq_pm = $self->prereq_pm;
3327 if (defined $prereq_pm) {
3328 for my $pre (keys %$prereq_pm) {
3329 my $premo = CPAN::Shell->expand("Module",$pre);
3330 $premo->color_cmd_tmps($depth+1,$color);
3334 delete $self->{sponsored_mods};
3335 delete $self->{badtestcnt};
3337 $self->{incommandcolor} = $color;
3340 #-> sub CPAN::Distribution::as_string ;
3343 $self->containsmods;
3344 $self->SUPER::as_string(@_);
3347 #-> sub CPAN::Distribution::containsmods ;
3350 return keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
3351 my $dist_id = $self->{ID};
3352 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
3353 my $mod_file = $mod->cpan_file or next;
3354 my $mod_id = $mod->{ID} or next;
3355 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
3357 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
3359 keys %{$self->{CONTAINSMODS}};
3362 #-> sub CPAN::Distribution::called_for ;
3365 $self->{CALLED_FOR} = $id if defined $id;
3366 return $self->{CALLED_FOR};
3369 #-> sub CPAN::Distribution::get ;
3374 exists $self->{'build_dir'} and push @e,
3375 "Is already unwrapped into directory $self->{'build_dir'}";
3376 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3381 $CPAN::Config->{keep_source_where},
3384 split("/",$self->id)
3387 $self->debug("Doing localize") if $CPAN::DEBUG;
3388 my $CWD = CPAN::anycwd();
3390 CPAN::FTP->localize("authors/id/$self->{ID}", $local_wanted)
3391 or $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n");
3392 return if $CPAN::Signal;
3393 $self->{localfile} = $local_file;
3394 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
3395 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
3396 $self->debug("doing chdir $builddir") if $CPAN::DEBUG;
3397 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
3400 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
3401 if ($CPAN::META->has_inst("MD5")) {
3402 $self->debug("MD5 is installed, verifying");
3405 $self->debug("MD5 is NOT installed");
3407 $self->debug("Removing tmp") if $CPAN::DEBUG;
3408 File::Path::rmtree("tmp");
3409 mkdir "tmp", 0755 or Carp::croak "Couldn't mkdir tmp: $!";
3410 chdir "tmp" or $CPAN::Frontend->mydie(qq{Could not chdir to "tmp": $!});;
3411 $self->debug("Changed directory to tmp") if $CPAN::DEBUG;
3412 return if $CPAN::Signal;
3413 if (! $local_file) {
3414 Carp::croak "bad download, can't do anything :-(\n";
3415 } elsif ($local_file =~ /(\.tar\.(gz|Z)|\.tgz)(?!\n)\Z/i){
3416 $self->{was_uncompressed}++ unless CPAN::Tarzip->gtest($local_file);
3417 $self->untar_me($local_file);
3418 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
3419 $self->unzip_me($local_file);
3420 } elsif ( $local_file =~ /\.pm\.(gz|Z)(?!\n)\Z/) {
3421 $self->{was_uncompressed}++ unless CPAN::Tarzip->gtest($local_file);
3422 $self->pm2dir_me($local_file);
3424 $self->{archived} = "NO";
3426 my $updir = File::Spec->updir;
3427 unless (chdir $updir) {
3428 my $cwd = CPAN::anycwd();
3429 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] to updir[$updir]: $!});
3431 if ($self->{archived} ne 'NO') {
3432 my $cwd = File::Spec->catdir(File::Spec->curdir, "tmp");
3433 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
3434 # Let's check if the package has its own directory.
3435 my $dh = DirHandle->new(File::Spec->curdir)
3436 or Carp::croak("Couldn't opendir .: $!");
3437 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
3439 my ($distdir,$packagedir);
3440 if (@readdir == 1 && -d $readdir[0]) {
3441 $distdir = $readdir[0];
3442 $packagedir = MM->catdir($builddir,$distdir);
3443 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
3445 File::Path::rmtree($packagedir);
3446 rename($distdir,$packagedir) or
3447 Carp::confess("Couldn't rename $distdir to $packagedir: $!");
3449 my $userid = $self->cpan_userid;
3451 CPAN->debug("no userid? self[$self]");
3454 my $pragmatic_dir = $userid . '000';
3455 $pragmatic_dir =~ s/\W_//g;
3456 $pragmatic_dir++ while -d "../$pragmatic_dir";
3457 $packagedir = MM->catdir($builddir,$pragmatic_dir);
3458 File::Path::mkpath($packagedir);
3460 for $f (@readdir) { # is already without "." and ".."
3461 my $to = MM->catdir($packagedir,$f);
3462 rename($f,$to) or Carp::confess("Couldn't rename $f to $to: $!");
3465 $self->{'build_dir'} = $packagedir;
3467 unless (chdir $updir) {
3468 my $cwd = CPAN::anycwd();
3469 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] to updir[$updir]: $!});
3472 $self->debug("Changed directory to .. (self[$self]=[".
3473 $self->as_string."])") if $CPAN::DEBUG;
3474 File::Path::rmtree("tmp");
3475 if ($CPAN::Config->{keep_source_where} =~ /^no/i ){
3476 $CPAN::Frontend->myprint("Going to unlink $local_file\n");
3477 unlink $local_file or Carp::carp "Couldn't unlink $local_file";
3479 my($makefilepl) = MM->catfile($packagedir,"Makefile.PL");
3480 unless (-f $makefilepl) {
3481 my($configure) = MM->catfile($packagedir,"Configure");
3482 if (-f $configure) {
3483 # do we have anything to do?
3484 $self->{'configure'} = $configure;
3485 } elsif (-f MM->catfile($packagedir,"Makefile")) {
3486 $CPAN::Frontend->myprint(qq{
3487 Package comes with a Makefile and without a Makefile.PL.
3488 We\'ll try to build it with that Makefile then.
3490 $self->{writemakefile} = "YES";
3493 my $cf = $self->called_for || "unknown";
3498 $cf =~ s|[/\\:]||g; # risk of filesystem damage
3499 $cf = "unknown" unless length($cf);
3500 $CPAN::Frontend->myprint(qq{Package comes without Makefile.PL.
3501 Writing one on our own (calling it $cf)\n});
3502 $self->{had_no_makefile_pl}++;
3503 my $fh = FileHandle->new(">$makefilepl")
3504 or Carp::croak("Could not open >$makefilepl");
3506 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
3507 # because there was no Makefile.PL supplied.
3508 # Autogenerated on: }.scalar localtime().qq{
3510 use ExtUtils::MakeMaker;
3511 WriteMakefile(NAME => q[$cf]);
3518 chdir $CWD or die "Could not chdir to $CWD: $!";
3522 # CPAN::Distribution::untar_me ;
3524 my($self,$local_file) = @_;
3525 $self->{archived} = "tar";
3526 if (CPAN::Tarzip->untar($local_file)) {
3527 $self->{unwrapped} = "YES";
3529 $self->{unwrapped} = "NO";
3533 # CPAN::Distribution::unzip_me ;
3535 my($self,$local_file) = @_;
3536 $self->{archived} = "zip";
3537 if (CPAN::Tarzip->unzip($local_file)) {
3538 $self->{unwrapped} = "YES";
3540 $self->{unwrapped} = "NO";
3546 my($self,$local_file) = @_;
3547 $self->{archived} = "pm";
3548 my $to = File::Basename::basename($local_file);
3549 $to =~ s/\.(gz|Z)(?!\n)\Z//;
3550 if (CPAN::Tarzip->gunzip($local_file,$to)) {
3551 $self->{unwrapped} = "YES";
3553 $self->{unwrapped} = "NO";
3557 #-> sub CPAN::Distribution::new ;
3559 my($class,%att) = @_;
3561 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
3563 my $this = { %att };
3564 return bless $this, $class;
3567 #-> sub CPAN::Distribution::look ;
3571 if ($^O eq 'MacOS') {
3572 $self->ExtUtils::MM_MacOS::look;
3576 if ( $CPAN::Config->{'shell'} ) {
3577 $CPAN::Frontend->myprint(qq{
3578 Trying to open a subshell in the build directory...
3581 $CPAN::Frontend->myprint(qq{
3582 Your configuration does not define a value for subshells.
3583 Please define it with "o conf shell <your shell>"
3587 my $dist = $self->id;
3588 my $dir = $self->dir or $self->get;
3590 my $pwd = CPAN::anycwd();
3591 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
3592 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
3593 system($CPAN::Config->{'shell'}) == 0
3594 or $CPAN::Frontend->mydie("Subprocess shell error");
3595 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
3598 # CPAN::Distribution::cvs_import ;
3602 my $dir = $self->dir;
3604 my $package = $self->called_for;
3605 my $module = $CPAN::META->instance('CPAN::Module', $package);
3606 my $version = $module->cpan_version;
3608 my $userid = $self->cpan_userid;
3610 my $cvs_dir = (split '/', $dir)[-1];
3611 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
3613 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
3615 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
3616 if ($cvs_site_perl) {
3617 $cvs_dir = "$cvs_site_perl/$cvs_dir";
3619 my $cvs_log = qq{"imported $package $version sources"};
3620 $version =~ s/\./_/g;
3621 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
3622 "$cvs_dir", $userid, "v$version");
3624 my $pwd = CPAN::anycwd();
3625 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
3627 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
3629 $CPAN::Frontend->myprint(qq{@cmd\n});
3630 system(@cmd) == 0 or
3631 $CPAN::Frontend->mydie("cvs import failed");
3632 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
3635 #-> sub CPAN::Distribution::readme ;
3638 my($dist) = $self->id;
3639 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
3640 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
3644 $CPAN::Config->{keep_source_where},
3647 split("/","$sans.readme"),
3649 $self->debug("Doing localize") if $CPAN::DEBUG;
3650 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
3652 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
3654 if ($^O eq 'MacOS') {
3655 ExtUtils::MM_MacOS::launch_file($local_file);
3659 my $fh_pager = FileHandle->new;
3660 local($SIG{PIPE}) = "IGNORE";
3661 $fh_pager->open("|$CPAN::Config->{'pager'}")
3662 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
3663 my $fh_readme = FileHandle->new;
3664 $fh_readme->open($local_file)
3665 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
3666 $CPAN::Frontend->myprint(qq{
3669 with pager "$CPAN::Config->{'pager'}"
3672 $fh_pager->print(<$fh_readme>);
3675 #-> sub CPAN::Distribution::verifyMD5 ;
3680 $self->{MD5_STATUS} ||= "";
3681 $self->{MD5_STATUS} eq "OK" and push @e, "MD5 Checksum was ok";
3682 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3684 my($lc_want,$lc_file,@local,$basename);
3685 @local = split("/",$self->{ID});
3687 push @local, "CHECKSUMS";
3689 MM->catfile($CPAN::Config->{keep_source_where},
3690 "authors", "id", @local);
3695 $self->MD5_check_file($lc_want)
3697 return $self->{MD5_STATUS} = "OK";
3699 $lc_file = CPAN::FTP->localize("authors/id/@local",
3702 $local[-1] .= ".gz";
3703 $lc_file = CPAN::FTP->localize("authors/id/@local",
3706 $lc_file =~ s/\.gz(?!\n)\Z//;
3707 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
3712 $self->MD5_check_file($lc_file);
3715 #-> sub CPAN::Distribution::MD5_check_file ;
3716 sub MD5_check_file {
3717 my($self,$chk_file) = @_;
3718 my($cksum,$file,$basename);
3719 $file = $self->{localfile};
3720 $basename = File::Basename::basename($file);
3721 my $fh = FileHandle->new;
3722 if (open $fh, $chk_file){
3725 $eval =~ s/\015?\012/\n/g;
3727 my($comp) = Safe->new();
3728 $cksum = $comp->reval($eval);
3730 rename $chk_file, "$chk_file.bad";
3731 Carp::confess($@) if $@;
3734 Carp::carp "Could not open $chk_file for reading";
3737 if (exists $cksum->{$basename}{md5}) {
3738 $self->debug("Found checksum for $basename:" .
3739 "$cksum->{$basename}{md5}\n") if $CPAN::DEBUG;
3743 my $eq = $self->eq_MD5($fh,$cksum->{$basename}{'md5'});
3745 $fh = CPAN::Tarzip->TIEHANDLE($file);
3748 # had to inline it, when I tied it, the tiedness got lost on
3749 # the call to eq_MD5. (Jan 1998)
3753 while ($fh->READ($ref, 4096) > 0){
3756 my $hexdigest = $md5->hexdigest;
3757 $eq += $hexdigest eq $cksum->{$basename}{'md5-ungz'};
3761 $CPAN::Frontend->myprint("Checksum for $file ok\n");
3762 return $self->{MD5_STATUS} = "OK";
3764 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
3765 qq{distribution file. }.
3766 qq{Please investigate.\n\n}.
3768 $CPAN::META->instance(
3773 my $wrap = qq{I\'d recommend removing $file. Its MD5
3774 checksum is incorrect. Maybe you have configured your 'urllist' with
3775 a bad URL. Please check this array with 'o conf urllist', and
3778 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
3780 # former versions just returned here but this seems a
3781 # serious threat that deserves a die
3783 # $CPAN::Frontend->myprint("\n\n");
3787 # close $fh if fileno($fh);
3789 $self->{MD5_STATUS} ||= "";
3790 if ($self->{MD5_STATUS} eq "NIL") {
3791 $CPAN::Frontend->mywarn(qq{
3792 Warning: No md5 checksum for $basename in $chk_file.
3794 The cause for this may be that the file is very new and the checksum
3795 has not yet been calculated, but it may also be that something is
3796 going awry right now.
3798 my $answer = ExtUtils::MakeMaker::prompt("Proceed?", "yes");
3799 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.");
3801 $self->{MD5_STATUS} = "NIL";
3806 #-> sub CPAN::Distribution::eq_MD5 ;
3808 my($self,$fh,$expectMD5) = @_;
3811 while (read($fh, $data, 4096)){
3814 # $md5->addfile($fh);
3815 my $hexdigest = $md5->hexdigest;
3816 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
3817 $hexdigest eq $expectMD5;
3820 #-> sub CPAN::Distribution::force ;
3822 # Both modules and distributions know if "force" is in effect by
3823 # autoinspection, not by inspecting a global variable. One of the
3824 # reason why this was chosen to work that way was the treatment of
3825 # dependencies. They should not autpomatically inherit the force
3826 # status. But this has the downside that ^C and die() will return to
3827 # the prompt but will not be able to reset the force_update
3828 # attributes. We try to correct for it currently in the read_metadata
3829 # routine, and immediately before we check for a Signal. I hope this
3830 # works out in one of v1.57_53ff
3833 my($self, $method) = @_;
3835 MD5_STATUS archived build_dir localfile make install unwrapped
3838 delete $self->{$att};
3840 if ($method && $method eq "install") {
3841 $self->{"force_update"}++; # name should probably have been force_install
3845 #-> sub CPAN::Distribution::unforce ;
3848 delete $self->{'force_update'};
3851 #-> sub CPAN::Distribution::isa_perl ;
3854 my $file = File::Basename::basename($self->id);
3855 if ($file =~ m{ ^ perl
3868 } elsif ($self->cpan_comment
3870 $self->cpan_comment =~ /isa_perl\(.+?\)/){
3875 #-> sub CPAN::Distribution::perl ;
3878 my($perl) = MM->file_name_is_absolute($^X) ? $^X : "";
3879 my $pwd = CPAN::anycwd();
3880 my $candidate = MM->catfile($pwd,$^X);
3881 $perl ||= $candidate if MM->maybe_command($candidate);
3883 my ($component,$perl_name);
3884 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
3885 PATH_COMPONENT: foreach $component (MM->path(),
3886 $Config::Config{'binexp'}) {
3887 next unless defined($component) && $component;
3888 my($abs) = MM->catfile($component,$perl_name);
3889 if (MM->maybe_command($abs)) {
3899 #-> sub CPAN::Distribution::make ;
3902 $CPAN::Frontend->myprint(sprintf "Running make for %s\n", $self->id);
3903 # Emergency brake if they said install Pippi and get newest perl
3904 if ($self->isa_perl) {
3906 $self->called_for ne $self->id &&
3907 ! $self->{force_update}
3909 # if we die here, we break bundles
3910 $CPAN::Frontend->mywarn(sprintf qq{
3911 The most recent version "%s" of the module "%s"
3912 comes with the current version of perl (%s).
3913 I\'ll build that only if you ask for something like
3918 $CPAN::META->instance(
3932 $self->{archived} eq "NO" and push @e,
3933 "Is neither a tar nor a zip archive.";
3935 $self->{unwrapped} eq "NO" and push @e,
3936 "had problems unarchiving. Please build manually";
3938 exists $self->{writemakefile} &&
3939 $self->{writemakefile} =~ m/ ^ NO\s* ( .* ) /sx and push @e,
3940 $1 || "Had some problem writing Makefile";
3942 defined $self->{'make'} and push @e,
3943 "Has already been processed within this session";
3945 exists $self->{later} and length($self->{later}) and
3946 push @e, $self->{later};
3948 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3950 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
3951 my $builddir = $self->dir;
3952 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
3953 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
3955 if ($^O eq 'MacOS') {
3956 ExtUtils::MM_MacOS::make($self);
3961 if ($self->{'configure'}) {
3962 $system = $self->{'configure'};
3964 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
3966 # This needs a handler that can be turned on or off:
3967 # $switch = "-MExtUtils::MakeMaker ".
3968 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
3970 $system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}";
3972 unless (exists $self->{writemakefile}) {
3973 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
3976 if ($CPAN::Config->{inactivity_timeout}) {
3978 alarm $CPAN::Config->{inactivity_timeout};
3979 local $SIG{CHLD}; # = sub { wait };
3980 if (defined($pid = fork)) {
3985 # note, this exec isn't necessary if
3986 # inactivity_timeout is 0. On the Mac I'd
3987 # suggest, we set it always to 0.
3991 $CPAN::Frontend->myprint("Cannot fork: $!");
3999 $CPAN::Frontend->myprint($@);
4000 $self->{writemakefile} = "NO $@";
4005 $ret = system($system);
4007 $self->{writemakefile} = "NO Makefile.PL returned status $ret";
4011 if (-f "Makefile") {
4012 $self->{writemakefile} = "YES";
4013 delete $self->{make_clean}; # if cleaned before, enable next
4015 $self->{writemakefile} =
4016 qq{NO Makefile.PL refused to write a Makefile.};
4017 # It's probably worth to record the reason, so let's retry
4019 # my $fh = IO::File->new("$system |"); # STDERR? STDIN?
4020 # $self->{writemakefile} .= <$fh>;
4024 delete $self->{force_update};
4027 if (my @prereq = $self->unsat_prereq){
4028 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4030 $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
4031 if (system($system) == 0) {
4032 $CPAN::Frontend->myprint(" $system -- OK\n");
4033 $self->{'make'} = "YES";
4035 $self->{writemakefile} ||= "YES";
4036 $self->{'make'} = "NO";
4037 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4041 sub follow_prereqs {
4045 $CPAN::Frontend->myprint("---- Unsatisfied dependencies detected ".
4046 "during [$id] -----\n");
4048 for my $p (@prereq) {
4049 $CPAN::Frontend->myprint(" $p\n");
4052 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
4054 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
4055 require ExtUtils::MakeMaker;
4056 my $answer = ExtUtils::MakeMaker::prompt(
4057 "Shall I follow them and prepend them to the queue
4058 of modules we are processing right now?", "yes");
4059 $follow = $answer =~ /^\s*y/i;
4063 myprint(" Ignoring dependencies on modules @prereq\n");
4066 # color them as dirty
4067 for my $p (@prereq) {
4068 CPAN::Shell->expandany($p)->color_cmd_tmps(0,1);
4070 CPAN::Queue->jumpqueue(@prereq,$id); # queue them and requeue yourself
4071 $self->{later} = "Delayed until after prerequisites";
4072 return 1; # signal success to the queuerunner
4076 #-> sub CPAN::Distribution::unsat_prereq ;
4079 my $prereq_pm = $self->prereq_pm or return;
4081 NEED: while (my($need_module, $need_version) = each %$prereq_pm) {
4082 my $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
4083 # we were too demanding:
4084 next if $nmo->uptodate;
4086 # if they have not specified a version, we accept any installed one
4087 if (not defined $need_version or
4088 $need_version == 0 or
4089 $need_version eq "undef") {
4090 next if defined $nmo->inst_file;
4093 # We only want to install prereqs if either they're not installed
4094 # or if the installed version is too old. We cannot omit this
4095 # check, because if 'force' is in effect, nobody else will check.
4099 defined $nmo->inst_file &&
4100 ! CPAN::Version->vgt($need_version, $nmo->inst_version)
4102 CPAN->debug(sprintf "id[%s]inst_file[%s]inst_version[%s]need_version[%s]",
4106 CPAN::Version->readable($need_version)
4112 if ($self->{sponsored_mods}{$need_module}++){
4113 # We have already sponsored it and for some reason it's still
4114 # not available. So we do nothing. Or what should we do?
4115 # if we push it again, we have a potential infinite loop
4118 push @need, $need_module;
4123 #-> sub CPAN::Distribution::prereq_pm ;
4126 return $self->{prereq_pm} if
4127 exists $self->{prereq_pm_detected} && $self->{prereq_pm_detected};
4128 return unless $self->{writemakefile}; # no need to have succeeded
4129 # but we must have run it
4130 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
4131 my $makefile = File::Spec->catfile($build_dir,"Makefile");
4136 $fh = FileHandle->new("<$makefile\0")) {
4140 # A.Speer @p -> %p, where %p is $p{Module::Name}=Required_Version
4142 last if /MakeMaker post_initialize section/;
4144 \s+PREREQ_PM\s+=>\s+(.+)
4147 # warn "Found prereq expr[$p]";
4149 # Regexp modified by A.Speer to remember actual version of file
4150 # PREREQ_PM hash key wants, then add to
4151 while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
4152 # In case a prereq is mentioned twice, complain.
4153 if ( defined $p{$1} ) {
4154 warn "Warning: PREREQ_PM mentions $1 more than once, last mention wins";
4161 $self->{prereq_pm_detected}++;
4162 return $self->{prereq_pm} = \%p;
4165 #-> sub CPAN::Distribution::test ;
4170 delete $self->{force_update};
4173 $CPAN::Frontend->myprint("Running make test\n");
4174 if (my @prereq = $self->unsat_prereq){
4175 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4179 exists $self->{make} or exists $self->{later} or push @e,
4180 "Make had some problems, maybe interrupted? Won't test";
4182 exists $self->{'make'} and
4183 $self->{'make'} eq 'NO' and
4184 push @e, "Can't test without successful make";
4186 exists $self->{build_dir} or push @e, "Has no own directory";
4187 $self->{badtestcnt} ||= 0;
4188 $self->{badtestcnt} > 0 and
4189 push @e, "Won't repeat unsuccessful test during this command";
4191 exists $self->{later} and length($self->{later}) and
4192 push @e, $self->{later};
4194 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4196 chdir $self->{'build_dir'} or
4197 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4198 $self->debug("Changed directory to $self->{'build_dir'}")
4201 if ($^O eq 'MacOS') {
4202 ExtUtils::MM_MacOS::make_test($self);
4206 my $system = join " ", $CPAN::Config->{'make'}, "test";
4207 if (system($system) == 0) {
4208 $CPAN::Frontend->myprint(" $system -- OK\n");
4209 $self->{make_test} = "YES";
4211 $self->{make_test} = "NO";
4212 $self->{badtestcnt}++;
4213 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4217 #-> sub CPAN::Distribution::clean ;
4220 $CPAN::Frontend->myprint("Running make clean\n");
4223 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
4224 push @e, "make clean already called once";
4225 exists $self->{build_dir} or push @e, "Has no own directory";
4226 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4228 chdir $self->{'build_dir'} or
4229 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4230 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
4232 if ($^O eq 'MacOS') {
4233 ExtUtils::MM_MacOS::make_clean($self);
4237 my $system = join " ", $CPAN::Config->{'make'}, "clean";
4238 if (system($system) == 0) {
4239 $CPAN::Frontend->myprint(" $system -- OK\n");
4243 # Jost Krieger pointed out that this "force" was wrong because
4244 # it has the effect that the next "install" on this distribution
4245 # will untar everything again. Instead we should bring the
4246 # object's state back to where it is after untarring.
4248 delete $self->{force_update};
4249 delete $self->{install};
4250 delete $self->{writemakefile};
4251 delete $self->{make};
4252 delete $self->{make_test}; # no matter if yes or no, tests must be redone
4253 $self->{make_clean} = "YES";
4256 # Hmmm, what to do if make clean failed?
4258 $CPAN::Frontend->myprint(qq{ $system -- NOT OK
4260 make clean did not succeed, marking directory as unusable for further work.
4262 $self->force("make"); # so that this directory won't be used again
4267 #-> sub CPAN::Distribution::install ;
4272 delete $self->{force_update};
4275 $CPAN::Frontend->myprint("Running make install\n");
4278 exists $self->{build_dir} or push @e, "Has no own directory";
4280 exists $self->{make} or exists $self->{later} or push @e,
4281 "Make had some problems, maybe interrupted? Won't install";
4283 exists $self->{'make'} and
4284 $self->{'make'} eq 'NO' and
4285 push @e, "make had returned bad status, install seems impossible";
4287 push @e, "make test had returned bad status, ".
4288 "won't install without force"
4289 if exists $self->{'make_test'} and
4290 $self->{'make_test'} eq 'NO' and
4291 ! $self->{'force_update'};
4293 exists $self->{'install'} and push @e,
4294 $self->{'install'} eq "YES" ?
4295 "Already done" : "Already tried without success";
4297 exists $self->{later} and length($self->{later}) and
4298 push @e, $self->{later};
4300 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4302 chdir $self->{'build_dir'} or
4303 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4304 $self->debug("Changed directory to $self->{'build_dir'}")
4307 if ($^O eq 'MacOS') {
4308 ExtUtils::MM_MacOS::make_install($self);
4312 my $system = join(" ", $CPAN::Config->{'make'},
4313 "install", $CPAN::Config->{make_install_arg});
4314 my($stderr) = $^O =~ /Win/i ? "" : " 2>&1 ";
4315 my($pipe) = FileHandle->new("$system $stderr |");
4318 $CPAN::Frontend->myprint($_);
4323 $CPAN::Frontend->myprint(" $system -- OK\n");
4324 return $self->{'install'} = "YES";
4326 $self->{'install'} = "NO";
4327 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4328 if ($makeout =~ /permission/s && $> > 0) {
4329 $CPAN::Frontend->myprint(qq{ You may have to su }.
4330 qq{to root to install the package\n});
4333 delete $self->{force_update};
4336 #-> sub CPAN::Distribution::dir ;
4338 shift->{'build_dir'};
4341 package CPAN::Bundle;
4345 delete $self->{later};
4346 for my $c ( $self->contains ) {
4347 my $obj = CPAN::Shell->expandany($c) or next;
4352 #-> sub CPAN::Bundle::color_cmd_tmps ;
4353 sub color_cmd_tmps {
4355 my($depth) = shift || 0;
4356 my($color) = shift || 0;
4357 # a module needs to recurse to its cpan_file, a distribution needs
4358 # to recurse into its prereq_pms, a bundle needs to recurse into its modules
4360 return if exists $self->{incommandcolor}
4361 && $self->{incommandcolor}==$color;
4362 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
4363 "color_cmd_tmps depth[%s] self[%s] id[%s]",
4368 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
4370 for my $c ( $self->contains ) {
4371 my $obj = CPAN::Shell->expandany($c) or next;
4372 CPAN->debug("c[$c]obj[$obj]") if $CPAN::DEBUG;
4373 $obj->color_cmd_tmps($depth+1,$color);
4376 delete $self->{badtestcnt};
4378 $self->{incommandcolor} = $color;
4381 #-> sub CPAN::Bundle::as_string ;
4385 # following line must be "=", not "||=" because we have a moving target
4386 $self->{INST_VERSION} = $self->inst_version;
4387 return $self->SUPER::as_string;
4390 #-> sub CPAN::Bundle::contains ;
4393 my($parsefile) = $self->inst_file;
4394 my($id) = $self->id;
4395 $self->debug("parsefile[$parsefile]id[$id]") if $CPAN::DEBUG;
4396 unless ($parsefile) {
4397 # Try to get at it in the cpan directory
4398 $self->debug("no parsefile") if $CPAN::DEBUG;
4399 Carp::confess "I don't know a $id" unless $self->cpan_file;
4400 my $dist = $CPAN::META->instance('CPAN::Distribution',
4403 $self->debug($dist->as_string) if $CPAN::DEBUG;
4404 my($todir) = $CPAN::Config->{'cpan_home'};
4405 my(@me,$from,$to,$me);
4406 @me = split /::/, $self->id;
4408 $me = MM->catfile(@me);
4409 $from = $self->find_bundle_file($dist->{'build_dir'},$me);
4410 $to = MM->catfile($todir,$me);
4411 File::Path::mkpath(File::Basename::dirname($to));
4412 File::Copy::copy($from, $to)
4413 or Carp::confess("Couldn't copy $from to $to: $!");
4417 my $fh = FileHandle->new;
4419 open($fh,$parsefile) or die "Could not open '$parsefile': $!";
4421 $self->debug("parsefile[$parsefile]") if $CPAN::DEBUG;
4423 $in_cont = m/^=(?!head1\s+CONTENTS)/ ? 0 :
4424 m/^=head1\s+CONTENTS/ ? 1 : $in_cont;
4425 next unless $in_cont;
4430 push @result, (split " ", $_, 2)[0];
4433 delete $self->{STATUS};
4434 $self->{CONTAINS} = \@result;
4435 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
4437 $CPAN::Frontend->mywarn(qq{
4438 The bundle file "$parsefile" may be a broken
4439 bundlefile. It seems not to contain any bundle definition.
4440 Please check the file and if it is bogus, please delete it.
4441 Sorry for the inconvenience.
4447 #-> sub CPAN::Bundle::find_bundle_file
4448 sub find_bundle_file {
4449 my($self,$where,$what) = @_;
4450 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
4451 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
4452 ### my $bu = MM->catfile($where,$what);
4453 ### return $bu if -f $bu;
4454 my $manifest = MM->catfile($where,"MANIFEST");
4455 unless (-f $manifest) {
4456 require ExtUtils::Manifest;
4457 my $cwd = CPAN::anycwd();
4458 chdir $where or $CPAN::Frontend->mydie(qq{Could not chdir to "$where": $!});
4459 ExtUtils::Manifest::mkmanifest();
4460 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
4462 my $fh = FileHandle->new($manifest)
4463 or Carp::croak("Couldn't open $manifest: $!");
4466 if ($^O eq 'MacOS') {
4469 $what2 =~ s/:Bundle://;
4472 $what2 =~ s|Bundle[/\\]||;
4477 my($file) = /(\S+)/;
4478 if ($file =~ m|\Q$what\E$|) {
4480 # return MM->catfile($where,$bu); # bad
4483 # retry if she managed to
4484 # have no Bundle directory
4485 $bu = $file if $file =~ m|\Q$what2\E$|;
4487 $bu =~ tr|/|:| if $^O eq 'MacOS';
4488 return MM->catfile($where, $bu) if $bu;
4489 Carp::croak("Couldn't find a Bundle file in $where");
4492 # needs to work slightly different from Module::inst_file because of
4493 # cpan_home/Bundle/ directory.
4495 #-> sub CPAN::Bundle::inst_file ;
4498 return $self->{INST_FILE} if
4499 exists $self->{INST_FILE} && $self->{INST_FILE};
4502 @me = split /::/, $self->id;
4504 $inst_file = MM->catfile($CPAN::Config->{'cpan_home'}, @me);
4505 return $self->{INST_FILE} = $inst_file if -f $inst_file;
4506 $self->SUPER::inst_file;
4509 #-> sub CPAN::Bundle::rematein ;
4511 my($self,$meth) = @_;
4512 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
4513 my($id) = $self->id;
4514 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
4515 unless $self->inst_file || $self->cpan_file;
4517 for $s ($self->contains) {
4518 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
4519 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
4520 if ($type eq 'CPAN::Distribution') {
4521 $CPAN::Frontend->mywarn(qq{
4522 The Bundle }.$self->id.qq{ contains
4523 explicitly a file $s.
4527 # possibly noisy action:
4528 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
4529 my $obj = $CPAN::META->instance($type,$s);
4531 if ($obj->isa(CPAN::Bundle)
4533 exists $obj->{install_failed}
4535 ref($obj->{install_failed}) eq "HASH"
4537 for (keys %{$obj->{install_failed}}) {
4538 $self->{install_failed}{$_} = undef; # propagate faiure up
4541 $fail{$s} = 1; # the bundle itself may have succeeded but
4546 $success = $obj->can("uptodate") ? $obj->uptodate : 0;
4547 $success ||= $obj->{'install'} && $obj->{'install'} eq "YES";
4549 delete $self->{install_failed}{$s};
4556 # recap with less noise
4557 if ( $meth eq "install" ) {
4560 my $raw = sprintf(qq{Bundle summary:
4561 The following items in bundle %s had installation problems:},
4564 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
4565 $CPAN::Frontend->myprint("\n");
4568 for $s ($self->contains) {
4570 $paragraph .= "$s ";
4571 $self->{install_failed}{$s} = undef;
4572 $reported{$s} = undef;
4575 my $report_propagated;
4576 for $s (sort keys %{$self->{install_failed}}) {
4577 next if exists $reported{$s};
4578 $paragraph .= "and the following items had problems
4579 during recursive bundle calls: " unless $report_propagated++;
4580 $paragraph .= "$s ";
4582 $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
4583 $CPAN::Frontend->myprint("\n");
4585 $self->{'install'} = 'YES';
4590 #sub CPAN::Bundle::xs_file
4592 # If a bundle contains another that contains an xs_file we have
4593 # here, we just don't bother I suppose
4597 #-> sub CPAN::Bundle::force ;
4598 sub force { shift->rematein('force',@_); }
4599 #-> sub CPAN::Bundle::get ;
4600 sub get { shift->rematein('get',@_); }
4601 #-> sub CPAN::Bundle::make ;
4602 sub make { shift->rematein('make',@_); }
4603 #-> sub CPAN::Bundle::test ;
4606 $self->{badtestcnt} ||= 0;
4607 $self->rematein('test',@_);
4609 #-> sub CPAN::Bundle::install ;
4612 $self->rematein('install',@_);
4614 #-> sub CPAN::Bundle::clean ;
4615 sub clean { shift->rematein('clean',@_); }
4617 #-> sub CPAN::Bundle::readme ;
4620 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
4621 No File found for bundle } . $self->id . qq{\n}), return;
4622 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
4623 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
4626 package CPAN::Module;
4629 # sub cpan_userid { shift->{RO}{CPAN_USERID} }
4632 return unless exists $self->{RO}{userid};
4633 $self->{RO}{userid};
4635 sub description { shift->{RO}{description} }
4639 delete $self->{later};
4640 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
4645 #-> sub CPAN::Module::color_cmd_tmps ;
4646 sub color_cmd_tmps {
4648 my($depth) = shift || 0;
4649 my($color) = shift || 0;
4650 # a module needs to recurse to its cpan_file
4652 return if exists $self->{incommandcolor}
4653 && $self->{incommandcolor}==$color;
4654 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
4655 "color_cmd_tmps depth[%s] self[%s] id[%s]",
4660 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
4662 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
4663 $dist->color_cmd_tmps($depth+1,$color);
4666 delete $self->{badtestcnt};
4668 $self->{incommandcolor} = $color;
4671 #-> sub CPAN::Module::as_glimpse ;
4675 my $class = ref($self);
4676 $class =~ s/^CPAN:://;
4680 $CPAN::Shell::COLOR_REGISTERED
4682 $CPAN::META->has_inst("Term::ANSIColor")
4684 $self->{RO}{description}
4686 $color_on = Term::ANSIColor::color("green");
4687 $color_off = Term::ANSIColor::color("reset");
4689 push @m, sprintf("%-15s %s%-15s%s (%s)\n",
4698 #-> sub CPAN::Module::as_string ;
4702 CPAN->debug($self) if $CPAN::DEBUG;
4703 my $class = ref($self);
4704 $class =~ s/^CPAN:://;
4706 push @m, $class, " id = $self->{ID}\n";
4707 my $sprintf = " %-12s %s\n";
4708 push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
4709 if $self->description;
4710 my $sprintf2 = " %-12s %s (%s)\n";
4712 if ($userid = $self->cpan_userid || $self->userid){
4714 if ($author = CPAN::Shell->expand('Author',$userid)) {
4717 if ($m = $author->email) {
4724 $author->fullname . $email
4728 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
4729 if $self->cpan_version;
4730 push @m, sprintf($sprintf, 'CPAN_FILE', $self->cpan_file)
4731 if $self->cpan_file;
4732 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
4733 my(%statd,%stats,%statl,%stati);
4734 @statd{qw,? i c a b R M S,} = qw,unknown idea
4735 pre-alpha alpha beta released mature standard,;
4736 @stats{qw,? m d u n,} = qw,unknown mailing-list
4737 developer comp.lang.perl.* none,;
4738 @statl{qw,? p c + o h,} = qw,unknown perl C C++ other hybrid,;
4739 @stati{qw,? f r O h,} = qw,unknown functions
4740 references+ties object-oriented hybrid,;
4741 $statd{' '} = 'unknown';
4742 $stats{' '} = 'unknown';
4743 $statl{' '} = 'unknown';
4744 $stati{' '} = 'unknown';
4752 $statd{$self->{RO}{statd}},
4753 $stats{$self->{RO}{stats}},
4754 $statl{$self->{RO}{statl}},
4755 $stati{$self->{RO}{stati}}
4756 ) if $self->{RO}{statd};
4757 my $local_file = $self->inst_file;
4758 unless ($self->{MANPAGE}) {
4760 $self->{MANPAGE} = $self->manpage_headline($local_file);
4762 # If we have already untarred it, we should look there
4763 my $dist = $CPAN::META->instance('CPAN::Distribution',
4765 # warn "dist[$dist]";
4766 # mff=manifest file; mfh=manifest handle
4768 if ($dist->{build_dir} and
4769 -f ($mff = MM->catfile($dist->{build_dir}, "MANIFEST")) and
4770 $mfh = FileHandle->new($mff)
4773 my $lfre = $self->id; # local file RE
4776 my($lfl); # local file file
4778 my(@mflines) = <$mfh>;
4779 while (length($lfre)>5 and !$lfl) {
4780 ($lfl) = grep /$lfre/, @mflines;
4782 # warn "lfl[$lfl]lfre[$lfre]";
4784 $lfl =~ s/\s.*//; # remove comments
4785 $lfl =~ s/\s+//g; # chomp would maybe be too system-specific
4786 my $lfl_abs = MM->catfile($dist->{build_dir},$lfl);
4787 # warn "lfl_abs[$lfl_abs]";
4789 $self->{MANPAGE} = $self->manpage_headline($lfl_abs);
4795 for $item (qw/MANPAGE/) {
4796 push @m, sprintf($sprintf, $item, $self->{$item})
4797 if exists $self->{$item};
4799 for $item (qw/CONTAINS/) {
4800 push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
4801 if exists $self->{$item} && @{$self->{$item}};
4803 push @m, sprintf($sprintf, 'INST_FILE',
4804 $local_file || "(not installed)");
4805 push @m, sprintf($sprintf, 'INST_VERSION',
4806 $self->inst_version) if $local_file;
4810 sub manpage_headline {
4811 my($self,$local_file) = @_;
4812 my(@local_file) = $local_file;
4813 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
4814 push @local_file, $local_file;
4816 for $locf (@local_file) {
4817 next unless -f $locf;
4818 my $fh = FileHandle->new($locf)
4819 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
4823 $inpod = m/^=(?!head1\s+NAME)/ ? 0 :
4824 m/^=head1\s+NAME/ ? 1 : $inpod;
4837 #-> sub CPAN::Module::cpan_file ;
4840 CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
4841 unless (defined $self->{RO}{CPAN_FILE}) {
4842 CPAN::Index->reload;
4844 if (exists $self->{RO}{CPAN_FILE} && defined $self->{RO}{CPAN_FILE}){
4845 return $self->{RO}{CPAN_FILE};
4846 } elsif ( defined $self->userid ) {
4847 my $fullname = $CPAN::META->instance("CPAN::Author",
4848 $self->userid)->fullname;
4849 my $email = $CPAN::META->instance("CPAN::Author",
4850 $self->userid)->email;
4851 unless (defined $fullname && defined $email) {
4852 my $userid = $self->userid;
4853 return sprintf("Contact Author %s (Try 'a %s')",
4858 return "Contact Author $fullname <$email>";
4864 *name = \&cpan_file;
4866 #-> sub CPAN::Module::cpan_version ;
4870 $self->{RO}{CPAN_VERSION} = 'undef'
4871 unless defined $self->{RO}{CPAN_VERSION};
4872 # I believe this is always a bug in the index and should be reported
4873 # as such, but usually I find out such an error and do not want to
4874 # provoke too many bugreports
4876 $self->{RO}{CPAN_VERSION};
4879 #-> sub CPAN::Module::force ;
4882 $self->{'force_update'}++;
4885 #-> sub CPAN::Module::rematein ;
4887 my($self,$meth) = @_;
4888 $CPAN::Frontend->myprint(sprintf("Running %s for module %s\n",
4891 my $cpan_file = $self->cpan_file;
4892 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
4893 $CPAN::Frontend->mywarn(sprintf qq{
4894 The module %s isn\'t available on CPAN.
4896 Either the module has not yet been uploaded to CPAN, or it is
4897 temporary unavailable. Please contact the author to find out
4898 more about the status. Try 'i %s'.
4905 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
4906 $pack->called_for($self->id);
4907 $pack->force($meth) if exists $self->{'force_update'};
4909 $pack->unforce if $pack->can("unforce") && exists $self->{'force_update'};
4910 delete $self->{'force_update'};
4913 #-> sub CPAN::Module::readme ;
4914 sub readme { shift->rematein('readme') }
4915 #-> sub CPAN::Module::look ;
4916 sub look { shift->rematein('look') }
4917 #-> sub CPAN::Module::cvs_import ;
4918 sub cvs_import { shift->rematein('cvs_import') }
4919 #-> sub CPAN::Module::get ;
4920 sub get { shift->rematein('get',@_); }
4921 #-> sub CPAN::Module::make ;
4924 $self->rematein('make');
4926 #-> sub CPAN::Module::test ;
4929 $self->{badtestcnt} ||= 0;
4930 $self->rematein('test',@_);
4932 #-> sub CPAN::Module::uptodate ;
4935 my($latest) = $self->cpan_version;
4937 my($inst_file) = $self->inst_file;
4939 if (defined $inst_file) {
4940 $have = $self->inst_version;
4945 ! CPAN::Version->vgt($latest, $have)
4947 CPAN->debug("returning uptodate. inst_file[$inst_file] ".
4948 "latest[$latest] have[$have]") if $CPAN::DEBUG;
4953 #-> sub CPAN::Module::install ;
4959 not exists $self->{'force_update'}
4961 $CPAN::Frontend->myprint( $self->id. " is up to date.\n");
4965 $self->rematein('install') if $doit;
4967 #-> sub CPAN::Module::clean ;
4968 sub clean { shift->rematein('clean') }
4970 #-> sub CPAN::Module::inst_file ;
4974 @packpath = split /::/, $self->{ID};
4975 $packpath[-1] .= ".pm";
4976 foreach $dir (@INC) {
4977 my $pmfile = MM->catfile($dir,@packpath);
4985 #-> sub CPAN::Module::xs_file ;
4989 @packpath = split /::/, $self->{ID};
4990 push @packpath, $packpath[-1];
4991 $packpath[-1] .= "." . $Config::Config{'dlext'};
4992 foreach $dir (@INC) {
4993 my $xsfile = MM->catfile($dir,'auto',@packpath);
5001 #-> sub CPAN::Module::inst_version ;
5004 my $parsefile = $self->inst_file or return;
5005 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
5008 # there was a bug in 5.6.0 that let lots of unini warnings out of
5009 # parse_version. Fixed shortly after 5.6.0 by PMQS. We can remove
5010 # the following workaround after 5.6.1 is out.
5011 local($SIG{__WARN__}) = sub { my $w = shift;
5012 return if $w =~ /uninitialized/i;
5016 $have = MM->parse_version($parsefile) || "undef";
5017 $have =~ s/^ //; # since the %vd hack these two lines here are needed
5018 $have =~ s/ $//; # trailing whitespace happens all the time
5020 # My thoughts about why %vd processing should happen here
5022 # Alt1 maintain it as string with leading v:
5023 # read index files do nothing
5024 # compare it use utility for compare
5025 # print it do nothing
5027 # Alt2 maintain it as what is is
5028 # read index files convert
5029 # compare it use utility because there's still a ">" vs "gt" issue
5030 # print it use CPAN::Version for print
5032 # Seems cleaner to hold it in memory as a string starting with a "v"
5034 # If the author of this module made a mistake and wrote a quoted
5035 # "v1.13" instead of v1.13, we simply leave it at that with the
5036 # effect that *we* will treat it like a v-tring while the rest of
5037 # perl won't. Seems sensible when we consider that any action we
5038 # could take now would just add complexity.
5040 $have = CPAN::Version->readable($have);
5042 $have =~ s/\s*//g; # stringify to float around floating point issues
5043 $have; # no stringify needed, \s* above matches always
5046 package CPAN::Tarzip;
5048 # CPAN::Tarzip::gzip
5050 my($class,$read,$write) = @_;
5051 if ($CPAN::META->has_inst("Compress::Zlib")) {
5053 $fhw = FileHandle->new($read)
5054 or $CPAN::Frontend->mydie("Could not open $read: $!");
5055 my $gz = Compress::Zlib::gzopen($write, "wb")
5056 or $CPAN::Frontend->mydie("Cannot gzopen $write: $!\n");
5057 $gz->gzwrite($buffer)
5058 while read($fhw,$buffer,4096) > 0 ;
5063 system("$CPAN::Config->{gzip} -c $read > $write")==0;
5068 # CPAN::Tarzip::gunzip
5070 my($class,$read,$write) = @_;
5071 if ($CPAN::META->has_inst("Compress::Zlib")) {
5073 $fhw = FileHandle->new(">$write")
5074 or $CPAN::Frontend->mydie("Could not open >$write: $!");
5075 my $gz = Compress::Zlib::gzopen($read, "rb")
5076 or $CPAN::Frontend->mydie("Cannot gzopen $read: $!\n");
5077 $fhw->print($buffer)
5078 while $gz->gzread($buffer) > 0 ;
5079 $CPAN::Frontend->mydie("Error reading from $read: $!\n")
5080 if $gz->gzerror != Compress::Zlib::Z_STREAM_END();
5085 system("$CPAN::Config->{gzip} -dc $read > $write")==0;
5090 # CPAN::Tarzip::gtest
5092 my($class,$read) = @_;
5093 # After I had reread the documentation in zlib.h, I discovered that
5094 # uncompressed files do not lead to an gzerror (anymore?).
5095 if ( $CPAN::META->has_inst("Compress::Zlib") ) {
5098 my $gz = Compress::Zlib::gzopen($read, "rb")
5099 or $CPAN::Frontend->mydie(sprintf("Cannot gzopen %s: %s\n",
5101 $Compress::Zlib::gzerrno));
5102 while ($gz->gzread($buffer) > 0 ){
5103 $len += length($buffer);
5106 my $err = $gz->gzerror;
5107 my $success = ! $err || $err == Compress::Zlib::Z_STREAM_END();
5108 if ($len == -s $read){
5110 CPAN->debug("hit an uncompressed file") if $CPAN::DEBUG;
5113 CPAN->debug("err[$err]success[$success]") if $CPAN::DEBUG;
5116 return system("$CPAN::Config->{gzip} -dt $read")==0;
5121 # CPAN::Tarzip::TIEHANDLE
5123 my($class,$file) = @_;
5125 $class->debug("file[$file]");
5126 if ($CPAN::META->has_inst("Compress::Zlib")) {
5127 my $gz = Compress::Zlib::gzopen($file,"rb") or
5128 die "Could not gzopen $file";
5129 $ret = bless {GZ => $gz}, $class;
5131 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $file |";
5132 my $fh = FileHandle->new($pipe) or die "Could pipe[$pipe]: $!";
5134 $ret = bless {FH => $fh}, $class;
5140 # CPAN::Tarzip::READLINE
5143 if (exists $self->{GZ}) {
5144 my $gz = $self->{GZ};
5145 my($line,$bytesread);
5146 $bytesread = $gz->gzreadline($line);
5147 return undef if $bytesread <= 0;
5150 my $fh = $self->{FH};
5151 return scalar <$fh>;
5156 # CPAN::Tarzip::READ
5158 my($self,$ref,$length,$offset) = @_;
5159 die "read with offset not implemented" if defined $offset;
5160 if (exists $self->{GZ}) {
5161 my $gz = $self->{GZ};
5162 my $byteread = $gz->gzread($$ref,$length);# 30eaf79e8b446ef52464b5422da328a8
5165 my $fh = $self->{FH};
5166 return read($fh,$$ref,$length);
5171 # CPAN::Tarzip::DESTROY
5174 if (exists $self->{GZ}) {
5175 my $gz = $self->{GZ};
5176 $gz->gzclose() if defined $gz; # hard to say if it is allowed
5177 # to be undef ever. AK, 2000-09
5179 my $fh = $self->{FH};
5180 $fh->close if defined $fh;
5186 # CPAN::Tarzip::untar
5188 my($class,$file) = @_;
5189 if (0) { # makes changing order easier
5190 } elsif (MM->maybe_command($CPAN::Config->{gzip})
5192 MM->maybe_command($CPAN::Config->{'tar'})) {
5194 my $is_compressed = $class->gtest($file);
5195 if ($is_compressed) {
5196 $system = "$CPAN::Config->{gzip} --decompress --stdout " .
5197 "< $file | $CPAN::Config->{tar} xvf -";
5199 $system = "$CPAN::Config->{tar} xvf $file";
5201 if (system($system) != 0) {
5202 # people find the most curious tar binaries that cannot handle
5204 if ($is_compressed) {
5205 (my $ungzf = $file) =~ s/\.gz(?!\n)\Z//;
5206 if (CPAN::Tarzip->gunzip($file, $ungzf)) {
5207 $CPAN::Frontend->myprint(qq{Uncompressed $file successfully\n});
5209 $CPAN::Frontend->mydie(qq{Couldn\'t uncompress $file\n});
5213 $system = "$CPAN::Config->{tar} xvf $file";
5214 $CPAN::Frontend->myprint(qq{Using Tar:$system:\n});
5215 if (system($system)==0) {
5216 $CPAN::Frontend->myprint(qq{Untarred $file successfully\n});
5218 $CPAN::Frontend->mydie(qq{Couldn\'t untar $file\n});
5224 } elsif ($CPAN::META->has_inst("Archive::Tar")
5226 $CPAN::META->has_inst("Compress::Zlib") ) {
5227 my $tar = Archive::Tar->new($file,1);
5228 my $af; # archive file
5230 for $af ($tar->list_files) {
5231 if ($af =~ m!^(/|\.\./)!) {
5232 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5233 "illegal member [$af]");
5235 $CPAN::Frontend->myprint("$af\n");
5237 return if $CPAN::Signal;
5241 ExtUtils::MM_MacOS::convert_files([$tar->list_files], 1)
5242 if ($^O eq 'MacOS');
5246 $CPAN::Frontend->mydie(qq{
5247 CPAN.pm needs either both external programs tar and gzip installed or
5248 both the modules Archive::Tar and Compress::Zlib. Neither prerequisite
5249 is available. Can\'t continue.
5255 my($class,$file) = @_;
5256 if ($CPAN::META->has_inst("Archive::Zip")) {
5257 # blueprint of the code from Archive::Zip::Tree::extractTree();
5258 my $zip = Archive::Zip->new();
5260 $status = $zip->read($file);
5261 die "Read of file[$file] failed\n" if $status != Archive::Zip::AZ_OK();
5262 $CPAN::META->debug("Successfully read file[$file]") if $CPAN::DEBUG;
5263 my @members = $zip->members();
5264 for my $member ( @members ) {
5265 my $af = $member->fileName();
5266 if ($af =~ m!^(/|\.\./)!) {
5267 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5268 "illegal member [$af]");
5270 my $status = $member->extractToFileNamed( $af );
5271 $CPAN::META->debug("af[$af]status[$status]") if $CPAN::DEBUG;
5272 die "Extracting of file[$af] from zipfile[$file] failed\n" if
5273 $status != Archive::Zip::AZ_OK();
5274 return if $CPAN::Signal;
5278 my $unzip = $CPAN::Config->{unzip} or
5279 $CPAN::Frontend->mydie("Cannot unzip, no unzip program available");
5280 my @system = ($unzip, $file);
5281 return system(@system) == 0;
5286 package CPAN::Version;
5287 # CPAN::Version::vcmp courtesy Jost Krieger
5289 my($self,$l,$r) = @_;
5291 CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG;
5293 return 0 if $l eq $r; # short circuit for quicker success
5295 if ($l=~/^v/ <=> $r=~/^v/) {
5298 $_ = $self->float2vv($_);
5303 ($l ne "undef") <=> ($r ne "undef") ||
5307 $self->vstring($l) cmp $self->vstring($r)) ||
5313 my($self,$l,$r) = @_;
5314 $self->vcmp($l,$r) > 0;
5319 $n =~ s/^v// or die "CPAN::Version::vstring() called with invalid arg [$n]";
5320 pack "U*", split /\./, $n;
5323 # vv => visible vstring
5328 my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits so that
5329 # architecture cannot
5332 $mantissa .= "0" while length($mantissa)%3;
5333 my $ret = "v" . $rev;
5335 $mantissa =~ s/(\d{1,3})// or
5336 die "Panic: length>0 but not a digit? mantissa[$mantissa]";
5337 $ret .= ".".int($1);
5339 # warn "n[$n]ret[$ret]";
5345 $n =~ /^([\w\-\+\.]+)/;
5347 return $1 if defined $1 && length($1)>0;
5348 # if the first user reaches version v43, he will be treated as "+".
5349 # We'll have to decide about a new rule here then, depending on what
5350 # will be the prevailing versioning behavior then.
5352 if ($] < 5.006) { # or whenever v-strings were introduced
5353 # we get them wrong anyway, whatever we do, because 5.005 will
5354 # have already interpreted 0.2.4 to be "0.24". So even if he
5355 # indexer sends us something like "v0.2.4" we compare wrongly.
5357 # And if they say v1.2, then the old perl takes it as "v12"
5359 $CPAN::Frontend->mywarn("Suspicious version string seen [$n]");
5362 my $better = sprintf "v%vd", $n;
5363 CPAN->debug("n[$n] better[$better]") if $CPAN::DEBUG;
5375 CPAN - query, download and build perl modules from CPAN sites
5381 perl -MCPAN -e shell;
5387 autobundle, clean, install, make, recompile, test
5391 The CPAN module is designed to automate the make and install of perl
5392 modules and extensions. It includes some searching capabilities and
5393 knows how to use Net::FTP or LWP (or lynx or an external ftp client)
5394 to fetch the raw data from the net.
5396 Modules are fetched from one or more of the mirrored CPAN
5397 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
5400 The CPAN module also supports the concept of named and versioned
5401 I<bundles> of modules. Bundles simplify the handling of sets of
5402 related modules. See Bundles below.
5404 The package contains a session manager and a cache manager. There is
5405 no status retained between sessions. The session manager keeps track
5406 of what has been fetched, built and installed in the current
5407 session. The cache manager keeps track of the disk space occupied by
5408 the make processes and deletes excess space according to a simple FIFO
5411 For extended searching capabilities there's a plugin for CPAN available,
5412 L<CPAN::WAIT>. C<CPAN::WAIT> is a full-text search engine that indexes
5413 all documents available in CPAN authors directories. If C<CPAN::WAIT>
5414 is installed on your system, the interactive shell of <CPAN.pm> will
5415 enable the C<wq>, C<wr>, C<wd>, C<wl>, and C<wh> commands which send
5416 queries to the WAIT server that has been configured for your
5419 All other methods provided are accessible in a programmer style and in an
5420 interactive shell style.
5422 =head2 Interactive Mode
5424 The interactive mode is entered by running
5426 perl -MCPAN -e shell
5428 which puts you into a readline interface. You will have the most fun if
5429 you install Term::ReadKey and Term::ReadLine to enjoy both history and
5432 Once you are on the command line, type 'h' and the rest should be
5435 The function call C<shell> takes two optional arguments, one is the
5436 prompt, the second is the default initial command line (the latter
5437 only works if a real ReadLine interface module is installed).
5439 The most common uses of the interactive modes are
5443 =item Searching for authors, bundles, distribution files and modules
5445 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
5446 for each of the four categories and another, C<i> for any of the
5447 mentioned four. Each of the four entities is implemented as a class
5448 with slightly differing methods for displaying an object.
5450 Arguments you pass to these commands are either strings exactly matching
5451 the identification string of an object or regular expressions that are
5452 then matched case-insensitively against various attributes of the
5453 objects. The parser recognizes a regular expression only if you
5454 enclose it between two slashes.
5456 The principle is that the number of found objects influences how an
5457 item is displayed. If the search finds one item, the result is
5458 displayed with the rather verbose method C<as_string>, but if we find
5459 more than one, we display each object with the terse method
5462 =item make, test, install, clean modules or distributions
5464 These commands take any number of arguments and investigate what is
5465 necessary to perform the action. If the argument is a distribution
5466 file name (recognized by embedded slashes), it is processed. If it is
5467 a module, CPAN determines the distribution file in which this module
5468 is included and processes that, following any dependencies named in
5469 the module's Makefile.PL (this behavior is controlled by
5470 I<prerequisites_policy>.)
5472 Any C<make> or C<test> are run unconditionally. An
5474 install <distribution_file>
5476 also is run unconditionally. But for
5480 CPAN checks if an install is actually needed for it and prints
5481 I<module up to date> in the case that the distribution file containing
5482 the module doesn't need to be updated.
5484 CPAN also keeps track of what it has done within the current session
5485 and doesn't try to build a package a second time regardless if it
5486 succeeded or not. The C<force> command takes as a first argument the
5487 method to invoke (currently: C<make>, C<test>, or C<install>) and executes the
5488 command from scratch.
5492 cpan> install OpenGL
5493 OpenGL is up to date.
5494 cpan> force install OpenGL
5497 OpenGL-0.4/COPYRIGHT
5500 A C<clean> command results in a
5504 being executed within the distribution file's working directory.
5506 =item get, readme, look module or distribution
5508 C<get> downloads a distribution file without further action. C<readme>
5509 displays the README file of the associated distribution. C<Look> gets
5510 and untars (if not yet done) the distribution file, changes to the
5511 appropriate directory and opens a subshell process in that directory.
5515 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
5516 in the cpan-shell it is intended that you can press C<^C> anytime and
5517 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
5518 to clean up and leave the shell loop. You can emulate the effect of a
5519 SIGTERM by sending two consecutive SIGINTs, which usually means by
5520 pressing C<^C> twice.
5522 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
5523 SIGALRM is used during the run of the C<perl Makefile.PL> subprocess.
5529 The commands that are available in the shell interface are methods in
5530 the package CPAN::Shell. If you enter the shell command, all your
5531 input is split by the Text::ParseWords::shellwords() routine which
5532 acts like most shells do. The first word is being interpreted as the
5533 method to be called and the rest of the words are treated as arguments
5534 to this method. Continuation lines are supported if a line ends with a
5539 C<autobundle> writes a bundle file into the
5540 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
5541 a list of all modules that are both available from CPAN and currently
5542 installed within @INC. The name of the bundle file is based on the
5543 current date and a counter.
5547 recompile() is a very special command in that it takes no argument and
5548 runs the make/test/install cycle with brute force over all installed
5549 dynamically loadable extensions (aka XS modules) with 'force' in
5550 effect. The primary purpose of this command is to finish a network
5551 installation. Imagine, you have a common source tree for two different
5552 architectures. You decide to do a completely independent fresh
5553 installation. You start on one architecture with the help of a Bundle
5554 file produced earlier. CPAN installs the whole Bundle for you, but
5555 when you try to repeat the job on the second architecture, CPAN
5556 responds with a C<"Foo up to date"> message for all modules. So you
5557 invoke CPAN's recompile on the second architecture and you're done.
5559 Another popular use for C<recompile> is to act as a rescue in case your
5560 perl breaks binary compatibility. If one of the modules that CPAN uses
5561 is in turn depending on binary compatibility (so you cannot run CPAN
5562 commands), then you should try the CPAN::Nox module for recovery.
5564 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
5566 Although it may be considered internal, the class hierarchy does matter
5567 for both users and programmer. CPAN.pm deals with above mentioned four
5568 classes, and all those classes share a set of methods. A classical
5569 single polymorphism is in effect. A metaclass object registers all
5570 objects of all kinds and indexes them with a string. The strings
5571 referencing objects have a separated namespace (well, not completely
5576 words containing a "/" (slash) Distribution
5577 words starting with Bundle:: Bundle
5578 everything else Module or Author
5580 Modules know their associated Distribution objects. They always refer
5581 to the most recent official release. Developers may mark their releases
5582 as unstable development versions (by inserting an underbar into the
5583 visible version number), so the really hottest and newest distribution
5584 file is not always the default. If a module Foo circulates on CPAN in
5585 both version 1.23 and 1.23_90, CPAN.pm offers a convenient way to
5586 install version 1.23 by saying
5590 This would install the complete distribution file (say
5591 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
5592 like to install version 1.23_90, you need to know where the
5593 distribution file resides on CPAN relative to the authors/id/
5594 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
5595 so you would have to say
5597 install BAR/Foo-1.23_90.tar.gz
5599 The first example will be driven by an object of the class
5600 CPAN::Module, the second by an object of class CPAN::Distribution.
5602 =head2 Programmer's interface
5604 If you do not enter the shell, the available shell commands are both
5605 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
5606 functions in the calling package (C<install(...)>).
5608 There's currently only one class that has a stable interface -
5609 CPAN::Shell. All commands that are available in the CPAN shell are
5610 methods of the class CPAN::Shell. Each of the commands that produce
5611 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
5612 the IDs of all modules within the list.
5616 =item expand($type,@things)
5618 The IDs of all objects available within a program are strings that can
5619 be expanded to the corresponding real objects with the
5620 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
5621 list of CPAN::Module objects according to the C<@things> arguments
5622 given. In scalar context it only returns the first element of the
5625 =item Programming Examples
5627 This enables the programmer to do operations that combine
5628 functionalities that are available in the shell.
5630 # install everything that is outdated on my disk:
5631 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
5633 # install my favorite programs if necessary:
5634 for $mod (qw(Net::FTP MD5 Data::Dumper)){
5635 my $obj = CPAN::Shell->expand('Module',$mod);
5639 # list all modules on my disk that have no VERSION number
5640 for $mod (CPAN::Shell->expand("Module","/./")){
5641 next unless $mod->inst_file;
5642 # MakeMaker convention for undefined $VERSION:
5643 next unless $mod->inst_version eq "undef";
5644 print "No VERSION in ", $mod->id, "\n";
5647 # find out which distribution on CPAN contains a module:
5648 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
5650 Or if you want to write a cronjob to watch The CPAN, you could list
5651 all modules that need updating. First a quick and dirty way:
5653 perl -e 'use CPAN; CPAN::Shell->r;'
5655 If you don't want to get any output in the case that all modules are
5656 up to date, you can parse the output of above command for the regular
5657 expression //modules are up to date// and decide to mail the output
5658 only if it doesn't match. Ick?
5660 If you prefer to do it more in a programmer style in one single
5661 process, maybe something like this suites you better:
5663 # list all modules on my disk that have newer versions on CPAN
5664 for $mod (CPAN::Shell->expand("Module","/./")){
5665 next unless $mod->inst_file;
5666 next if $mod->uptodate;
5667 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
5668 $mod->id, $mod->inst_version, $mod->cpan_version;
5671 If that gives you too much output every day, you maybe only want to
5672 watch for three modules. You can write
5674 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")){
5676 as the first line instead. Or you can combine some of the above
5679 # watch only for a new mod_perl module
5680 $mod = CPAN::Shell->expand("Module","mod_perl");
5681 exit if $mod->uptodate;
5682 # new mod_perl arrived, let me know all update recommendations
5687 =head2 Methods in the four Classes
5689 =head2 Cache Manager
5691 Currently the cache manager only keeps track of the build directory
5692 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
5693 deletes complete directories below C<build_dir> as soon as the size of
5694 all directories there gets bigger than $CPAN::Config->{build_cache}
5695 (in MB). The contents of this cache may be used for later
5696 re-installations that you intend to do manually, but will never be
5697 trusted by CPAN itself. This is due to the fact that the user might
5698 use these directories for building modules on different architectures.
5700 There is another directory ($CPAN::Config->{keep_source_where}) where
5701 the original distribution files are kept. This directory is not
5702 covered by the cache manager and must be controlled by the user. If
5703 you choose to have the same directory as build_dir and as
5704 keep_source_where directory, then your sources will be deleted with
5705 the same fifo mechanism.
5709 A bundle is just a perl module in the namespace Bundle:: that does not
5710 define any functions or methods. It usually only contains documentation.
5712 It starts like a perl module with a package declaration and a $VERSION
5713 variable. After that the pod section looks like any other pod with the
5714 only difference being that I<one special pod section> exists starting with
5719 In this pod section each line obeys the format
5721 Module_Name [Version_String] [- optional text]
5723 The only required part is the first field, the name of a module
5724 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
5725 of the line is optional. The comment part is delimited by a dash just
5726 as in the man page header.
5728 The distribution of a bundle should follow the same convention as
5729 other distributions.
5731 Bundles are treated specially in the CPAN package. If you say 'install
5732 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
5733 the modules in the CONTENTS section of the pod. You can install your
5734 own Bundles locally by placing a conformant Bundle file somewhere into
5735 your @INC path. The autobundle() command which is available in the
5736 shell interface does that for you by including all currently installed
5737 modules in a snapshot bundle file.
5739 =head2 Prerequisites
5741 If you have a local mirror of CPAN and can access all files with
5742 "file:" URLs, then you only need a perl better than perl5.003 to run
5743 this module. Otherwise Net::FTP is strongly recommended. LWP may be
5744 required for non-UNIX systems or if your nearest CPAN site is
5745 associated with an URL that is not C<ftp:>.
5747 If you have neither Net::FTP nor LWP, there is a fallback mechanism
5748 implemented for an external ftp command or for an external lynx
5751 =head2 Finding packages and VERSION
5753 This module presumes that all packages on CPAN
5759 declare their $VERSION variable in an easy to parse manner. This
5760 prerequisite can hardly be relaxed because it consumes far too much
5761 memory to load all packages into the running program just to determine
5762 the $VERSION variable. Currently all programs that are dealing with
5763 version use something like this
5765 perl -MExtUtils::MakeMaker -le \
5766 'print MM->parse_version(shift)' filename
5768 If you are author of a package and wonder if your $VERSION can be
5769 parsed, please try the above method.
5773 come as compressed or gzipped tarfiles or as zip files and contain a
5774 Makefile.PL (well, we try to handle a bit more, but without much
5781 The debugging of this module is a bit complex, because we have
5782 interferences of the software producing the indices on CPAN, of the
5783 mirroring process on CPAN, of packaging, of configuration, of
5784 synchronicity, and of bugs within CPAN.pm.
5786 For code debugging in interactive mode you can try "o debug" which
5787 will list options for debugging the various parts of the code. You
5788 should know that "o debug" has built-in completion support.
5790 For data debugging there is the C<dump> command which takes the same
5791 arguments as make/test/install and outputs the object's Data::Dumper
5794 =head2 Floppy, Zip, Offline Mode
5796 CPAN.pm works nicely without network too. If you maintain machines
5797 that are not networked at all, you should consider working with file:
5798 URLs. Of course, you have to collect your modules somewhere first. So
5799 you might use CPAN.pm to put together all you need on a networked
5800 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
5801 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
5802 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
5803 with this floppy. See also below the paragraph about CD-ROM support.
5805 =head1 CONFIGURATION
5807 When the CPAN module is installed, a site wide configuration file is
5808 created as CPAN/Config.pm. The default values defined there can be
5809 overridden in another configuration file: CPAN/MyConfig.pm. You can
5810 store this file in $HOME/.cpan/CPAN/MyConfig.pm if you want, because
5811 $HOME/.cpan is added to the search path of the CPAN module before the
5812 use() or require() statements.
5814 Currently the following keys in the hash reference $CPAN::Config are
5817 build_cache size of cache for directories to build modules
5818 build_dir locally accessible directory to build modules
5819 index_expire after this many days refetch index files
5820 cache_metadata use serializer to cache metadata
5821 cpan_home local directory reserved for this package
5822 dontload_hash anonymous hash: modules in the keys will not be
5823 loaded by the CPAN::has_inst() routine
5824 gzip location of external program gzip
5825 inactivity_timeout breaks interactive Makefile.PLs after this
5826 many seconds inactivity. Set to 0 to never break.
5827 inhibit_startup_message
5828 if true, does not print the startup message
5829 keep_source_where directory in which to keep the source (if we do)
5830 make location of external make program
5831 make_arg arguments that should always be passed to 'make'
5832 make_install_arg same as make_arg for 'make install'
5833 makepl_arg arguments passed to 'perl Makefile.PL'
5834 pager location of external program more (or any pager)
5835 prerequisites_policy
5836 what to do if you are missing module prerequisites
5837 ('follow' automatically, 'ask' me, or 'ignore')
5838 scan_cache controls scanning of cache ('atstart' or 'never')
5839 tar location of external program tar
5840 term_is_latin if true internal UTF-8 is translated to ISO-8859-1
5841 (and nonsense for characters outside latin range)
5842 unzip location of external program unzip
5843 urllist arrayref to nearby CPAN sites (or equivalent locations)
5844 wait_list arrayref to a wait server to try (See CPAN::WAIT)
5845 ftp_proxy, } the three usual variables for configuring
5846 http_proxy, } proxy requests. Both as CPAN::Config variables
5847 no_proxy } and as environment variables configurable.
5849 You can set and query each of these options interactively in the cpan
5850 shell with the command set defined within the C<o conf> command:
5854 =item C<o conf E<lt>scalar optionE<gt>>
5856 prints the current value of the I<scalar option>
5858 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
5860 Sets the value of the I<scalar option> to I<value>
5862 =item C<o conf E<lt>list optionE<gt>>
5864 prints the current value of the I<list option> in MakeMaker's
5867 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
5869 shifts or pops the array in the I<list option> variable
5871 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
5873 works like the corresponding perl commands.
5877 =head2 Note on urllist parameter's format
5879 urllist parameters are URLs according to RFC 1738. We do a little
5880 guessing if your URL is not compliant, but if you have problems with
5881 file URLs, please try the correct format. Either:
5883 file://localhost/whatever/ftp/pub/CPAN/
5887 file:///home/ftp/pub/CPAN/
5889 =head2 urllist parameter has CD-ROM support
5891 The C<urllist> parameter of the configuration table contains a list of
5892 URLs that are to be used for downloading. If the list contains any
5893 C<file> URLs, CPAN always tries to get files from there first. This
5894 feature is disabled for index files. So the recommendation for the
5895 owner of a CD-ROM with CPAN contents is: include your local, possibly
5896 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
5898 o conf urllist push file://localhost/CDROM/CPAN
5900 CPAN.pm will then fetch the index files from one of the CPAN sites
5901 that come at the beginning of urllist. It will later check for each
5902 module if there is a local copy of the most recent version.
5904 Another peculiarity of urllist is that the site that we could
5905 successfully fetch the last file from automatically gets a preference
5906 token and is tried as the first site for the next request. So if you
5907 add a new site at runtime it may happen that the previously preferred
5908 site will be tried another time. This means that if you want to disallow
5909 a site for the next transfer, it must be explicitly removed from
5914 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
5915 install foreign, unmasked, unsigned code on your machine. We compare
5916 to a checksum that comes from the net just as the distribution file
5917 itself. If somebody has managed to tamper with the distribution file,
5918 they may have as well tampered with the CHECKSUMS file. Future
5919 development will go towards strong authentication.
5923 Most functions in package CPAN are exported per default. The reason
5924 for this is that the primary use is intended for the cpan shell or for
5927 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
5929 To populate a freshly installed perl with my favorite modules is pretty
5930 easiest by maintaining a private bundle definition file. To get a useful
5931 blueprint of a bundle definition file, the command autobundle can be used
5932 on the CPAN shell command line. This command writes a bundle definition
5933 file for all modules that are installed for the currently running perl
5934 interpreter. It's recommended to run this command only once and from then
5935 on maintain the file manually under a private name, say
5936 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
5938 cpan> install Bundle::my_bundle
5940 then answer a few questions and then go out for a coffee.
5942 Maintaining a bundle definition file means to keep track of two
5943 things: dependencies and interactivity. CPAN.pm sometimes fails on
5944 calculating dependencies because not all modules define all MakeMaker
5945 attributes correctly, so a bundle definition file should specify
5946 prerequisites as early as possible. On the other hand, it's a bit
5947 annoying that many distributions need some interactive configuring. So
5948 what I try to accomplish in my private bundle file is to have the
5949 packages that need to be configured early in the file and the gentle
5950 ones later, so I can go out after a few minutes and leave CPAN.pm
5953 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
5955 Thanks to Graham Barr for contributing the following paragraphs about
5956 the interaction between perl, and various firewall configurations. For
5957 further informations on firewalls, it is recommended to consult the
5958 documentation that comes with the ncftp program. If you are unable to
5959 go through the firewall with a simple Perl setup, it is very likely
5960 that you can configure ncftp so that it works for your firewall.
5962 =head2 Three basic types of firewalls
5964 Firewalls can be categorized into three basic types.
5970 This is where the firewall machine runs a web server and to access the
5971 outside world you must do it via the web server. If you set environment
5972 variables like http_proxy or ftp_proxy to a values beginning with http://
5973 or in your web browser you have to set proxy information then you know
5974 you are running a http firewall.
5976 To access servers outside these types of firewalls with perl (even for
5977 ftp) you will need to use LWP.
5981 This where the firewall machine runs a ftp server. This kind of
5982 firewall will only let you access ftp servers outside the firewall.
5983 This is usually done by connecting to the firewall with ftp, then
5984 entering a username like "user@outside.host.com"
5986 To access servers outside these type of firewalls with perl you
5987 will need to use Net::FTP.
5989 =item One way visibility
5991 I say one way visibility as these firewalls try to make themselve look
5992 invisible to the users inside the firewall. An FTP data connection is
5993 normally created by sending the remote server your IP address and then
5994 listening for the connection. But the remote server will not be able to
5995 connect to you because of the firewall. So for these types of firewall
5996 FTP connections need to be done in a passive mode.
5998 There are two that I can think off.
6004 If you are using a SOCKS firewall you will need to compile perl and link
6005 it with the SOCKS library, this is what is normally called a 'socksified'
6006 perl. With this executable you will be able to connect to servers outside
6007 the firewall as if it is not there.
6011 This is the firewall implemented in the Linux kernel, it allows you to
6012 hide a complete network behind one IP address. With this firewall no
6013 special compiling is need as you can access hosts directly.
6019 =head2 Configuring lynx or ncftp for going through a firewall
6021 If you can go through your firewall with e.g. lynx, presumably with a
6024 /usr/local/bin/lynx -pscott:tiger
6026 then you would configure CPAN.pm with the command
6028 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
6030 That's all. Similarly for ncftp or ftp, you would configure something
6033 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
6035 Your milage may vary...
6041 =item 1) I installed a new version of module X but CPAN keeps saying,
6042 I have the old version installed
6044 Most probably you B<do> have the old version installed. This can
6045 happen if a module installs itself into a different directory in the
6046 @INC path than it was previously installed. This is not really a
6047 CPAN.pm problem, you would have the same problem when installing the
6048 module manually. The easiest way to prevent this behaviour is to add
6049 the argument C<UNINST=1> to the C<make install> call, and that is why
6050 many people add this argument permanently by configuring
6052 o conf make_install_arg UNINST=1
6054 =item 2) So why is UNINST=1 not the default?
6056 Because there are people who have their precise expectations about who
6057 may install where in the @INC path and who uses which @INC array. In
6058 fine tuned environments C<UNINST=1> can cause damage.
6060 =item 3) I want to clean up my mess, and install a new perl along with
6061 all modules I have. How do I go about it?
6063 Run the autobundle command for your old perl and optionally rename the
6064 resulting bundle file (e.g. Bundle/mybundle.pm), install the new perl
6065 with the Configure option prefix, e.g.
6067 ./Configure -Dprefix=/usr/local/perl-5.6.78.9
6069 Install the bundle file you produced in the first step with something like
6071 cpan> install Bundle::mybundle
6075 =item 4) When I install bundles or multiple modules with one command
6076 there is too much output to keep track of
6078 You may want to configure something like
6080 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
6081 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
6083 so that STDOUT is captured in a file for later inspection.
6086 =item 5) I am not root, how can I install a module in a personal
6089 You will most probably like something like this:
6091 o conf makepl_arg "LIB=~/myperl/lib \
6092 INSTALLMAN1DIR=~/myperl/man/man1 \
6093 INSTALLMAN3DIR=~/myperl/man/man3"
6094 install Sybase::Sybperl
6096 You can make this setting permanent like all C<o conf> settings with
6099 You will have to add ~/myperl/man to the MANPATH environment variable
6100 and also tell your perl programs to look into ~/myperl/lib, e.g. by
6103 use lib "$ENV{HOME}/myperl/lib";
6105 or setting the PERL5LIB environment variable.
6107 Another thing you should bear in mind is that the UNINST parameter
6108 should never be set if you are not root.
6110 =item 6) How to get a package, unwrap it, and make a change before
6113 look Sybase::Sybperl
6115 =item 7) I installed a Bundle and had a couple of fails. When I
6116 retried, everything resolved nicely. Can this be fixed to work
6119 The reason for this is that CPAN does not know the dependencies of all
6120 modules when it starts out. To decide about the additional items to
6121 install, it just uses data found in the generated Makefile. An
6122 undetected missing piece breaks the process. But it may well be that
6123 your Bundle installs some prerequisite later than some depending item
6124 and thus your second try is able to resolve everything. Please note,
6125 CPAN.pm does not know the dependency tree in advance and cannot sort
6126 the queue of things to install in a topologically correct order. It
6127 resolves perfectly well IFF all modules declare the prerequisites
6128 correctly with the PREREQ_PM attribute to MakeMaker. For bundles which
6129 fail and you need to install often, it is recommended sort the Bundle
6130 definition file manually. It is planned to improve the metadata
6131 situation for dependencies on CPAN in general, but this will still
6134 =item 8) In our intranet we have many modules for internal use. How
6135 can I integrate these modules with CPAN.pm but without uploading
6136 the modules to CPAN?
6138 Have a look at the CPAN::Site module.
6140 =item 9) When I run CPAN's shell, I get error msg about line 1 to 4,
6141 setting meta input/output via the /etc/inputrc file.
6143 I guess, /etc/inputrc interacts with Term::ReadLine somehow. Maybe
6144 just remove /etc/inputrc or set the INPUTRC environment variable (see
6145 the readline documentation).
6151 We should give coverage for B<all> of the CPAN and not just the PAUSE
6152 part, right? In this discussion CPAN and PAUSE have become equal --
6153 but they are not. PAUSE is authors/, modules/ and scripts/. CPAN is
6154 PAUSE plus the clpa/, doc/, misc/, ports/, and src/.
6156 Future development should be directed towards a better integration of
6159 If a Makefile.PL requires special customization of libraries, prompts
6160 the user for special input, etc. then you may find CPAN is not able to
6161 build the distribution. In that case, you should attempt the
6162 traditional method of building a Perl module package from a shell.
6166 Andreas Koenig E<lt>andreas.koenig@anima.deE<gt>
6170 perl(1), CPAN::Nox(3)