1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
4 $CPAN::VERSION = '1.87_62';
5 $CPAN::VERSION = eval $CPAN::VERSION;
7 use CPAN::HandleConfig;
16 use ExtUtils::MakeMaker qw(prompt); # for some unknown reason,
17 # 5.005_04 does not work without
19 use File::Basename ();
26 use Sys::Hostname qw(hostname);
27 use Text::ParseWords ();
30 # we need to run chdir all over and we would get at wrong libraries
33 if (File::Spec->can("rel2abs")) {
35 $inc = File::Spec->rel2abs($inc);
41 require Mac::BuildTools if $^O eq 'MacOS';
43 END { $CPAN::End++; &cleanup; }
46 $CPAN::Frontend ||= "CPAN::Shell";
47 @CPAN::Defaultsites = ("http://www.perl.org/CPAN/","ftp://ftp.perl.org/pub/CPAN/")
48 unless @CPAN::Defaultsites;
49 # $CPAN::iCwd (i for initial) is going to be initialized during find_perl
50 $CPAN::Perl ||= CPAN::find_perl();
51 $CPAN::Defaultdocs ||= "http://search.cpan.org/perldoc?";
52 $CPAN::Defaultrecent ||= "http://search.cpan.org/recent";
55 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $HAS_USABLE $term
56 $Signal $Suppress_readline $Frontend
57 @Defaultsites $Have_warned $Defaultdocs $Defaultrecent
60 @CPAN::ISA = qw(CPAN::Debug Exporter);
62 # note that these functions live in CPAN::Shell and get executed via
63 # AUTOLOAD when called directly
85 sub soft_chdir_with_alternatives ($);
87 #-> sub CPAN::AUTOLOAD ;
92 @EXPORT{@EXPORT} = '';
93 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
94 if (exists $EXPORT{$l}){
97 die(qq{Unknown CPAN command "$AUTOLOAD". }.
98 qq{Type ? for help.\n});
102 #-> sub CPAN::shell ;
105 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
106 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
108 my $oprompt = shift || CPAN::Prompt->new;
109 my $prompt = $oprompt;
110 my $commandline = shift || "";
111 $CPAN::CurrentCommandId ||= 1;
114 unless ($Suppress_readline) {
115 require Term::ReadLine;
118 $term->ReadLine eq "Term::ReadLine::Stub"
120 $term = Term::ReadLine->new('CPAN Monitor');
122 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
123 my $attribs = $term->Attribs;
124 $attribs->{attempted_completion_function} = sub {
125 &CPAN::Complete::gnu_cpl;
128 $readline::rl_completion_function =
129 $readline::rl_completion_function = 'CPAN::Complete::cpl';
131 if (my $histfile = $CPAN::Config->{'histfile'}) {{
132 unless ($term->can("AddHistory")) {
133 $CPAN::Frontend->mywarn("Terminal does not support AddHistory.\n");
136 my($fh) = FileHandle->new;
137 open $fh, "<$histfile" or last;
141 $term->AddHistory($_);
145 for ($CPAN::Config->{term_ornaments}) { # alias
146 local $Term::ReadLine::termcap_nowarn = 1;
147 $term->ornaments($_) if defined;
149 # $term->OUT is autoflushed anyway
150 my $odef = select STDERR;
157 # no strict; # I do not recall why no strict was here (2000-09-03)
161 File::Spec->can("tmpdir") ? File::Spec->tmpdir() : (),
162 File::Spec->rootdir(),
164 my $try_detect_readline;
165 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
166 my $rl_avail = $Suppress_readline ? "suppressed" :
167 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
168 "available (try 'install Bundle::CPAN')";
170 unless ($CPAN::Config->{'inhibit_startup_message'}){
171 $CPAN::Frontend->myprint(
173 cpan shell -- CPAN exploration and modules installation (v%s)
181 my($continuation) = "";
182 my $last_term_ornaments;
183 SHELLCOMMAND: while () {
184 if ($Suppress_readline) {
186 last SHELLCOMMAND unless defined ($_ = <> );
189 last SHELLCOMMAND unless
190 defined ($_ = $term->readline($prompt, $commandline));
192 $_ = "$continuation$_" if $continuation;
194 next SHELLCOMMAND if /^$/;
195 $_ = 'h' if /^\s*\?/;
196 if (/^(?:q(?:uit)?|bye|exit)$/i) {
207 use vars qw($import_done);
208 CPAN->import(':DEFAULT') unless $import_done++;
209 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
216 if ($] < 5.00322) { # parsewords had a bug until recently
219 eval { @line = Text::ParseWords::shellwords($_) };
220 warn($@), next SHELLCOMMAND if $@;
221 warn("Text::Parsewords could not parse the line [$_]"),
222 next SHELLCOMMAND unless @line;
224 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
225 my $command = shift @line;
226 eval { CPAN::Shell->$command(@line) };
228 if ($command =~ /^(make|test|install|force|notest|clean|upgrade)$/) {
229 CPAN::Shell->failed($CPAN::CurrentCommandId,1);
231 soft_chdir_with_alternatives(\@cwd);
232 $CPAN::Frontend->myprint("\n");
234 $CPAN::CurrentCommandId++;
238 $commandline = ""; # I do want to be able to pass a default to
239 # shell, but on the second command I see no
242 CPAN::Queue->nullify_queue;
243 if ($try_detect_readline) {
244 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
246 $CPAN::META->has_inst("Term::ReadLine::Perl")
248 delete $INC{"Term/ReadLine.pm"};
250 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
251 require Term::ReadLine;
252 $CPAN::Frontend->myprint("\n$redef subroutines in ".
253 "Term::ReadLine redefined\n");
258 for ($CPAN::Config->{term_ornaments}) { # alias
260 if (not defined $last_term_ornaments
261 or $_ != $last_term_ornaments
263 local $Term::ReadLine::termcap_nowarn = 1;
264 $term->ornaments($_);
265 $last_term_ornaments = $_;
268 undef $last_term_ornaments;
272 soft_chdir_with_alternatives(\@cwd);
275 sub soft_chdir_with_alternatives ($) {
277 while (not chdir $cwd->[0]) {
279 $CPAN::Frontend->mywarn(qq{Could not chdir to "$cwd->[0]": $!
280 Trying to chdir to "$cwd->[1]" instead.
284 $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd->[0]": $!});
289 package CPAN::CacheMgr;
291 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
296 use vars qw($Ua $Thesite $ThesiteURL $Themethod);
297 @CPAN::FTP::ISA = qw(CPAN::Debug);
299 package CPAN::LWP::UserAgent;
301 use vars qw(@ISA $USER $PASSWD $SETUPDONE);
302 # we delay requiring LWP::UserAgent and setting up inheritance until we need it
304 package CPAN::Complete;
306 @CPAN::Complete::ISA = qw(CPAN::Debug);
307 @CPAN::Complete::COMMANDS = sort qw(
308 ! a b d h i m o q r u
332 use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03);
333 @CPAN::Index::ISA = qw(CPAN::Debug);
336 # use constant PROTOCOL => "2.0"; # outcommented to avoid warning on upgrade from 1.57
339 package CPAN::InfoObj;
341 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
343 package CPAN::Author;
345 @CPAN::Author::ISA = qw(CPAN::InfoObj);
347 package CPAN::Distribution;
349 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
351 package CPAN::Bundle;
353 @CPAN::Bundle::ISA = qw(CPAN::Module);
355 package CPAN::Module;
357 @CPAN::Module::ISA = qw(CPAN::InfoObj);
359 package CPAN::Exception::RecursiveDependency;
361 use overload '""' => "as_string";
368 for my $dep (@$deps) {
370 last if $seen{$dep}++;
372 bless { deps => \@deps }, $class;
377 "\nRecursive dependency detected:\n " .
378 join("\n => ", @{$self->{deps}}) .
379 ".\nCannot continue.\n";
382 package CPAN::Prompt; use overload '""' => "as_string";
383 use vars qw($prompt);
385 $CPAN::CurrentCommandId ||= 0;
390 if ($CPAN::Config->{commandnumber_in_prompt}) {
391 sprintf "cpan[%d]> ", $CPAN::CurrentCommandId;
397 package CPAN::Distrostatus;
398 use overload '""' => "as_string",
401 my($class,$arg) = @_;
404 FAILED => substr($arg,0,2) eq "NO",
405 COMMANDID => $CPAN::CurrentCommandId,
408 sub commandid { shift->{COMMANDID} }
409 sub failed { shift->{FAILED} }
413 $self->{TEXT} = $set;
424 use vars qw($AUTOLOAD @ISA $COLOR_REGISTERED $ADVANCED_QUERY);
425 @CPAN::Shell::ISA = qw(CPAN::Debug);
426 $COLOR_REGISTERED ||= 0;
428 #-> sub CPAN::Shell::AUTOLOAD ;
430 my($autoload) = $AUTOLOAD;
431 my $class = shift(@_);
432 # warn "autoload[$autoload] class[$class]";
433 $autoload =~ s/.*:://;
434 if ($autoload =~ /^w/) {
435 if ($CPAN::META->has_inst('CPAN::WAIT')) {
436 CPAN::WAIT->$autoload(@_);
438 $CPAN::Frontend->mywarn(qq{
439 Commands starting with "w" require CPAN::WAIT to be installed.
440 Please consider installing CPAN::WAIT to use the fulltext index.
441 For this you just need to type
446 $CPAN::Frontend->mywarn(qq{Unknown shell command '$autoload @_'. }.
455 # One use of the queue is to determine if we should or shouldn't
456 # announce the availability of a new CPAN module
458 # Now we try to use it for dependency tracking. For that to happen
459 # we need to draw a dependency tree and do the leaves first. This can
460 # easily be reached by running CPAN.pm recursively, but we don't want
461 # to waste memory and run into deep recursion. So what we can do is
464 # CPAN::Queue is the package where the queue is maintained. Dependencies
465 # often have high priority and must be brought to the head of the queue,
466 # possibly by jumping the queue if they are already there. My first code
467 # attempt tried to be extremely correct. Whenever a module needed
468 # immediate treatment, I either unshifted it to the front of the queue,
469 # or, if it was already in the queue, I spliced and let it bypass the
470 # others. This became a too correct model that made it impossible to put
471 # an item more than once into the queue. Why would you need that? Well,
472 # you need temporary duplicates as the manager of the queue is a loop
475 # (1) looks at the first item in the queue without shifting it off
477 # (2) cares for the item
479 # (3) removes the item from the queue, *even if its agenda failed and
480 # even if the item isn't the first in the queue anymore* (that way
481 # protecting against never ending queues)
483 # So if an item has prerequisites, the installation fails now, but we
484 # want to retry later. That's easy if we have it twice in the queue.
486 # I also expect insane dependency situations where an item gets more
487 # than two lives in the queue. Simplest example is triggered by 'install
488 # Foo Foo Foo'. People make this kind of mistakes and I don't want to
489 # get in the way. I wanted the queue manager to be a dumb servant, not
490 # one that knows everything.
492 # Who would I tell in this model that the user wants to be asked before
493 # processing? I can't attach that information to the module object,
494 # because not modules are installed but distributions. So I'd have to
495 # tell the distribution object that it should ask the user before
496 # processing. Where would the question be triggered then? Most probably
497 # in CPAN::Distribution::rematein.
498 # Hope that makes sense, my head is a bit off:-) -- AK
505 my $self = bless { qmod => $s }, $class;
510 # CPAN::Queue::first ;
516 # CPAN::Queue::delete_first ;
518 my($class,$what) = @_;
520 for my $i (0..$#All) {
521 if ( $All[$i]->{qmod} eq $what ) {
528 # CPAN::Queue::jumpqueue ;
532 CPAN->debug(sprintf("before jumpqueue All[%s] what[%s]",
533 join(",",map {$_->{qmod}} @All),
536 WHAT: for my $what (reverse @what) {
538 for (my $i=0; $i<$#All;$i++) { #prevent deep recursion
539 CPAN->debug("i[$All[$i]]what[$what]") if $CPAN::DEBUG;
540 if ($All[$i]->{qmod} eq $what){
542 if ($jumped > 100) { # one's OK if e.g. just
543 # processing now; more are OK if
544 # user typed it several times
545 $CPAN::Frontend->mywarn(
546 qq{Object [$what] queued more than 100 times, ignoring}
552 my $obj = bless { qmod => $what }, $class;
555 CPAN->debug(sprintf("after jumpqueue All[%s] what[%s]",
556 join(",",map {$_->{qmod}} @All),
561 # CPAN::Queue::exists ;
563 my($self,$what) = @_;
564 my @all = map { $_->{qmod} } @All;
565 my $exists = grep { $_->{qmod} eq $what } @All;
566 # warn "in exists what[$what] all[@all] exists[$exists]";
570 # CPAN::Queue::delete ;
573 @All = grep { $_->{qmod} ne $mod } @All;
576 # CPAN::Queue::nullify_queue ;
586 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
588 # from here on only subs.
589 ################################################################################
591 sub suggest_myconfig () {
592 SUGGEST_MYCONFIG: if(!$INC{'CPAN/MyConfig.pm'}) {
593 $CPAN::Frontend->myprint("You don't seem to have a user ".
594 "configuration (MyConfig.pm) yet.\n");
595 my $new = CPAN::Shell::colorable_makemaker_prompt("Do you want to create a ".
596 "user configuration now? (Y/n)",
599 CPAN::Shell->mkmyconfig();
602 $CPAN::Frontend->mydie("OK, giving up.");
607 #-> sub CPAN::all_objects ;
609 my($mgr,$class) = @_;
610 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
611 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
613 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
615 *all = \&all_objects;
617 # Called by shell, not in batch mode. In batch mode I see no risk in
618 # having many processes updating something as installations are
619 # continually checked at runtime. In shell mode I suspect it is
620 # unintentional to open more than one shell at a time
622 #-> sub CPAN::checklock ;
625 my $lockfile = File::Spec->catfile($CPAN::Config->{cpan_home},".lock");
626 if (-f $lockfile && -M _ > 0) {
627 my $fh = FileHandle->new($lockfile) or
628 $CPAN::Frontend->mydie("Could not open lockfile '$lockfile': $!");
629 my $otherpid = <$fh>;
630 my $otherhost = <$fh>;
632 if (defined $otherpid && $otherpid) {
635 if (defined $otherhost && $otherhost) {
638 my $thishost = hostname();
639 if (defined $otherhost && defined $thishost &&
640 $otherhost ne '' && $thishost ne '' &&
641 $otherhost ne $thishost) {
642 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile '$lockfile'\n".
643 "reports other host $otherhost and other ".
644 "process $otherpid.\n".
645 "Cannot proceed.\n"));
647 elsif (defined $otherpid && $otherpid) {
648 return if $$ == $otherpid; # should never happen
649 $CPAN::Frontend->mywarn(
651 There seems to be running another CPAN process (pid $otherpid). Contacting...
653 if (kill 0, $otherpid) {
654 $CPAN::Frontend->mydie(qq{Other job is running.
655 You may want to kill it and delete the lockfile, maybe. On UNIX try:
659 } elsif (-w $lockfile) {
661 CPAN::Shell::colorable_makemaker_prompt
662 (qq{Other job not responding. Shall I overwrite }.
663 qq{the lockfile '$lockfile'? (Y/n)},"y");
664 $CPAN::Frontend->myexit("Ok, bye\n")
665 unless $ans =~ /^y/i;
668 qq{Lockfile '$lockfile' not writeable by you. }.
669 qq{Cannot proceed.\n}.
671 qq{ rm '$lockfile'\n}.
672 qq{ and then rerun us.\n}
676 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile '$lockfile'\n".
677 "reports other process with ID ".
678 "$otherpid. Cannot proceed.\n"));
681 my $dotcpan = $CPAN::Config->{cpan_home};
682 eval { File::Path::mkpath($dotcpan);};
684 # A special case at least for Jarkko.
689 $symlinkcpan = readlink $dotcpan;
690 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
691 eval { File::Path::mkpath($symlinkcpan); };
695 $CPAN::Frontend->mywarn(qq{
696 Working directory $symlinkcpan created.
700 unless (-d $dotcpan) {
702 Your configuration suggests "$dotcpan" as your
703 CPAN.pm working directory. I could not create this directory due
704 to this error: $firsterror\n};
706 As "$dotcpan" is a symlink to "$symlinkcpan",
707 I tried to create that, but I failed with this error: $seconderror
710 Please make sure the directory exists and is writable.
712 $CPAN::Frontend->myprint($mess);
713 return suggest_myconfig;
715 } # $@ after eval mkpath $dotcpan
717 unless ($fh = FileHandle->new(">$lockfile")) {
718 if ($! =~ /Permission/) {
719 $CPAN::Frontend->myprint(qq{
721 Your configuration suggests that CPAN.pm should use a working
723 $CPAN::Config->{cpan_home}
724 Unfortunately we could not create the lock file
726 due to permission problems.
728 Please make sure that the configuration variable
729 \$CPAN::Config->{cpan_home}
730 points to a directory where you can write a .lock file. You can set
731 this variable in either a CPAN/MyConfig.pm or a CPAN/Config.pm in your
734 return suggest_myconfig;
737 $fh->print($$, "\n");
738 $fh->print(hostname(), "\n");
739 $self->{LOCK} = $lockfile;
743 $CPAN::Frontend->mydie("Got SIGTERM, leaving");
748 $CPAN::Frontend->mydie("Got another SIGINT") if $Signal;
749 print "Caught SIGINT\n";
753 # From: Larry Wall <larry@wall.org>
754 # Subject: Re: deprecating SIGDIE
755 # To: perl5-porters@perl.org
756 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
758 # The original intent of __DIE__ was only to allow you to substitute one
759 # kind of death for another on an application-wide basis without respect
760 # to whether you were in an eval or not. As a global backstop, it should
761 # not be used any more lightly (or any more heavily :-) than class
762 # UNIVERSAL. Any attempt to build a general exception model on it should
763 # be politely squashed. Any bug that causes every eval {} to have to be
764 # modified should be not so politely squashed.
766 # Those are my current opinions. It is also my optinion that polite
767 # arguments degenerate to personal arguments far too frequently, and that
768 # when they do, it's because both people wanted it to, or at least didn't
769 # sufficiently want it not to.
773 # global backstop to cleanup if we should really die
774 $SIG{__DIE__} = \&cleanup;
775 $self->debug("Signal handler set.") if $CPAN::DEBUG;
778 #-> sub CPAN::DESTROY ;
780 &cleanup; # need an eval?
783 #-> sub CPAN::anycwd ;
786 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
791 sub cwd {Cwd::cwd();}
793 #-> sub CPAN::getcwd ;
794 sub getcwd {Cwd::getcwd();}
796 #-> sub CPAN::fastcwd ;
797 sub fastcwd {Cwd::fastcwd();}
799 #-> sub CPAN::backtickcwd ;
800 sub backtickcwd {my $cwd = `cwd`; chomp $cwd; $cwd}
802 #-> sub CPAN::find_perl ;
804 my($perl) = File::Spec->file_name_is_absolute($^X) ? $^X : "";
805 my $pwd = $CPAN::iCwd = CPAN::anycwd();
806 my $candidate = File::Spec->catfile($pwd,$^X);
807 $perl ||= $candidate if MM->maybe_command($candidate);
810 my ($component,$perl_name);
811 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
812 PATH_COMPONENT: foreach $component (File::Spec->path(),
813 $Config::Config{'binexp'}) {
814 next unless defined($component) && $component;
815 my($abs) = File::Spec->catfile($component,$perl_name);
816 if (MM->maybe_command($abs)) {
828 #-> sub CPAN::exists ;
830 my($mgr,$class,$id) = @_;
831 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
833 ### Carp::croak "exists called without class argument" unless $class;
835 $id =~ s/:+/::/g if $class eq "CPAN::Module";
836 exists $META->{readonly}{$class}{$id} or
837 exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
840 #-> sub CPAN::delete ;
842 my($mgr,$class,$id) = @_;
843 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
844 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
847 #-> sub CPAN::has_usable
848 # has_inst is sometimes too optimistic, we should replace it with this
849 # has_usable whenever a case is given
851 my($self,$mod,$message) = @_;
852 return 1 if $HAS_USABLE->{$mod};
853 my $has_inst = $self->has_inst($mod,$message);
854 return unless $has_inst;
857 LWP => [ # we frequently had "Can't locate object
858 # method "new" via package "LWP::UserAgent" at
859 # (eval 69) line 2006
861 sub {require LWP::UserAgent},
862 sub {require HTTP::Request},
863 sub {require URI::URL},
866 sub {require Net::FTP},
867 sub {require Net::Config},
870 sub {require File::HomeDir;
871 unless (File::HomeDir->VERSION >= 0.52){
872 for ("Will not use File::HomeDir, need 0.52\n") {
873 $CPAN::Frontend->mywarn($_);
880 if ($usable->{$mod}) {
881 for my $c (0..$#{$usable->{$mod}}) {
882 my $code = $usable->{$mod}[$c];
883 my $ret = eval { &$code() };
884 $ret = "" unless defined $ret;
886 # warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
891 return $HAS_USABLE->{$mod} = 1;
894 #-> sub CPAN::has_inst
896 my($self,$mod,$message) = @_;
897 Carp::croak("CPAN->has_inst() called without an argument")
899 my %dont = map { $_ => 1 } keys %{$CPAN::META->{dontload_hash}||{}},
900 keys %{$CPAN::Config->{dontload_hash}||{}},
901 @{$CPAN::Config->{dontload_list}||[]};
902 if (defined $message && $message eq "no" # afair only used by Nox
906 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
914 # checking %INC is wrong, because $INC{LWP} may be true
915 # although $INC{"URI/URL.pm"} may have failed. But as
916 # I really want to say "bla loaded OK", I have to somehow
918 ### warn "$file in %INC"; #debug
920 } elsif (eval { require $file }) {
921 # eval is good: if we haven't yet read the database it's
922 # perfect and if we have installed the module in the meantime,
923 # it tries again. The second require is only a NOOP returning
924 # 1 if we had success, otherwise it's retrying
926 $CPAN::Frontend->myprint("CPAN: $mod loaded ok\n");
927 if ($mod eq "CPAN::WAIT") {
928 push @CPAN::Shell::ISA, 'CPAN::WAIT';
931 } elsif ($mod eq "Net::FTP") {
932 $CPAN::Frontend->mywarn(qq{
933 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
935 install Bundle::libnet
937 }) unless $Have_warned->{"Net::FTP"}++;
938 $CPAN::Frontend->mysleep(3);
939 } elsif ($mod eq "Digest::SHA"){
940 if ($Have_warned->{"Digest::SHA"}++) {
941 $CPAN::Frontend->myprint(qq{CPAN: checksum security checks disabled}.
942 qq{because Digest::SHA not installed.\n});
944 $CPAN::Frontend->mywarn(qq{
945 CPAN: checksum security checks disabled because Digest::SHA not installed.
946 Please consider installing the Digest::SHA module.
949 $CPAN::Frontend->mysleep(2);
951 } elsif ($mod eq "Module::Signature"){
952 if (not $CPAN::Config->{check_sigs}) {
953 # they do not want us:-(
954 } elsif (not $Have_warned->{"Module::Signature"}++) {
955 # No point in complaining unless the user can
956 # reasonably install and use it.
957 if (eval { require Crypt::OpenPGP; 1 } ||
959 defined $CPAN::Config->{'gpg'}
961 $CPAN::Config->{'gpg'} =~ /\S/
964 $CPAN::Frontend->mywarn(qq{
965 CPAN: Module::Signature security checks disabled because Module::Signature
966 not installed. Please consider installing the Module::Signature module.
967 You may also need to be able to connect over the Internet to the public
968 keyservers like pgp.mit.edu (port 11371).
971 $CPAN::Frontend->mysleep(2);
975 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
980 #-> sub CPAN::instance ;
982 my($mgr,$class,$id) = @_;
985 # unsafe meta access, ok?
986 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
987 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
995 #-> sub CPAN::cleanup ;
997 # warn "cleanup called with arg[@_] End[$CPAN::End] Signal[$Signal]";
998 local $SIG{__DIE__} = '';
1003 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
1004 $ineval = 1, last if
1005 $subroutine eq '(eval)';
1007 return if $ineval && !$CPAN::End;
1008 return unless defined $META->{LOCK};
1009 return unless -f $META->{LOCK};
1011 unlink $META->{LOCK};
1013 # Carp::cluck("DEBUGGING");
1014 $CPAN::Frontend->myprint("Lockfile removed.\n");
1017 #-> sub CPAN::savehist
1020 my($histfile,$histsize);
1021 unless ($histfile = $CPAN::Config->{'histfile'}){
1022 $CPAN::Frontend->mywarn("No history written (no histfile specified).\n");
1025 $histsize = $CPAN::Config->{'histsize'} || 100;
1027 unless ($CPAN::term->can("GetHistory")) {
1028 $CPAN::Frontend->mywarn("Terminal does not support GetHistory.\n");
1034 my @h = $CPAN::term->GetHistory;
1035 splice @h, 0, @h-$histsize if @h>$histsize;
1036 my($fh) = FileHandle->new;
1037 open $fh, ">$histfile" or $CPAN::Frontend->mydie("Couldn't open >$histfile: $!");
1038 local $\ = local $, = "\n";
1044 my($self,$what) = @_;
1045 $self->{is_tested}{$what} = 1;
1049 my($self,$what) = @_;
1050 delete $self->{is_tested}{$what};
1055 $self->{is_tested} ||= {};
1056 return unless %{$self->{is_tested}};
1057 my $env = $ENV{PERL5LIB};
1058 $env = $ENV{PERLLIB} unless defined $env;
1060 push @env, $env if defined $env and length $env;
1061 my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}};
1062 $CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
1063 $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1066 package CPAN::CacheMgr;
1069 #-> sub CPAN::CacheMgr::as_string ;
1071 eval { require Data::Dumper };
1073 return shift->SUPER::as_string;
1075 return Data::Dumper::Dumper(shift);
1079 #-> sub CPAN::CacheMgr::cachesize ;
1084 #-> sub CPAN::CacheMgr::tidyup ;
1087 return unless -d $self->{ID};
1088 while ($self->{DU} > $self->{'MAX'} ) {
1089 my($toremove) = shift @{$self->{FIFO}};
1090 $CPAN::Frontend->myprint(sprintf(
1091 "Deleting from cache".
1092 ": $toremove (%.1f>%.1f MB)\n",
1093 $self->{DU}, $self->{'MAX'})
1095 return if $CPAN::Signal;
1096 $self->force_clean_cache($toremove);
1097 return if $CPAN::Signal;
1101 #-> sub CPAN::CacheMgr::dir ;
1106 #-> sub CPAN::CacheMgr::entries ;
1108 my($self,$dir) = @_;
1109 return unless defined $dir;
1110 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
1111 $dir ||= $self->{ID};
1112 my($cwd) = CPAN::anycwd();
1113 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
1114 my $dh = DirHandle->new(File::Spec->curdir)
1115 or Carp::croak("Couldn't opendir $dir: $!");
1118 next if $_ eq "." || $_ eq "..";
1120 push @entries, File::Spec->catfile($dir,$_);
1122 push @entries, File::Spec->catdir($dir,$_);
1124 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
1127 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
1128 sort { -M $b <=> -M $a} @entries;
1131 #-> sub CPAN::CacheMgr::disk_usage ;
1133 my($self,$dir) = @_;
1134 return if exists $self->{SIZE}{$dir};
1135 return if $CPAN::Signal;
1139 unless (chmod 0755, $dir) {
1140 $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
1141 "permission to change the permission; cannot ".
1142 "estimate disk usage of '$dir'\n");
1143 $CPAN::Frontend->mysleep(5);
1148 $CPAN::Frontend->mywarn("Directory '$dir' has gone. Cannot continue.\n");
1149 $CPAN::Frontend->mysleep(2);
1154 $File::Find::prune++ if $CPAN::Signal;
1156 if ($^O eq 'MacOS') {
1158 my $cat = Mac::Files::FSpGetCatInfo($_);
1159 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
1163 unless (chmod 0755, $_) {
1164 $CPAN::Frontend->mywarn("I have neither the -x permission nor ".
1165 "the permission to change the permission; ".
1166 "can only partially estimate disk usage ".
1168 $CPAN::Frontend->mysleep(5);
1179 return if $CPAN::Signal;
1180 $self->{SIZE}{$dir} = $Du/1024/1024;
1181 push @{$self->{FIFO}}, $dir;
1182 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
1183 $self->{DU} += $Du/1024/1024;
1187 #-> sub CPAN::CacheMgr::force_clean_cache ;
1188 sub force_clean_cache {
1189 my($self,$dir) = @_;
1190 return unless -e $dir;
1191 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
1193 File::Path::rmtree($dir);
1194 $self->{DU} -= $self->{SIZE}{$dir};
1195 delete $self->{SIZE}{$dir};
1198 #-> sub CPAN::CacheMgr::new ;
1205 ID => $CPAN::Config->{'build_dir'},
1206 MAX => $CPAN::Config->{'build_cache'},
1207 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
1210 File::Path::mkpath($self->{ID});
1211 my $dh = DirHandle->new($self->{ID});
1212 bless $self, $class;
1215 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
1217 CPAN->debug($debug) if $CPAN::DEBUG;
1221 #-> sub CPAN::CacheMgr::scan_cache ;
1224 return if $self->{SCAN} eq 'never';
1225 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
1226 unless $self->{SCAN} eq 'atstart';
1227 $CPAN::Frontend->myprint(
1228 sprintf("Scanning cache %s for sizes\n",
1231 for $e ($self->entries($self->{ID})) {
1232 next if $e eq ".." || $e eq ".";
1233 $self->disk_usage($e);
1234 return if $CPAN::Signal;
1239 package CPAN::Shell;
1242 #-> sub CPAN::Shell::h ;
1244 my($class,$about) = @_;
1245 if (defined $about) {
1246 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
1248 my $filler = " " x (80 - 28 - length($CPAN::VERSION));
1249 $CPAN::Frontend->myprint(qq{
1250 Display Information $filler (ver $CPAN::VERSION)
1251 command argument description
1252 a,b,d,m WORD or /REGEXP/ about authors, bundles, distributions, modules
1253 i WORD or /REGEXP/ about any of the above
1254 ls AUTHOR or GLOB about files in the author's directory
1255 (with WORD being a module, bundle or author name or a distribution
1256 name of the form AUTHOR/DISTRIBUTION)
1258 Download, Test, Make, Install...
1259 get download clean make clean
1260 make make (implies get) look open subshell in dist directory
1261 test make test (implies make) readme display these README files
1262 install make install (implies test) perldoc display POD documentation
1265 force COMMAND unconditionally do command
1266 notest COMMAND skip testing
1269 h,? display this menu ! perl-code eval a perl command
1270 r report module updates upgrade upgrade all modules
1271 o conf [opt] set and query options q quit the cpan shell
1272 reload cpan load CPAN.pm again reload index load newer indices
1273 autobundle Snapshot recent latest CPAN uploads});
1279 #-> sub CPAN::Shell::a ;
1281 my($self,@arg) = @_;
1282 # authors are always UPPERCASE
1284 $_ = uc $_ unless /=/;
1286 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1289 #-> sub CPAN::Shell::globls ;
1291 my($self,$s,$pragmas) = @_;
1292 # ls is really very different, but we had it once as an ordinary
1293 # command in the Shell (upto rev. 321) and we could not handle
1295 my(@accept,@preexpand);
1296 if ($s =~ /[\*\?\/]/) {
1297 if ($CPAN::META->has_inst("Text::Glob")) {
1298 if (my($au,$pathglob) = $s =~ m|(.*?)/(.*)|) {
1299 my $rau = Text::Glob::glob_to_regex(uc $au);
1300 CPAN::Shell->debug("au[$au]pathglob[$pathglob]rau[$rau]")
1302 push @preexpand, map { $_->id . "/" . $pathglob }
1303 CPAN::Shell->expand_by_method('CPAN::Author',['id'],"/$rau/");
1305 my $rau = Text::Glob::glob_to_regex(uc $s);
1306 push @preexpand, map { $_->id }
1307 CPAN::Shell->expand_by_method('CPAN::Author',
1312 $CPAN::Frontend->mydie("Text::Glob not installed, cannot proceed");
1315 push @preexpand, uc $s;
1318 unless (/^[A-Z0-9\-]+(\/|$)/i) {
1319 $CPAN::Frontend->mywarn("ls command rejects argument $_: not an author\n");
1324 my $silent = @accept>1;
1325 my $last_alpha = "";
1327 for my $a (@accept){
1328 my($author,$pathglob);
1329 if ($a =~ m|(.*?)/(.*)|) {
1332 $author = CPAN::Shell->expand_by_method('CPAN::Author',
1334 $a2) or die "No author found for $a2";
1336 $author = CPAN::Shell->expand_by_method('CPAN::Author',
1338 $a) or die "No author found for $a";
1341 my $alpha = substr $author->id, 0, 1;
1343 if ($alpha eq $last_alpha) {
1347 $last_alpha = $alpha;
1349 $CPAN::Frontend->myprint($ad);
1351 for my $pragma (@$pragmas) {
1352 if ($author->can($pragma)) {
1356 push @results, $author->ls($pathglob,$silent); # silent if
1359 for my $pragma (@$pragmas) {
1360 my $meth = "un$pragma";
1361 if ($author->can($meth)) {
1369 #-> sub CPAN::Shell::local_bundles ;
1371 my($self,@which) = @_;
1372 my($incdir,$bdir,$dh);
1373 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1374 my @bbase = "Bundle";
1375 while (my $bbase = shift @bbase) {
1376 $bdir = File::Spec->catdir($incdir,split /::/, $bbase);
1377 CPAN->debug("bdir[$bdir]\@bbase[@bbase]") if $CPAN::DEBUG;
1378 if ($dh = DirHandle->new($bdir)) { # may fail
1380 for $entry ($dh->read) {
1381 next if $entry =~ /^\./;
1382 next unless $entry =~ /^\w+(\.pm)?(?!\n)\Z/;
1383 if (-d File::Spec->catdir($bdir,$entry)){
1384 push @bbase, "$bbase\::$entry";
1386 next unless $entry =~ s/\.pm(?!\n)\Z//;
1387 $CPAN::META->instance('CPAN::Bundle',"$bbase\::$entry");
1395 #-> sub CPAN::Shell::b ;
1397 my($self,@which) = @_;
1398 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1399 $self->local_bundles;
1400 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1403 #-> sub CPAN::Shell::d ;
1404 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1406 #-> sub CPAN::Shell::m ;
1407 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
1409 $CPAN::Frontend->myprint($self->format_result('Module',@_));
1412 #-> sub CPAN::Shell::i ;
1416 @args = '/./' unless @args;
1418 for my $type (qw/Bundle Distribution Module/) {
1419 push @result, $self->expand($type,@args);
1421 # Authors are always uppercase.
1422 push @result, $self->expand("Author", map { uc $_ } @args);
1424 my $result = @result == 1 ?
1425 $result[0]->as_string :
1427 "No objects found of any type for argument @args\n" :
1429 (map {$_->as_glimpse} @result),
1430 scalar @result, " items found\n",
1432 $CPAN::Frontend->myprint($result);
1435 #-> sub CPAN::Shell::o ;
1437 # CPAN::Shell::o and CPAN::HandleConfig::edit are closely related. 'o
1438 # conf' calls through to CPAN::HandleConfig::edit. 'o conf' should
1439 # have been called 'set' and 'o debug' maybe 'set debug' or 'debug'
1440 # 'o conf XXX' calls ->edit in CPAN/HandleConfig.pm
1442 my($self,$o_type,@o_what) = @_;
1445 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1446 if ($o_type eq 'conf') {
1447 if (!@o_what) { # print all things, "o conf"
1449 $CPAN::Frontend->myprint("\$CPAN::Config options from ");
1451 if (exists $INC{'CPAN/Config.pm'}) {
1452 push @from, $INC{'CPAN/Config.pm'};
1454 if (exists $INC{'CPAN/MyConfig.pm'}) {
1455 push @from, $INC{'CPAN/MyConfig.pm'};
1457 $CPAN::Frontend->myprint(join " and ", map {"'$_'"} @from);
1458 $CPAN::Frontend->myprint(":\n");
1459 for $k (sort keys %CPAN::HandleConfig::can) {
1460 $v = $CPAN::HandleConfig::can{$k};
1461 $CPAN::Frontend->myprint(sprintf " %-18s [%s]\n", $k, $v);
1463 $CPAN::Frontend->myprint("\n");
1464 for $k (sort keys %$CPAN::Config) {
1465 CPAN::HandleConfig->prettyprint($k);
1467 $CPAN::Frontend->myprint("\n");
1468 } elsif (!CPAN::HandleConfig->edit(@o_what)) {
1469 $CPAN::Frontend->myprint(qq{Type 'o conf' to view all configuration }.
1472 } elsif ($o_type eq 'debug') {
1474 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1477 my($what) = shift @o_what;
1478 if ($what =~ s/^-// && exists $CPAN::DEBUG{$what}) {
1479 $CPAN::DEBUG &= $CPAN::DEBUG ^ $CPAN::DEBUG{$what};
1482 if ( exists $CPAN::DEBUG{$what} ) {
1483 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1484 } elsif ($what =~ /^\d/) {
1485 $CPAN::DEBUG = $what;
1486 } elsif (lc $what eq 'all') {
1488 for (values %CPAN::DEBUG) {
1491 $CPAN::DEBUG = $max;
1494 for (keys %CPAN::DEBUG) {
1495 next unless lc($_) eq lc($what);
1496 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1499 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1504 my $raw = "Valid options for debug are ".
1505 join(", ",sort(keys %CPAN::DEBUG), 'all').
1506 qq{ or a number. Completion works on the options. }.
1507 qq{Case is ignored.};
1509 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
1510 $CPAN::Frontend->myprint("\n\n");
1513 $CPAN::Frontend->myprint("Options set for debugging:\n");
1515 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1516 $v = $CPAN::DEBUG{$k};
1517 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
1518 if $v & $CPAN::DEBUG;
1521 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1524 $CPAN::Frontend->myprint(qq{
1526 conf set or get configuration variables
1527 debug set or get debugging options
1532 sub paintdots_onreload {
1535 if ( $_[0] =~ /[Ss]ubroutine ([\w:]+) redefined/ ) {
1539 # $CPAN::Frontend->myprint(".($subr)");
1540 $CPAN::Frontend->myprint(".");
1547 #-> sub CPAN::Shell::reload ;
1549 my($self,$command,@arg) = @_;
1551 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1552 if ($command =~ /cpan/i) {
1554 chdir $CPAN::iCwd if $CPAN::iCwd; # may fail
1558 "CPAN/HandleConfig.pm",
1559 "CPAN/FirstTime.pm",
1564 if ($CPAN::Config->{test_report}) {
1565 push @relo, "CPAN/Reporter.pm";
1567 MFILE: for my $f (@relo) {
1568 local($SIG{__WARN__}) = paintdots_onreload(\$redef);
1569 $self->reload_this($f) or $failed++;
1571 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1572 $failed++ unless $redef;
1574 $CPAN::Frontend->mywarn("\n$failed errors during reload. You better quit ".
1577 } elsif ($command =~ /index/) {
1578 CPAN::Index->force_reload;
1580 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN.pm file
1581 index re-reads the index files\n});
1587 return 1 unless $INC{$f};
1588 my $pwd = CPAN::anycwd();
1589 CPAN->debug("reloading the whole '$f' from '$INC{$f}' while pwd='$pwd'")
1592 for my $inc (@INC) {
1593 $read = File::Spec->catfile($inc,split /\//, $f);
1600 $CPAN::Frontend->mywarn("Found no file to reload for '$f'\n");
1603 my $fh = FileHandle->new($read) or
1604 $CPAN::Frontend->mydie("Could not open $read: $!");
1608 CPAN->debug(sprintf("evaling [%s...]\n",substr($eval,0,64)))
1618 #-> sub CPAN::Shell::mkmyconfig ;
1620 my($self, $cpanpm, %args) = @_;
1621 require CPAN::FirstTime;
1622 my $home = CPAN::HandleConfig::home;
1623 $cpanpm = $INC{'CPAN/MyConfig.pm'} ||
1624 File::Spec->catfile(split /\//, "$home/.cpan/CPAN/MyConfig.pm");
1625 File::Path::mkpath(File::Basename::dirname($cpanpm)) unless -e $cpanpm;
1626 CPAN::HandleConfig::require_myconfig_or_config;
1627 $CPAN::Config ||= {};
1632 keep_source_where => undef,
1635 CPAN::FirstTime::init($cpanpm, %args);
1638 #-> sub CPAN::Shell::_binary_extensions ;
1639 sub _binary_extensions {
1640 my($self) = shift @_;
1641 my(@result,$module,%seen,%need,$headerdone);
1642 for $module ($self->expand('Module','/./')) {
1643 my $file = $module->cpan_file;
1644 next if $file eq "N/A";
1645 next if $file =~ /^Contact Author/;
1646 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
1647 next if $dist->isa_perl;
1648 next unless $module->xs_file;
1650 $CPAN::Frontend->myprint(".");
1651 push @result, $module;
1653 # print join " | ", @result;
1654 $CPAN::Frontend->myprint("\n");
1658 #-> sub CPAN::Shell::recompile ;
1660 my($self) = shift @_;
1661 my($module,@module,$cpan_file,%dist);
1662 @module = $self->_binary_extensions();
1663 for $module (@module){ # we force now and compile later, so we
1665 $cpan_file = $module->cpan_file;
1666 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1668 $dist{$cpan_file}++;
1670 for $cpan_file (sort keys %dist) {
1671 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1672 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1674 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1675 # stop a package from recompiling,
1676 # e.g. IO-1.12 when we have perl5.003_10
1680 #-> sub CPAN::Shell::scripts ;
1682 my($self, $arg) = @_;
1683 $CPAN::Frontend->mywarn(">>>> experimental command, currently unsupported <<<<\n\n");
1685 for my $req (qw( HTML::LinkExtor Sort::Versions List::Util )) {
1686 unless ($CPAN::META->has_inst($req)) {
1687 $CPAN::Frontend->mywarn(" $req not available\n");
1690 my $p = HTML::LinkExtor->new();
1691 my $indexfile = "/home/ftp/pub/PAUSE/scripts/new/index.html";
1692 unless (-f $indexfile) {
1693 $CPAN::Frontend->mydie("found no indexfile[$indexfile]\n");
1695 $p->parse_file($indexfile);
1698 if ($arg =~ s|^/(.+)/$|$1|) {
1699 $qrarg = eval 'qr/$arg/'; # hide construct from 5.004
1701 for my $l ($p->links) {
1702 my $tag = shift @$l;
1703 next unless $tag eq "a";
1705 my $href = $att{href};
1706 next unless $href =~ s|^\.\./authors/id/./../||;
1709 if ($href =~ $qrarg) {
1713 if ($href =~ /\Q$arg\E/) {
1721 # now filter for the latest version if there is more than one of a name
1727 $stems{$stem} ||= [];
1728 push @{$stems{$stem}}, $href;
1730 for (sort keys %stems) {
1732 if (@{$stems{$_}} > 1) {
1733 $highest = List::Util::reduce {
1734 Sort::Versions::versioncmp($a,$b) > 0 ? $a : $b
1737 $highest = $stems{$_}[0];
1739 $CPAN::Frontend->myprint("$highest\n");
1743 #-> sub CPAN::Shell::upgrade ;
1745 my($self) = shift @_;
1746 $self->install($self->r);
1749 #-> sub CPAN::Shell::_u_r_common ;
1751 my($self) = shift @_;
1752 my($what) = shift @_;
1753 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1754 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
1755 $what && $what =~ /^[aru]$/;
1757 @args = '/./' unless @args;
1758 my(@result,$module,%seen,%need,$headerdone,
1759 $version_undefs,$version_zeroes);
1760 $version_undefs = $version_zeroes = 0;
1761 my $sprintf = "%s%-25s%s %9s %9s %s\n";
1762 my @expand = $self->expand('Module',@args);
1763 my $expand = scalar @expand;
1764 if (0) { # Looks like noise to me, was very useful for debugging
1765 # for metadata cache
1766 $CPAN::Frontend->myprint(sprintf "%d matches in the database\n", $expand);
1768 MODULE: for $module (@expand) {
1769 my $file = $module->cpan_file;
1770 next MODULE unless defined $file; # ??
1771 $file =~ s|^./../||;
1772 my($latest) = $module->cpan_version;
1773 my($inst_file) = $module->inst_file;
1775 return if $CPAN::Signal;
1778 $have = $module->inst_version;
1779 } elsif ($what eq "r") {
1780 $have = $module->inst_version;
1782 if ($have eq "undef"){
1784 } elsif ($have == 0){
1787 next MODULE unless CPAN::Version->vgt($latest, $have);
1788 # to be pedantic we should probably say:
1789 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1790 # to catch the case where CPAN has a version 0 and we have a version undef
1791 } elsif ($what eq "u") {
1797 } elsif ($what eq "r") {
1799 } elsif ($what eq "u") {
1803 return if $CPAN::Signal; # this is sometimes lengthy
1806 push @result, sprintf "%s %s\n", $module->id, $have;
1807 } elsif ($what eq "r") {
1808 push @result, $module->id;
1809 next MODULE if $seen{$file}++;
1810 } elsif ($what eq "u") {
1811 push @result, $module->id;
1812 next MODULE if $seen{$file}++;
1813 next MODULE if $file =~ /^Contact/;
1815 unless ($headerdone++){
1816 $CPAN::Frontend->myprint("\n");
1817 $CPAN::Frontend->myprint(sprintf(
1820 "Package namespace",
1832 $CPAN::META->has_inst("Term::ANSIColor")
1834 $module->description
1836 $color_on = Term::ANSIColor::color("green");
1837 $color_off = Term::ANSIColor::color("reset");
1839 $CPAN::Frontend->myprint(sprintf $sprintf,
1846 $need{$module->id}++;
1850 $CPAN::Frontend->myprint("No modules found for @args\n");
1851 } elsif ($what eq "r") {
1852 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1856 if ($version_zeroes) {
1857 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1858 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1859 qq{a version number of 0\n});
1861 if ($version_undefs) {
1862 my $s_has = $version_undefs > 1 ? "s have" : " has";
1863 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1864 qq{parseable version number\n});
1870 #-> sub CPAN::Shell::r ;
1872 shift->_u_r_common("r",@_);
1875 #-> sub CPAN::Shell::u ;
1877 shift->_u_r_common("u",@_);
1880 #-> sub CPAN::Shell::failed ;
1882 my($self,$only_id,$silent) = @_;
1884 DIST: for my $d ($CPAN::META->all_objects("CPAN::Distribution")) {
1886 NAY: for my $nosayer (
1894 next unless exists $d->{$nosayer};
1896 $d->{$nosayer}->can("failed") ?
1897 $d->{$nosayer}->failed :
1898 $d->{$nosayer} =~ /^NO/
1900 next NAY if $only_id && $only_id != (
1901 $d->{$nosayer}->can("commandid")
1903 $d->{$nosayer}->commandid
1905 $CPAN::CurrentCommandId
1910 next DIST unless $failed;
1914 # " %-45s: %s %s\n",
1917 $d->{$failed}->can("failed") ?
1919 $d->{$failed}->commandid,
1922 $d->{$failed}->text,
1932 my $scope = $only_id ? "command" : "session";
1934 my $print = join "",
1935 map { sprintf " %-45s: %s %s\n", @$_[1,2,3] }
1936 sort { $a->[0] <=> $b->[0] } @failed;
1937 $CPAN::Frontend->myprint("Failed during this $scope:\n$print");
1938 } elsif (!$only_id || !$silent) {
1939 $CPAN::Frontend->myprint("Nothing failed in this $scope\n");
1943 # XXX intentionally undocumented because completely bogus, unportable,
1946 #-> sub CPAN::Shell::status ;
1949 require Devel::Size;
1950 my $ps = FileHandle->new;
1951 open $ps, "/proc/$$/status";
1954 next unless /VmSize:\s+(\d+)/;
1958 $CPAN::Frontend->mywarn(sprintf(
1959 "%-27s %6d\n%-27s %6d\n",
1963 Devel::Size::total_size($CPAN::META)/1024,
1965 for my $k (sort keys %$CPAN::META) {
1966 next unless substr($k,0,4) eq "read";
1967 warn sprintf " %-26s %6d\n", $k, Devel::Size::total_size($CPAN::META->{$k})/1024;
1968 for my $k2 (sort keys %{$CPAN::META->{$k}}) {
1969 warn sprintf " %-25s %6d %6d\n",
1971 Devel::Size::total_size($CPAN::META->{$k}{$k2})/1024,
1972 scalar keys %{$CPAN::META->{$k}{$k2}};
1977 #-> sub CPAN::Shell::autobundle ;
1980 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
1981 my(@bundle) = $self->_u_r_common("a",@_);
1982 my($todir) = File::Spec->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1983 File::Path::mkpath($todir);
1984 unless (-d $todir) {
1985 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
1988 my($y,$m,$d) = (localtime)[5,4,3];
1992 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1993 my($to) = File::Spec->catfile($todir,"$me.pm");
1995 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1996 $to = File::Spec->catfile($todir,"$me.pm");
1998 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
2000 "package Bundle::$me;\n\n",
2001 "\$VERSION = '0.01';\n\n",
2005 "Bundle::$me - Snapshot of installation on ",
2006 $Config::Config{'myhostname'},
2009 "\n\n=head1 SYNOPSIS\n\n",
2010 "perl -MCPAN -e 'install Bundle::$me'\n\n",
2011 "=head1 CONTENTS\n\n",
2012 join("\n", @bundle),
2013 "\n\n=head1 CONFIGURATION\n\n",
2015 "\n\n=head1 AUTHOR\n\n",
2016 "This Bundle has been generated automatically ",
2017 "by the autobundle routine in CPAN.pm.\n",
2020 $CPAN::Frontend->myprint("\nWrote bundle file
2024 #-> sub CPAN::Shell::expandany ;
2027 CPAN->debug("s[$s]") if $CPAN::DEBUG;
2028 if ($s =~ m|/|) { # looks like a file
2029 $s = CPAN::Distribution->normalize($s);
2030 return $CPAN::META->instance('CPAN::Distribution',$s);
2031 # Distributions spring into existence, not expand
2032 } elsif ($s =~ m|^Bundle::|) {
2033 $self->local_bundles; # scanning so late for bundles seems
2034 # both attractive and crumpy: always
2035 # current state but easy to forget
2037 return $self->expand('Bundle',$s);
2039 return $self->expand('Module',$s)
2040 if $CPAN::META->exists('CPAN::Module',$s);
2045 #-> sub CPAN::Shell::expand ;
2048 my($type,@args) = @_;
2049 CPAN->debug("type[$type]args[@args]") if $CPAN::DEBUG;
2050 my $class = "CPAN::$type";
2051 my $methods = ['id'];
2052 for my $meth (qw(name)) {
2053 next if $] < 5.00303; # no "can"
2054 next unless $class->can($meth);
2055 push @$methods, $meth;
2057 $self->expand_by_method($class,$methods,@args);
2060 sub expand_by_method {
2062 my($class,$methods,@args) = @_;
2065 my($regex,$command);
2066 if ($arg =~ m|^/(.*)/$|) {
2068 } elsif ($arg =~ m/=/) {
2072 CPAN->debug(sprintf "class[%s]regex[%s]command[%s]",
2074 defined $regex ? $regex : "UNDEFINED",
2075 defined $command ? $command : "UNDEFINED",
2077 if (defined $regex) {
2079 $CPAN::META->all_objects($class)
2082 # BUG, we got an empty object somewhere
2083 require Data::Dumper;
2084 CPAN->debug(sprintf(
2085 "Bug in CPAN: Empty id on obj[%s][%s]",
2087 Data::Dumper::Dumper($obj)
2091 for my $method (@$methods) {
2092 if ($obj->$method() =~ /$regex/i) {
2098 } elsif ($command) {
2099 die "equal sign in command disabled (immature interface), ".
2101 ! \$CPAN::Shell::ADVANCED_QUERY=1
2102 to enable it. But please note, this is HIGHLY EXPERIMENTAL code
2103 that may go away anytime.\n"
2104 unless $ADVANCED_QUERY;
2105 my($method,$criterion) = $arg =~ /(.+?)=(.+)/;
2106 my($matchcrit) = $criterion =~ m/^~(.+)/;
2110 $CPAN::META->all_objects($class)
2112 my $lhs = $self->$method() or next; # () for 5.00503
2114 push @m, $self if $lhs =~ m/$matchcrit/;
2116 push @m, $self if $lhs eq $criterion;
2121 if ( $class eq 'CPAN::Bundle' ) {
2122 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
2123 } elsif ($class eq "CPAN::Distribution") {
2124 $xarg = CPAN::Distribution->normalize($arg);
2128 if ($CPAN::META->exists($class,$xarg)) {
2129 $obj = $CPAN::META->instance($class,$xarg);
2130 } elsif ($CPAN::META->exists($class,$arg)) {
2131 $obj = $CPAN::META->instance($class,$arg);
2138 @m = sort {$a->id cmp $b->id} @m;
2139 if ( $CPAN::DEBUG ) {
2140 my $wantarray = wantarray;
2141 my $join_m = join ",", map {$_->id} @m;
2142 $self->debug("wantarray[$wantarray]join_m[$join_m]");
2144 return wantarray ? @m : $m[0];
2147 #-> sub CPAN::Shell::format_result ;
2150 my($type,@args) = @_;
2151 @args = '/./' unless @args;
2152 my(@result) = $self->expand($type,@args);
2153 my $result = @result == 1 ?
2154 $result[0]->as_string :
2156 "No objects of type $type found for argument @args\n" :
2158 (map {$_->as_glimpse} @result),
2159 scalar @result, " items found\n",
2164 #-> sub CPAN::Shell::report_fh ;
2166 my $installation_report_fh;
2167 my $previously_noticed = 0;
2170 return $installation_report_fh if $installation_report_fh;
2171 if ($CPAN::META->has_inst("File::Temp")) {
2172 $installation_report_fh
2174 template => 'cpan_install_XXXX',
2179 unless ( $installation_report_fh ) {
2180 warn("Couldn't open installation report file; " .
2181 "no report file will be generated."
2182 ) unless $previously_noticed++;
2188 # The only reason for this method is currently to have a reliable
2189 # debugging utility that reveals which output is going through which
2190 # channel. No, I don't like the colors ;-)
2192 # to turn colordebugging on, write
2193 # cpan> o conf colorize_output 1
2195 #-> sub CPAN::Shell::print_ornamented ;
2197 my $print_ornamented_have_warned = 0;
2198 sub colorize_output {
2199 my $colorize_output = $CPAN::Config->{colorize_output};
2200 if ($colorize_output && !$CPAN::META->has_inst("Term::ANSIColor")) {
2201 unless ($print_ornamented_have_warned++) {
2202 # no myprint/mywarn within myprint/mywarn!
2203 warn "Colorize_output is set to true but Term::ANSIColor is not
2204 installed. To activate colorized output, please install Term::ANSIColor.\n\n";
2206 $colorize_output = 0;
2208 return $colorize_output;
2213 sub print_ornamented {
2214 my($self,$what,$ornament) = @_;
2215 return unless defined $what;
2217 local $| = 1; # Flush immediately
2218 if ( $CPAN::Be_Silent ) {
2219 print {report_fh()} $what;
2222 my $swhat = "$what"; # stringify if it is an object
2223 if ($CPAN::Config->{term_is_latin}){
2226 =~ s{([\xC0-\xDF])([\x80-\xBF])}{chr(ord($1)<<6&0xC0|ord($2)&0x3F)}eg; #};
2229 my $longest = 0; # Does list::util work on 5.004?
2230 for $line (split /\n/, $swhat) {
2231 $longest = length($line) if length($line) > $longest;
2233 $longest = 78 if $longest > 78; # yes, arbitrary, who wants it set-able?
2234 if ($self->colorize_output) {
2235 my $color_on = eval { Term::ANSIColor::color($ornament) } || "";
2237 print "Term::ANSIColor rejects color[$ornament]: $@\n
2238 Please choose a different color (Hint: try 'o conf init color.*')\n";
2240 my $demobug = 0; # (=0) works, (=1) has some obscure bugs and
2241 # breaks 30shell.t, (=2) has some obvious
2242 # bugs but passes 30shell.t
2243 if ($demobug == 1) {
2244 my $nl = chomp $swhat ? "\n" : "";
2245 while (length $swhat) {
2248 $swhat =~ s/(.*\n?)//m;
2252 while (length $swhat) {
2253 my $c = substr($swhat,0,1);
2254 $swhat = substr($swhat,1);
2262 # my($nl) = chomp $line ? "\n" : "";
2263 # ->debug verboten within print_ornamented ==> recursion!
2264 # warn("line[$line]ornament[$ornament]sprintf[$sprintf]\n") if $CPAN::DEBUG;
2266 sprintf("%-*s",$longest,$line),
2267 Term::ANSIColor::color("reset"),
2268 $line =~ /\n/ ? "" : $nl;
2270 } elsif ($demobug == 2) {
2271 my $block = join "\n",
2277 Term::ANSIColor::color("reset"),
2280 split /[\r ]*\n/, $swhat;
2285 Term::ANSIColor::color("reset");
2292 # where is myprint/mywarn/Frontend/etc. documented? We need guidelines
2293 # where to use what! I think, we send everything to STDOUT and use
2294 # print for normal/good news and warn for news that need more
2295 # attention. Yes, this is our working contract for now.
2297 my($self,$what) = @_;
2299 $self->print_ornamented($what, $CPAN::Config->{colorize_print}||'bold blue');
2303 my($self,$what) = @_;
2304 $self->myprint($what);
2309 my($self,$what) = @_;
2310 $self->print_ornamented($what, $CPAN::Config->{colorize_warn}||'bold red');
2313 # only to be used for shell commands
2315 my($self,$what) = @_;
2316 $self->print_ornamented($what, $CPAN::Config->{colorize_warn}||'bold red');
2318 # If it is the shell, we want that the following die to be silent,
2319 # but if it is not the shell, we would need a 'die $what'. We need
2320 # to take care that only shell commands use mydie. Is this
2326 # sub CPAN::Shell::colorable_makemaker_prompt
2327 sub colorable_makemaker_prompt {
2329 if (CPAN::Shell->colorize_output) {
2330 my $ornament = $CPAN::Config->{colorize_print}||'bold blue';
2331 my $color_on = eval { Term::ANSIColor::color($ornament); } || "";
2334 my $ans = ExtUtils::MakeMaker::prompt($foo,$bar);
2335 if (CPAN::Shell->colorize_output) {
2336 print Term::ANSIColor::color('reset');
2341 # use this only for unrecoverable errors!
2342 sub unrecoverable_error {
2343 my($self,$what) = @_;
2344 my @lines = split /\n/, $what;
2346 for my $l (@lines) {
2347 $longest = length $l if length $l > $longest;
2349 $longest = 62 if $longest > 62;
2350 for my $l (@lines) {
2356 if (length $l < 66) {
2357 $l = pack "A66 A*", $l, "<==";
2361 unshift @lines, "\n";
2362 $self->mydie(join "", @lines);
2366 my($self, $sleep) = @_;
2371 return if -t STDOUT;
2372 my $odef = select STDERR;
2379 #-> sub CPAN::Shell::rematein ;
2380 # RE-adme||MA-ke||TE-st||IN-stall
2383 my($meth,@some) = @_;
2385 while($meth =~ /^(force|notest)$/) {
2386 push @pragma, $meth;
2387 $meth = shift @some or
2388 $CPAN::Frontend->mydie("Pragma $pragma[-1] used without method: ".
2392 CPAN->debug("pragma[@pragma]meth[$meth]some[@some]") if $CPAN::DEBUG;
2394 # Here is the place to set "test_count" on all involved parties to
2395 # 0. We then can pass this counter on to the involved
2396 # distributions and those can refuse to test if test_count > X. In
2397 # the first stab at it we could use a 1 for "X".
2399 # But when do I reset the distributions to start with 0 again?
2400 # Jost suggested to have a random or cycling interaction ID that
2401 # we pass through. But the ID is something that is just left lying
2402 # around in addition to the counter, so I'd prefer to set the
2403 # counter to 0 now, and repeat at the end of the loop. But what
2404 # about dependencies? They appear later and are not reset, they
2405 # enter the queue but not its copy. How do they get a sensible
2408 # construct the queue
2410 STHING: foreach $s (@some) {
2413 CPAN->debug("s is an object[$s]") if $CPAN::DEBUG;
2415 } elsif ($s =~ m|^/|) { # looks like a regexp
2416 $CPAN::Frontend->mywarn("Sorry, $meth with a regular expression is ".
2418 $CPAN::Frontend->mysleep(2);
2420 } elsif ($meth eq "ls") {
2421 $self->globls($s,\@pragma);
2424 CPAN->debug("calling expandany [$s]") if $CPAN::DEBUG;
2425 $obj = CPAN::Shell->expandany($s);
2428 $obj->color_cmd_tmps(0,1);
2429 CPAN::Queue->new($obj->id);
2431 } elsif ($CPAN::META->exists('CPAN::Author',uc($s))) {
2432 $obj = $CPAN::META->instance('CPAN::Author',uc($s));
2433 if ($meth =~ /^(dump|ls)$/) {
2436 $CPAN::Frontend->mywarn(
2438 "Don't be silly, you can't $meth ",
2442 $CPAN::Frontend->mysleep(2);
2446 ->mywarn(qq{Warning: Cannot $meth $s, }.
2447 qq{don\'t know what it is.
2452 to find objects with matching identifiers.
2454 $CPAN::Frontend->mysleep(2);
2458 # queuerunner (please be warned: when I started to change the
2459 # queue to hold objects instead of names, I made one or two
2460 # mistakes and never found which. I reverted back instead)
2461 while ($s = CPAN::Queue->first) {
2464 $obj = $s; # I do not believe, we would survive if this happened
2466 $obj = CPAN::Shell->expandany($s);
2468 for my $pragma (@pragma) {
2471 ($] < 5.00303 || $obj->can($pragma))){
2472 ### compatibility with 5.003
2473 $obj->$pragma($meth); # the pragma "force" in
2474 # "CPAN::Distribution" must know
2475 # what we are intending
2478 if ($]>=5.00303 && $obj->can('called_for')) {
2479 $obj->called_for($s);
2482 qq{pragma[@pragma]meth[$meth]obj[$obj]as_string[$obj->{ID}]}
2486 CPAN::Queue->delete($s);
2488 CPAN->debug("failed");
2492 CPAN::Queue->delete_first($s);
2494 for my $obj (@qcopy) {
2495 $obj->color_cmd_tmps(0,0);
2496 delete $obj->{incommandcolor};
2500 #-> sub CPAN::Shell::recent ;
2504 CPAN::Distribution::_display_url( $self, $CPAN::Defaultrecent );
2509 # set up the dispatching methods
2511 for my $command (qw(
2526 *$command = sub { shift->rematein($command, @_); };
2530 package CPAN::LWP::UserAgent;
2534 return if $SETUPDONE;
2535 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2536 require LWP::UserAgent;
2537 @ISA = qw(Exporter LWP::UserAgent);
2540 $CPAN::Frontend->mywarn(" LWP::UserAgent not available\n");
2544 sub get_basic_credentials {
2545 my($self, $realm, $uri, $proxy) = @_;
2546 if ($USER && $PASSWD) {
2547 return ($USER, $PASSWD);
2550 ($USER,$PASSWD) = $self->get_proxy_credentials();
2552 ($USER,$PASSWD) = $self->get_non_proxy_credentials();
2554 return($USER,$PASSWD);
2557 sub get_proxy_credentials {
2559 my ($user, $password);
2560 if ( defined $CPAN::Config->{proxy_user} &&
2561 defined $CPAN::Config->{proxy_pass}) {
2562 $user = $CPAN::Config->{proxy_user};
2563 $password = $CPAN::Config->{proxy_pass};
2564 return ($user, $password);
2566 my $username_prompt = "\nProxy authentication needed!
2567 (Note: to permanently configure username and password run
2568 o conf proxy_user your_username
2569 o conf proxy_pass your_password
2571 ($user, $password) =
2572 _get_username_and_password_from_user($username_prompt);
2573 return ($user,$password);
2576 sub get_non_proxy_credentials {
2578 my ($user,$password);
2579 if ( defined $CPAN::Config->{username} &&
2580 defined $CPAN::Config->{password}) {
2581 $user = $CPAN::Config->{username};
2582 $password = $CPAN::Config->{password};
2583 return ($user, $password);
2585 my $username_prompt = "\nAuthentication needed!
2586 (Note: to permanently configure username and password run
2587 o conf username your_username
2588 o conf password your_password
2591 ($user, $password) =
2592 _get_username_and_password_from_user($username_prompt);
2593 return ($user,$password);
2596 sub _get_username_and_password_from_user {
2598 my $username_message = shift;
2599 my ($username,$password);
2601 ExtUtils::MakeMaker->import(qw(prompt));
2602 $username = prompt($username_message);
2603 if ($CPAN::META->has_inst("Term::ReadKey")) {
2604 Term::ReadKey::ReadMode("noecho");
2607 $CPAN::Frontend->mywarn(
2608 "Warning: Term::ReadKey seems not to be available, your password will be echoed to the terminal!\n"
2611 $password = prompt("Password:");
2613 if ($CPAN::META->has_inst("Term::ReadKey")) {
2614 Term::ReadKey::ReadMode("restore");
2616 $CPAN::Frontend->myprint("\n\n");
2617 return ($username,$password);
2620 # mirror(): Its purpose is to deal with proxy authentication. When we
2621 # call SUPER::mirror, we relly call the mirror method in
2622 # LWP::UserAgent. LWP::UserAgent will then call
2623 # $self->get_basic_credentials or some equivalent and this will be
2624 # $self->dispatched to our own get_basic_credentials method.
2626 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
2628 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
2629 # although we have gone through our get_basic_credentials, the proxy
2630 # server refuses to connect. This could be a case where the username or
2631 # password has changed in the meantime, so I'm trying once again without
2632 # $USER and $PASSWD to give the get_basic_credentials routine another
2633 # chance to set $USER and $PASSWD.
2635 # mirror(): Its purpose is to deal with proxy authentication. When we
2636 # call SUPER::mirror, we relly call the mirror method in
2637 # LWP::UserAgent. LWP::UserAgent will then call
2638 # $self->get_basic_credentials or some equivalent and this will be
2639 # $self->dispatched to our own get_basic_credentials method.
2641 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
2643 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
2644 # although we have gone through our get_basic_credentials, the proxy
2645 # server refuses to connect. This could be a case where the username or
2646 # password has changed in the meantime, so I'm trying once again without
2647 # $USER and $PASSWD to give the get_basic_credentials routine another
2648 # chance to set $USER and $PASSWD.
2651 my($self,$url,$aslocal) = @_;
2652 my $result = $self->SUPER::mirror($url,$aslocal);
2653 if ($result->code == 407) {
2656 $result = $self->SUPER::mirror($url,$aslocal);
2664 #-> sub CPAN::FTP::ftp_get ;
2666 my($class,$host,$dir,$file,$target) = @_;
2668 qq[Going to fetch file [$file] from dir [$dir]
2669 on host [$host] as local [$target]\n]
2671 my $ftp = Net::FTP->new($host);
2673 $CPAN::Frontend->mywarn(" Could not connect to host '$host' with Net::FTP\n");
2676 return 0 unless defined $ftp;
2677 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
2678 $class->debug(qq[Going to login("anonymous","$Config::Config{cf_email}")]);
2679 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
2680 my $msg = $ftp->message;
2681 $CPAN::Frontend->mywarn(" Couldn't login on $host: $msg");
2684 unless ( $ftp->cwd($dir) ){
2685 my $msg = $ftp->message;
2686 $CPAN::Frontend->mywarn(" Couldn't cwd $dir: $msg");
2690 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
2691 unless ( $ftp->get($file,$target) ){
2692 my $msg = $ftp->message;
2693 $CPAN::Frontend->mywarn(" Couldn't fetch $file from $host: $msg");
2696 $ftp->quit; # it's ok if this fails
2700 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
2702 # > *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
2703 # > --- /tmp/cp Wed Sep 24 13:26:40 1997
2705 # > *** 1562,1567 ****
2706 # > --- 1562,1580 ----
2707 # > return 1 if substr($url,0,4) eq "file";
2708 # > return 1 unless $url =~ m|://([^/]+)|;
2710 # > + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
2712 # > + $proxy =~ m|://([^/:]+)|;
2714 # > + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
2715 # > + if ($noproxy) {
2716 # > + if ($host !~ /$noproxy$/) {
2717 # > + $host = $proxy;
2720 # > + $host = $proxy;
2723 # > require Net::Ping;
2724 # > return 1 unless $Net::Ping::VERSION >= 2;
2728 #-> sub CPAN::FTP::localize ;
2730 my($self,$file,$aslocal,$force) = @_;
2732 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
2733 unless defined $aslocal;
2734 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
2737 if ($^O eq 'MacOS') {
2738 # Comment by AK on 2000-09-03: Uniq short filenames would be
2739 # available in CHECKSUMS file
2740 my($name, $path) = File::Basename::fileparse($aslocal, '');
2741 if (length($name) > 31) {
2752 my $size = 31 - length($suf);
2753 while (length($name) > $size) {
2757 $aslocal = File::Spec->catfile($path, $name);
2761 if (-f $aslocal && -r _ && !($force & 1)){
2763 if ($size = -s $aslocal) {
2764 $self->debug("aslocal[$aslocal]size[$size]") if $CPAN::DEBUG;
2767 # empty file from a previous unsuccessful attempt to download it
2769 $CPAN::Frontend->mydie("Found a zero-length '$aslocal' that I ".
2770 "could not remove.");
2775 rename $aslocal, "$aslocal.bak";
2779 my($aslocal_dir) = File::Basename::dirname($aslocal);
2780 File::Path::mkpath($aslocal_dir);
2781 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
2782 qq{directory "$aslocal_dir".
2783 I\'ll continue, but if you encounter problems, they may be due
2784 to insufficient permissions.\n}) unless -w $aslocal_dir;
2786 # Inheritance is not easier to manage than a few if/else branches
2787 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2789 CPAN::LWP::UserAgent->config;
2790 eval {$Ua = CPAN::LWP::UserAgent->new;}; # Why is has_usable still not fit enough?
2792 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n")
2796 $Ua->proxy('ftp', $var)
2797 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
2798 $Ua->proxy('http', $var)
2799 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
2802 # >>>>> On Wed, 13 Dec 2000 09:21:34 -0500, "Robison, Jonathon (J.M.)" <jrobiso2@visteon.com> said:
2804 # > I note that although CPAN.pm can use proxies, it doesn't seem equipped to
2805 # > use ones that require basic autorization.
2807 # > Example of when I use it manually in my own stuff:
2809 # > $ua->proxy(['http','ftp'], http://my.proxy.server:83');
2810 # > $req->proxy_authorization_basic("username","password");
2811 # > $res = $ua->request($req);
2815 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
2819 for my $prx (qw(ftp_proxy http_proxy no_proxy)) {
2820 $ENV{$prx} = $CPAN::Config->{$prx} if $CPAN::Config->{$prx};
2823 # Try the list of urls for each single object. We keep a record
2824 # where we did get a file from
2825 my(@reordered,$last);
2826 $CPAN::Config->{urllist} ||= [];
2827 unless (ref $CPAN::Config->{urllist} eq 'ARRAY') {
2828 $CPAN::Frontend->mywarn("Malformed urllist; ignoring. Configuration file corrupt?\n");
2829 $CPAN::Config->{urllist} = [];
2831 $last = $#{$CPAN::Config->{urllist}};
2832 if ($force & 2) { # local cpans probably out of date, don't reorder
2833 @reordered = (0..$last);
2837 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
2839 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
2841 defined($ThesiteURL)
2843 ($CPAN::Config->{urllist}[$b] eq $ThesiteURL)
2845 ($CPAN::Config->{urllist}[$a] eq $ThesiteURL)
2850 @levels = ($Themethod, grep {$_ ne $Themethod} qw/easy hard hardest/);
2852 @levels = qw/easy hard hardest/;
2854 @levels = qw/easy/ if $^O eq 'MacOS';
2856 local $ENV{FTP_PASSIVE} =
2857 exists $CPAN::Config->{ftp_passive} ?
2858 $CPAN::Config->{ftp_passive} : 1;
2859 for $levelno (0..$#levels) {
2860 my $level = $levels[$levelno];
2861 my $method = "host$level";
2862 my @host_seq = $level eq "easy" ?
2863 @reordered : 0..$last; # reordered has CDROM up front
2864 my @urllist = map { $CPAN::Config->{urllist}[$_] } @host_seq;
2865 for my $u (@urllist) {
2866 $u .= "/" unless substr($u,-1) eq "/";
2868 for my $u (@CPAN::Defaultsites) {
2869 push @urllist, $u unless grep { $_ eq $u } @urllist;
2871 $self->debug("synth. urllist[@urllist]") if $CPAN::DEBUG;
2872 my $ret = $self->$method(\@urllist,$file,$aslocal);
2874 $Themethod = $level;
2876 # utime $now, $now, $aslocal; # too bad, if we do that, we
2877 # might alter a local mirror
2878 $self->debug("level[$level]") if $CPAN::DEBUG;
2882 last if $CPAN::Signal; # need to cleanup
2885 unless ($CPAN::Signal) {
2888 if (@{$CPAN::Config->{urllist}}) {
2890 qq{Please check, if the URLs I found in your configuration file \(}.
2891 join(", ", @{$CPAN::Config->{urllist}}).
2894 push @mess, qq{Your urllist is empty!};
2896 push @mess, qq{The urllist can be edited.},
2897 qq{E.g. with 'o conf urllist push ftp://myurl/'};
2898 $CPAN::Frontend->mywarn(Text::Wrap::wrap("","","@mess"). "\n\n");
2899 $CPAN::Frontend->mywarn("Could not fetch $file\n");
2900 $CPAN::Frontend->mysleep(2);
2903 rename "$aslocal.bak", $aslocal;
2904 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
2905 $self->ls($aslocal));
2911 # package CPAN::FTP;
2913 my($self,$host_seq,$file,$aslocal) = @_;
2915 HOSTEASY: for $ro_url (@$host_seq) {
2916 my $url .= "$ro_url$file";
2917 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
2918 if ($url =~ /^file:/) {
2920 if ($CPAN::META->has_inst('URI::URL')) {
2921 my $u = URI::URL->new($url);
2923 } else { # works only on Unix, is poorly constructed, but
2924 # hopefully better than nothing.
2925 # RFC 1738 says fileurl BNF is
2926 # fileurl = "file://" [ host | "localhost" ] "/" fpath
2927 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
2929 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
2930 $l =~ s|^file:||; # assume they
2934 if ! -f $l && $l =~ m|^/\w:|; # e.g. /P:
2936 $self->debug("local file[$l]") if $CPAN::DEBUG;
2937 if ( -f $l && -r _) {
2938 $ThesiteURL = $ro_url;
2941 if ($l =~ /(.+)\.gz$/) {
2943 if ( -f $ungz && -r _) {
2944 $ThesiteURL = $ro_url;
2948 # Maybe mirror has compressed it?
2950 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
2951 CPAN::Tarzip->new("$l.gz")->gunzip($aslocal);
2953 $ThesiteURL = $ro_url;
2958 if ($CPAN::META->has_usable('LWP')) {
2959 $CPAN::Frontend->myprint("Fetching with LWP:
2963 CPAN::LWP::UserAgent->config;
2964 eval { $Ua = CPAN::LWP::UserAgent->new; };
2966 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n");
2969 my $res = $Ua->mirror($url, $aslocal);
2970 if ($res->is_success) {
2971 $ThesiteURL = $ro_url;
2973 utime $now, $now, $aslocal; # download time is more
2974 # important than upload time
2976 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2977 my $gzurl = "$url.gz";
2978 $CPAN::Frontend->myprint("Fetching with LWP:
2981 $res = $Ua->mirror($gzurl, "$aslocal.gz");
2982 if ($res->is_success &&
2983 CPAN::Tarzip->new("$aslocal.gz")->gunzip($aslocal)
2985 $ThesiteURL = $ro_url;
2989 $CPAN::Frontend->myprint(sprintf(
2990 "LWP failed with code[%s] message[%s]\n",
2994 # Alan Burlison informed me that in firewall environments
2995 # Net::FTP can still succeed where LWP fails. So we do not
2996 # skip Net::FTP anymore when LWP is available.
2999 $CPAN::Frontend->mywarn(" LWP not available\n");
3001 return if $CPAN::Signal;
3002 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
3003 # that's the nice and easy way thanks to Graham
3004 my($host,$dir,$getfile) = ($1,$2,$3);
3005 if ($CPAN::META->has_usable('Net::FTP')) {
3007 $CPAN::Frontend->myprint("Fetching with Net::FTP:
3010 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
3011 "aslocal[$aslocal]") if $CPAN::DEBUG;
3012 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
3013 $ThesiteURL = $ro_url;
3016 if ($aslocal !~ /\.gz(?!\n)\Z/) {
3017 my $gz = "$aslocal.gz";
3018 $CPAN::Frontend->myprint("Fetching with Net::FTP
3021 if (CPAN::FTP->ftp_get($host,
3025 CPAN::Tarzip->new($gz)->gunzip($aslocal)
3027 $ThesiteURL = $ro_url;
3034 return if $CPAN::Signal;
3038 # package CPAN::FTP;
3040 my($self,$host_seq,$file,$aslocal) = @_;
3042 # Came back if Net::FTP couldn't establish connection (or
3043 # failed otherwise) Maybe they are behind a firewall, but they
3044 # gave us a socksified (or other) ftp program...
3047 my($devnull) = $CPAN::Config->{devnull} || "";
3049 my($aslocal_dir) = File::Basename::dirname($aslocal);
3050 File::Path::mkpath($aslocal_dir);
3051 HOSTHARD: for $ro_url (@$host_seq) {
3052 my $url = "$ro_url$file";
3053 my($proto,$host,$dir,$getfile);
3055 # Courtesy Mark Conty mark_conty@cargill.com change from
3056 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
3058 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
3059 # proto not yet used
3060 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
3062 next HOSTHARD; # who said, we could ftp anything except ftp?
3064 next HOSTHARD if $proto eq "file"; # file URLs would have had
3065 # success above. Likely a bogus URL
3067 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
3069 # Try the most capable first and leave ncftp* for last as it only
3071 DLPRG: for my $f (qw(curl wget lynx ncftpget ncftp)) {
3072 my $funkyftp = CPAN::HandleConfig->safe_quote($CPAN::Config->{$f});
3073 next unless defined $funkyftp;
3074 next if $funkyftp =~ /^\s*$/;
3076 my($asl_ungz, $asl_gz);
3077 ($asl_ungz = $aslocal) =~ s/\.gz//;
3078 $asl_gz = "$asl_ungz.gz";
3080 my($src_switch) = "";
3082 my($stdout_redir) = " > $asl_ungz";
3084 $src_switch = " -source";
3085 } elsif ($f eq "ncftp"){
3086 $src_switch = " -c";
3087 } elsif ($f eq "wget"){
3088 $src_switch = " -O $asl_ungz";
3090 } elsif ($f eq 'curl'){
3091 $src_switch = ' -L -f -s -S --netrc-optional';
3094 if ($f eq "ncftpget"){
3095 $chdir = "cd $aslocal_dir && ";
3098 $CPAN::Frontend->myprint(
3100 Trying with "$funkyftp$src_switch" to get
3104 "$chdir$funkyftp$src_switch \"$url\" $devnull$stdout_redir";
3105 $self->debug("system[$system]") if $CPAN::DEBUG;
3106 my($wstatus) = system($system);
3108 # lynx returns 0 when it fails somewhere
3110 my $content = do { local *FH; open FH, $asl_ungz or die; local $/; <FH> };
3111 if ($content =~ /^<.*<title>[45]/si) {
3112 $CPAN::Frontend->mywarn(qq{
3113 No success, the file that lynx has has downloaded looks like an error message:
3116 $CPAN::Frontend->mysleep(1);
3120 $CPAN::Frontend->myprint(qq{
3121 No success, the file that lynx has has downloaded is an empty file.
3126 if ($wstatus == 0) {
3129 } elsif ($asl_ungz ne $aslocal) {
3130 # test gzip integrity
3131 if (CPAN::Tarzip->new($asl_ungz)->gtest) {
3132 # e.g. foo.tar is gzipped --> foo.tar.gz
3133 rename $asl_ungz, $aslocal;
3135 CPAN::Tarzip->new($asl_gz)->gzip($asl_ungz);
3138 $ThesiteURL = $ro_url;
3140 } elsif ($url !~ /\.gz(?!\n)\Z/) {
3142 -f $asl_ungz && -s _ == 0;
3143 my $gz = "$aslocal.gz";
3144 my $gzurl = "$url.gz";
3145 $CPAN::Frontend->myprint(
3147 Trying with "$funkyftp$src_switch" to get
3150 my($system) = "$funkyftp$src_switch \"$url.gz\" $devnull > $asl_gz";
3151 $self->debug("system[$system]") if $CPAN::DEBUG;
3153 if (($wstatus = system($system)) == 0
3157 # test gzip integrity
3158 my $ct = CPAN::Tarzip->new($asl_gz);
3160 $ct->gunzip($aslocal);
3162 # somebody uncompressed file for us?
3163 rename $asl_ungz, $aslocal;
3165 $ThesiteURL = $ro_url;
3168 unlink $asl_gz if -f $asl_gz;
3171 my $estatus = $wstatus >> 8;
3172 my $size = -f $aslocal ?
3173 ", left\n$aslocal with size ".-s _ :
3174 "\nWarning: expected file [$aslocal] doesn't exist";
3175 $CPAN::Frontend->myprint(qq{
3176 System call "$system"
3177 returned status $estatus (wstat $wstatus)$size
3180 return if $CPAN::Signal;
3181 } # transfer programs
3185 # package CPAN::FTP;
3187 my($self,$host_seq,$file,$aslocal) = @_;
3190 my($aslocal_dir) = File::Basename::dirname($aslocal);
3191 File::Path::mkpath($aslocal_dir);
3192 my $ftpbin = $CPAN::Config->{ftp};
3193 unless (length $ftpbin && MM->maybe_command($ftpbin)) {
3194 $CPAN::Frontend->myprint("No external ftp command available\n\n");
3197 $CPAN::Frontend->mywarn(qq{
3198 As a last ressort we now switch to the external ftp command '$ftpbin'
3201 Doing so often leads to problems that are hard to diagnose.
3203 If you're victim of such problems, please consider unsetting the ftp
3204 config variable with
3210 $CPAN::Frontend->mysleep(2);
3211 HOSTHARDEST: for $ro_url (@$host_seq) {
3212 my $url = "$ro_url$file";
3213 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
3214 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
3217 my($host,$dir,$getfile) = ($1,$2,$3);
3219 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
3220 $ctime,$blksize,$blocks) = stat($aslocal);
3221 $timestamp = $mtime ||= 0;
3222 my($netrc) = CPAN::FTP::netrc->new;
3223 my($netrcfile) = $netrc->netrc;
3224 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
3225 my $targetfile = File::Basename::basename($aslocal);
3231 map("cd $_", split /\//, $dir), # RFC 1738
3233 "get $getfile $targetfile",
3237 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
3238 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
3239 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
3241 $netrc->contains($host))) if $CPAN::DEBUG;
3242 if ($netrc->protected) {
3243 my $dialog = join "", map { " $_\n" } @dialog;
3245 if ($netrc->contains($host)) {
3246 $netrc_explain = "Relying that your .netrc entry for '$host' ".
3247 "manages the login";
3249 $netrc_explain = "Relying that your default .netrc entry ".
3250 "manages the login";
3252 $CPAN::Frontend->myprint(qq{
3253 Trying with external ftp to get
3256 Going to send the dialog
3260 $self->talk_ftp("$ftpbin$verbose $host",
3262 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3263 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
3265 if ($mtime > $timestamp) {
3266 $CPAN::Frontend->myprint("GOT $aslocal\n");
3267 $ThesiteURL = $ro_url;
3270 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
3272 return if $CPAN::Signal;
3274 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
3275 qq{correctly protected.\n});
3278 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
3279 nor does it have a default entry\n");
3282 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
3283 # then and login manually to host, using e-mail as
3285 $CPAN::Frontend->myprint(qq{Issuing "$ftpbin$verbose -n"\n});
3289 "user anonymous $Config::Config{'cf_email'}"
3291 my $dialog = join "", map { " $_\n" } @dialog;
3292 $CPAN::Frontend->myprint(qq{
3293 Trying with external ftp to get
3295 Going to send the dialog
3299 $self->talk_ftp("$ftpbin$verbose -n", @dialog);
3300 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3301 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
3303 if ($mtime > $timestamp) {
3304 $CPAN::Frontend->myprint("GOT $aslocal\n");
3305 $ThesiteURL = $ro_url;
3308 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
3310 return if $CPAN::Signal;
3311 $CPAN::Frontend->mywarn("Can't access URL $url.\n\n");
3312 $CPAN::Frontend->mysleep(2);
3316 # package CPAN::FTP;
3318 my($self,$command,@dialog) = @_;
3319 my $fh = FileHandle->new;
3320 $fh->open("|$command") or die "Couldn't open ftp: $!";
3321 foreach (@dialog) { $fh->print("$_\n") }
3322 $fh->close; # Wait for process to complete
3324 my $estatus = $wstatus >> 8;
3325 $CPAN::Frontend->myprint(qq{
3326 Subprocess "|$command"
3327 returned status $estatus (wstat $wstatus)
3331 # find2perl needs modularization, too, all the following is stolen
3335 my($self,$name) = @_;
3336 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
3337 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
3339 my($perms,%user,%group);
3343 $blocks = int(($blocks + 1) / 2);
3346 $blocks = int(($sizemm + 1023) / 1024);
3349 if (-f _) { $perms = '-'; }
3350 elsif (-d _) { $perms = 'd'; }
3351 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
3352 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
3353 elsif (-p _) { $perms = 'p'; }
3354 elsif (-S _) { $perms = 's'; }
3355 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
3357 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
3358 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
3359 my $tmpmode = $mode;
3360 my $tmp = $rwx[$tmpmode & 7];
3362 $tmp = $rwx[$tmpmode & 7] . $tmp;
3364 $tmp = $rwx[$tmpmode & 7] . $tmp;
3365 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
3366 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
3367 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
3370 my $user = $user{$uid} || $uid; # too lazy to implement lookup
3371 my $group = $group{$gid} || $gid;
3373 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
3375 my($moname) = $moname[$mon];
3376 if (-M _ > 365.25 / 2) {
3377 $timeyear = $year + 1900;
3380 $timeyear = sprintf("%02d:%02d", $hour, $min);
3383 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
3397 package CPAN::FTP::netrc;
3400 # package CPAN::FTP::netrc;
3403 my $home = CPAN::HandleConfig::home;
3404 my $file = File::Spec->catfile($home,".netrc");
3406 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3407 $atime,$mtime,$ctime,$blksize,$blocks)
3412 my($fh,@machines,$hasdefault);
3414 $fh = FileHandle->new or die "Could not create a filehandle";
3416 if($fh->open($file)){
3417 $protected = ($mode & 077) == 0;
3419 NETRC: while (<$fh>) {
3420 my(@tokens) = split " ", $_;
3421 TOKEN: while (@tokens) {
3422 my($t) = shift @tokens;
3423 if ($t eq "default"){
3427 last TOKEN if $t eq "macdef";
3428 if ($t eq "machine") {
3429 push @machines, shift @tokens;
3434 $file = $hasdefault = $protected = "";
3438 'mach' => [@machines],
3440 'hasdefault' => $hasdefault,
3441 'protected' => $protected,
3445 # CPAN::FTP::netrc::hasdefault;
3446 sub hasdefault { shift->{'hasdefault'} }
3447 sub netrc { shift->{'netrc'} }
3448 sub protected { shift->{'protected'} }
3450 my($self,$mach) = @_;
3451 for ( @{$self->{'mach'}} ) {
3452 return 1 if $_ eq $mach;
3457 package CPAN::Complete;
3461 my($text, $line, $start, $end) = @_;
3462 my(@perlret) = cpl($text, $line, $start);
3463 # find longest common match. Can anybody show me how to peruse
3464 # T::R::Gnu to have this done automatically? Seems expensive.
3465 return () unless @perlret;
3466 my($newtext) = $text;
3467 for (my $i = length($text)+1;;$i++) {
3468 last unless length($perlret[0]) && length($perlret[0]) >= $i;
3469 my $try = substr($perlret[0],0,$i);
3470 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
3471 # warn "try[$try]tries[@tries]";
3472 if (@tries == @perlret) {
3478 ($newtext,@perlret);
3481 #-> sub CPAN::Complete::cpl ;
3483 my($word,$line,$pos) = @_;
3487 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3489 if ($line =~ s/^(force\s*)//) {
3494 @return = grep /^$word/, @CPAN::Complete::COMMANDS;
3495 } elsif ( $line !~ /^[\!abcdghimorutl]/ ) {
3497 } elsif ($line =~ /^(a|ls)\s/) {
3498 @return = cplx('CPAN::Author',uc($word));
3499 } elsif ($line =~ /^b\s/) {
3500 CPAN::Shell->local_bundles;
3501 @return = cplx('CPAN::Bundle',$word);
3502 } elsif ($line =~ /^d\s/) {
3503 @return = cplx('CPAN::Distribution',$word);
3504 } elsif ($line =~ m/^(
3505 [mru]|make|clean|dump|get|test|install|readme|look|cvs_import|perldoc|recent
3507 if ($word =~ /^Bundle::/) {
3508 CPAN::Shell->local_bundles;
3510 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
3511 } elsif ($line =~ /^i\s/) {
3512 @return = cpl_any($word);
3513 } elsif ($line =~ /^reload\s/) {
3514 @return = cpl_reload($word,$line,$pos);
3515 } elsif ($line =~ /^o\s/) {
3516 @return = cpl_option($word,$line,$pos);
3517 } elsif ($line =~ m/^\S+\s/ ) {
3518 # fallback for future commands and what we have forgotten above
3519 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
3526 #-> sub CPAN::Complete::cplx ;
3528 my($class, $word) = @_;
3529 # I believed for many years that this was sorted, today I
3530 # realized, it wasn't sorted anymore. Now (rev 1.301 / v 1.55) I
3531 # make it sorted again. Maybe sort was dropped when GNU-readline
3532 # support came in? The RCS file is difficult to read on that:-(
3533 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
3536 #-> sub CPAN::Complete::cpl_any ;
3540 cplx('CPAN::Author',$word),
3541 cplx('CPAN::Bundle',$word),
3542 cplx('CPAN::Distribution',$word),
3543 cplx('CPAN::Module',$word),
3547 #-> sub CPAN::Complete::cpl_reload ;
3549 my($word,$line,$pos) = @_;
3551 my(@words) = split " ", $line;
3552 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3553 my(@ok) = qw(cpan index);
3554 return @ok if @words == 1;
3555 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
3558 #-> sub CPAN::Complete::cpl_option ;
3560 my($word,$line,$pos) = @_;
3562 my(@words) = split " ", $line;
3563 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3564 my(@ok) = qw(conf debug);
3565 return @ok if @words == 1;
3566 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
3568 } elsif ($words[1] eq 'index') {
3570 } elsif ($words[1] eq 'conf') {
3571 return CPAN::HandleConfig::cpl(@_);
3572 } elsif ($words[1] eq 'debug') {
3573 return sort grep /^\Q$word\E/i,
3574 sort keys %CPAN::DEBUG, 'all';
3578 package CPAN::Index;
3581 #-> sub CPAN::Index::force_reload ;
3584 $CPAN::Index::LAST_TIME = 0;
3588 #-> sub CPAN::Index::reload ;
3590 my($cl,$force) = @_;
3593 # XXX check if a newer one is available. (We currently read it
3594 # from time to time)
3595 for ($CPAN::Config->{index_expire}) {
3596 $_ = 0.001 unless $_ && $_ > 0.001;
3598 unless (1 || $CPAN::Have_warned->{readmetadatacache}++) {
3599 # debug here when CPAN doesn't seem to read the Metadata
3601 Carp::cluck("META-PROTOCOL[$CPAN::META->{PROTOCOL}]");
3603 unless ($CPAN::META->{PROTOCOL}) {
3604 $cl->read_metadata_cache;
3605 $CPAN::META->{PROTOCOL} ||= "1.0";
3607 if ( $CPAN::META->{PROTOCOL} < PROTOCOL ) {
3608 # warn "Setting last_time to 0";
3609 $LAST_TIME = 0; # No warning necessary
3611 return if $LAST_TIME + $CPAN::Config->{index_expire}*86400 > $time
3614 # IFF we are developing, it helps to wipe out the memory
3615 # between reloads, otherwise it is not what a user expects.
3616 undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
3617 $CPAN::META = CPAN->new;
3621 local $LAST_TIME = $time;
3622 local $CPAN::META->{PROTOCOL} = PROTOCOL;
3624 my $needshort = $^O eq "dos";
3626 $cl->rd_authindex($cl
3628 "authors/01mailrc.txt.gz",
3630 File::Spec->catfile('authors', '01mailrc.gz') :
3631 File::Spec->catfile('authors', '01mailrc.txt.gz'),
3634 $debug = "timing reading 01[".($t2 - $time)."]";
3636 return if $CPAN::Signal; # this is sometimes lengthy
3637 $cl->rd_modpacks($cl
3639 "modules/02packages.details.txt.gz",
3641 File::Spec->catfile('modules', '02packag.gz') :
3642 File::Spec->catfile('modules', '02packages.details.txt.gz'),
3645 $debug .= "02[".($t2 - $time)."]";
3647 return if $CPAN::Signal; # this is sometimes lengthy
3650 "modules/03modlist.data.gz",
3652 File::Spec->catfile('modules', '03mlist.gz') :
3653 File::Spec->catfile('modules', '03modlist.data.gz'),
3655 $cl->write_metadata_cache;
3657 $debug .= "03[".($t2 - $time)."]";
3659 CPAN->debug($debug) if $CPAN::DEBUG;
3662 $CPAN::META->{PROTOCOL} = PROTOCOL;
3665 #-> sub CPAN::Index::reload_x ;
3667 my($cl,$wanted,$localname,$force) = @_;
3668 $force |= 2; # means we're dealing with an index here
3669 CPAN::HandleConfig->load; # we should guarantee loading wherever we rely
3671 $localname ||= $wanted;
3672 my $abs_wanted = File::Spec->catfile($CPAN::Config->{'keep_source_where'},
3676 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
3679 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
3680 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
3681 qq{day$s. I\'ll use that.});
3684 $force |= 1; # means we're quite serious about it.
3686 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
3689 #-> sub CPAN::Index::rd_authindex ;
3691 my($cl, $index_target) = @_;
3693 return unless defined $index_target;
3694 $CPAN::Frontend->myprint("Going to read $index_target\n");
3696 tie *FH, 'CPAN::Tarzip', $index_target;
3699 push @lines, split /\012/ while <FH>;
3701 my($userid,$fullname,$email) =
3702 m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
3703 next unless $userid && $fullname && $email;
3705 # instantiate an author object
3706 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
3707 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
3708 return if $CPAN::Signal;
3713 my($self,$dist) = @_;
3714 $dist = $self->{'id'} unless defined $dist;
3715 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
3719 #-> sub CPAN::Index::rd_modpacks ;
3721 my($self, $index_target) = @_;
3723 return unless defined $index_target;
3724 $CPAN::Frontend->myprint("Going to read $index_target\n");
3725 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3728 while ($_ = $fh->READLINE) {
3730 my @ls = map {"$_\n"} split /\n/, $_;
3731 unshift @ls, "\n" x length($1) if /^(\n+)/;
3735 my($line_count,$last_updated);
3737 my $shift = shift(@lines);
3738 last if $shift =~ /^\s*$/;
3739 $shift =~ /^Line-Count:\s+(\d+)/ and $line_count = $1;
3740 $shift =~ /^Last-Updated:\s+(.+)/ and $last_updated = $1;
3742 if (not defined $line_count) {
3744 $CPAN::Frontend->mywarn(qq{Warning: Your $index_target does not contain a Line-Count header.
3745 Please check the validity of the index file by comparing it to more
3746 than one CPAN mirror. I'll continue but problems seem likely to
3750 $CPAN::Frontend->mysleep(5);
3751 } elsif ($line_count != scalar @lines) {
3753 warn sprintf qq{Warning: Your %s
3754 contains a Line-Count header of %d but I see %d lines there. Please
3755 check the validity of the index file by comparing it to more than one
3756 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
3757 $index_target, $line_count, scalar(@lines);
3760 if (not defined $last_updated) {
3762 $CPAN::Frontend->mywarn(qq{Warning: Your $index_target does not contain a Last-Updated header.
3763 Please check the validity of the index file by comparing it to more
3764 than one CPAN mirror. I'll continue but problems seem likely to
3768 $CPAN::Frontend->mysleep(5);
3772 ->myprint(sprintf qq{ Database was generated on %s\n},
3774 $DATE_OF_02 = $last_updated;
3777 if ($CPAN::META->has_inst('HTTP::Date')) {
3779 $age -= HTTP::Date::str2time($last_updated);
3781 $CPAN::Frontend->mywarn(" HTTP::Date not available\n");
3782 require Time::Local;
3783 my(@d) = $last_updated =~ / (\d+) (\w+) (\d+) (\d+):(\d+):(\d+) /;
3784 $d[1] = index("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", $d[1])/4;
3785 $age -= $d[1]>=0 ? Time::Local::timegm(@d[5,4,3,0,1,2]) : 0;
3792 qq{Warning: This index file is %d days old.
3793 Please check the host you chose as your CPAN mirror for staleness.
3794 I'll continue but problems seem likely to happen.\a\n},
3797 } elsif ($age < -1) {
3801 qq{Warning: Your system date is %d days behind this index file!
3803 Timestamp index file: %s
3804 Please fix your system time, problems with the make command expected.\n},
3814 # A necessity since we have metadata_cache: delete what isn't
3816 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
3817 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
3821 # before 1.56 we split into 3 and discarded the rest. From
3822 # 1.57 we assign remaining text to $comment thus allowing to
3823 # influence isa_perl
3824 my($mod,$version,$dist,$comment) = split " ", $_, 4;
3825 my($bundle,$id,$userid);
3827 if ($mod eq 'CPAN' &&
3829 CPAN::Queue->exists('Bundle::CPAN') ||
3830 CPAN::Queue->exists('CPAN')
3834 if ($version > $CPAN::VERSION){
3835 $CPAN::Frontend->mywarn(qq{
3836 New CPAN.pm version (v$version) available.
3837 [Currently running version is v$CPAN::VERSION]
3838 You might want to try
3841 to both upgrade CPAN.pm and run the new version without leaving
3842 the current session.
3845 $CPAN::Frontend->mysleep(2);
3846 $CPAN::Frontend->myprint(qq{\n});
3848 last if $CPAN::Signal;
3849 } elsif ($mod =~ /^Bundle::(.*)/) {
3854 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
3855 # Let's make it a module too, because bundles have so much
3856 # in common with modules.
3858 # Changed in 1.57_63: seems like memory bloat now without
3859 # any value, so commented out
3861 # $CPAN::META->instance('CPAN::Module',$mod);
3865 # instantiate a module object
3866 $id = $CPAN::META->instance('CPAN::Module',$mod);
3870 # Although CPAN prohibits same name with different version the
3871 # indexer may have changed the version for the same distro
3872 # since the last time ("Force Reindexing" feature)
3873 if ($id->cpan_file ne $dist
3875 $id->cpan_version ne $version
3877 $userid = $id->userid || $self->userid($dist);
3879 'CPAN_USERID' => $userid,
3880 'CPAN_VERSION' => $version,
3881 'CPAN_FILE' => $dist,
3885 # instantiate a distribution object
3886 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
3887 # we do not need CONTAINSMODS unless we do something with
3888 # this dist, so we better produce it on demand.
3890 ## my $obj = $CPAN::META->instance(
3891 ## 'CPAN::Distribution' => $dist
3893 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
3895 $CPAN::META->instance(
3896 'CPAN::Distribution' => $dist
3898 'CPAN_USERID' => $userid,
3899 'CPAN_COMMENT' => $comment,
3903 for my $name ($mod,$dist) {
3904 CPAN->debug("exists name[$name]") if $CPAN::DEBUG;
3905 $exists{$name} = undef;
3908 return if $CPAN::Signal;
3912 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
3913 for my $o ($CPAN::META->all_objects($class)) {
3914 next if exists $exists{$o->{ID}};
3915 $CPAN::META->delete($class,$o->{ID});
3916 CPAN->debug("deleting ID[$o->{ID}] in class[$class]")
3923 #-> sub CPAN::Index::rd_modlist ;
3925 my($cl,$index_target) = @_;
3926 return unless defined $index_target;
3927 $CPAN::Frontend->myprint("Going to read $index_target\n");
3928 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3932 while ($_ = $fh->READLINE) {
3934 my @ls = map {"$_\n"} split /\n/, $_;
3935 unshift @ls, "\n" x length($1) if /^(\n+)/;
3939 my $shift = shift(@eval);
3940 if ($shift =~ /^Date:\s+(.*)/){
3941 return if $DATE_OF_03 eq $1;
3944 last if $shift =~ /^\s*$/;
3947 push @eval, q{CPAN::Modulelist->data;};
3949 my($comp) = Safe->new("CPAN::Safe1");
3950 my($eval) = join("", @eval);
3951 my $ret = $comp->reval($eval);
3952 Carp::confess($@) if $@;
3953 return if $CPAN::Signal;
3955 my $obj = $CPAN::META->instance("CPAN::Module",$_);
3956 delete $ret->{$_}{modid}; # not needed here, maybe elsewhere
3957 $obj->set(%{$ret->{$_}});
3958 return if $CPAN::Signal;
3962 #-> sub CPAN::Index::write_metadata_cache ;
3963 sub write_metadata_cache {
3965 return unless $CPAN::Config->{'cache_metadata'};
3966 return unless $CPAN::META->has_usable("Storable");
3968 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
3969 CPAN::Distribution)) {
3970 $cache->{$k} = $CPAN::META->{readonly}{$k}; # unsafe meta access, ok
3972 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3973 $cache->{last_time} = $LAST_TIME;
3974 $cache->{DATE_OF_02} = $DATE_OF_02;
3975 $cache->{PROTOCOL} = PROTOCOL;
3976 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
3977 eval { Storable::nstore($cache, $metadata_file) };
3978 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
3981 #-> sub CPAN::Index::read_metadata_cache ;
3982 sub read_metadata_cache {
3984 return unless $CPAN::Config->{'cache_metadata'};
3985 return unless $CPAN::META->has_usable("Storable");
3986 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3987 return unless -r $metadata_file and -f $metadata_file;
3988 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
3990 eval { $cache = Storable::retrieve($metadata_file) };
3991 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
3992 if (!$cache || ref $cache ne 'HASH'){
3996 if (exists $cache->{PROTOCOL}) {
3997 if (PROTOCOL > $cache->{PROTOCOL}) {
3998 $CPAN::Frontend->mywarn(sprintf("Ignoring Metadata cache written ".
3999 "with protocol v%s, requiring v%s\n",
4006 $CPAN::Frontend->mywarn("Ignoring Metadata cache written ".
4007 "with protocol v1.0\n");
4012 while(my($class,$v) = each %$cache) {
4013 next unless $class =~ /^CPAN::/;
4014 $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok
4015 while (my($id,$ro) = each %$v) {
4016 $CPAN::META->{readwrite}{$class}{$id} ||=
4017 $class->new(ID=>$id, RO=>$ro);
4022 unless ($clcnt) { # sanity check
4023 $CPAN::Frontend->myprint("Warning: Found no data in $metadata_file\n");
4026 if ($idcnt < 1000) {
4027 $CPAN::Frontend->myprint("Warning: Found only $idcnt objects ".
4028 "in $metadata_file\n");
4031 $CPAN::META->{PROTOCOL} ||=
4032 $cache->{PROTOCOL}; # reading does not up or downgrade, but it
4033 # does initialize to some protocol
4034 $LAST_TIME = $cache->{last_time};
4035 $DATE_OF_02 = $cache->{DATE_OF_02};
4036 $CPAN::Frontend->myprint(" Database was generated on $DATE_OF_02\n")
4037 if defined $DATE_OF_02; # An old cache may not contain DATE_OF_02
4041 package CPAN::InfoObj;
4046 exists $self->{RO} and return $self->{RO};
4051 my $ro = $self->ro or return "N/A"; # N/A for bundles found locally
4052 return $ro->{CPAN_USERID} || "N/A";
4055 sub id { shift->{ID}; }
4057 #-> sub CPAN::InfoObj::new ;
4059 my $this = bless {}, shift;
4064 # The set method may only be used by code that reads index data or
4065 # otherwise "objective" data from the outside world. All session
4066 # related material may do anything else with instance variables but
4067 # must not touch the hash under the RO attribute. The reason is that
4068 # the RO hash gets written to Metadata file and is thus persistent.
4070 #-> sub CPAN::InfoObj::safe_chdir ;
4072 my($self,$todir) = @_;
4073 # we die if we cannot chdir and we are debuggable
4074 Carp::confess("safe_chdir called without todir argument")
4075 unless defined $todir and length $todir;
4077 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
4081 unless (-x $todir) {
4082 unless (chmod 0755, $todir) {
4083 my $cwd = CPAN::anycwd();
4084 $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
4085 "permission to change the permission; cannot ".
4086 "chdir to '$todir'\n");
4087 $CPAN::Frontend->mysleep(5);
4088 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
4089 qq{to todir[$todir]: $!});
4093 $CPAN::Frontend->mydie("Directory '$todir' has gone. Cannot continue.\n");
4096 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
4099 my $cwd = CPAN::anycwd();
4100 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
4101 qq{to todir[$todir] (a chmod has been issued): $!});
4106 #-> sub CPAN::InfoObj::set ;
4108 my($self,%att) = @_;
4109 my $class = ref $self;
4111 # This must be ||=, not ||, because only if we write an empty
4112 # reference, only then the set method will write into the readonly
4113 # area. But for Distributions that spring into existence, maybe
4114 # because of a typo, we do not like it that they are written into
4115 # the readonly area and made permanent (at least for a while) and
4116 # that is why we do not "allow" other places to call ->set.
4117 unless ($self->id) {
4118 CPAN->debug("Bug? Empty ID, rejecting");
4121 my $ro = $self->{RO} =
4122 $CPAN::META->{readonly}{$class}{$self->id} ||= {};
4124 while (my($k,$v) = each %att) {
4129 #-> sub CPAN::InfoObj::as_glimpse ;
4133 my $class = ref($self);
4134 $class =~ s/^CPAN:://;
4135 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
4139 #-> sub CPAN::InfoObj::as_string ;
4143 my $class = ref($self);
4144 $class =~ s/^CPAN:://;
4145 push @m, $class, " id = $self->{ID}\n";
4147 unless ($ro = $self->ro) {
4148 $CPAN::Frontend->mydie("Unknown object $self->{ID}");
4150 for (sort keys %$ro) {
4151 # next if m/^(ID|RO)$/;
4153 if ($_ eq "CPAN_USERID") {
4155 $extra .= $self->fullname;
4156 my $email; # old perls!
4157 if ($email = $CPAN::META->instance("CPAN::Author",
4160 $extra .= " <$email>";
4162 $extra .= " <no email>";
4165 } elsif ($_ eq "FULLNAME") { # potential UTF-8 conversion
4166 push @m, sprintf " %-12s %s\n", $_, $self->fullname;
4169 next unless defined $ro->{$_};
4170 push @m, sprintf " %-12s %s%s\n", $_, $ro->{$_}, $extra;
4172 for (sort keys %$self) {
4173 next if m/^(ID|RO)$/;
4174 if (ref($self->{$_}) eq "ARRAY") {
4175 push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
4176 } elsif (ref($self->{$_}) eq "HASH") {
4180 join(" ",sort keys %{$self->{$_}}),
4183 push @m, sprintf " %-12s %s\n", $_, $self->{$_};
4189 #-> sub CPAN::InfoObj::fullname ;
4192 $CPAN::META->instance("CPAN::Author",$self->cpan_userid)->fullname;
4195 #-> sub CPAN::InfoObj::dump ;
4198 unless ($CPAN::META->has_inst("Data::Dumper")) {
4199 $CPAN::Frontend->mydie("dump command requires Data::Dumper installed");
4201 local $Data::Dumper::Sortkeys;
4202 $Data::Dumper::Sortkeys = 1;
4203 $CPAN::Frontend->myprint(Data::Dumper::Dumper($self));
4206 package CPAN::Author;
4209 #-> sub CPAN::Author::force
4215 #-> sub CPAN::Author::force
4218 delete $self->{force};
4221 #-> sub CPAN::Author::id
4224 my $id = $self->{ID};
4225 $CPAN::Frontend->mydie("Illegal author id[$id]") unless $id =~ /^[A-Z]/;
4229 #-> sub CPAN::Author::as_glimpse ;
4233 my $class = ref($self);
4234 $class =~ s/^CPAN:://;
4235 push @m, sprintf(qq{%-15s %s ("%s" <%s>)\n},
4243 #-> sub CPAN::Author::fullname ;
4245 shift->ro->{FULLNAME};
4249 #-> sub CPAN::Author::email ;
4250 sub email { shift->ro->{EMAIL}; }
4252 #-> sub CPAN::Author::ls ;
4255 my $glob = shift || "";
4256 my $silent = shift || 0;
4259 # adapted from CPAN::Distribution::verifyCHECKSUM ;
4260 my(@csf); # chksumfile
4261 @csf = $self->id =~ /(.)(.)(.*)/;
4262 $csf[1] = join "", @csf[0,1];
4263 $csf[2] = join "", @csf[1,2]; # ("A","AN","ANDK")
4265 @dl = $self->dir_listing([$csf[0],"CHECKSUMS"], 0, 1);
4266 unless (grep {$_->[2] eq $csf[1]} @dl) {
4267 $CPAN::Frontend->myprint("Directory $csf[1]/ does not exist\n") unless $silent ;
4270 @dl = $self->dir_listing([@csf[0,1],"CHECKSUMS"], 0, 1);
4271 unless (grep {$_->[2] eq $csf[2]} @dl) {
4272 $CPAN::Frontend->myprint("Directory $id/ does not exist\n") unless $silent;
4275 @dl = $self->dir_listing([@csf,"CHECKSUMS"], 1, 1);
4277 if ($CPAN::META->has_inst("Text::Glob")) {
4278 my $rglob = Text::Glob::glob_to_regex($glob);
4279 @dl = grep { $_->[2] =~ /$rglob/ } @dl;
4281 $CPAN::Frontend->mydie("Text::Glob not installed, cannot proceed");
4284 $CPAN::Frontend->myprint(join "", map {
4285 sprintf("%8d %10s %s/%s\n", $_->[0], $_->[1], $id, $_->[2])
4286 } sort { $a->[2] cmp $b->[2] } @dl);
4290 # returns an array of arrays, the latter contain (size,mtime,filename)
4291 #-> sub CPAN::Author::dir_listing ;
4294 my $chksumfile = shift;
4295 my $recursive = shift;
4296 my $may_ftp = shift;
4299 File::Spec->catfile($CPAN::Config->{keep_source_where},
4300 "authors", "id", @$chksumfile);
4304 # Purge and refetch old (pre-PGP) CHECKSUMS; they are a security
4305 # hazard. (Without GPG installed they are not that much better,
4307 $fh = FileHandle->new;
4308 if (open($fh, $lc_want)) {
4309 my $line = <$fh>; close $fh;
4310 unlink($lc_want) unless $line =~ /PGP/;
4314 # connect "force" argument with "index_expire".
4315 my $force = $self->{force};
4316 if (my @stat = stat $lc_want) {
4317 $force ||= $stat[9] + $CPAN::Config->{index_expire}*86400 <= time;
4321 $lc_file = CPAN::FTP->localize(
4322 "authors/id/@$chksumfile",
4327 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
4328 $chksumfile->[-1] .= ".gz";
4329 $lc_file = CPAN::FTP->localize("authors/id/@$chksumfile",
4332 $lc_file =~ s{\.gz(?!\n)\Z}{}; #};
4333 CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file);
4339 $lc_file = $lc_want;
4340 # we *could* second-guess and if the user has a file: URL,
4341 # then we could look there. But on the other hand, if they do
4342 # have a file: URL, wy did they choose to set
4343 # $CPAN::Config->{show_upload_date} to false?
4346 # adapted from CPAN::Distribution::CHECKSUM_check_file ;
4347 $fh = FileHandle->new;
4349 if (open $fh, $lc_file){
4352 $eval =~ s/\015?\012/\n/g;
4354 my($comp) = Safe->new();
4355 $cksum = $comp->reval($eval);
4357 rename $lc_file, "$lc_file.bad";
4358 Carp::confess($@) if $@;
4360 } elsif ($may_ftp) {
4361 Carp::carp "Could not open '$lc_file' for reading.";
4363 # Maybe should warn: "You may want to set show_upload_date to a true value"
4367 for $f (sort keys %$cksum) {
4368 if (exists $cksum->{$f}{isdir}) {
4370 my(@dir) = @$chksumfile;
4372 push @dir, $f, "CHECKSUMS";
4374 [$_->[0], $_->[1], "$f/$_->[2]"]
4375 } $self->dir_listing(\@dir,1,$may_ftp);
4377 push @result, [ 0, "-", $f ];
4381 ($cksum->{$f}{"size"}||0),
4382 $cksum->{$f}{"mtime"}||"---",
4390 package CPAN::Distribution;
4396 my $ro = $self->ro or return;
4400 # CPAN::Distribution::undelay
4403 delete $self->{later};
4406 # add the A/AN/ stuff
4407 # CPAN::Distribution::normalize
4410 $s = $self->id unless defined $s;
4414 $s !~ m|[A-Z]/[A-Z-]{2}/[A-Z-]{2,}/|
4416 return $s if $s =~ m:^N/A|^Contact Author: ;
4417 $s =~ s|^(.)(.)([^/]*/)(.+)$|$1/$1$2/$1$2$3$4| or
4418 $CPAN::Frontend->mywarn("Strange distribution name [$s]\n");
4419 CPAN->debug("s[$s]") if $CPAN::DEBUG;
4424 #-> sub CPAN::Distribution::author ;
4427 my($authorid) = $self->pretty_id =~ /^([\w\-]+)/;
4428 CPAN::Shell->expand("Author",$authorid);
4431 # tries to get the yaml from CPAN instead of the distro itself:
4432 # EXPERIMENTAL, UNDOCUMENTED AND UNTESTED, for Tels
4435 my $meta = $self->pretty_id;
4436 $meta =~ s/\.(tar.gz|tgz|zip|tar.bz2)/.meta/;
4437 my(@ls) = CPAN::Shell->globls($meta);
4438 my $norm = $self->normalize($meta);
4442 File::Spec->catfile(
4443 $CPAN::Config->{keep_source_where},
4448 $self->debug("Doing localize") if $CPAN::DEBUG;
4449 unless ($local_file =
4450 CPAN::FTP->localize("authors/id/$norm",
4452 $CPAN::Frontend->mydie("Giving up on downloading yaml file '$local_wanted'\n");
4454 if ($CPAN::META->has_inst("YAML")) {
4455 my $yaml = YAML::LoadFile($local_file);
4458 $CPAN::Frontend->mydie("Yaml not installed, cannot parse '$local_file'\n");
4465 return $id unless $id =~ m|^./../|;
4469 # mark as dirty/clean
4470 #-> sub CPAN::Distribution::color_cmd_tmps ;
4471 sub color_cmd_tmps {
4473 my($depth) = shift || 0;
4474 my($color) = shift || 0;
4475 my($ancestors) = shift || [];
4476 # a distribution needs to recurse into its prereq_pms
4478 return if exists $self->{incommandcolor}
4479 && $self->{incommandcolor}==$color;
4481 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
4483 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
4484 my $prereq_pm = $self->prereq_pm;
4485 if (defined $prereq_pm) {
4486 PREREQ: for my $pre (keys %$prereq_pm) {
4488 unless ($premo = CPAN::Shell->expand("Module",$pre)) {
4489 $CPAN::Frontend->mywarn("prerequisite module[$pre] not known\n");
4490 $CPAN::Frontend->mysleep(2);
4493 $premo->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
4497 delete $self->{sponsored_mods};
4498 delete $self->{badtestcnt};
4500 $self->{incommandcolor} = $color;
4503 #-> sub CPAN::Distribution::as_string ;
4506 $self->containsmods;
4508 $self->SUPER::as_string(@_);
4511 #-> sub CPAN::Distribution::containsmods ;
4514 return keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
4515 my $dist_id = $self->{ID};
4516 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
4517 my $mod_file = $mod->cpan_file or next;
4518 my $mod_id = $mod->{ID} or next;
4519 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
4521 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
4523 keys %{$self->{CONTAINSMODS}};
4526 #-> sub CPAN::Distribution::upload_date ;
4529 return $self->{UPLOAD_DATE} if exists $self->{UPLOAD_DATE};
4530 my(@local_wanted) = split(/\//,$self->id);
4531 my $filename = pop @local_wanted;
4532 push @local_wanted, "CHECKSUMS";
4533 my $author = CPAN::Shell->expand("Author",$self->cpan_userid);
4534 return unless $author;
4535 my @dl = $author->dir_listing(\@local_wanted,0,$CPAN::Config->{show_upload_date});
4537 my($dirent) = grep { $_->[2] eq $filename } @dl;
4538 # warn sprintf "dirent[%s]id[%s]", $dirent, $self->id;
4539 return unless $dirent->[1];
4540 return $self->{UPLOAD_DATE} = $dirent->[1];
4543 #-> sub CPAN::Distribution::uptodate ;
4547 foreach $c ($self->containsmods) {
4548 my $obj = CPAN::Shell->expandany($c);
4549 unless ($obj->uptodate){
4550 my $id = $self->pretty_id;
4551 $self->debug("$id not uptodate due to $c") if $CPAN::DEBUG;
4558 #-> sub CPAN::Distribution::called_for ;
4561 $self->{CALLED_FOR} = $id if defined $id;
4562 return $self->{CALLED_FOR};
4565 #-> sub CPAN::Distribution::get ;
4570 exists $self->{'build_dir'} and push @e,
4571 "Is already unwrapped into directory $self->{'build_dir'}";
4572 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4574 my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
4577 # Get the file on local disk
4582 File::Spec->catfile(
4583 $CPAN::Config->{keep_source_where},
4586 split(/\//,$self->id)
4589 $self->debug("Doing localize") if $CPAN::DEBUG;
4590 unless ($local_file =
4591 CPAN::FTP->localize("authors/id/$self->{ID}",
4594 if ($CPAN::Index::DATE_OF_02) {
4595 $note = "Note: Current database in memory was generated ".
4596 "on $CPAN::Index::DATE_OF_02\n";
4598 $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n$note");
4600 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
4601 $self->{localfile} = $local_file;
4602 return if $CPAN::Signal;
4607 if ($CPAN::META->has_inst("Digest::SHA")) {
4608 $self->debug("Digest::SHA is installed, verifying");
4609 $self->verifyCHECKSUM;
4611 $self->debug("Digest::SHA is NOT installed");
4613 return if $CPAN::Signal;
4616 # Create a clean room and go there
4618 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
4619 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
4620 $self->safe_chdir($builddir);
4621 $self->debug("Removing tmp") if $CPAN::DEBUG;
4622 File::Path::rmtree("tmp");
4623 unless (mkdir "tmp", 0755) {
4624 $CPAN::Frontend->unrecoverable_error(<<EOF);
4625 Couldn't mkdir '$builddir/tmp': $!
4627 Cannot continue: Please find the reason why I cannot make the
4630 and fix the problem, then retry.
4635 $self->safe_chdir($sub_wd);
4638 $self->safe_chdir("tmp");
4643 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
4644 my $ct = CPAN::Tarzip->new($local_file);
4645 if ($local_file =~ /(\.tar\.(bz2|gz|Z)|\.tgz)(?!\n)\Z/i){
4646 $self->{was_uncompressed}++ unless $ct->gtest();
4647 $self->untar_me($ct);
4648 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
4649 $self->unzip_me($ct);
4651 $self->{was_uncompressed}++ unless $ct->gtest();
4652 $self->debug("calling pm2dir for local_file[$local_file]")
4654 $local_file = $self->handle_singlefile($local_file);
4656 # $self->{archived} = "NO";
4657 # $self->safe_chdir($sub_wd);
4661 # we are still in the tmp directory!
4662 # Let's check if the package has its own directory.
4663 my $dh = DirHandle->new(File::Spec->curdir)
4664 or Carp::croak("Couldn't opendir .: $!");
4665 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
4667 my ($distdir,$packagedir);
4668 if (@readdir == 1 && -d $readdir[0]) {
4669 $distdir = $readdir[0];
4670 $packagedir = File::Spec->catdir($builddir,$distdir);
4671 $self->debug("packagedir[$packagedir]builddir[$builddir]distdir[$distdir]")
4673 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
4675 File::Path::rmtree($packagedir);
4676 unless (File::Copy::move($distdir,$packagedir)) {
4677 $CPAN::Frontend->unrecoverable_error(<<EOF);
4678 Couldn't move '$distdir' to '$packagedir': $!
4680 Cannot continue: Please find the reason why I cannot move
4681 $builddir/tmp/$distdir
4684 and fix the problem, then retry
4688 $self->debug(sprintf("moved distdir[%s] to packagedir[%s] -e[%s]-d[%s]",
4695 my $userid = $self->cpan_userid;
4697 CPAN->debug("no userid? self[$self]");
4700 my $pragmatic_dir = $userid . '000';
4701 $pragmatic_dir =~ s/\W_//g;
4702 $pragmatic_dir++ while -d "../$pragmatic_dir";
4703 $packagedir = File::Spec->catdir($builddir,$pragmatic_dir);
4704 $self->debug("packagedir[$packagedir]") if $CPAN::DEBUG;
4705 File::Path::mkpath($packagedir);
4707 for $f (@readdir) { # is already without "." and ".."
4708 my $to = File::Spec->catdir($packagedir,$f);
4709 File::Copy::move($f,$to) or Carp::confess("Couldn't move $f to $to: $!");
4713 $self->safe_chdir($sub_wd);
4717 $self->{'build_dir'} = $packagedir;
4718 $self->safe_chdir($builddir);
4719 File::Path::rmtree("tmp");
4721 $self->safe_chdir($packagedir);
4722 if ($CPAN::Config->{check_sigs}) {
4723 if ($CPAN::META->has_inst("Module::Signature")) {
4724 if (-f "SIGNATURE") {
4725 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
4726 my $rv = Module::Signature::verify();
4727 if ($rv != Module::Signature::SIGNATURE_OK() and
4728 $rv != Module::Signature::SIGNATURE_MISSING()) {
4729 $CPAN::Frontend->myprint(
4730 qq{\nSignature invalid for }.
4731 qq{distribution file. }.
4732 qq{Please investigate.\n\n}.
4734 $CPAN::META->instance(
4741 sprintf(qq{I'd recommend removing %s. Its signature
4742 is invalid. Maybe you have configured your 'urllist' with
4743 a bad URL. Please check this array with 'o conf urllist', and
4744 retry. For more information, try opening a subshell with
4752 $self->{signature_verify} = CPAN::Distrostatus->new("NO");
4753 $CPAN::Frontend->mywarn(Text::Wrap::wrap("","",$wrap));
4754 $CPAN::Frontend->mysleep(5) if $CPAN::Frontend->can("mysleep");
4756 $self->{signature_verify} = CPAN::Distrostatus->new("YES");
4757 $self->debug("Module::Signature has verified") if $CPAN::DEBUG;
4760 $CPAN::Frontend->mywarn(qq{Package came without SIGNATURE\n\n});
4763 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
4766 $self->safe_chdir($builddir);
4767 return if $CPAN::Signal;
4770 my($mpl) = File::Spec->catfile($packagedir,"Makefile.PL");
4771 my($mpl_exists) = -f $mpl;
4772 unless ($mpl_exists) {
4773 # NFS has been reported to have racing problems after the
4774 # renaming of a directory in some environments.
4776 $CPAN::Frontend->mysleep(1);
4777 my $mpldh = DirHandle->new($packagedir)
4778 or Carp::croak("Couldn't opendir $packagedir: $!");
4779 $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read;
4782 my $prefer_installer = "eumm"; # eumm|mb
4783 if (-f File::Spec->catfile($packagedir,"Build.PL")) {
4784 if ($mpl_exists) { # they *can* choose
4785 if ($CPAN::META->has_inst("Module::Build")) {
4786 $prefer_installer = $CPAN::Config->{prefer_installer};
4789 $prefer_installer = "mb";
4792 if (lc($prefer_installer) eq "mb") {
4793 $self->{modulebuild} = 1;
4794 } elsif (! $mpl_exists) {
4795 $self->debug(sprintf("makefilepl[%s]anycwd[%s]",
4799 my($configure) = File::Spec->catfile($packagedir,"Configure");
4800 if (-f $configure) {
4801 # do we have anything to do?
4802 $self->{'configure'} = $configure;
4803 } elsif (-f File::Spec->catfile($packagedir,"Makefile")) {
4804 $CPAN::Frontend->mywarn(qq{
4805 Package comes with a Makefile and without a Makefile.PL.
4806 We\'ll try to build it with that Makefile then.
4808 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
4809 $CPAN::Frontend->mysleep(2);
4811 my $cf = $self->called_for || "unknown";
4816 $cf =~ s|[/\\:]||g; # risk of filesystem damage
4817 $cf = "unknown" unless length($cf);
4818 $CPAN::Frontend->mywarn(qq{Package seems to come without Makefile.PL.
4819 (The test -f "$mpl" returned false.)
4820 Writing one on our own (setting NAME to $cf)\a\n});
4821 $self->{had_no_makefile_pl}++;
4822 $CPAN::Frontend->mysleep(3);
4824 # Writing our own Makefile.PL
4827 if ($self->{archived} eq "maybe_pl"){
4828 my $fh = FileHandle->new;
4829 my $script_file = File::Spec->catfile($packagedir,$local_file);
4830 $fh->open($script_file)
4831 or Carp::croak("Could not open $script_file: $!");
4833 # name parsen und prereq
4834 my($state) = "poddir";
4835 my($name, $prereq) = ("", "");
4837 if ($state eq "poddir" && /^=head\d\s+(\S+)/) {
4840 } elsif ($1 eq 'PREREQUISITES') {
4843 } elsif ($state =~ m{^(name|prereq)$}) {
4848 } elsif ($state eq "name") {
4853 } elsif ($state eq "prereq") {
4856 } elsif (/^=cut\b/) {
4863 s{.*<}{}; # strip X<...>
4867 $prereq = join " ", split /\s+/, $prereq;
4868 my($PREREQ_PM) = join("\n", map {
4869 s{.*<}{}; # strip X<...>
4871 if (/[\s\'\"]/) { # prose?
4873 s/[^\w:]$//; # period?
4874 " "x28 . "'$_' => 0,";
4876 } split /\s*,\s*/, $prereq);
4879 EXE_FILES => ['$name'],
4885 my $to_file = File::Spec->catfile($packagedir, $name);
4886 rename $script_file, $to_file
4887 or die "Can't rename $script_file to $to_file: $!";
4890 my $fh = FileHandle->new;
4892 or Carp::croak("Could not open >$mpl: $!");
4894 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
4895 # because there was no Makefile.PL supplied.
4896 # Autogenerated on: }.scalar localtime().qq{
4898 use ExtUtils::MakeMaker;
4900 NAME => q[$cf],$script
4910 # CPAN::Distribution::untar_me ;
4913 $self->{archived} = "tar";
4915 $self->{unwrapped} = "YES";
4917 $self->{unwrapped} = "NO";
4921 # CPAN::Distribution::unzip_me ;
4924 $self->{archived} = "zip";
4926 $self->{unwrapped} = "YES";
4928 $self->{unwrapped} = "NO";
4933 sub handle_singlefile {
4934 my($self,$local_file) = @_;
4936 if ( $local_file =~ /\.pm(\.(gz|Z))?(?!\n)\Z/ ){
4937 $self->{archived} = "pm";
4939 $self->{archived} = "maybe_pl";
4942 my $to = File::Basename::basename($local_file);
4943 if ($to =~ s/\.(gz|Z)(?!\n)\Z//) {
4944 if (CPAN::Tarzip->new($local_file)->gunzip($to)) {
4945 $self->{unwrapped} = "YES";
4947 $self->{unwrapped} = "NO";
4950 File::Copy::cp($local_file,".");
4951 $self->{unwrapped} = "YES";
4956 #-> sub CPAN::Distribution::new ;
4958 my($class,%att) = @_;
4960 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
4962 my $this = { %att };
4963 return bless $this, $class;
4966 #-> sub CPAN::Distribution::look ;
4970 if ($^O eq 'MacOS') {
4971 $self->Mac::BuildTools::look;
4975 if ( $CPAN::Config->{'shell'} ) {
4976 $CPAN::Frontend->myprint(qq{
4977 Trying to open a subshell in the build directory...
4980 $CPAN::Frontend->myprint(qq{
4981 Your configuration does not define a value for subshells.
4982 Please define it with "o conf shell <your shell>"
4986 my $dist = $self->id;
4988 unless ($dir = $self->dir) {
4991 unless ($dir ||= $self->dir) {
4992 $CPAN::Frontend->mywarn(qq{
4993 Could not determine which directory to use for looking at $dist.
4997 my $pwd = CPAN::anycwd();
4998 $self->safe_chdir($dir);
4999 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
5001 local $ENV{CPAN_SHELL_LEVEL} = $ENV{CPAN_SHELL_LEVEL}||0;
5002 $ENV{CPAN_SHELL_LEVEL} += 1;
5003 my $shell = CPAN::HandleConfig->safe_quote($CPAN::Config->{'shell'});
5004 unless (system($shell) == 0) {
5006 $CPAN::Frontend->mywarn("Subprocess shell exit code $code\n");
5009 $self->safe_chdir($pwd);
5012 # CPAN::Distribution::cvs_import ;
5016 my $dir = $self->dir;
5018 my $package = $self->called_for;
5019 my $module = $CPAN::META->instance('CPAN::Module', $package);
5020 my $version = $module->cpan_version;
5022 my $userid = $self->cpan_userid;
5024 my $cvs_dir = (split /\//, $dir)[-1];
5025 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
5027 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
5029 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
5030 if ($cvs_site_perl) {
5031 $cvs_dir = "$cvs_site_perl/$cvs_dir";
5033 my $cvs_log = qq{"imported $package $version sources"};
5034 $version =~ s/\./_/g;
5036 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
5037 "$cvs_dir", $userid, "v$version");
5039 my $pwd = CPAN::anycwd();
5040 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
5042 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
5044 $CPAN::Frontend->myprint(qq{@cmd\n});
5045 system(@cmd) == 0 or
5047 $CPAN::Frontend->mydie("cvs import failed");
5048 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
5051 #-> sub CPAN::Distribution::readme ;
5054 my($dist) = $self->id;
5055 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
5056 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
5059 File::Spec->catfile(
5060 $CPAN::Config->{keep_source_where},
5063 split(/\//,"$sans.readme"),
5065 $self->debug("Doing localize") if $CPAN::DEBUG;
5066 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
5068 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
5070 if ($^O eq 'MacOS') {
5071 Mac::BuildTools::launch_file($local_file);
5075 my $fh_pager = FileHandle->new;
5076 local($SIG{PIPE}) = "IGNORE";
5077 my $pager = $CPAN::Config->{'pager'} || "cat";
5078 $fh_pager->open("|$pager")
5079 or die "Could not open pager $pager\: $!";
5080 my $fh_readme = FileHandle->new;
5081 $fh_readme->open($local_file)
5082 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
5083 $CPAN::Frontend->myprint(qq{
5088 $fh_pager->print(<$fh_readme>);
5092 #-> sub CPAN::Distribution::verifyCHECKSUM ;
5093 sub verifyCHECKSUM {
5097 $self->{CHECKSUM_STATUS} ||= "";
5098 $self->{CHECKSUM_STATUS} eq "OK" and push @e, "Checksum was ok";
5099 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5101 my($lc_want,$lc_file,@local,$basename);
5102 @local = split(/\//,$self->id);
5104 push @local, "CHECKSUMS";
5106 File::Spec->catfile($CPAN::Config->{keep_source_where},
5107 "authors", "id", @local);
5109 if (my $size = -s $lc_want) {
5110 $self->debug("lc_want[$lc_want]size[$size]") if $CPAN::DEBUG;
5111 if ($self->CHECKSUM_check_file($lc_want,1)) {
5112 return $self->{CHECKSUM_STATUS} = "OK";
5115 $lc_file = CPAN::FTP->localize("authors/id/@local",
5118 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
5119 $local[-1] .= ".gz";
5120 $lc_file = CPAN::FTP->localize("authors/id/@local",
5123 $lc_file =~ s/\.gz(?!\n)\Z//;
5124 CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file);
5129 if ($self->CHECKSUM_check_file($lc_file)) {
5130 return $self->{CHECKSUM_STATUS} = "OK";
5134 #-> sub CPAN::Distribution::SIG_check_file ;
5135 sub SIG_check_file {
5136 my($self,$chk_file) = @_;
5137 my $rv = eval { Module::Signature::_verify($chk_file) };
5139 if ($rv == Module::Signature::SIGNATURE_OK()) {
5140 $CPAN::Frontend->myprint("Signature for $chk_file ok\n");
5141 return $self->{SIG_STATUS} = "OK";
5143 $CPAN::Frontend->myprint(qq{\nSignature invalid for }.
5144 qq{distribution file. }.
5145 qq{Please investigate.\n\n}.
5147 $CPAN::META->instance(
5152 my $wrap = qq{I\'d recommend removing $chk_file. Its signature
5153 is invalid. Maybe you have configured your 'urllist' with
5154 a bad URL. Please check this array with 'o conf urllist', and
5157 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
5161 #-> sub CPAN::Distribution::CHECKSUM_check_file ;
5163 # sloppy is 1 when we have an old checksums file that maybe is good
5166 sub CHECKSUM_check_file {
5167 my($self,$chk_file,$sloppy) = @_;
5168 my($cksum,$file,$basename);
5171 $self->debug("chk_file[$chk_file]sloppy[$sloppy]") if $CPAN::DEBUG;
5172 if ($CPAN::Config->{check_sigs}) {
5173 if ($CPAN::META->has_inst("Module::Signature") and Module::Signature->VERSION >= 0.26) {
5174 $self->debug("Module::Signature is installed, verifying");
5175 $self->SIG_check_file($chk_file);
5177 $self->debug("Module::Signature is NOT installed");
5181 $file = $self->{localfile};
5182 $basename = File::Basename::basename($file);
5183 my $fh = FileHandle->new;
5184 if (open $fh, $chk_file){
5187 $eval =~ s/\015?\012/\n/g;
5189 my($comp) = Safe->new();
5190 $cksum = $comp->reval($eval);
5192 rename $chk_file, "$chk_file.bad";
5193 Carp::confess($@) if $@;
5196 Carp::carp "Could not open $chk_file for reading";
5199 if (! ref $cksum or ref $cksum ne "HASH") {
5200 $CPAN::Frontend->mywarn(qq{
5201 Warning: checksum file '$chk_file' broken.
5203 When trying to read that file I expected to get a hash reference
5204 for further processing, but got garbage instead.
5206 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed nonetheless?", "no");
5207 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
5208 $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS file broken";
5210 } elsif (exists $cksum->{$basename}{sha256}) {
5211 $self->debug("Found checksum for $basename:" .
5212 "$cksum->{$basename}{sha256}\n") if $CPAN::DEBUG;
5216 my $eq = $self->eq_CHECKSUM($fh,$cksum->{$basename}{sha256});
5218 $fh = CPAN::Tarzip->TIEHANDLE($file);
5221 my $dg = Digest::SHA->new(256);
5224 while ($fh->READ($ref, 4096) > 0){
5227 my $hexdigest = $dg->hexdigest;
5228 $eq += $hexdigest eq $cksum->{$basename}{'sha256-ungz'};
5232 $CPAN::Frontend->myprint("Checksum for $file ok\n");
5233 return $self->{CHECKSUM_STATUS} = "OK";
5235 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
5236 qq{distribution file. }.
5237 qq{Please investigate.\n\n}.
5239 $CPAN::META->instance(
5244 my $wrap = qq{I\'d recommend removing $file. Its
5245 checksum is incorrect. Maybe you have configured your 'urllist' with
5246 a bad URL. Please check this array with 'o conf urllist', and
5249 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
5251 # former versions just returned here but this seems a
5252 # serious threat that deserves a die
5254 # $CPAN::Frontend->myprint("\n\n");
5258 # close $fh if fileno($fh);
5261 unless ($self->{CHECKSUM_STATUS}) {
5262 $CPAN::Frontend->mywarn(qq{
5263 Warning: No checksum for $basename in $chk_file.
5265 The cause for this may be that the file is very new and the checksum
5266 has not yet been calculated, but it may also be that something is
5267 going awry right now.
5269 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed?", "yes");
5270 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
5272 $self->{CHECKSUM_STATUS} = "NIL -- distro not in CHECKSUMS file";
5277 #-> sub CPAN::Distribution::eq_CHECKSUM ;
5279 my($self,$fh,$expect) = @_;
5280 if ($CPAN::META->has_inst("Digest::SHA")) {
5281 my $dg = Digest::SHA->new(256);
5283 while (read($fh, $data, 4096)){
5286 my $hexdigest = $dg->hexdigest;
5287 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
5288 return $hexdigest eq $expect;
5293 #-> sub CPAN::Distribution::force ;
5295 # Both CPAN::Modules and CPAN::Distributions know if "force" is in
5296 # effect by autoinspection, not by inspecting a global variable. One
5297 # of the reason why this was chosen to work that way was the treatment
5298 # of dependencies. They should not automatically inherit the force
5299 # status. But this has the downside that ^C and die() will return to
5300 # the prompt but will not be able to reset the force_update
5301 # attributes. We try to correct for it currently in the read_metadata
5302 # routine, and immediately before we check for a Signal. I hope this
5303 # works out in one of v1.57_53ff
5305 # "Force get forgets previous error conditions"
5307 #-> sub CPAN::Distribution::force ;
5309 my($self, $method) = @_;
5311 CHECKSUM_STATUS archived build_dir localfile make install unwrapped
5312 writemakefile modulebuild make_test
5314 delete $self->{$att};
5316 if ($method && $method =~ /make|test|install/) {
5317 $self->{"force_update"}++; # name should probably have been force_install
5322 my($self, $method) = @_;
5323 # warn "XDEBUG: set notest for $self $method";
5324 $self->{"notest"}++; # name should probably have been force_install
5329 # warn "XDEBUG: deleting notest";
5330 delete $self->{'notest'};
5333 #-> sub CPAN::Distribution::unforce ;
5336 delete $self->{'force_update'};
5339 #-> sub CPAN::Distribution::isa_perl ;
5342 my $file = File::Basename::basename($self->id);
5343 if ($file =~ m{ ^ perl
5356 } elsif ($self->cpan_comment
5358 $self->cpan_comment =~ /isa_perl\(.+?\)/){
5364 #-> sub CPAN::Distribution::perl ;
5369 carp __PACKAGE__ . "::perl was called without parameters.";
5371 return CPAN::HandleConfig->safe_quote($CPAN::Perl);
5375 #-> sub CPAN::Distribution::make ;
5378 my $make = $self->{modulebuild} ? "Build" : "make";
5379 $CPAN::Frontend->myprint(sprintf "Running %s for %s\n", $make, $self->id);
5380 # Emergency brake if they said install Pippi and get newest perl
5381 if ($self->isa_perl) {
5383 $self->called_for ne $self->id &&
5384 ! $self->{force_update}
5386 # if we die here, we break bundles
5387 $CPAN::Frontend->mywarn(sprintf qq{
5388 The most recent version "%s" of the module "%s"
5389 comes with the current version of perl (%s).
5390 I\'ll build that only if you ask for something like
5395 $CPAN::META->instance(
5403 $self->{make} = CPAN::Distrostatus->new("NO isa perl");
5404 $CPAN::Frontend->mysleep(1);
5410 delete $self->{force_update};
5415 !$self->{archived} || $self->{archived} eq "NO" and push @e,
5416 "Is neither a tar nor a zip archive.";
5418 !$self->{unwrapped} || $self->{unwrapped} eq "NO" and push @e,
5419 "Had problems unarchiving. Please build manually";
5421 unless ($self->{force_update}) {
5422 exists $self->{signature_verify} and (
5423 $self->{signature_verify}->can("failed") ?
5424 $self->{signature_verify}->failed :
5425 $self->{signature_verify} =~ /^NO/
5427 and push @e, "Did not pass the signature test.";
5430 if (exists $self->{writemakefile} &&
5432 $self->{writemakefile}->can("failed") ?
5433 $self->{writemakefile}->failed :
5434 $self->{writemakefile} =~ /^NO/
5436 # XXX maybe a retry would be in order?
5437 my $err = $self->{writemakefile}->can("text") ?
5438 $self->{writemakefile}->text :
5439 $self->{writemakefile};
5441 $err ||= "Had some problem writing Makefile";
5442 $err .= ", won't make";
5446 defined $self->{make} and push @e,
5447 "Has already been processed within this session";
5449 if (exists $self->{later} and length($self->{later})) {
5450 if ($self->unsat_prereq) {
5451 push @e, $self->{later};
5452 # RT ticket 18438 raises doubts if the deletion of {later} is valid.
5453 # YAML-0.53 triggered the later hodge-podge here, but my margin notes
5454 # are not sufficient to be sure if we really must/may do the delete
5455 # here. SO I accept the suggested patch for now. If we trigger a bug
5456 # again, I must go into deep contemplation about the {later} flag.
5459 # delete $self->{later};
5463 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5466 delete $self->{force_update};
5469 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
5470 my $builddir = $self->dir or
5471 $CPAN::Frontend->mydie("PANIC: Cannot determine build directory\n");
5472 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
5473 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
5475 if ($^O eq 'MacOS') {
5476 Mac::BuildTools::make($self);
5481 if ($self->{'configure'}) {
5482 $system = $self->{'configure'};
5483 } elsif ($self->{modulebuild}) {
5484 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
5485 $system = "$perl Build.PL $CPAN::Config->{mbuildpl_arg}";
5487 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
5489 # This needs a handler that can be turned on or off:
5490 # $switch = "-MExtUtils::MakeMaker ".
5491 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
5493 $system = sprintf("%s%s Makefile.PL%s",
5495 $switch ? " $switch" : "",
5496 $CPAN::Config->{makepl_arg} ? " $CPAN::Config->{makepl_arg}" : "",
5499 unless (exists $self->{writemakefile}) {
5500 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
5503 if ($CPAN::Config->{inactivity_timeout}) {
5505 alarm $CPAN::Config->{inactivity_timeout};
5506 local $SIG{CHLD}; # = sub { wait };
5507 if (defined($pid = fork)) {
5512 # note, this exec isn't necessary if
5513 # inactivity_timeout is 0. On the Mac I'd
5514 # suggest, we set it always to 0.
5518 $CPAN::Frontend->myprint("Cannot fork: $!");
5527 $CPAN::Frontend->myprint($err);
5528 $self->{writemakefile} = CPAN::Distrostatus->new("NO $err");
5533 $ret = system($system);
5535 $self->{writemakefile} = CPAN::Distrostatus
5536 ->new("NO '$system' returned status $ret");
5537 $CPAN::Frontend->mywarn("Warning: No success on command[$system]\n");
5541 if (-f "Makefile" || -f "Build") {
5542 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
5543 delete $self->{make_clean}; # if cleaned before, enable next
5545 $self->{writemakefile} = CPAN::Distrostatus
5546 ->new(qq{NO -- Unknown reason.});
5550 delete $self->{force_update};
5553 if (my @prereq = $self->unsat_prereq){
5554 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
5556 if ($self->{modulebuild}) {
5557 unless (-f "Build") {
5559 $CPAN::Frontend->mywarn("Alert: no Build file available for 'make $self->{id}'".
5560 " in cwd[$cwd]. Danger, Will Robinson!");
5561 $CPAN::Frontend->mysleep(5);
5563 $system = sprintf "%s %s", $self->_build_command(), $CPAN::Config->{mbuild_arg};
5565 $system = join " ", $self->_make_command(), $CPAN::Config->{make_arg};
5567 if (system($system) == 0) {
5568 $CPAN::Frontend->myprint(" $system -- OK\n");
5569 $self->{make} = CPAN::Distrostatus->new("YES");
5571 $self->{writemakefile} ||= CPAN::Distrostatus->new("YES");
5572 $self->{make} = CPAN::Distrostatus->new("NO");
5573 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
5583 $CPAN::Config->{make} || $Config::Config{make} || 'make'
5586 # Old style call, without object. Deprecated
5587 Carp::confess("CPAN::_make_command() used as function. Don't Do That.");
5589 safe_quote(undef, $CPAN::Config->{make} || $Config::Config{make} || 'make');
5593 #-> sub CPAN::Distribution::follow_prereqs ;
5594 sub follow_prereqs {
5596 my(@prereq) = grep {$_ ne "perl"} @_;
5597 return unless @prereq;
5599 $CPAN::Frontend->myprint("---- Unsatisfied dependencies detected ".
5600 "during [$id] -----\n");
5602 for my $p (@prereq) {
5603 $CPAN::Frontend->myprint(" $p\n");
5606 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
5608 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
5609 my $answer = CPAN::Shell::colorable_makemaker_prompt(
5610 "Shall I follow them and prepend them to the queue
5611 of modules we are processing right now?", "yes");
5612 $follow = $answer =~ /^\s*y/i;
5616 myprint(" Ignoring dependencies on modules @prereq\n");
5619 # color them as dirty
5620 for my $p (@prereq) {
5621 # warn "calling color_cmd_tmps(0,1)";
5622 CPAN::Shell->expandany($p)->color_cmd_tmps(0,1);
5624 CPAN::Queue->jumpqueue(@prereq,$id); # queue them and requeue yourself
5625 $self->{later} = "Delayed until after prerequisites";
5626 return 1; # signal success to the queuerunner
5630 #-> sub CPAN::Distribution::unsat_prereq ;
5633 my $prereq_pm = $self->prereq_pm or return;
5635 NEED: while (my($need_module, $need_version) = each %$prereq_pm) {
5636 my $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
5637 # we were too demanding:
5638 next if $nmo->uptodate;
5640 # if they have not specified a version, we accept any installed one
5641 if (not defined $need_version or
5642 $need_version eq "0" or
5643 $need_version eq "undef") {
5644 next if defined $nmo->inst_file;
5647 # We only want to install prereqs if either they're not installed
5648 # or if the installed version is too old. We cannot omit this
5649 # check, because if 'force' is in effect, nobody else will check.
5650 if (defined $nmo->inst_file) {
5651 my(@all_requirements) = split /\s*,\s*/, $need_version;
5654 RQ: for my $rq (@all_requirements) {
5655 if ($rq =~ s|>=\s*||) {
5656 } elsif ($rq =~ s|>\s*||) {
5658 if (CPAN::Version->vgt($nmo->inst_version,$rq)){
5662 } elsif ($rq =~ s|!=\s*||) {
5664 if (CPAN::Version->vcmp($nmo->inst_version,$rq)){
5670 } elsif ($rq =~ m|<=?\s*|) {
5672 $CPAN::Frontend->mywarn("Downgrading not supported (rq[$rq])");
5676 if (! CPAN::Version->vgt($rq, $nmo->inst_version)){
5679 CPAN->debug(sprintf "id[%s]inst_file[%s]inst_version[%s]rq[%s]ok[%d]",
5683 CPAN::Version->readable($rq),
5687 next NEED if $ok == @all_requirements;
5690 if ($self->{sponsored_mods}{$need_module}++){
5691 # We have already sponsored it and for some reason it's still
5692 # not available. So we do nothing. Or what should we do?
5693 # if we push it again, we have a potential infinite loop
5696 push @need, $need_module;
5701 #-> sub CPAN::Distribution::read_yaml ;
5704 return $self->{yaml_content} if exists $self->{yaml_content};
5705 my $build_dir = $self->{build_dir};
5706 my $yaml = File::Spec->catfile($build_dir,"META.yml");
5707 $self->debug("yaml[$yaml]") if $CPAN::DEBUG;
5708 return unless -f $yaml;
5709 if ($CPAN::META->has_inst("YAML")) {
5710 eval { $self->{yaml_content} = YAML::LoadFile($yaml); };
5712 $CPAN::Frontend->mywarn("Error while parsing META.yml: $@");
5715 if (not exists $self->{yaml_content}{dynamic_config}
5716 or $self->{yaml_content}{dynamic_config}
5718 $self->{yaml_content} = undef;
5721 $self->debug("yaml_content[$self->{yaml_content}]") if $CPAN::DEBUG;
5722 return $self->{yaml_content};
5725 #-> sub CPAN::Distribution::prereq_pm ;
5728 return $self->{prereq_pm} if
5729 exists $self->{prereq_pm_detected} && $self->{prereq_pm_detected};
5730 return unless $self->{writemakefile} # no need to have succeeded
5731 # but we must have run it
5732 || $self->{modulebuild};
5734 if (my $yaml = $self->read_yaml) {
5735 $req = $yaml->{requires};
5736 undef $req unless ref $req eq "HASH" && %$req;
5738 if ($yaml->{generated_by} =~ /ExtUtils::MakeMaker version ([\d\._]+)/) {
5739 my $eummv = do { local $^W = 0; $1+0; };
5740 if ($eummv < 6.2501) {
5741 # thanks to Slaven for digging that out: MM before
5742 # that could be wrong because it could reflect a
5749 while (my($k,$v) = each %{$req||{}}) {
5752 } elsif ($k =~ /[A-Za-z]/ &&
5754 $CPAN::META->exists("Module",$v)
5756 $CPAN::Frontend->mywarn("Suspicious key-value pair in META.yml's ".
5757 "requires hash: $k => $v; I'll take both ".
5758 "key and value as a module name\n");
5759 $CPAN::Frontend->mysleep(1);
5765 $req = $areq if $do_replace;
5767 if ($yaml->{build_requires}
5768 && ref $yaml->{build_requires}
5769 && ref $yaml->{build_requires} eq "HASH") {
5770 while (my($k,$v) = each %{$yaml->{build_requires}}) {
5772 # merging of two "requires"-type values--what should we do?
5779 delete $req->{perl};
5783 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
5784 my $makefile = File::Spec->catfile($build_dir,"Makefile");
5788 $fh = FileHandle->new("<$makefile\0")) {
5791 last if /MakeMaker post_initialize section/;
5793 \s+PREREQ_PM\s+=>\s+(.+)
5796 # warn "Found prereq expr[$p]";
5798 # Regexp modified by A.Speer to remember actual version of file
5799 # PREREQ_PM hash key wants, then add to
5800 while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
5801 # In case a prereq is mentioned twice, complain.
5802 if ( defined $req->{$1} ) {
5803 warn "Warning: PREREQ_PM mentions $1 more than once, ".
5804 "last mention wins";
5810 } elsif (-f "Build") {
5811 if ($CPAN::META->has_inst("Module::Build")) {
5812 my $requires = Module::Build->current->requires();
5813 my $brequires = Module::Build->current->build_requires();
5814 $req = { %$requires, %$brequires };
5818 if (-f "Build.PL" && ! -f "Makefile.PL" && ! exists $req->{"Module::Build"}) {
5819 $CPAN::Frontend->mywarn(" Warning: CPAN.pm discovered Module::Build as ".
5820 "undeclared prerequisite.\n".
5821 " Adding it now as a prerequisite.\n"
5823 $CPAN::Frontend->mysleep(5);
5824 $req->{"Module::Build"} = 0;
5825 delete $self->{writemakefile};
5827 $self->{prereq_pm_detected}++;
5828 return $self->{prereq_pm} = $req;
5831 #-> sub CPAN::Distribution::test ;
5836 delete $self->{force_update};
5839 # warn "XDEBUG: checking for notest: $self->{notest} $self";
5840 if ($self->{notest}) {
5841 $CPAN::Frontend->myprint("Skipping test because of notest pragma\n");
5845 my $make = $self->{modulebuild} ? "Build" : "make";
5846 $CPAN::Frontend->myprint("Running $make test\n");
5847 if (my @prereq = $self->unsat_prereq){
5848 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
5852 unless (exists $self->{make} or exists $self->{later}) {
5854 "Make had some problems, won't test";
5857 exists $self->{make} and
5859 $self->{make}->can("failed") ?
5860 $self->{make}->failed :
5861 $self->{make} =~ /^NO/
5862 ) and push @e, "Can't test without successful make";
5864 exists $self->{build_dir} or push @e, "Has no own directory";
5865 $self->{badtestcnt} ||= 0;
5866 $self->{badtestcnt} > 0 and
5867 push @e, "Won't repeat unsuccessful test during this command";
5869 exists $self->{later} and length($self->{later}) and
5870 push @e, $self->{later};
5872 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5874 chdir $self->{'build_dir'} or
5875 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
5876 $self->debug("Changed directory to $self->{'build_dir'}")
5879 if ($^O eq 'MacOS') {
5880 Mac::BuildTools::make_test($self);
5884 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
5886 : ($ENV{PERLLIB} || "");
5888 $CPAN::META->set_perl5lib;
5889 local $ENV{MAKEFLAGS}; # protect us from outer make calls
5892 if ($self->{modulebuild}) {
5893 $system = sprintf "%s test", $self->_build_command();
5895 $system = join " ", $self->_make_command(), "test";
5898 if ( $CPAN::Config->{test_report} &&
5899 $CPAN::META->has_inst("CPAN::Reporter") ) {
5900 $tests_ok = CPAN::Reporter::test($self, $system);
5902 $tests_ok = system($system) == 0;
5905 $CPAN::Frontend->myprint(" $system -- OK\n");
5906 $CPAN::META->is_tested($self->{'build_dir'});
5907 $self->{make_test} = CPAN::Distrostatus->new("YES");
5909 $self->{make_test} = CPAN::Distrostatus->new("NO");
5910 $self->{badtestcnt}++;
5911 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
5915 #-> sub CPAN::Distribution::clean ;
5918 my $make = $self->{modulebuild} ? "Build" : "make";
5919 $CPAN::Frontend->myprint("Running $make clean\n");
5920 unless (exists $self->{archived}) {
5921 $CPAN::Frontend->mywarn("Distribution seems to have never been unzipped".
5922 "/untarred, nothing done\n");
5925 unless (exists $self->{build_dir}) {
5926 $CPAN::Frontend->mywarn("Distribution has no own directory, nothing to do.\n");
5931 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
5932 push @e, "make clean already called once";
5933 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5935 chdir $self->{'build_dir'} or
5936 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
5937 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
5939 if ($^O eq 'MacOS') {
5940 Mac::BuildTools::make_clean($self);
5945 if ($self->{modulebuild}) {
5946 unless (-f "Build") {
5948 $CPAN::Frontend->mywarn("Alert: no Build file available for 'clean $self->{id}".
5949 " in cwd[$cwd]. Danger, Will Robinson!");
5950 $CPAN::Frontend->mysleep(5);
5952 $system = sprintf "%s clean", $self->_build_command();
5954 $system = join " ", $self->_make_command(), "clean";
5956 if (system($system) == 0) {
5957 $CPAN::Frontend->myprint(" $system -- OK\n");
5961 # Jost Krieger pointed out that this "force" was wrong because
5962 # it has the effect that the next "install" on this distribution
5963 # will untar everything again. Instead we should bring the
5964 # object's state back to where it is after untarring.
5975 $self->{make_clean} = CPAN::Distrostatus->new("YES");
5978 # Hmmm, what to do if make clean failed?
5980 $self->{make_clean} = CPAN::Distrostatus->new("NO");
5981 $CPAN::Frontend->mywarn(qq{ $system -- NOT OK\n});
5983 # 2006-02-27: seems silly to me to force a make now
5984 # $self->force("make"); # so that this directory won't be used again
5989 #-> sub CPAN::Distribution::install ;
5994 delete $self->{force_update};
5997 my $make = $self->{modulebuild} ? "Build" : "make";
5998 $CPAN::Frontend->myprint("Running $make install\n");
6001 exists $self->{build_dir} or push @e, "Has no own directory";
6003 unless (exists $self->{make} or exists $self->{later}) {
6005 "Make had some problems, won't install";
6008 exists $self->{make} and
6010 $self->{make}->can("failed") ?
6011 $self->{make}->failed :
6012 $self->{make} =~ /^NO/
6014 push @e, "make had returned bad status, install seems impossible";
6016 if (exists $self->{make_test} and
6018 $self->{make_test}->can("failed") ?
6019 $self->{make_test}->failed :
6020 $self->{make_test} =~ /^NO/
6022 if ($self->{force_update}) {
6023 $self->{make_test}->text("FAILED but failure ignored because ".
6024 "'force' in effect");
6026 push @e, "make test had returned bad status, ".
6027 "won't install without force"
6030 if (exists $self->{'install'}) {
6031 if ($self->{'install'}->can("text") ?
6032 $self->{'install'}->text eq "YES" :
6033 $self->{'install'} =~ /^YES/
6035 push @e, "Already done";
6037 # comment in Todo on 2006-02-11; maybe retry?
6038 push @e, "Already tried without success";
6042 exists $self->{later} and length($self->{later}) and
6043 push @e, $self->{later};
6045 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
6047 chdir $self->{'build_dir'} or
6048 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
6049 $self->debug("Changed directory to $self->{'build_dir'}")
6052 if ($^O eq 'MacOS') {
6053 Mac::BuildTools::make_install($self);
6058 if ($self->{modulebuild}) {
6059 my($mbuild_install_build_command) =
6060 exists $CPAN::HandleConfig::keys{mbuild_install_build_command} &&
6061 $CPAN::Config->{mbuild_install_build_command} ?
6062 $CPAN::Config->{mbuild_install_build_command} :
6063 $self->_build_command();
6064 $system = sprintf("%s install %s",
6065 $mbuild_install_build_command,
6066 $CPAN::Config->{mbuild_install_arg},
6069 my($make_install_make_command) = $CPAN::Config->{make_install_make_command} ||
6070 $self->_make_command();
6071 $system = sprintf("%s install %s",
6072 $make_install_make_command,
6073 $CPAN::Config->{make_install_arg},
6077 my($stderr) = $^O eq "MSWin32" ? "" : " 2>&1 ";
6078 my($pipe) = FileHandle->new("$system $stderr |");
6081 print $_; # intentionally NOT use Frontend->myprint because it
6082 # looks irritating when we markup in color what we
6083 # just pass through from an external program
6088 $CPAN::Frontend->myprint(" $system -- OK\n");
6089 $CPAN::META->is_installed($self->{build_dir});
6090 return $self->{install} = CPAN::Distrostatus->new("YES");
6092 $self->{install} = CPAN::Distrostatus->new("NO");
6093 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
6095 $makeout =~ /permission/s
6098 ! $CPAN::Config->{make_install_make_command}
6099 || $CPAN::Config->{make_install_make_command} eq $CPAN::Config->{make}
6102 $CPAN::Frontend->myprint(
6104 qq{ You may have to su }.
6105 qq{to root to install the package\n}.
6106 qq{ (Or you may want to run something like\n}.
6107 qq{ o conf make_install_make_command 'sudo make'\n}.
6108 qq{ to raise your permissions.}
6112 delete $self->{force_update};
6115 #-> sub CPAN::Distribution::dir ;
6117 shift->{'build_dir'};
6120 #-> sub CPAN::Distribution::perldoc ;
6124 my($dist) = $self->id;
6125 my $package = $self->called_for;
6127 $self->_display_url( $CPAN::Defaultdocs . $package );
6130 #-> sub CPAN::Distribution::_check_binary ;
6132 my ($dist,$shell,$binary) = @_;
6135 $CPAN::Frontend->myprint(qq{ + _check_binary($binary)\n})
6139 $pid = open README, "which $binary|"
6140 or $CPAN::Frontend->mydie(qq{Could not fork 'which $binary': $!});
6144 close README or die "Could not run 'which $binary': $!";
6146 $CPAN::Frontend->myprint(qq{ + $out \n})
6147 if $CPAN::DEBUG && $out;
6152 #-> sub CPAN::Distribution::_display_url ;
6154 my($self,$url) = @_;
6155 my($res,$saved_file,$pid,$out);
6157 $CPAN::Frontend->myprint(qq{ + _display_url($url)\n})
6160 # should we define it in the config instead?
6161 my $html_converter = "html2text";
6163 my $web_browser = $CPAN::Config->{'lynx'} || undef;
6164 my $web_browser_out = $web_browser
6165 ? CPAN::Distribution->_check_binary($self,$web_browser)
6168 if ($web_browser_out) {
6169 # web browser found, run the action
6170 my $browser = CPAN::HandleConfig->safe_quote($CPAN::Config->{'lynx'});
6171 $CPAN::Frontend->myprint(qq{system[$browser $url]})
6173 $CPAN::Frontend->myprint(qq{
6176 with browser $browser
6178 $CPAN::Frontend->mysleep(1);
6179 system("$browser $url");
6180 if ($saved_file) { 1 while unlink($saved_file) }
6182 # web browser not found, let's try text only
6183 my $html_converter_out =
6184 CPAN::Distribution->_check_binary($self,$html_converter);
6185 $html_converter_out = CPAN::HandleConfig->safe_quote($html_converter_out);
6187 if ($html_converter_out ) {
6188 # html2text found, run it
6189 $saved_file = CPAN::Distribution->_getsave_url( $self, $url );
6190 $CPAN::Frontend->mydie(qq{ERROR: problems while getting $url\n})
6191 unless defined($saved_file);
6194 $pid = open README, "$html_converter $saved_file |"
6195 or $CPAN::Frontend->mydie(qq{
6196 Could not fork '$html_converter $saved_file': $!});
6198 if ($CPAN::META->has_inst("File::Temp")) {
6199 $fh = File::Temp->new(
6200 template => 'cpan_htmlconvert_XXXX',
6204 $filename = $fh->filename;
6206 $filename = "cpan_htmlconvert_$$.txt";
6207 $fh = FileHandle->new();
6208 open $fh, ">$filename" or die;
6214 $CPAN::Frontend->mydie(qq{Could not run '$html_converter $saved_file': $!});
6215 my $tmpin = $fh->filename;
6216 $CPAN::Frontend->myprint(sprintf(qq{
6218 saved output to %s\n},
6226 or $CPAN::Frontend->mydie(qq{Could not open "$tmpin": $!});
6227 my $fh_pager = FileHandle->new;
6228 local($SIG{PIPE}) = "IGNORE";
6229 my $pager = $CPAN::Config->{'pager'} || "cat";
6230 $fh_pager->open("|pager")
6231 or $CPAN::Frontend->mydie(qq{
6232 Could not open pager $pager\: $!});
6233 $CPAN::Frontend->myprint(qq{
6238 $CPAN::Frontend->mysleep(1);
6239 $fh_pager->print(<FH>);
6242 # coldn't find the web browser or html converter
6243 $CPAN::Frontend->myprint(qq{
6244 You need to install lynx or $html_converter to use this feature.});
6249 #-> sub CPAN::Distribution::_getsave_url ;
6251 my($dist, $shell, $url) = @_;
6253 $CPAN::Frontend->myprint(qq{ + _getsave_url($url)\n})
6257 if ($CPAN::META->has_inst("File::Temp")) {
6258 $fh = File::Temp->new(
6259 template => "cpan_getsave_url_XXXX",
6263 $filename = $fh->filename;
6265 $fh = FileHandle->new;
6266 $filename = "cpan_getsave_url_$$.html";
6268 my $tmpin = $filename;
6269 if ($CPAN::META->has_usable('LWP')) {
6270 $CPAN::Frontend->myprint("Fetching with LWP:
6274 CPAN::LWP::UserAgent->config;
6275 eval { $Ua = CPAN::LWP::UserAgent->new; };
6277 $CPAN::Frontend->mywarn("ERROR: CPAN::LWP::UserAgent->new dies with $@\n");
6281 $Ua->proxy('http', $var)
6282 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
6284 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
6287 my $req = HTTP::Request->new(GET => $url);
6288 $req->header('Accept' => 'text/html');
6289 my $res = $Ua->request($req);
6290 if ($res->is_success) {
6291 $CPAN::Frontend->myprint(" + request successful.\n")
6293 print $fh $res->content;
6295 $CPAN::Frontend->myprint(qq{ + saved content to $tmpin \n})
6299 $CPAN::Frontend->myprint(sprintf(
6300 "LWP failed with code[%s], message[%s]\n",
6307 $CPAN::Frontend->mywarn(" LWP not available\n");
6312 # sub CPAN::Distribution::_build_command
6313 sub _build_command {
6315 if ($^O eq "MSWin32") { # special code needed at least up to
6316 # Module::Build 0.2611 and 0.2706; a fix
6317 # in M:B has been promised 2006-01-30
6319 my($perl) = $self->perl or $CPAN::Frontend->mydie("Couldn't find executable perl\n");
6320 return "$perl ./Build";
6325 package CPAN::Bundle;
6330 $CPAN::Frontend->myprint($self->as_string);
6335 delete $self->{later};
6336 for my $c ( $self->contains ) {
6337 my $obj = CPAN::Shell->expandany($c) or next;
6342 # mark as dirty/clean
6343 #-> sub CPAN::Bundle::color_cmd_tmps ;
6344 sub color_cmd_tmps {
6346 my($depth) = shift || 0;
6347 my($color) = shift || 0;
6348 my($ancestors) = shift || [];
6349 # a module needs to recurse to its cpan_file, a distribution needs
6350 # to recurse into its prereq_pms, a bundle needs to recurse into its modules
6352 return if exists $self->{incommandcolor}
6353 && $self->{incommandcolor}==$color;
6355 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
6357 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
6359 for my $c ( $self->contains ) {
6360 my $obj = CPAN::Shell->expandany($c) or next;
6361 CPAN->debug("c[$c]obj[$obj]") if $CPAN::DEBUG;
6362 $obj->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
6365 delete $self->{badtestcnt};
6367 $self->{incommandcolor} = $color;
6370 #-> sub CPAN::Bundle::as_string ;
6374 # following line must be "=", not "||=" because we have a moving target
6375 $self->{INST_VERSION} = $self->inst_version;
6376 return $self->SUPER::as_string;
6379 #-> sub CPAN::Bundle::contains ;
6382 my($inst_file) = $self->inst_file || "";
6383 my($id) = $self->id;
6384 $self->debug("inst_file[$inst_file]id[$id]") if $CPAN::DEBUG;
6385 if ($inst_file && CPAN::Version->vlt($self->inst_version,$self->cpan_version)) {
6388 unless ($inst_file) {
6389 # Try to get at it in the cpan directory
6390 $self->debug("no inst_file") if $CPAN::DEBUG;
6392 $CPAN::Frontend->mydie("I don't know a bundle with ID $id\n") unless
6393 $cpan_file = $self->cpan_file;
6394 if ($cpan_file eq "N/A") {
6395 $CPAN::Frontend->mydie("Bundle $id not found on disk and not on CPAN.
6396 Maybe stale symlink? Maybe removed during session? Giving up.\n");
6398 my $dist = $CPAN::META->instance('CPAN::Distribution',
6401 $self->debug("id[$dist->{ID}]") if $CPAN::DEBUG;
6402 my($todir) = $CPAN::Config->{'cpan_home'};
6403 my(@me,$from,$to,$me);
6404 @me = split /::/, $self->id;
6406 $me = File::Spec->catfile(@me);
6407 $from = $self->find_bundle_file($dist->{'build_dir'},join('/',@me));
6408 $to = File::Spec->catfile($todir,$me);
6409 File::Path::mkpath(File::Basename::dirname($to));
6410 File::Copy::copy($from, $to)
6411 or Carp::confess("Couldn't copy $from to $to: $!");
6415 my $fh = FileHandle->new;
6417 open($fh,$inst_file) or die "Could not open '$inst_file': $!";
6419 $self->debug("inst_file[$inst_file]") if $CPAN::DEBUG;
6421 $in_cont = m/^=(?!head1\s+CONTENTS)/ ? 0 :
6422 m/^=head1\s+CONTENTS/ ? 1 : $in_cont;
6423 next unless $in_cont;
6428 push @result, (split " ", $_, 2)[0];
6431 delete $self->{STATUS};
6432 $self->{CONTAINS} = \@result;
6433 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
6435 $CPAN::Frontend->mywarn(qq{
6436 The bundle file "$inst_file" may be a broken
6437 bundlefile. It seems not to contain any bundle definition.
6438 Please check the file and if it is bogus, please delete it.
6439 Sorry for the inconvenience.
6445 #-> sub CPAN::Bundle::find_bundle_file
6446 # $where is in local format, $what is in unix format
6447 sub find_bundle_file {
6448 my($self,$where,$what) = @_;
6449 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
6450 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
6451 ### my $bu = File::Spec->catfile($where,$what);
6452 ### return $bu if -f $bu;
6453 my $manifest = File::Spec->catfile($where,"MANIFEST");
6454 unless (-f $manifest) {
6455 require ExtUtils::Manifest;
6456 my $cwd = CPAN::anycwd();
6457 $self->safe_chdir($where);
6458 ExtUtils::Manifest::mkmanifest();
6459 $self->safe_chdir($cwd);
6461 my $fh = FileHandle->new($manifest)
6462 or Carp::croak("Couldn't open $manifest: $!");
6464 my $bundle_filename = $what;
6465 $bundle_filename =~ s|Bundle.*/||;
6466 my $bundle_unixpath;
6469 my($file) = /(\S+)/;
6470 if ($file =~ m|\Q$what\E$|) {
6471 $bundle_unixpath = $file;
6472 # return File::Spec->catfile($where,$bundle_unixpath); # bad
6475 # retry if she managed to have no Bundle directory
6476 $bundle_unixpath = $file if $file =~ m|\Q$bundle_filename\E$|;
6478 return File::Spec->catfile($where, split /\//, $bundle_unixpath)
6479 if $bundle_unixpath;
6480 Carp::croak("Couldn't find a Bundle file in $where");
6483 # needs to work quite differently from Module::inst_file because of
6484 # cpan_home/Bundle/ directory and the possibility that we have
6485 # shadowing effect. As it makes no sense to take the first in @INC for
6486 # Bundles, we parse them all for $VERSION and take the newest.
6488 #-> sub CPAN::Bundle::inst_file ;
6493 @me = split /::/, $self->id;
6496 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
6497 my $bfile = File::Spec->catfile($incdir, @me);
6498 CPAN->debug("bfile[$bfile]") if $CPAN::DEBUG;
6499 next unless -f $bfile;
6500 my $foundv = MM->parse_version($bfile);
6501 if (!$bestv || CPAN::Version->vgt($foundv,$bestv)) {
6502 $self->{INST_FILE} = $bfile;
6503 $self->{INST_VERSION} = $bestv = $foundv;
6509 #-> sub CPAN::Bundle::inst_version ;
6512 $self->inst_file; # finds INST_VERSION as side effect
6513 $self->{INST_VERSION};
6516 #-> sub CPAN::Bundle::rematein ;
6518 my($self,$meth) = @_;
6519 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
6520 my($id) = $self->id;
6521 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
6522 unless $self->inst_file || $self->cpan_file;
6524 for $s ($self->contains) {
6525 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
6526 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
6527 if ($type eq 'CPAN::Distribution') {
6528 $CPAN::Frontend->mywarn(qq{
6529 The Bundle }.$self->id.qq{ contains
6530 explicitly a file $s.
6532 $CPAN::Frontend->mysleep(3);
6534 # possibly noisy action:
6535 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
6536 my $obj = $CPAN::META->instance($type,$s);
6538 if ($obj->isa('CPAN::Bundle')
6540 exists $obj->{install_failed}
6542 ref($obj->{install_failed}) eq "HASH"
6544 for (keys %{$obj->{install_failed}}) {
6545 $self->{install_failed}{$_} = undef; # propagate faiure up
6548 $fail{$s} = 1; # the bundle itself may have succeeded but
6553 $success = $obj->can("uptodate") ? $obj->uptodate : 0;
6554 $success ||= $obj->{'install'} && $obj->{'install'} eq "YES";
6556 delete $self->{install_failed}{$s};
6563 # recap with less noise
6564 if ( $meth eq "install" ) {
6567 my $raw = sprintf(qq{Bundle summary:
6568 The following items in bundle %s had installation problems:},
6571 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
6572 $CPAN::Frontend->myprint("\n");
6575 for $s ($self->contains) {
6577 $paragraph .= "$s ";
6578 $self->{install_failed}{$s} = undef;
6579 $reported{$s} = undef;
6582 my $report_propagated;
6583 for $s (sort keys %{$self->{install_failed}}) {
6584 next if exists $reported{$s};
6585 $paragraph .= "and the following items had problems
6586 during recursive bundle calls: " unless $report_propagated++;
6587 $paragraph .= "$s ";
6589 $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
6590 $CPAN::Frontend->myprint("\n");
6592 $self->{'install'} = 'YES';
6597 # If a bundle contains another that contains an xs_file we have here,
6598 # we just don't bother I suppose
6599 #-> sub CPAN::Bundle::xs_file
6604 #-> sub CPAN::Bundle::force ;
6605 sub force { shift->rematein('force',@_); }
6606 #-> sub CPAN::Bundle::notest ;
6607 sub notest { shift->rematein('notest',@_); }
6608 #-> sub CPAN::Bundle::get ;
6609 sub get { shift->rematein('get',@_); }
6610 #-> sub CPAN::Bundle::make ;
6611 sub make { shift->rematein('make',@_); }
6612 #-> sub CPAN::Bundle::test ;
6615 $self->{badtestcnt} ||= 0;
6616 $self->rematein('test',@_);
6618 #-> sub CPAN::Bundle::install ;
6621 $self->rematein('install',@_);
6623 #-> sub CPAN::Bundle::clean ;
6624 sub clean { shift->rematein('clean',@_); }
6626 #-> sub CPAN::Bundle::uptodate ;
6629 return 0 unless $self->SUPER::uptodate; # we mut have the current Bundle def
6631 foreach $c ($self->contains) {
6632 my $obj = CPAN::Shell->expandany($c);
6633 return 0 unless $obj->uptodate;
6638 #-> sub CPAN::Bundle::readme ;
6641 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
6642 No File found for bundle } . $self->id . qq{\n}), return;
6643 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
6644 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
6647 package CPAN::Module;
6651 # sub CPAN::Module::userid
6656 return $ro->{userid} || $ro->{CPAN_USERID};
6658 # sub CPAN::Module::description
6661 my $ro = $self->ro or return "";
6667 CPAN::Shell->expand("Distribution",$self->cpan_file);
6670 # sub CPAN::Module::undelay
6673 delete $self->{later};
6674 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
6679 # mark as dirty/clean
6680 #-> sub CPAN::Module::color_cmd_tmps ;
6681 sub color_cmd_tmps {
6683 my($depth) = shift || 0;
6684 my($color) = shift || 0;
6685 my($ancestors) = shift || [];
6686 # a module needs to recurse to its cpan_file
6688 return if exists $self->{incommandcolor}
6689 && $self->{incommandcolor}==$color;
6690 return if $depth>=1 && $self->uptodate;
6692 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
6694 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
6696 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
6697 $dist->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
6700 delete $self->{badtestcnt};
6702 $self->{incommandcolor} = $color;
6705 #-> sub CPAN::Module::as_glimpse ;
6709 my $class = ref($self);
6710 $class =~ s/^CPAN:://;
6714 $CPAN::Shell::COLOR_REGISTERED
6716 $CPAN::META->has_inst("Term::ANSIColor")
6720 $color_on = Term::ANSIColor::color("green");
6721 $color_off = Term::ANSIColor::color("reset");
6723 my $uptodateness = " ";
6724 if ($class eq "Bundle") {
6725 } elsif ($self->uptodate) {
6726 $uptodateness = "=";
6727 } elsif ($self->inst_version) {
6728 $uptodateness = "<";
6730 push @m, sprintf("%-7s %1s %s%-22s%s (%s)\n",
6736 ($self->distribution ?
6737 $self->distribution->pretty_id :
6744 #-> sub CPAN::Module::dslip_status
6748 @{$stat->{D}}{qw,i c a b R M S,} = qw,idea
6749 pre-alpha alpha beta released
6751 @{$stat->{S}}{qw,m d u n a,} = qw,mailing-list
6752 developer comp.lang.perl.*
6754 @{$stat->{L}}{qw,p c + o h,} = qw,perl C C++ other hybrid,;
6755 @{$stat->{I}}{qw,f r O p h n,} = qw,functions
6757 object-oriented pragma
6759 @{$stat->{P}}{qw,p g l b a o d r n,} = qw,Standard-Perl
6763 distribution_allowed
6764 restricted_distribution
6766 for my $x (qw(d s l i p)) {
6767 $stat->{$x}{' '} = 'unknown';
6768 $stat->{$x}{'?'} = 'unknown';
6771 return +{} unless $ro && $ro->{statd};
6778 DV => $stat->{D}{$ro->{statd}},
6779 SV => $stat->{S}{$ro->{stats}},
6780 LV => $stat->{L}{$ro->{statl}},
6781 IV => $stat->{I}{$ro->{stati}},
6782 PV => $stat->{P}{$ro->{statp}},
6786 #-> sub CPAN::Module::as_string ;
6790 CPAN->debug("$self entering as_string") if $CPAN::DEBUG;
6791 my $class = ref($self);
6792 $class =~ s/^CPAN:://;
6794 push @m, $class, " id = $self->{ID}\n";
6795 my $sprintf = " %-12s %s\n";
6796 push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
6797 if $self->description;
6798 my $sprintf2 = " %-12s %s (%s)\n";
6800 $userid = $self->userid;
6803 if ($author = CPAN::Shell->expand('Author',$userid)) {
6806 if ($m = $author->email) {
6813 $author->fullname . $email
6817 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
6818 if $self->cpan_version;
6819 if (my $cpan_file = $self->cpan_file){
6820 push @m, sprintf($sprintf, 'CPAN_FILE', $cpan_file);
6821 if (my $dist = CPAN::Shell->expand("Distribution",$cpan_file)) {
6822 my $upload_date = $dist->upload_date;
6824 push @m, sprintf($sprintf, 'UPLOAD_DATE', $upload_date);
6828 my $sprintf3 = " %-12s %1s%1s%1s%1s%1s (%s,%s,%s,%s,%s)\n";
6829 my $dslip = $self->dslip_status;
6833 @{$dslip}{qw(D S L I P DV SV LV IV PV)},
6835 my $local_file = $self->inst_file;
6836 unless ($self->{MANPAGE}) {
6839 $manpage = $self->manpage_headline($local_file);
6841 # If we have already untarred it, we should look there
6842 my $dist = $CPAN::META->instance('CPAN::Distribution',
6844 # warn "dist[$dist]";
6845 # mff=manifest file; mfh=manifest handle
6850 (-f ($mff = File::Spec->catfile($dist->{build_dir}, "MANIFEST")))
6852 $mfh = FileHandle->new($mff)
6854 CPAN->debug("mff[$mff]") if $CPAN::DEBUG;
6855 my $lfre = $self->id; # local file RE
6858 my($lfl); # local file file
6860 my(@mflines) = <$mfh>;
6865 while (length($lfre)>5 and !$lfl) {
6866 ($lfl) = grep /$lfre/, @mflines;
6867 CPAN->debug("lfl[$lfl]lfre[$lfre]") if $CPAN::DEBUG;
6870 $lfl =~ s/\s.*//; # remove comments
6871 $lfl =~ s/\s+//g; # chomp would maybe be too system-specific
6872 my $lfl_abs = File::Spec->catfile($dist->{build_dir},$lfl);
6873 # warn "lfl_abs[$lfl_abs]";
6875 $manpage = $self->manpage_headline($lfl_abs);
6879 $self->{MANPAGE} = $manpage if $manpage;
6882 for $item (qw/MANPAGE/) {
6883 push @m, sprintf($sprintf, $item, $self->{$item})
6884 if exists $self->{$item};
6886 for $item (qw/CONTAINS/) {
6887 push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
6888 if exists $self->{$item} && @{$self->{$item}};
6890 push @m, sprintf($sprintf, 'INST_FILE',
6891 $local_file || "(not installed)");
6892 push @m, sprintf($sprintf, 'INST_VERSION',
6893 $self->inst_version) if $local_file;
6897 sub manpage_headline {
6898 my($self,$local_file) = @_;
6899 my(@local_file) = $local_file;
6900 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
6901 push @local_file, $local_file;
6903 for $locf (@local_file) {
6904 next unless -f $locf;
6905 my $fh = FileHandle->new($locf)
6906 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
6910 $inpod = m/^=(?!head1\s+NAME\s*$)/ ? 0 :
6911 m/^=head1\s+NAME\s*$/ ? 1 : $inpod;
6928 #-> sub CPAN::Module::cpan_file ;
6929 # Note: also inherited by CPAN::Bundle
6932 CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
6933 unless ($self->ro) {
6934 CPAN::Index->reload;
6937 if ($ro && defined $ro->{CPAN_FILE}){
6938 return $ro->{CPAN_FILE};
6940 my $userid = $self->userid;
6942 if ($CPAN::META->exists("CPAN::Author",$userid)) {
6943 my $author = $CPAN::META->instance("CPAN::Author",
6945 my $fullname = $author->fullname;
6946 my $email = $author->email;
6947 unless (defined $fullname && defined $email) {
6948 return sprintf("Contact Author %s",
6952 return "Contact Author $fullname <$email>";
6954 return "Contact Author $userid (Email address not available)";
6962 #-> sub CPAN::Module::cpan_version ;
6968 # Can happen with modules that are not on CPAN
6971 $ro->{CPAN_VERSION} = 'undef'
6972 unless defined $ro->{CPAN_VERSION};
6973 $ro->{CPAN_VERSION};
6976 #-> sub CPAN::Module::force ;
6979 $self->{'force_update'}++;
6984 # warn "XDEBUG: set notest for Module";
6985 $self->{'notest'}++;
6988 #-> sub CPAN::Module::rematein ;
6990 my($self,$meth) = @_;
6991 $CPAN::Frontend->myprint(sprintf("Running %s for module %s\n",
6994 my $cpan_file = $self->cpan_file;
6995 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
6996 $CPAN::Frontend->mywarn(sprintf qq{
6997 The module %s isn\'t available on CPAN.
6999 Either the module has not yet been uploaded to CPAN, or it is
7000 temporary unavailable. Please contact the author to find out
7001 more about the status. Try 'i %s'.
7008 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
7009 $pack->called_for($self->id);
7010 $pack->force($meth) if exists $self->{'force_update'};
7011 $pack->notest($meth) if exists $self->{'notest'};
7016 $pack->unforce if $pack->can("unforce") && exists $self->{'force_update'};
7017 $pack->unnotest if $pack->can("unnotest") && exists $self->{'notest'};
7018 delete $self->{'force_update'};
7019 delete $self->{'notest'};
7025 #-> sub CPAN::Module::perldoc ;
7026 sub perldoc { shift->rematein('perldoc') }
7027 #-> sub CPAN::Module::readme ;
7028 sub readme { shift->rematein('readme') }
7029 #-> sub CPAN::Module::look ;
7030 sub look { shift->rematein('look') }
7031 #-> sub CPAN::Module::cvs_import ;
7032 sub cvs_import { shift->rematein('cvs_import') }
7033 #-> sub CPAN::Module::get ;
7034 sub get { shift->rematein('get',@_) }
7035 #-> sub CPAN::Module::make ;
7036 sub make { shift->rematein('make') }
7037 #-> sub CPAN::Module::test ;
7040 $self->{badtestcnt} ||= 0;
7041 $self->rematein('test',@_);
7043 #-> sub CPAN::Module::uptodate ;
7046 local($_); # protect against a bug in MakeMaker 6.17
7047 my($latest) = $self->cpan_version;
7049 my($inst_file) = $self->inst_file;
7051 if (defined $inst_file) {
7052 $have = $self->inst_version;
7057 ! CPAN::Version->vgt($latest, $have)
7059 CPAN->debug("returning uptodate. inst_file[$inst_file] ".
7060 "latest[$latest] have[$have]") if $CPAN::DEBUG;
7065 #-> sub CPAN::Module::install ;
7071 not exists $self->{'force_update'}
7073 $CPAN::Frontend->myprint(sprintf("%s is up to date (%s).\n",
7075 $self->inst_version,
7081 if ($ro && $ro->{stats} && $ro->{stats} eq "a") {
7082 $CPAN::Frontend->mywarn(qq{
7083 \n\n\n ***WARNING***
7084 The module $self->{ID} has no active maintainer.\n\n\n
7086 $CPAN::Frontend->mysleep(5);
7088 $self->rematein('install') if $doit;
7090 #-> sub CPAN::Module::clean ;
7091 sub clean { shift->rematein('clean') }
7093 #-> sub CPAN::Module::inst_file ;
7097 @packpath = split /::/, $self->{ID};
7098 $packpath[-1] .= ".pm";
7099 if (@packpath == 1 && $packpath[0] eq "readline.pm") {
7100 unshift @packpath, "Term", "ReadLine"; # historical reasons
7102 foreach $dir (@INC) {
7103 my $pmfile = File::Spec->catfile($dir,@packpath);
7111 #-> sub CPAN::Module::xs_file ;
7115 @packpath = split /::/, $self->{ID};
7116 push @packpath, $packpath[-1];
7117 $packpath[-1] .= "." . $Config::Config{'dlext'};
7118 foreach $dir (@INC) {
7119 my $xsfile = File::Spec->catfile($dir,'auto',@packpath);
7127 #-> sub CPAN::Module::inst_version ;
7130 my $parsefile = $self->inst_file or return;
7131 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
7134 $have = MM->parse_version($parsefile) || "undef";
7135 $have =~ s/^ //; # since the %vd hack these two lines here are needed
7136 $have =~ s/ $//; # trailing whitespace happens all the time
7138 # My thoughts about why %vd processing should happen here
7140 # Alt1 maintain it as string with leading v:
7141 # read index files do nothing
7142 # compare it use utility for compare
7143 # print it do nothing
7145 # Alt2 maintain it as what it is
7146 # read index files convert
7147 # compare it use utility because there's still a ">" vs "gt" issue
7148 # print it use CPAN::Version for print
7150 # Seems cleaner to hold it in memory as a string starting with a "v"
7152 # If the author of this module made a mistake and wrote a quoted
7153 # "v1.13" instead of v1.13, we simply leave it at that with the
7154 # effect that *we* will treat it like a v-tring while the rest of
7155 # perl won't. Seems sensible when we consider that any action we
7156 # could take now would just add complexity.
7158 $have = CPAN::Version->readable($have);
7160 $have =~ s/\s*//g; # stringify to float around floating point issues
7161 $have; # no stringify needed, \s* above matches always
7174 CPAN - query, download and build perl modules from CPAN sites
7180 perl -MCPAN -e shell;
7188 $mod = "Acme::Meta";
7190 CPAN::Shell->install($mod); # same thing
7191 CPAN::Shell->expandany($mod)->install; # same thing
7192 CPAN::Shell->expand("Module",$mod)->install; # same thing
7193 CPAN::Shell->expand("Module",$mod)
7194 ->distribution->install; # same thing
7198 $distro = "NWCLARK/Acme-Meta-0.01.tar.gz";
7199 install $distro; # same thing
7200 CPAN::Shell->install($distro); # same thing
7201 CPAN::Shell->expandany($distro)->install; # same thing
7202 CPAN::Shell->expand("Distribution",$distro)->install; # same thing
7206 This module will eventually be replaced by CPANPLUS. CPANPLUS is kind
7207 of a modern rewrite from ground up with greater extensibility and more
7208 features but no full compatibility. If you're new to CPAN.pm, you
7209 probably should investigate if CPANPLUS is the better choice for you.
7211 If you're already used to CPAN.pm you're welcome to continue using it.
7212 I intend to support it until somebody convinces me that there is a
7213 both superior and sufficiently compatible drop-in replacement.
7215 =head1 COMPATIBILITY
7217 CPAN.pm is regularly tested to run under 5.004, 5.005, and assorted
7218 newer versions. It is getting more and more difficult to get the
7219 minimal prerequisites working on older perls. It is close to
7220 impossible to get the whole Bundle::CPAN working there. If you're in
7221 the position to have only these old versions, be advised that CPAN is
7222 designed to work fine without the Bundle::CPAN installed.
7224 To get things going, note that GBARR/Scalar-List-Utils-1.18.tar.gz is
7225 compatible with ancient perls and that File::Temp is listed as a
7226 prerequisite but CPAN has reasonable workarounds if it is missing.
7230 The CPAN module is designed to automate the make and install of perl
7231 modules and extensions. It includes some primitive searching
7232 capabilities and knows how to use Net::FTP or LWP (or some external
7233 download clients) to fetch the raw data from the net.
7235 Modules are fetched from one or more of the mirrored CPAN
7236 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
7239 The CPAN module also supports the concept of named and versioned
7240 I<bundles> of modules. Bundles simplify the handling of sets of
7241 related modules. See Bundles below.
7243 The package contains a session manager and a cache manager. There is
7244 no status retained between sessions. The session manager keeps track
7245 of what has been fetched, built and installed in the current
7246 session. The cache manager keeps track of the disk space occupied by
7247 the make processes and deletes excess space according to a simple FIFO
7250 All methods provided are accessible in a programmer style and in an
7251 interactive shell style.
7253 =head2 Interactive Mode
7255 The interactive mode is entered by running
7257 perl -MCPAN -e shell
7259 which puts you into a readline interface. You will have the most fun if
7260 you install Term::ReadKey and Term::ReadLine to enjoy both history and
7263 Once you are on the command line, type 'h' and the rest should be
7266 The function call C<shell> takes two optional arguments, one is the
7267 prompt, the second is the default initial command line (the latter
7268 only works if a real ReadLine interface module is installed).
7270 The most common uses of the interactive modes are
7274 =item Searching for authors, bundles, distribution files and modules
7276 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
7277 for each of the four categories and another, C<i> for any of the
7278 mentioned four. Each of the four entities is implemented as a class
7279 with slightly differing methods for displaying an object.
7281 Arguments you pass to these commands are either strings exactly matching
7282 the identification string of an object or regular expressions that are
7283 then matched case-insensitively against various attributes of the
7284 objects. The parser recognizes a regular expression only if you
7285 enclose it between two slashes.
7287 The principle is that the number of found objects influences how an
7288 item is displayed. If the search finds one item, the result is
7289 displayed with the rather verbose method C<as_string>, but if we find
7290 more than one, we display each object with the terse method
7293 =item make, test, install, clean modules or distributions
7295 These commands take any number of arguments and investigate what is
7296 necessary to perform the action. If the argument is a distribution
7297 file name (recognized by embedded slashes), it is processed. If it is
7298 a module, CPAN determines the distribution file in which this module
7299 is included and processes that, following any dependencies named in
7300 the module's META.yml or Makefile.PL (this behavior is controlled by
7301 the configuration parameter C<prerequisites_policy>.)
7303 Any C<make> or C<test> are run unconditionally. An
7305 install <distribution_file>
7307 also is run unconditionally. But for
7311 CPAN checks if an install is actually needed for it and prints
7312 I<module up to date> in the case that the distribution file containing
7313 the module doesn't need to be updated.
7315 CPAN also keeps track of what it has done within the current session
7316 and doesn't try to build a package a second time regardless if it
7317 succeeded or not. The C<force> pragma may precede another command
7318 (currently: C<make>, C<test>, or C<install>) and executes the
7319 command from scratch and tries to continue in case of some errors.
7323 cpan> install OpenGL
7324 OpenGL is up to date.
7325 cpan> force install OpenGL
7328 OpenGL-0.4/COPYRIGHT
7331 The C<notest> pragma may be set to skip the test part in the build
7336 cpan> notest install Tk
7338 A C<clean> command results in a
7342 being executed within the distribution file's working directory.
7344 =item get, readme, perldoc, look module or distribution
7346 C<get> downloads a distribution file without further action. C<readme>
7347 displays the README file of the associated distribution. C<Look> gets
7348 and untars (if not yet done) the distribution file, changes to the
7349 appropriate directory and opens a subshell process in that directory.
7350 C<perldoc> displays the pod documentation of the module in html or
7355 =item ls globbing_expression
7357 The first form lists all distribution files in and below an author's
7358 CPAN directory as they are stored in the CHECKUMS files distributed on
7359 CPAN. The listing goes recursive into all subdirectories.
7361 The second form allows to limit or expand the output with shell
7362 globbing as in the following examples:
7368 The last example is very slow and outputs extra progress indicators
7369 that break the alignment of the result.
7371 Note that globbing only lists directories explicitly asked for, for
7372 example FOO/* will not list FOO/bar/Acme-Sthg-n.nn.tar.gz. This may be
7373 regarded as a bug and may be changed in future versions.
7377 The C<failed> command reports all distributions that failed on one of
7378 C<make>, C<test> or C<install> for some reason in the currently
7379 running shell session.
7383 Interactive sessions maintain a lockfile, per default C<~/.cpan/.lock>
7384 (but the directory can be configured via the C<cpan_home> config
7385 variable). The shell is a bit picky if you try to start another CPAN
7386 session. It dies immediately if there is a lockfile and the lock seems
7387 to belong to a running process. In case you want to run a second shell
7388 session, it is probably safest to maintain another directory, say
7389 C<~/.cpan-for-X/> and a C<~/.cpan-for-X/CPAN/MyConfig.pm> that
7390 contains the configuration options. Then you can start the second
7393 perl -I ~/.cpan-for-X -MCPAN::MyConfig -MCPAN -e shell
7397 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
7398 in the cpan-shell it is intended that you can press C<^C> anytime and
7399 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
7400 to clean up and leave the shell loop. You can emulate the effect of a
7401 SIGTERM by sending two consecutive SIGINTs, which usually means by
7402 pressing C<^C> twice.
7404 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
7405 SIGALRM is used during the run of the C<perl Makefile.PL> or C<perl
7406 Build.PL> subprocess.
7412 The commands that are available in the shell interface are methods in
7413 the package CPAN::Shell. If you enter the shell command, all your
7414 input is split by the Text::ParseWords::shellwords() routine which
7415 acts like most shells do. The first word is being interpreted as the
7416 method to be called and the rest of the words are treated as arguments
7417 to this method. Continuation lines are supported if a line ends with a
7422 C<autobundle> writes a bundle file into the
7423 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
7424 a list of all modules that are both available from CPAN and currently
7425 installed within @INC. The name of the bundle file is based on the
7426 current date and a counter.
7430 recompile() is a very special command in that it takes no argument and
7431 runs the make/test/install cycle with brute force over all installed
7432 dynamically loadable extensions (aka XS modules) with 'force' in
7433 effect. The primary purpose of this command is to finish a network
7434 installation. Imagine, you have a common source tree for two different
7435 architectures. You decide to do a completely independent fresh
7436 installation. You start on one architecture with the help of a Bundle
7437 file produced earlier. CPAN installs the whole Bundle for you, but
7438 when you try to repeat the job on the second architecture, CPAN
7439 responds with a C<"Foo up to date"> message for all modules. So you
7440 invoke CPAN's recompile on the second architecture and you're done.
7442 Another popular use for C<recompile> is to act as a rescue in case your
7443 perl breaks binary compatibility. If one of the modules that CPAN uses
7444 is in turn depending on binary compatibility (so you cannot run CPAN
7445 commands), then you should try the CPAN::Nox module for recovery.
7449 The C<upgrade> command first runs an C<r> command and then installs
7450 the newest versions of all modules that were listed by that.
7454 mkmyconfig() writes your own CPAN::MyConfig file into your ~/.cpan/
7455 directory so that you can save your own preferences instead of the
7458 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
7460 Although it may be considered internal, the class hierarchy does matter
7461 for both users and programmer. CPAN.pm deals with above mentioned four
7462 classes, and all those classes share a set of methods. A classical
7463 single polymorphism is in effect. A metaclass object registers all
7464 objects of all kinds and indexes them with a string. The strings
7465 referencing objects have a separated namespace (well, not completely
7470 words containing a "/" (slash) Distribution
7471 words starting with Bundle:: Bundle
7472 everything else Module or Author
7474 Modules know their associated Distribution objects. They always refer
7475 to the most recent official release. Developers may mark their releases
7476 as unstable development versions (by inserting an underbar into the
7477 module version number which will also be reflected in the distribution
7478 name when you run 'make dist'), so the really hottest and newest
7479 distribution is not always the default. If a module Foo circulates
7480 on CPAN in both version 1.23 and 1.23_90, CPAN.pm offers a convenient
7481 way to install version 1.23 by saying
7485 This would install the complete distribution file (say
7486 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
7487 like to install version 1.23_90, you need to know where the
7488 distribution file resides on CPAN relative to the authors/id/
7489 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
7490 so you would have to say
7492 install BAR/Foo-1.23_90.tar.gz
7494 The first example will be driven by an object of the class
7495 CPAN::Module, the second by an object of class CPAN::Distribution.
7497 =head2 Programmer's interface
7499 If you do not enter the shell, the available shell commands are both
7500 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
7501 functions in the calling package (C<install(...)>).
7503 There's currently only one class that has a stable interface -
7504 CPAN::Shell. All commands that are available in the CPAN shell are
7505 methods of the class CPAN::Shell. Each of the commands that produce
7506 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
7507 the IDs of all modules within the list.
7511 =item expand($type,@things)
7513 The IDs of all objects available within a program are strings that can
7514 be expanded to the corresponding real objects with the
7515 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
7516 list of CPAN::Module objects according to the C<@things> arguments
7517 given. In scalar context it only returns the first element of the
7520 =item expandany(@things)
7522 Like expand, but returns objects of the appropriate type, i.e.
7523 CPAN::Bundle objects for bundles, CPAN::Module objects for modules and
7524 CPAN::Distribution objects for distributions. Note: it does not expand
7525 to CPAN::Author objects.
7527 =item Programming Examples
7529 This enables the programmer to do operations that combine
7530 functionalities that are available in the shell.
7532 # install everything that is outdated on my disk:
7533 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
7535 # install my favorite programs if necessary:
7536 for $mod (qw(Net::FTP Digest::SHA Data::Dumper)){
7537 my $obj = CPAN::Shell->expand('Module',$mod);
7541 # list all modules on my disk that have no VERSION number
7542 for $mod (CPAN::Shell->expand("Module","/./")){
7543 next unless $mod->inst_file;
7544 # MakeMaker convention for undefined $VERSION:
7545 next unless $mod->inst_version eq "undef";
7546 print "No VERSION in ", $mod->id, "\n";
7549 # find out which distribution on CPAN contains a module:
7550 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
7552 Or if you want to write a cronjob to watch The CPAN, you could list
7553 all modules that need updating. First a quick and dirty way:
7555 perl -e 'use CPAN; CPAN::Shell->r;'
7557 If you don't want to get any output in the case that all modules are
7558 up to date, you can parse the output of above command for the regular
7559 expression //modules are up to date// and decide to mail the output
7560 only if it doesn't match. Ick?
7562 If you prefer to do it more in a programmer style in one single
7563 process, maybe something like this suits you better:
7565 # list all modules on my disk that have newer versions on CPAN
7566 for $mod (CPAN::Shell->expand("Module","/./")){
7567 next unless $mod->inst_file;
7568 next if $mod->uptodate;
7569 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
7570 $mod->id, $mod->inst_version, $mod->cpan_version;
7573 If that gives you too much output every day, you maybe only want to
7574 watch for three modules. You can write
7576 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")){
7578 as the first line instead. Or you can combine some of the above
7581 # watch only for a new mod_perl module
7582 $mod = CPAN::Shell->expand("Module","mod_perl");
7583 exit if $mod->uptodate;
7584 # new mod_perl arrived, let me know all update recommendations
7589 =head2 Methods in the other Classes
7591 The programming interface for the classes CPAN::Module,
7592 CPAN::Distribution, CPAN::Bundle, and CPAN::Author is still considered
7593 beta and partially even alpha. In the following paragraphs only those
7594 methods are documented that have proven useful over a longer time and
7595 thus are unlikely to change.
7599 =item CPAN::Author::as_glimpse()
7601 Returns a one-line description of the author
7603 =item CPAN::Author::as_string()
7605 Returns a multi-line description of the author
7607 =item CPAN::Author::email()
7609 Returns the author's email address
7611 =item CPAN::Author::fullname()
7613 Returns the author's name
7615 =item CPAN::Author::name()
7617 An alias for fullname
7619 =item CPAN::Bundle::as_glimpse()
7621 Returns a one-line description of the bundle
7623 =item CPAN::Bundle::as_string()
7625 Returns a multi-line description of the bundle
7627 =item CPAN::Bundle::clean()
7629 Recursively runs the C<clean> method on all items contained in the bundle.
7631 =item CPAN::Bundle::contains()
7633 Returns a list of objects' IDs contained in a bundle. The associated
7634 objects may be bundles, modules or distributions.
7636 =item CPAN::Bundle::force($method,@args)
7638 Forces CPAN to perform a task that normally would have failed. Force
7639 takes as arguments a method name to be called and any number of
7640 additional arguments that should be passed to the called method. The
7641 internals of the object get the needed changes so that CPAN.pm does
7642 not refuse to take the action. The C<force> is passed recursively to
7643 all contained objects.
7645 =item CPAN::Bundle::get()
7647 Recursively runs the C<get> method on all items contained in the bundle
7649 =item CPAN::Bundle::inst_file()
7651 Returns the highest installed version of the bundle in either @INC or
7652 C<$CPAN::Config->{cpan_home}>. Note that this is different from
7653 CPAN::Module::inst_file.
7655 =item CPAN::Bundle::inst_version()
7657 Like CPAN::Bundle::inst_file, but returns the $VERSION
7659 =item CPAN::Bundle::uptodate()
7661 Returns 1 if the bundle itself and all its members are uptodate.
7663 =item CPAN::Bundle::install()
7665 Recursively runs the C<install> method on all items contained in the bundle
7667 =item CPAN::Bundle::make()
7669 Recursively runs the C<make> method on all items contained in the bundle
7671 =item CPAN::Bundle::readme()
7673 Recursively runs the C<readme> method on all items contained in the bundle
7675 =item CPAN::Bundle::test()
7677 Recursively runs the C<test> method on all items contained in the bundle
7679 =item CPAN::Distribution::as_glimpse()
7681 Returns a one-line description of the distribution
7683 =item CPAN::Distribution::as_string()
7685 Returns a multi-line description of the distribution
7687 =item CPAN::Distribution::author
7689 Returns the CPAN::Author object of the maintainer who uploaded this
7692 =item CPAN::Distribution::clean()
7694 Changes to the directory where the distribution has been unpacked and
7695 runs C<make clean> there.
7697 =item CPAN::Distribution::containsmods()
7699 Returns a list of IDs of modules contained in a distribution file.
7700 Only works for distributions listed in the 02packages.details.txt.gz
7701 file. This typically means that only the most recent version of a
7702 distribution is covered.
7704 =item CPAN::Distribution::cvs_import()
7706 Changes to the directory where the distribution has been unpacked and
7709 cvs -d $cvs_root import -m $cvs_log $cvs_dir $userid v$version
7713 =item CPAN::Distribution::dir()
7715 Returns the directory into which this distribution has been unpacked.
7717 =item CPAN::Distribution::force($method,@args)
7719 Forces CPAN to perform a task that normally would have failed. Force
7720 takes as arguments a method name to be called and any number of
7721 additional arguments that should be passed to the called method. The
7722 internals of the object get the needed changes so that CPAN.pm does
7723 not refuse to take the action.
7725 =item CPAN::Distribution::get()
7727 Downloads the distribution from CPAN and unpacks it. Does nothing if
7728 the distribution has already been downloaded and unpacked within the
7731 =item CPAN::Distribution::install()
7733 Changes to the directory where the distribution has been unpacked and
7734 runs the external command C<make install> there. If C<make> has not
7735 yet been run, it will be run first. A C<make test> will be issued in
7736 any case and if this fails, the install will be canceled. The
7737 cancellation can be avoided by letting C<force> run the C<install> for
7740 Note that install() gives no meaningful return value. See uptodate().
7742 =item CPAN::Distribution::isa_perl()
7744 Returns 1 if this distribution file seems to be a perl distribution.
7745 Normally this is derived from the file name only, but the index from
7746 CPAN can contain a hint to achieve a return value of true for other
7749 =item CPAN::Distribution::look()
7751 Changes to the directory where the distribution has been unpacked and
7752 opens a subshell there. Exiting the subshell returns.
7754 =item CPAN::Distribution::make()
7756 First runs the C<get> method to make sure the distribution is
7757 downloaded and unpacked. Changes to the directory where the
7758 distribution has been unpacked and runs the external commands C<perl
7759 Makefile.PL> or C<perl Build.PL> and C<make> there.
7761 =item CPAN::Distribution::perldoc()
7763 Downloads the pod documentation of the file associated with a
7764 distribution (in html format) and runs it through the external
7765 command lynx specified in C<$CPAN::Config->{lynx}>. If lynx
7766 isn't available, it converts it to plain text with external
7767 command html2text and runs it through the pager specified
7768 in C<$CPAN::Config->{pager}>
7770 =item CPAN::Distribution::prereq_pm()
7772 Returns the hash reference that has been announced by a distribution
7773 as the merge of the C<requires> element and the C<build_requires>
7774 element of the META.yml or the C<PREREQ_PM> hash in the
7775 C<Makefile.PL>. Note: works only after an attempt has been made to
7776 C<make> the distribution. Returns undef otherwise.
7778 =item CPAN::Distribution::readme()
7780 Downloads the README file associated with a distribution and runs it
7781 through the pager specified in C<$CPAN::Config->{pager}>.
7783 =item CPAN::Distribution::read_yaml()
7785 Returns the content of the META.yml of this distro as a hashref. Note:
7786 works only after an attempt has been made to C<make> the distribution.
7787 Returns undef otherwise.
7789 =item CPAN::Distribution::test()
7791 Changes to the directory where the distribution has been unpacked and
7792 runs C<make test> there.
7794 =item CPAN::Distribution::uptodate()
7796 Returns 1 if all the modules contained in the distribution are
7797 uptodate. Relies on containsmods.
7799 =item CPAN::Index::force_reload()
7801 Forces a reload of all indices.
7803 =item CPAN::Index::reload()
7805 Reloads all indices if they have not been read for more than
7806 C<$CPAN::Config->{index_expire}> days.
7808 =item CPAN::InfoObj::dump()
7810 CPAN::Author, CPAN::Bundle, CPAN::Module, and CPAN::Distribution
7811 inherit this method. It prints the data structure associated with an
7812 object. Useful for debugging. Note: the data structure is considered
7813 internal and thus subject to change without notice.
7815 =item CPAN::Module::as_glimpse()
7817 Returns a one-line description of the module in four columns: The
7818 first column contains the word C<Module>, the second column consists
7819 of one character: an equals sign if this module is already installed
7820 and uptodate, a less-than sign if this module is installed but can be
7821 upgraded, and a space if the module is not installed. The third column
7822 is the name of the module and the fourth column gives maintainer or
7823 distribution information.
7825 =item CPAN::Module::as_string()
7827 Returns a multi-line description of the module
7829 =item CPAN::Module::clean()
7831 Runs a clean on the distribution associated with this module.
7833 =item CPAN::Module::cpan_file()
7835 Returns the filename on CPAN that is associated with the module.
7837 =item CPAN::Module::cpan_version()
7839 Returns the latest version of this module available on CPAN.
7841 =item CPAN::Module::cvs_import()
7843 Runs a cvs_import on the distribution associated with this module.
7845 =item CPAN::Module::description()
7847 Returns a 44 character description of this module. Only available for
7848 modules listed in The Module List (CPAN/modules/00modlist.long.html
7849 or 00modlist.long.txt.gz)
7851 =item CPAN::Module::distribution()
7853 Returns the CPAN::Distribution object that contains the current
7854 version of this module.
7856 =item CPAN::Module::dslip_status()
7858 Returns a hash reference. The keys of the hash are the letters C<D>,
7859 C<S>, C<L>, C<I>, and <P>, for development status, support level,
7860 language, interface and public licence respectively. The data for the
7861 DSLIP status are collected by pause.perl.org when authors register
7862 their namespaces. The values of the 5 hash elements are one-character
7863 words whose meaning is described in the table below. There are also 5
7864 hash elements C<DV>, C<SV>, C<LV>, C<IV>, and <PV> that carry a more
7865 verbose value of the 5 status variables.
7867 Where the 'DSLIP' characters have the following meanings:
7869 D - Development Stage (Note: *NO IMPLIED TIMESCALES*):
7870 i - Idea, listed to gain consensus or as a placeholder
7871 c - under construction but pre-alpha (not yet released)
7872 a/b - Alpha/Beta testing
7874 M - Mature (no rigorous definition)
7875 S - Standard, supplied with Perl 5
7880 u - Usenet newsgroup comp.lang.perl.modules
7881 n - None known, try comp.lang.perl.modules
7882 a - abandoned; volunteers welcome to take over maintainance
7885 p - Perl-only, no compiler needed, should be platform independent
7886 c - C and perl, a C compiler will be needed
7887 h - Hybrid, written in perl with optional C code, no compiler needed
7888 + - C++ and perl, a C++ compiler will be needed
7889 o - perl and another language other than C or C++
7892 f - plain Functions, no references used
7893 h - hybrid, object and function interfaces available
7894 n - no interface at all (huh?)
7895 r - some use of unblessed References or ties
7896 O - Object oriented using blessed references and/or inheritance
7899 p - Standard-Perl: user may choose between GPL and Artistic
7900 g - GPL: GNU General Public License
7901 l - LGPL: "GNU Lesser General Public License" (previously known as
7902 "GNU Library General Public License")
7903 b - BSD: The BSD License
7904 a - Artistic license alone
7905 o - open source: appoved by www.opensource.org
7906 d - allows distribution without restrictions
7907 r - restricted distribtion
7908 n - no license at all
7910 =item CPAN::Module::force($method,@args)
7912 Forces CPAN to perform a task that normally would have failed. Force
7913 takes as arguments a method name to be called and any number of
7914 additional arguments that should be passed to the called method. The
7915 internals of the object get the needed changes so that CPAN.pm does
7916 not refuse to take the action.
7918 =item CPAN::Module::get()
7920 Runs a get on the distribution associated with this module.
7922 =item CPAN::Module::inst_file()
7924 Returns the filename of the module found in @INC. The first file found
7925 is reported just like perl itself stops searching @INC when it finds a
7928 =item CPAN::Module::inst_version()
7930 Returns the version number of the module in readable format.
7932 =item CPAN::Module::install()
7934 Runs an C<install> on the distribution associated with this module.
7936 =item CPAN::Module::look()
7938 Changes to the directory where the distribution associated with this
7939 module has been unpacked and opens a subshell there. Exiting the
7942 =item CPAN::Module::make()
7944 Runs a C<make> on the distribution associated with this module.
7946 =item CPAN::Module::manpage_headline()
7948 If module is installed, peeks into the module's manpage, reads the
7949 headline and returns it. Moreover, if the module has been downloaded
7950 within this session, does the equivalent on the downloaded module even
7951 if it is not installed.
7953 =item CPAN::Module::perldoc()
7955 Runs a C<perldoc> on this module.
7957 =item CPAN::Module::readme()
7959 Runs a C<readme> on the distribution associated with this module.
7961 =item CPAN::Module::test()
7963 Runs a C<test> on the distribution associated with this module.
7965 =item CPAN::Module::uptodate()
7967 Returns 1 if the module is installed and up-to-date.
7969 =item CPAN::Module::userid()
7971 Returns the author's ID of the module.
7975 =head2 Cache Manager
7977 Currently the cache manager only keeps track of the build directory
7978 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
7979 deletes complete directories below C<build_dir> as soon as the size of
7980 all directories there gets bigger than $CPAN::Config->{build_cache}
7981 (in MB). The contents of this cache may be used for later
7982 re-installations that you intend to do manually, but will never be
7983 trusted by CPAN itself. This is due to the fact that the user might
7984 use these directories for building modules on different architectures.
7986 There is another directory ($CPAN::Config->{keep_source_where}) where
7987 the original distribution files are kept. This directory is not
7988 covered by the cache manager and must be controlled by the user. If
7989 you choose to have the same directory as build_dir and as
7990 keep_source_where directory, then your sources will be deleted with
7991 the same fifo mechanism.
7995 A bundle is just a perl module in the namespace Bundle:: that does not
7996 define any functions or methods. It usually only contains documentation.
7998 It starts like a perl module with a package declaration and a $VERSION
7999 variable. After that the pod section looks like any other pod with the
8000 only difference being that I<one special pod section> exists starting with
8005 In this pod section each line obeys the format
8007 Module_Name [Version_String] [- optional text]
8009 The only required part is the first field, the name of a module
8010 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
8011 of the line is optional. The comment part is delimited by a dash just
8012 as in the man page header.
8014 The distribution of a bundle should follow the same convention as
8015 other distributions.
8017 Bundles are treated specially in the CPAN package. If you say 'install
8018 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
8019 the modules in the CONTENTS section of the pod. You can install your
8020 own Bundles locally by placing a conformant Bundle file somewhere into
8021 your @INC path. The autobundle() command which is available in the
8022 shell interface does that for you by including all currently installed
8023 modules in a snapshot bundle file.
8025 =head2 Prerequisites
8027 If you have a local mirror of CPAN and can access all files with
8028 "file:" URLs, then you only need a perl better than perl5.003 to run
8029 this module. Otherwise Net::FTP is strongly recommended. LWP may be
8030 required for non-UNIX systems or if your nearest CPAN site is
8031 associated with a URL that is not C<ftp:>.
8033 If you have neither Net::FTP nor LWP, there is a fallback mechanism
8034 implemented for an external ftp command or for an external lynx
8037 =head2 Finding packages and VERSION
8039 This module presumes that all packages on CPAN
8045 declare their $VERSION variable in an easy to parse manner. This
8046 prerequisite can hardly be relaxed because it consumes far too much
8047 memory to load all packages into the running program just to determine
8048 the $VERSION variable. Currently all programs that are dealing with
8049 version use something like this
8051 perl -MExtUtils::MakeMaker -le \
8052 'print MM->parse_version(shift)' filename
8054 If you are author of a package and wonder if your $VERSION can be
8055 parsed, please try the above method.
8059 come as compressed or gzipped tarfiles or as zip files and contain a
8060 C<Makefile.PL> or C<Build.PL> (well, we try to handle a bit more, but
8061 without much enthusiasm).
8067 The debugging of this module is a bit complex, because we have
8068 interferences of the software producing the indices on CPAN, of the
8069 mirroring process on CPAN, of packaging, of configuration, of
8070 synchronicity, and of bugs within CPAN.pm.
8072 For code debugging in interactive mode you can try "o debug" which
8073 will list options for debugging the various parts of the code. You
8074 should know that "o debug" has built-in completion support.
8076 For data debugging there is the C<dump> command which takes the same
8077 arguments as make/test/install and outputs the object's Data::Dumper
8080 =head2 Floppy, Zip, Offline Mode
8082 CPAN.pm works nicely without network too. If you maintain machines
8083 that are not networked at all, you should consider working with file:
8084 URLs. Of course, you have to collect your modules somewhere first. So
8085 you might use CPAN.pm to put together all you need on a networked
8086 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
8087 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
8088 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
8089 with this floppy. See also below the paragraph about CD-ROM support.
8091 =head1 CONFIGURATION
8093 When the CPAN module is used for the first time, a configuration
8094 dialog tries to determine a couple of site specific options. The
8095 result of the dialog is stored in a hash reference C< $CPAN::Config >
8096 in a file CPAN/Config.pm.
8098 The default values defined in the CPAN/Config.pm file can be
8099 overridden in a user specific file: CPAN/MyConfig.pm. Such a file is
8100 best placed in $HOME/.cpan/CPAN/MyConfig.pm, because $HOME/.cpan is
8101 added to the search path of the CPAN module before the use() or
8102 require() statements.
8104 The configuration dialog can be started any time later again by
8105 issuing the command C< o conf init > in the CPAN shell. A subset of
8106 the configuration dialog can be run by issuing C<o conf init WORD>
8107 where WORD is any valid config variable or a regular expression.
8109 Currently the following keys in the hash reference $CPAN::Config are
8112 build_cache size of cache for directories to build modules
8113 build_dir locally accessible directory to build modules
8114 cache_metadata use serializer to cache metadata
8115 commands_quote prefered character to use for quoting external
8116 commands when running them. Defaults to double
8117 quote on Windows, single tick everywhere else;
8118 can be set to space to disable quoting
8119 check_sigs if signatures should be verified
8120 cpan_home local directory reserved for this package
8121 dontload_list arrayref: modules in the list will not be
8122 loaded by the CPAN::has_inst() routine
8124 gzip location of external program gzip
8125 histfile file to maintain history between sessions
8126 histsize maximum number of lines to keep in histfile
8127 inactivity_timeout breaks interactive Makefile.PLs or Build.PLs
8128 after this many seconds inactivity. Set to 0 to
8130 index_expire after this many days refetch index files
8131 inhibit_startup_message
8132 if true, does not print the startup message
8133 keep_source_where directory in which to keep the source (if we do)
8134 make location of external make program
8135 make_arg arguments that should always be passed to 'make'
8136 make_install_make_command
8137 the make command for running 'make install', for
8139 make_install_arg same as make_arg for 'make install'
8140 makepl_arg arguments passed to 'perl Makefile.PL'
8141 mbuild_arg arguments passed to './Build'
8142 mbuild_install_arg arguments passed to './Build install'
8143 mbuild_install_build_command
8144 command to use instead of './Build' when we are
8145 in the install stage, for example 'sudo ./Build'
8146 mbuildpl_arg arguments passed to 'perl Build.PL'
8147 pager location of external program more (or any pager)
8148 prefer_installer legal values are MB and EUMM: if a module comes
8149 with both a Makefile.PL and a Build.PL, use the
8150 former (EUMM) or the latter (MB); if the module
8151 comes with only one of the two, that one will be
8153 prerequisites_policy
8154 what to do if you are missing module prerequisites
8155 ('follow' automatically, 'ask' me, or 'ignore')
8156 proxy_user username for accessing an authenticating proxy
8157 proxy_pass password for accessing an authenticating proxy
8158 scan_cache controls scanning of cache ('atstart' or 'never')
8159 tar location of external program tar
8160 term_is_latin if true internal UTF-8 is translated to ISO-8859-1
8161 (and nonsense for characters outside latin range)
8162 test_report email test reports (if CPAN::Reporter is installed)
8163 unzip location of external program unzip
8164 urllist arrayref to nearby CPAN sites (or equivalent locations)
8165 wait_list arrayref to a wait server to try (See CPAN::WAIT)
8166 ftp_passive if set, the envariable FTP_PASSIVE is set for downloads
8167 ftp_proxy, } the three usual variables for configuring
8168 http_proxy, } proxy requests. Both as CPAN::Config variables
8169 no_proxy } and as environment variables configurable.
8171 You can set and query each of these options interactively in the cpan
8172 shell with the command set defined within the C<o conf> command:
8176 =item C<o conf E<lt>scalar optionE<gt>>
8178 prints the current value of the I<scalar option>
8180 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
8182 Sets the value of the I<scalar option> to I<value>
8184 =item C<o conf E<lt>list optionE<gt>>
8186 prints the current value of the I<list option> in MakeMaker's
8189 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
8191 shifts or pops the array in the I<list option> variable
8193 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
8195 works like the corresponding perl commands.
8199 =head2 Note on config variable getcwd
8201 CPAN.pm changes the current working directory often and needs to
8202 determine its own current working directory. Per default it uses
8203 Cwd::cwd but if this doesn't work on your system for some reason,
8204 alternatives can be configured according to the following table:
8208 fastcwd Cwd::fastcwd
8209 backtickcwd external command cwd
8211 =head2 Note on urllist parameter's format
8213 urllist parameters are URLs according to RFC 1738. We do a little
8214 guessing if your URL is not compliant, but if you have problems with
8215 file URLs, please try the correct format. Either:
8217 file://localhost/whatever/ftp/pub/CPAN/
8221 file:///home/ftp/pub/CPAN/
8223 =head2 urllist parameter has CD-ROM support
8225 The C<urllist> parameter of the configuration table contains a list of
8226 URLs that are to be used for downloading. If the list contains any
8227 C<file> URLs, CPAN always tries to get files from there first. This
8228 feature is disabled for index files. So the recommendation for the
8229 owner of a CD-ROM with CPAN contents is: include your local, possibly
8230 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
8232 o conf urllist push file://localhost/CDROM/CPAN
8234 CPAN.pm will then fetch the index files from one of the CPAN sites
8235 that come at the beginning of urllist. It will later check for each
8236 module if there is a local copy of the most recent version.
8238 Another peculiarity of urllist is that the site that we could
8239 successfully fetch the last file from automatically gets a preference
8240 token and is tried as the first site for the next request. So if you
8241 add a new site at runtime it may happen that the previously preferred
8242 site will be tried another time. This means that if you want to disallow
8243 a site for the next transfer, it must be explicitly removed from
8248 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
8249 install foreign, unmasked, unsigned code on your machine. We compare
8250 to a checksum that comes from the net just as the distribution file
8251 itself. But we try to make it easy to add security on demand:
8253 =head2 Cryptographically signed modules
8255 Since release 1.77 CPAN.pm has been able to verify cryptographically
8256 signed module distributions using Module::Signature. The CPAN modules
8257 can be signed by their authors, thus giving more security. The simple
8258 unsigned MD5 checksums that were used before by CPAN protect mainly
8259 against accidental file corruption.
8261 You will need to have Module::Signature installed, which in turn
8262 requires that you have at least one of Crypt::OpenPGP module or the
8263 command-line F<gpg> tool installed.
8265 You will also need to be able to connect over the Internet to the public
8266 keyservers, like pgp.mit.edu, and their port 11731 (the HKP protocol).
8268 The configuration parameter check_sigs is there to turn signature
8273 Most functions in package CPAN are exported per default. The reason
8274 for this is that the primary use is intended for the cpan shell or for
8279 When the CPAN shell enters a subshell via the look command, it sets
8280 the environment CPAN_SHELL_LEVEL to 1 or increments it if it is
8283 When the config variable ftp_passive is set, all downloads will be run
8284 with the environment variable FTP_PASSIVE set to this value. This is
8285 in general a good idea as it influences both Net::FTP and LWP based
8286 connections. The same effect can be achieved by starting the cpan
8287 shell with this environment variable set. For Net::FTP alone, one can
8288 also always set passive mode by running libnetcfg.
8290 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
8292 Populating a freshly installed perl with my favorite modules is pretty
8293 easy if you maintain a private bundle definition file. To get a useful
8294 blueprint of a bundle definition file, the command autobundle can be used
8295 on the CPAN shell command line. This command writes a bundle definition
8296 file for all modules that are installed for the currently running perl
8297 interpreter. It's recommended to run this command only once and from then
8298 on maintain the file manually under a private name, say
8299 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
8301 cpan> install Bundle::my_bundle
8303 then answer a few questions and then go out for a coffee.
8305 Maintaining a bundle definition file means keeping track of two
8306 things: dependencies and interactivity. CPAN.pm sometimes fails on
8307 calculating dependencies because not all modules define all MakeMaker
8308 attributes correctly, so a bundle definition file should specify
8309 prerequisites as early as possible. On the other hand, it's a bit
8310 annoying that many distributions need some interactive configuring. So
8311 what I try to accomplish in my private bundle file is to have the
8312 packages that need to be configured early in the file and the gentle
8313 ones later, so I can go out after a few minutes and leave CPAN.pm
8316 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
8318 Thanks to Graham Barr for contributing the following paragraphs about
8319 the interaction between perl, and various firewall configurations. For
8320 further information on firewalls, it is recommended to consult the
8321 documentation that comes with the ncftp program. If you are unable to
8322 go through the firewall with a simple Perl setup, it is very likely
8323 that you can configure ncftp so that it works for your firewall.
8325 =head2 Three basic types of firewalls
8327 Firewalls can be categorized into three basic types.
8333 This is where the firewall machine runs a web server and to access the
8334 outside world you must do it via the web server. If you set environment
8335 variables like http_proxy or ftp_proxy to a values beginning with http://
8336 or in your web browser you have to set proxy information then you know
8337 you are running an http firewall.
8339 To access servers outside these types of firewalls with perl (even for
8340 ftp) you will need to use LWP.
8344 This where the firewall machine runs an ftp server. This kind of
8345 firewall will only let you access ftp servers outside the firewall.
8346 This is usually done by connecting to the firewall with ftp, then
8347 entering a username like "user@outside.host.com"
8349 To access servers outside these type of firewalls with perl you
8350 will need to use Net::FTP.
8352 =item One way visibility
8354 I say one way visibility as these firewalls try to make themselves look
8355 invisible to the users inside the firewall. An FTP data connection is
8356 normally created by sending the remote server your IP address and then
8357 listening for the connection. But the remote server will not be able to
8358 connect to you because of the firewall. So for these types of firewall
8359 FTP connections need to be done in a passive mode.
8361 There are two that I can think off.
8367 If you are using a SOCKS firewall you will need to compile perl and link
8368 it with the SOCKS library, this is what is normally called a 'socksified'
8369 perl. With this executable you will be able to connect to servers outside
8370 the firewall as if it is not there.
8374 This is the firewall implemented in the Linux kernel, it allows you to
8375 hide a complete network behind one IP address. With this firewall no
8376 special compiling is needed as you can access hosts directly.
8378 For accessing ftp servers behind such firewalls you usually need to
8379 set the environment variable C<FTP_PASSIVE> or the config variable
8380 ftp_passive to a true value.
8386 =head2 Configuring lynx or ncftp for going through a firewall
8388 If you can go through your firewall with e.g. lynx, presumably with a
8391 /usr/local/bin/lynx -pscott:tiger
8393 then you would configure CPAN.pm with the command
8395 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
8397 That's all. Similarly for ncftp or ftp, you would configure something
8400 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
8402 Your mileage may vary...
8410 I installed a new version of module X but CPAN keeps saying,
8411 I have the old version installed
8413 Most probably you B<do> have the old version installed. This can
8414 happen if a module installs itself into a different directory in the
8415 @INC path than it was previously installed. This is not really a
8416 CPAN.pm problem, you would have the same problem when installing the
8417 module manually. The easiest way to prevent this behaviour is to add
8418 the argument C<UNINST=1> to the C<make install> call, and that is why
8419 many people add this argument permanently by configuring
8421 o conf make_install_arg UNINST=1
8425 So why is UNINST=1 not the default?
8427 Because there are people who have their precise expectations about who
8428 may install where in the @INC path and who uses which @INC array. In
8429 fine tuned environments C<UNINST=1> can cause damage.
8433 I want to clean up my mess, and install a new perl along with
8434 all modules I have. How do I go about it?
8436 Run the autobundle command for your old perl and optionally rename the
8437 resulting bundle file (e.g. Bundle/mybundle.pm), install the new perl
8438 with the Configure option prefix, e.g.
8440 ./Configure -Dprefix=/usr/local/perl-5.6.78.9
8442 Install the bundle file you produced in the first step with something like
8444 cpan> install Bundle::mybundle
8450 When I install bundles or multiple modules with one command
8451 there is too much output to keep track of.
8453 You may want to configure something like
8455 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
8456 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
8458 so that STDOUT is captured in a file for later inspection.
8463 I am not root, how can I install a module in a personal directory?
8465 First of all, you will want to use your own configuration, not the one
8466 that your root user installed. If you do not have permission to write
8467 in the cpan directory that root has configured, you will be asked if
8468 you want to create your own config. Answering "yes" will bring you into
8469 CPAN's configuration stage, using the system config for all defaults except
8470 things that have to do with CPAN's work directory, saving your choices to
8471 your MyConfig.pm file.
8473 You can also manually initiate this process with the following command:
8475 % perl -MCPAN -e 'mkmyconfig'
8481 from the CPAN shell.
8483 You will most probably also want to configure something like this:
8485 o conf makepl_arg "LIB=~/myperl/lib \
8486 INSTALLMAN1DIR=~/myperl/man/man1 \
8487 INSTALLMAN3DIR=~/myperl/man/man3"
8489 You can make this setting permanent like all C<o conf> settings with
8492 You will have to add ~/myperl/man to the MANPATH environment variable
8493 and also tell your perl programs to look into ~/myperl/lib, e.g. by
8496 use lib "$ENV{HOME}/myperl/lib";
8498 or setting the PERL5LIB environment variable.
8500 While we're speaking about $ENV{HOME}, it might be worth mentioning,
8501 that for Windows we use the File::HomeDir module that provides an
8502 equivalent to the concept of the home directory on Unix.
8504 Another thing you should bear in mind is that the UNINST parameter can
8505 be dnagerous when you are installing into a private area because you
8506 might accidentally remove modules that other people depend on that are
8507 not using the private area.
8511 How to get a package, unwrap it, and make a change before building it?
8513 Have a look at the C<look> (!) command.
8517 I installed a Bundle and had a couple of fails. When I
8518 retried, everything resolved nicely. Can this be fixed to work
8521 The reason for this is that CPAN does not know the dependencies of all
8522 modules when it starts out. To decide about the additional items to
8523 install, it just uses data found in the META.yml file or the generated
8524 Makefile. An undetected missing piece breaks the process. But it may
8525 well be that your Bundle installs some prerequisite later than some
8526 depending item and thus your second try is able to resolve everything.
8527 Please note, CPAN.pm does not know the dependency tree in advance and
8528 cannot sort the queue of things to install in a topologically correct
8529 order. It resolves perfectly well IF all modules declare the
8530 prerequisites correctly with the PREREQ_PM attribute to MakeMaker or
8531 the C<requires> stanza of Module::Build. For bundles which fail and
8532 you need to install often, it is recommended to sort the Bundle
8533 definition file manually.
8537 In our intranet we have many modules for internal use. How
8538 can I integrate these modules with CPAN.pm but without uploading
8539 the modules to CPAN?
8541 Have a look at the CPAN::Site module.
8545 When I run CPAN's shell, I get an error message about things in my
8546 /etc/inputrc (or ~/.inputrc) file.
8548 These are readline issues and can only be fixed by studying readline
8549 configuration on your architecture and adjusting the referenced file
8550 accordingly. Please make a backup of the /etc/inputrc or ~/.inputrc
8551 and edit them. Quite often harmless changes like uppercasing or
8552 lowercasing some arguments solves the problem.
8556 Some authors have strange characters in their names.
8558 Internally CPAN.pm uses the UTF-8 charset. If your terminal is
8559 expecting ISO-8859-1 charset, a converter can be activated by setting
8560 term_is_latin to a true value in your config file. One way of doing so
8563 cpan> o conf term_is_latin 1
8565 If other charset support is needed, please file a bugreport against
8566 CPAN.pm at rt.cpan.org and describe your needs. Maybe we can extend
8567 the support or maybe UTF-8 terminals become widely available.
8571 When an install fails for some reason and then I correct the error
8572 condition and retry, CPAN.pm refuses to install the module, saying
8573 C<Already tried without success>.
8575 Use the force pragma like so
8577 force install Foo::Bar
8579 This does a bit more than really needed because it untars the
8580 distribution again and runs make and test and only then install.
8582 Or, if you find this is too fast and you would prefer to do smaller
8587 first and then continue as always. C<Force get> I<forgets> previous
8594 and then 'make install' directly in the subshell.
8596 Or you leave the CPAN shell and start it again.
8598 For the really curious, by accessing internals directly, you I<could>
8600 !delete CPAN::Shell->expandany("Foo::Bar")->distribution->{install}
8602 but this is neither guaranteed to work in the future nor is it a
8607 How do I install a "DEVELOPER RELEASE" of a module?
8609 By default, CPAN will install the latest non-developer release of a
8610 module. If you want to install a dev release, you have to specify the
8611 partial path starting with the author id to the tarball you wish to
8614 cpan> install KWILLIAMS/Module-Build-0.27_07.tar.gz
8616 Note that you can use the C<ls> command to get this path listed.
8620 How do I install a module and all its dependencies from the commandline,
8621 without being prompted for anything, despite my CPAN configuration
8624 CPAN uses ExtUtils::MakeMaker's prompt() function to ask its questions, so
8625 if you set the PERL_MM_USE_DEFAULT environment variable, you shouldn't be
8626 asked any questions at all (assuming the modules you are installing are
8627 nice about obeying that variable as well):
8629 % PERL_MM_USE_DEFAULT=1 perl -MCPAN -e 'install My::Module'
8633 How do I create a Module::Build based Build.PL derived from an
8634 ExtUtils::MakeMaker focused Makefile.PL?
8636 http://search.cpan.org/search?query=Module::Build::Convert
8638 http://accognoscere.org/papers/perl-module-build-convert/module-build-convert.html
8645 Please report bugs via http://rt.cpan.org/
8647 Before submitting a bug, please make sure that the traditional method
8648 of building a Perl module package from a shell by following the
8649 installation instructions of that package still works in your
8652 =head1 SECURITY ADVICE
8654 This software enables you to upgrade software on your computer and so
8655 is inherently dangerous because the newly installed software may
8656 contain bugs and may alter the way your computer works or even make it
8657 unusable. Please consider backing up your data before every upgrade.
8661 Andreas Koenig C<< <andk@cpan.org> >>
8665 Kawai,Takanori provides a Japanese translation of this manpage at
8666 http://member.nifty.ne.jp/hippo2000/perltips/CPAN.htm
8670 cpan(1), CPAN::Nox(3pm), CPAN::Version(3pm)