1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
4 $CPAN::VERSION = '1.88_53';
5 $CPAN::VERSION = eval $CPAN::VERSION;
7 use CPAN::HandleConfig;
17 use ExtUtils::MakeMaker qw(prompt); # for some unknown reason,
18 # 5.005_04 does not work without
20 use File::Basename ();
27 use Sys::Hostname qw(hostname);
28 use Text::ParseWords ();
31 # we need to run chdir all over and we would get at wrong libraries
34 if (File::Spec->can("rel2abs")) {
36 $inc = File::Spec->rel2abs($inc);
42 require Mac::BuildTools if $^O eq 'MacOS';
44 END { $CPAN::End++; &cleanup; }
47 $CPAN::Frontend ||= "CPAN::Shell";
48 unless (@CPAN::Defaultsites){
49 @CPAN::Defaultsites = map {
50 CPAN::URL->new(TEXT => $_, FROM => "DEF")
52 "http://www.perl.org/CPAN/",
53 "ftp://ftp.perl.org/pub/CPAN/";
55 # $CPAN::iCwd (i for initial) is going to be initialized during find_perl
56 $CPAN::Perl ||= CPAN::find_perl();
57 $CPAN::Defaultdocs ||= "http://search.cpan.org/perldoc?";
58 $CPAN::Defaultrecent ||= "http://search.cpan.org/recent";
61 use vars qw($VERSION @EXPORT $AUTOLOAD
62 $DEBUG $META $HAS_USABLE $term
64 $Signal $Suppress_readline $Frontend
65 @Defaultsites $Have_warned $Defaultdocs $Defaultrecent
70 @CPAN::ISA = qw(CPAN::Debug Exporter);
72 # note that these functions live in CPAN::Shell and get executed via
73 # AUTOLOAD when called directly
95 sub soft_chdir_with_alternatives ($);
98 $autoload_recursion ||= 0;
100 #-> sub CPAN::AUTOLOAD ;
102 $autoload_recursion++;
106 warn "Refusing to autoload '$l' while signal pending";
107 $autoload_recursion--;
110 if ($autoload_recursion > 1) {
111 my $fullcommand = join " ", map { "'$_'" } $l, @_;
112 warn "Refusing to autoload $fullcommand in recursion\n";
113 $autoload_recursion--;
117 @export{@EXPORT} = '';
118 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
119 if (exists $export{$l}){
122 die(qq{Unknown CPAN command "$AUTOLOAD". }.
123 qq{Type ? for help.\n});
125 $autoload_recursion--;
129 #-> sub CPAN::shell ;
132 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
133 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
135 my $oprompt = shift || CPAN::Prompt->new;
136 my $prompt = $oprompt;
137 my $commandline = shift || "";
138 $CPAN::CurrentCommandId ||= 1;
141 unless ($Suppress_readline) {
142 require Term::ReadLine;
145 $term->ReadLine eq "Term::ReadLine::Stub"
147 $term = Term::ReadLine->new('CPAN Monitor');
149 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
150 my $attribs = $term->Attribs;
151 $attribs->{attempted_completion_function} = sub {
152 &CPAN::Complete::gnu_cpl;
155 $readline::rl_completion_function =
156 $readline::rl_completion_function = 'CPAN::Complete::cpl';
158 if (my $histfile = $CPAN::Config->{'histfile'}) {{
159 unless ($term->can("AddHistory")) {
160 $CPAN::Frontend->mywarn("Terminal does not support AddHistory.\n");
163 my($fh) = FileHandle->new;
164 open $fh, "<$histfile" or last;
168 $term->AddHistory($_);
172 for ($CPAN::Config->{term_ornaments}) { # alias
173 local $Term::ReadLine::termcap_nowarn = 1;
174 $term->ornaments($_) if defined;
176 # $term->OUT is autoflushed anyway
177 my $odef = select STDERR;
184 # no strict; # I do not recall why no strict was here (2000-09-03)
186 my @cwd = grep { defined $_ and length $_ }
188 File::Spec->can("tmpdir") ? File::Spec->tmpdir() : (),
189 File::Spec->rootdir();
190 my $try_detect_readline;
191 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
192 my $rl_avail = $Suppress_readline ? "suppressed" :
193 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
194 "available (try 'install Bundle::CPAN')";
196 unless ($CPAN::Config->{'inhibit_startup_message'}){
197 $CPAN::Frontend->myprint(
199 cpan shell -- CPAN exploration and modules installation (v%s)
207 my($continuation) = "";
208 my $last_term_ornaments;
209 SHELLCOMMAND: while () {
210 if ($Suppress_readline) {
212 last SHELLCOMMAND unless defined ($_ = <> );
215 last SHELLCOMMAND unless
216 defined ($_ = $term->readline($prompt, $commandline));
218 $_ = "$continuation$_" if $continuation;
220 next SHELLCOMMAND if /^$/;
221 $_ = 'h' if /^\s*\?/;
222 if (/^(?:q(?:uit)?|bye|exit)$/i) {
233 use vars qw($import_done);
234 CPAN->import(':DEFAULT') unless $import_done++;
235 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
242 eval { @line = Text::ParseWords::shellwords($_) };
243 warn($@), next SHELLCOMMAND if $@;
244 warn("Text::Parsewords could not parse the line [$_]"),
245 next SHELLCOMMAND unless @line;
246 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
247 my $command = shift @line;
248 eval { CPAN::Shell->$command(@line) };
250 if ($command =~ /^(make|test|install|force|notest|clean|upgrade)$/) {
251 CPAN::Shell->failed($CPAN::CurrentCommandId,1);
253 soft_chdir_with_alternatives(\@cwd);
254 $CPAN::Frontend->myprint("\n");
256 $CPAN::CurrentCommandId++;
260 $commandline = ""; # I do want to be able to pass a default to
261 # shell, but on the second command I see no
264 CPAN::Queue->nullify_queue;
265 if ($try_detect_readline) {
266 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
268 $CPAN::META->has_inst("Term::ReadLine::Perl")
270 delete $INC{"Term/ReadLine.pm"};
272 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
273 require Term::ReadLine;
274 $CPAN::Frontend->myprint("\n$redef subroutines in ".
275 "Term::ReadLine redefined\n");
279 if ($term and $term->can("ornaments")) {
280 for ($CPAN::Config->{term_ornaments}) { # alias
282 if (not defined $last_term_ornaments
283 or $_ != $last_term_ornaments
285 local $Term::ReadLine::termcap_nowarn = 1;
286 $term->ornaments($_);
287 $last_term_ornaments = $_;
290 undef $last_term_ornaments;
294 if ($CPAN::DEBUG && $CPAN::DEBUG & $CPAN::DEBUG{CPAN}) {
295 # debugging 'incommandcolor': should always be off at the end of a command
296 # (incommandcolor is used to detect recursive dependencies)
297 for my $class (qw(Module Distribution)) {
298 for my $dm (keys %{$CPAN::META->{readwrite}{"CPAN::$class"}}) {
299 next unless $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor};
300 CPAN->debug("BUG: $class '$dm' was in command state, resetting");
301 delete $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor};
306 $GOTOSHELL = 0; # not too often
307 $META->savehist if $CPAN::term && $CPAN::term->can("GetHistory");
312 soft_chdir_with_alternatives(\@cwd);
315 sub soft_chdir_with_alternatives ($) {
318 my $root = File::Spec->rootdir();
319 $CPAN::Frontend->mywarn(qq{Warning: no good directory to chdir to!
320 Trying '$root' as temporary haven.
325 if (chdir $cwd->[0]) {
329 $CPAN::Frontend->mywarn(qq{Could not chdir to "$cwd->[0]": $!
330 Trying to chdir to "$cwd->[1]" instead.
334 $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd->[0]": $!});
340 package CPAN::CacheMgr;
342 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
347 use vars qw($Ua $Thesite $ThesiteURL $Themethod);
348 @CPAN::FTP::ISA = qw(CPAN::Debug);
350 package CPAN::LWP::UserAgent;
352 use vars qw(@ISA $USER $PASSWD $SETUPDONE);
353 # we delay requiring LWP::UserAgent and setting up inheritance until we need it
355 package CPAN::Complete;
357 @CPAN::Complete::ISA = qw(CPAN::Debug);
358 @CPAN::Complete::COMMANDS = sort qw(
359 ! a b d h i m o q r u
383 use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03);
384 @CPAN::Index::ISA = qw(CPAN::Debug);
387 # use constant PROTOCOL => "2.0"; # outcommented to avoid warning on upgrade from 1.57
390 package CPAN::InfoObj;
392 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
394 package CPAN::Author;
396 @CPAN::Author::ISA = qw(CPAN::InfoObj);
398 package CPAN::Distribution;
400 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
402 package CPAN::Bundle;
404 @CPAN::Bundle::ISA = qw(CPAN::Module);
406 package CPAN::Module;
408 @CPAN::Module::ISA = qw(CPAN::InfoObj);
410 package CPAN::Exception::RecursiveDependency;
412 use overload '""' => "as_string";
419 for my $dep (@$deps) {
421 last if $seen{$dep}++;
423 bless { deps => \@deps }, $class;
428 "\nRecursive dependency detected:\n " .
429 join("\n => ", @{$self->{deps}}) .
430 ".\nCannot continue.\n";
433 package CPAN::Prompt; use overload '""' => "as_string";
434 use vars qw($prompt);
436 $CPAN::CurrentCommandId ||= 0;
441 if ($CPAN::Config->{commandnumber_in_prompt}) {
442 sprintf "cpan[%d]> ", $CPAN::CurrentCommandId;
448 package CPAN::URL; use overload '""' => "as_string", fallback => 1;
449 # accessors: TEXT(the url string), FROM(DEF=>defaultlist,USER=>urllist),
450 # planned are things like age or quality
452 my($class,%args) = @_;
464 $self->{TEXT} = $set;
469 package CPAN::Distrostatus;
470 use overload '""' => "as_string",
473 my($class,$arg) = @_;
476 FAILED => substr($arg,0,2) eq "NO",
477 COMMANDID => $CPAN::CurrentCommandId,
480 sub commandid { shift->{COMMANDID} }
481 sub failed { shift->{FAILED} }
485 $self->{TEXT} = $set;
504 @CPAN::Shell::ISA = qw(CPAN::Debug);
505 $COLOR_REGISTERED ||= 0;
508 # $GLOBAL_AUTOLOAD_RECURSION = 12;
509 $autoload_recursion ||= 0;
511 #-> sub CPAN::Shell::AUTOLOAD ;
513 $autoload_recursion++;
515 my $class = shift(@_);
516 # warn "autoload[$l] class[$class]";
519 warn "Refusing to autoload '$l' while signal pending";
520 $autoload_recursion--;
523 if ($autoload_recursion > 1) {
524 my $fullcommand = join " ", map { "'$_'" } $l, @_;
525 warn "Refusing to autoload $fullcommand in recursion\n";
526 $autoload_recursion--;
530 # XXX needs to be reconsidered
531 if ($CPAN::META->has_inst('CPAN::WAIT')) {
534 $CPAN::Frontend->mywarn(qq{
535 Commands starting with "w" require CPAN::WAIT to be installed.
536 Please consider installing CPAN::WAIT to use the fulltext index.
537 For this you just need to type
542 $CPAN::Frontend->mywarn(qq{Unknown shell command '$l'. }.
546 $autoload_recursion--;
553 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
555 # from here on only subs.
556 ################################################################################
558 sub suggest_myconfig () {
559 SUGGEST_MYCONFIG: if(!$INC{'CPAN/MyConfig.pm'}) {
560 $CPAN::Frontend->myprint("You don't seem to have a user ".
561 "configuration (MyConfig.pm) yet.\n");
562 my $new = CPAN::Shell::colorable_makemaker_prompt("Do you want to create a ".
563 "user configuration now? (Y/n)",
566 CPAN::Shell->mkmyconfig();
569 $CPAN::Frontend->mydie("OK, giving up.");
574 #-> sub CPAN::all_objects ;
576 my($mgr,$class) = @_;
577 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
578 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
580 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
583 # Called by shell, not in batch mode. In batch mode I see no risk in
584 # having many processes updating something as installations are
585 # continually checked at runtime. In shell mode I suspect it is
586 # unintentional to open more than one shell at a time
588 #-> sub CPAN::checklock ;
591 my $lockfile = File::Spec->catfile($CPAN::Config->{cpan_home},".lock");
592 if (-f $lockfile && -M _ > 0) {
593 my $fh = FileHandle->new($lockfile) or
594 $CPAN::Frontend->mydie("Could not open lockfile '$lockfile': $!");
595 my $otherpid = <$fh>;
596 my $otherhost = <$fh>;
598 if (defined $otherpid && $otherpid) {
601 if (defined $otherhost && $otherhost) {
604 my $thishost = hostname();
605 if (defined $otherhost && defined $thishost &&
606 $otherhost ne '' && $thishost ne '' &&
607 $otherhost ne $thishost) {
608 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile '$lockfile'\n".
609 "reports other host $otherhost and other ".
610 "process $otherpid.\n".
611 "Cannot proceed.\n"));
613 elsif (defined $otherpid && $otherpid) {
614 return if $$ == $otherpid; # should never happen
615 $CPAN::Frontend->mywarn(
617 There seems to be running another CPAN process (pid $otherpid). Contacting...
619 if (kill 0, $otherpid) {
620 $CPAN::Frontend->mydie(qq{Other job is running.
621 You may want to kill it and delete the lockfile, maybe. On UNIX try:
625 } elsif (-w $lockfile) {
627 CPAN::Shell::colorable_makemaker_prompt
628 (qq{Other job not responding. Shall I overwrite }.
629 qq{the lockfile '$lockfile'? (Y/n)},"y");
630 $CPAN::Frontend->myexit("Ok, bye\n")
631 unless $ans =~ /^y/i;
634 qq{Lockfile '$lockfile' not writeable by you. }.
635 qq{Cannot proceed.\n}.
637 qq{ rm '$lockfile'\n}.
638 qq{ and then rerun us.\n}
642 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile '$lockfile'\n".
643 "reports other process with ID ".
644 "$otherpid. Cannot proceed.\n"));
647 my $dotcpan = $CPAN::Config->{cpan_home};
648 eval { File::Path::mkpath($dotcpan);};
650 # A special case at least for Jarkko.
655 $symlinkcpan = readlink $dotcpan;
656 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
657 eval { File::Path::mkpath($symlinkcpan); };
661 $CPAN::Frontend->mywarn(qq{
662 Working directory $symlinkcpan created.
666 unless (-d $dotcpan) {
668 Your configuration suggests "$dotcpan" as your
669 CPAN.pm working directory. I could not create this directory due
670 to this error: $firsterror\n};
672 As "$dotcpan" is a symlink to "$symlinkcpan",
673 I tried to create that, but I failed with this error: $seconderror
676 Please make sure the directory exists and is writable.
678 $CPAN::Frontend->myprint($mess);
679 return suggest_myconfig;
681 } # $@ after eval mkpath $dotcpan
683 unless ($fh = FileHandle->new(">$lockfile")) {
684 if ($! =~ /Permission/) {
685 $CPAN::Frontend->myprint(qq{
687 Your configuration suggests that CPAN.pm should use a working
689 $CPAN::Config->{cpan_home}
690 Unfortunately we could not create the lock file
692 due to permission problems.
694 Please make sure that the configuration variable
695 \$CPAN::Config->{cpan_home}
696 points to a directory where you can write a .lock file. You can set
697 this variable in either a CPAN/MyConfig.pm or a CPAN/Config.pm in your
700 return suggest_myconfig;
703 $fh->print($$, "\n");
704 $fh->print(hostname(), "\n");
705 $self->{LOCK} = $lockfile;
710 $CPAN::Frontend->mydie("Got SIG$sig, leaving");
716 die "Got yet another signal" if $Signal > 1;
717 $CPAN::Frontend->mydie("Got another SIG$sig") if $Signal;
718 $CPAN::Frontend->mywarn("Caught SIG$sig, trying to continue\n");
722 # From: Larry Wall <larry@wall.org>
723 # Subject: Re: deprecating SIGDIE
724 # To: perl5-porters@perl.org
725 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
727 # The original intent of __DIE__ was only to allow you to substitute one
728 # kind of death for another on an application-wide basis without respect
729 # to whether you were in an eval or not. As a global backstop, it should
730 # not be used any more lightly (or any more heavily :-) than class
731 # UNIVERSAL. Any attempt to build a general exception model on it should
732 # be politely squashed. Any bug that causes every eval {} to have to be
733 # modified should be not so politely squashed.
735 # Those are my current opinions. It is also my optinion that polite
736 # arguments degenerate to personal arguments far too frequently, and that
737 # when they do, it's because both people wanted it to, or at least didn't
738 # sufficiently want it not to.
742 # global backstop to cleanup if we should really die
743 $SIG{__DIE__} = \&cleanup;
744 $self->debug("Signal handler set.") if $CPAN::DEBUG;
747 #-> sub CPAN::DESTROY ;
749 &cleanup; # need an eval?
752 #-> sub CPAN::anycwd ;
755 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
760 sub cwd {Cwd::cwd();}
762 #-> sub CPAN::getcwd ;
763 sub getcwd {Cwd::getcwd();}
765 #-> sub CPAN::fastcwd ;
766 sub fastcwd {Cwd::fastcwd();}
768 #-> sub CPAN::backtickcwd ;
769 sub backtickcwd {my $cwd = `cwd`; chomp $cwd; $cwd}
771 #-> sub CPAN::find_perl ;
773 my($perl) = File::Spec->file_name_is_absolute($^X) ? $^X : "";
774 my $pwd = $CPAN::iCwd = CPAN::anycwd();
775 my $candidate = File::Spec->catfile($pwd,$^X);
776 $perl ||= $candidate if MM->maybe_command($candidate);
779 my ($component,$perl_name);
780 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
781 PATH_COMPONENT: foreach $component (File::Spec->path(),
782 $Config::Config{'binexp'}) {
783 next unless defined($component) && $component;
784 my($abs) = File::Spec->catfile($component,$perl_name);
785 if (MM->maybe_command($abs)) {
797 #-> sub CPAN::exists ;
799 my($mgr,$class,$id) = @_;
800 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
802 ### Carp::croak "exists called without class argument" unless $class;
804 $id =~ s/:+/::/g if $class eq "CPAN::Module";
805 exists $META->{readonly}{$class}{$id} or
806 exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
809 #-> sub CPAN::delete ;
811 my($mgr,$class,$id) = @_;
812 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
813 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
816 #-> sub CPAN::has_usable
817 # has_inst is sometimes too optimistic, we should replace it with this
818 # has_usable whenever a case is given
820 my($self,$mod,$message) = @_;
821 return 1 if $HAS_USABLE->{$mod};
822 my $has_inst = $self->has_inst($mod,$message);
823 return unless $has_inst;
826 LWP => [ # we frequently had "Can't locate object
827 # method "new" via package "LWP::UserAgent" at
828 # (eval 69) line 2006
830 sub {require LWP::UserAgent},
831 sub {require HTTP::Request},
832 sub {require URI::URL},
835 sub {require Net::FTP},
836 sub {require Net::Config},
839 sub {require File::HomeDir;
840 unless (File::HomeDir->VERSION >= 0.52){
841 for ("Will not use File::HomeDir, need 0.52\n") {
842 $CPAN::Frontend->mywarn($_);
849 if ($usable->{$mod}) {
850 for my $c (0..$#{$usable->{$mod}}) {
851 my $code = $usable->{$mod}[$c];
852 my $ret = eval { &$code() };
853 $ret = "" unless defined $ret;
855 # warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
860 return $HAS_USABLE->{$mod} = 1;
863 #-> sub CPAN::has_inst
865 my($self,$mod,$message) = @_;
866 Carp::croak("CPAN->has_inst() called without an argument")
868 my %dont = map { $_ => 1 } keys %{$CPAN::META->{dontload_hash}||{}},
869 keys %{$CPAN::Config->{dontload_hash}||{}},
870 @{$CPAN::Config->{dontload_list}||[]};
871 if (defined $message && $message eq "no" # afair only used by Nox
875 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
883 # checking %INC is wrong, because $INC{LWP} may be true
884 # although $INC{"URI/URL.pm"} may have failed. But as
885 # I really want to say "bla loaded OK", I have to somehow
887 ### warn "$file in %INC"; #debug
889 } elsif (eval { require $file }) {
890 # eval is good: if we haven't yet read the database it's
891 # perfect and if we have installed the module in the meantime,
892 # it tries again. The second require is only a NOOP returning
893 # 1 if we had success, otherwise it's retrying
895 my $v = eval "\$$mod\::VERSION";
896 $v = $v ? " (v$v)" : "";
897 $CPAN::Frontend->myprint("CPAN: $mod loaded ok$v\n");
898 if ($mod eq "CPAN::WAIT") {
899 push @CPAN::Shell::ISA, 'CPAN::WAIT';
902 } elsif ($mod eq "Net::FTP") {
903 $CPAN::Frontend->mywarn(qq{
904 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
906 install Bundle::libnet
908 }) unless $Have_warned->{"Net::FTP"}++;
909 $CPAN::Frontend->mysleep(3);
910 } elsif ($mod eq "Digest::SHA"){
911 if ($Have_warned->{"Digest::SHA"}++) {
912 $CPAN::Frontend->myprint(qq{CPAN: checksum security checks disabled}.
913 qq{because Digest::SHA not installed.\n});
915 $CPAN::Frontend->mywarn(qq{
916 CPAN: checksum security checks disabled because Digest::SHA not installed.
917 Please consider installing the Digest::SHA module.
920 $CPAN::Frontend->mysleep(2);
922 } elsif ($mod eq "Module::Signature"){
923 if (not $CPAN::Config->{check_sigs}) {
924 # they do not want us:-(
925 } elsif (not $Have_warned->{"Module::Signature"}++) {
926 # No point in complaining unless the user can
927 # reasonably install and use it.
928 if (eval { require Crypt::OpenPGP; 1 } ||
930 defined $CPAN::Config->{'gpg'}
932 $CPAN::Config->{'gpg'} =~ /\S/
935 $CPAN::Frontend->mywarn(qq{
936 CPAN: Module::Signature security checks disabled because Module::Signature
937 not installed. Please consider installing the Module::Signature module.
938 You may also need to be able to connect over the Internet to the public
939 keyservers like pgp.mit.edu (port 11371).
942 $CPAN::Frontend->mysleep(2);
946 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
951 #-> sub CPAN::instance ;
953 my($mgr,$class,$id) = @_;
956 # unsafe meta access, ok?
957 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
958 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
966 #-> sub CPAN::cleanup ;
968 # warn "cleanup called with arg[@_] End[$CPAN::End] Signal[$Signal]";
969 local $SIG{__DIE__} = '';
974 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
976 $subroutine eq '(eval)';
978 return if $ineval && !$CPAN::End;
979 return unless defined $META->{LOCK};
980 return unless -f $META->{LOCK};
982 unlink $META->{LOCK};
984 # Carp::cluck("DEBUGGING");
985 $CPAN::Frontend->myprint("Lockfile removed.\n");
988 #-> sub CPAN::savehist
991 my($histfile,$histsize);
992 unless ($histfile = $CPAN::Config->{'histfile'}){
993 $CPAN::Frontend->mywarn("No history written (no histfile specified).\n");
996 $histsize = $CPAN::Config->{'histsize'} || 100;
998 unless ($CPAN::term->can("GetHistory")) {
999 $CPAN::Frontend->mywarn("Terminal does not support GetHistory.\n");
1005 my @h = $CPAN::term->GetHistory;
1006 splice @h, 0, @h-$histsize if @h>$histsize;
1007 my($fh) = FileHandle->new;
1008 open $fh, ">$histfile" or $CPAN::Frontend->mydie("Couldn't open >$histfile: $!");
1009 local $\ = local $, = "\n";
1015 my($self,$what) = @_;
1016 $self->{is_tested}{$what} = 1;
1019 # unsets the is_tested flag: as soon as the thing is installed, it is
1020 # not needed in set_perl5lib anymore
1022 my($self,$what) = @_;
1023 delete $self->{is_tested}{$what};
1028 $self->{is_tested} ||= {};
1029 return unless %{$self->{is_tested}};
1030 my $env = $ENV{PERL5LIB};
1031 $env = $ENV{PERLLIB} unless defined $env;
1033 push @env, $env if defined $env and length $env;
1034 my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}};
1035 $CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
1036 $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1039 package CPAN::CacheMgr;
1042 #-> sub CPAN::CacheMgr::as_string ;
1044 eval { require Data::Dumper };
1046 return shift->SUPER::as_string;
1048 return Data::Dumper::Dumper(shift);
1052 #-> sub CPAN::CacheMgr::cachesize ;
1057 #-> sub CPAN::CacheMgr::tidyup ;
1060 return unless -d $self->{ID};
1061 while ($self->{DU} > $self->{'MAX'} ) {
1062 my($toremove) = shift @{$self->{FIFO}};
1063 $CPAN::Frontend->myprint(sprintf(
1064 "Deleting from cache".
1065 ": $toremove (%.1f>%.1f MB)\n",
1066 $self->{DU}, $self->{'MAX'})
1068 return if $CPAN::Signal;
1069 $self->force_clean_cache($toremove);
1070 return if $CPAN::Signal;
1074 #-> sub CPAN::CacheMgr::dir ;
1079 #-> sub CPAN::CacheMgr::entries ;
1081 my($self,$dir) = @_;
1082 return unless defined $dir;
1083 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
1084 $dir ||= $self->{ID};
1085 my($cwd) = CPAN::anycwd();
1086 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
1087 my $dh = DirHandle->new(File::Spec->curdir)
1088 or Carp::croak("Couldn't opendir $dir: $!");
1091 next if $_ eq "." || $_ eq "..";
1093 push @entries, File::Spec->catfile($dir,$_);
1095 push @entries, File::Spec->catdir($dir,$_);
1097 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
1100 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
1101 sort { -M $b <=> -M $a} @entries;
1104 #-> sub CPAN::CacheMgr::disk_usage ;
1106 my($self,$dir) = @_;
1107 return if exists $self->{SIZE}{$dir};
1108 return if $CPAN::Signal;
1112 unless (chmod 0755, $dir) {
1113 $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
1114 "permission to change the permission; cannot ".
1115 "estimate disk usage of '$dir'\n");
1116 $CPAN::Frontend->mysleep(5);
1121 $CPAN::Frontend->mywarn("Directory '$dir' has gone. Cannot continue.\n");
1126 $File::Find::prune++ if $CPAN::Signal;
1128 if ($^O eq 'MacOS') {
1130 my $cat = Mac::Files::FSpGetCatInfo($_);
1131 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
1135 unless (chmod 0755, $_) {
1136 $CPAN::Frontend->mywarn("I have neither the -x permission nor ".
1137 "the permission to change the permission; ".
1138 "can only partially estimate disk usage ".
1140 $CPAN::Frontend->mysleep(5);
1151 return if $CPAN::Signal;
1152 $self->{SIZE}{$dir} = $Du/1024/1024;
1153 push @{$self->{FIFO}}, $dir;
1154 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
1155 $self->{DU} += $Du/1024/1024;
1159 #-> sub CPAN::CacheMgr::force_clean_cache ;
1160 sub force_clean_cache {
1161 my($self,$dir) = @_;
1162 return unless -e $dir;
1163 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
1165 File::Path::rmtree($dir);
1166 $self->{DU} -= $self->{SIZE}{$dir};
1167 delete $self->{SIZE}{$dir};
1170 #-> sub CPAN::CacheMgr::new ;
1177 ID => $CPAN::Config->{'build_dir'},
1178 MAX => $CPAN::Config->{'build_cache'},
1179 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
1182 File::Path::mkpath($self->{ID});
1183 my $dh = DirHandle->new($self->{ID});
1184 bless $self, $class;
1187 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
1189 CPAN->debug($debug) if $CPAN::DEBUG;
1193 #-> sub CPAN::CacheMgr::scan_cache ;
1196 return if $self->{SCAN} eq 'never';
1197 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
1198 unless $self->{SCAN} eq 'atstart';
1199 $CPAN::Frontend->myprint(
1200 sprintf("Scanning cache %s for sizes\n",
1203 for $e ($self->entries($self->{ID})) {
1204 next if $e eq ".." || $e eq ".";
1205 $self->disk_usage($e);
1206 return if $CPAN::Signal;
1211 package CPAN::Shell;
1214 #-> sub CPAN::Shell::h ;
1216 my($class,$about) = @_;
1217 if (defined $about) {
1218 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
1220 my $filler = " " x (80 - 28 - length($CPAN::VERSION));
1221 $CPAN::Frontend->myprint(qq{
1222 Display Information $filler (ver $CPAN::VERSION)
1223 command argument description
1224 a,b,d,m WORD or /REGEXP/ about authors, bundles, distributions, modules
1225 i WORD or /REGEXP/ about any of the above
1226 ls AUTHOR or GLOB about files in the author's directory
1227 (with WORD being a module, bundle or author name or a distribution
1228 name of the form AUTHOR/DISTRIBUTION)
1230 Download, Test, Make, Install...
1231 get download clean make clean
1232 make make (implies get) look open subshell in dist directory
1233 test make test (implies make) readme display these README files
1234 install make install (implies test) perldoc display POD documentation
1237 r WORDs or /REGEXP/ or NONE report updates for some/matching/all modules
1238 upgrade WORDs or /REGEXP/ or NONE upgrade some/matching/all modules
1241 force COMMAND unconditionally do command
1242 notest COMMAND skip testing
1245 h,? display this menu ! perl-code eval a perl command
1246 o conf [opt] set and query options q quit the cpan shell
1247 reload cpan load CPAN.pm again reload index load newer indices
1248 autobundle Snapshot recent latest CPAN uploads});
1254 #-> sub CPAN::Shell::a ;
1256 my($self,@arg) = @_;
1257 # authors are always UPPERCASE
1259 $_ = uc $_ unless /=/;
1261 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1264 #-> sub CPAN::Shell::globls ;
1266 my($self,$s,$pragmas) = @_;
1267 # ls is really very different, but we had it once as an ordinary
1268 # command in the Shell (upto rev. 321) and we could not handle
1270 my(@accept,@preexpand);
1271 if ($s =~ /[\*\?\/]/) {
1272 if ($CPAN::META->has_inst("Text::Glob")) {
1273 if (my($au,$pathglob) = $s =~ m|(.*?)/(.*)|) {
1274 my $rau = Text::Glob::glob_to_regex(uc $au);
1275 CPAN::Shell->debug("au[$au]pathglob[$pathglob]rau[$rau]")
1277 push @preexpand, map { $_->id . "/" . $pathglob }
1278 CPAN::Shell->expand_by_method('CPAN::Author',['id'],"/$rau/");
1280 my $rau = Text::Glob::glob_to_regex(uc $s);
1281 push @preexpand, map { $_->id }
1282 CPAN::Shell->expand_by_method('CPAN::Author',
1287 $CPAN::Frontend->mydie("Text::Glob not installed, cannot proceed");
1290 push @preexpand, uc $s;
1293 unless (/^[A-Z0-9\-]+(\/|$)/i) {
1294 $CPAN::Frontend->mywarn("ls command rejects argument $_: not an author\n");
1299 my $silent = @accept>1;
1300 my $last_alpha = "";
1302 for my $a (@accept){
1303 my($author,$pathglob);
1304 if ($a =~ m|(.*?)/(.*)|) {
1307 $author = CPAN::Shell->expand_by_method('CPAN::Author',
1309 $a2) or die "No author found for $a2";
1311 $author = CPAN::Shell->expand_by_method('CPAN::Author',
1313 $a) or die "No author found for $a";
1316 my $alpha = substr $author->id, 0, 1;
1318 if ($alpha eq $last_alpha) {
1322 $last_alpha = $alpha;
1324 $CPAN::Frontend->myprint($ad);
1326 for my $pragma (@$pragmas) {
1327 if ($author->can($pragma)) {
1331 push @results, $author->ls($pathglob,$silent); # silent if
1334 for my $pragma (@$pragmas) {
1335 my $meth = "un$pragma";
1336 if ($author->can($meth)) {
1344 #-> sub CPAN::Shell::local_bundles ;
1346 my($self,@which) = @_;
1347 my($incdir,$bdir,$dh);
1348 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1349 my @bbase = "Bundle";
1350 while (my $bbase = shift @bbase) {
1351 $bdir = File::Spec->catdir($incdir,split /::/, $bbase);
1352 CPAN->debug("bdir[$bdir]\@bbase[@bbase]") if $CPAN::DEBUG;
1353 if ($dh = DirHandle->new($bdir)) { # may fail
1355 for $entry ($dh->read) {
1356 next if $entry =~ /^\./;
1357 next unless $entry =~ /^\w+(\.pm)?(?!\n)\Z/;
1358 if (-d File::Spec->catdir($bdir,$entry)){
1359 push @bbase, "$bbase\::$entry";
1361 next unless $entry =~ s/\.pm(?!\n)\Z//;
1362 $CPAN::META->instance('CPAN::Bundle',"$bbase\::$entry");
1370 #-> sub CPAN::Shell::b ;
1372 my($self,@which) = @_;
1373 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1374 $self->local_bundles;
1375 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1378 #-> sub CPAN::Shell::d ;
1379 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1381 #-> sub CPAN::Shell::m ;
1382 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
1384 $CPAN::Frontend->myprint($self->format_result('Module',@_));
1387 #-> sub CPAN::Shell::i ;
1391 @args = '/./' unless @args;
1393 for my $type (qw/Bundle Distribution Module/) {
1394 push @result, $self->expand($type,@args);
1396 # Authors are always uppercase.
1397 push @result, $self->expand("Author", map { uc $_ } @args);
1399 my $result = @result == 1 ?
1400 $result[0]->as_string :
1402 "No objects found of any type for argument @args\n" :
1404 (map {$_->as_glimpse} @result),
1405 scalar @result, " items found\n",
1407 $CPAN::Frontend->myprint($result);
1410 #-> sub CPAN::Shell::o ;
1412 # CPAN::Shell::o and CPAN::HandleConfig::edit are closely related. 'o
1413 # conf' calls through to CPAN::HandleConfig::edit. 'o conf' should
1414 # probably have been called 'set' and 'o debug' maybe 'set debug' or
1415 # 'debug'; 'o conf ARGS' calls ->edit in CPAN/HandleConfig.pm
1417 my($self,$o_type,@o_what) = @_;
1420 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1421 if ($o_type eq 'conf') {
1422 if (!@o_what) { # print all things, "o conf"
1424 $CPAN::Frontend->myprint("\$CPAN::Config options from ");
1426 if (exists $INC{'CPAN/Config.pm'}) {
1427 push @from, $INC{'CPAN/Config.pm'};
1429 if (exists $INC{'CPAN/MyConfig.pm'}) {
1430 push @from, $INC{'CPAN/MyConfig.pm'};
1432 $CPAN::Frontend->myprint(join " and ", map {"'$_'"} @from);
1433 $CPAN::Frontend->myprint(":\n");
1434 for $k (sort keys %CPAN::HandleConfig::can) {
1435 $v = $CPAN::HandleConfig::can{$k};
1436 $CPAN::Frontend->myprint(sprintf " %-18s [%s]\n", $k, $v);
1438 $CPAN::Frontend->myprint("\n");
1439 for $k (sort keys %$CPAN::Config) {
1440 CPAN::HandleConfig->prettyprint($k);
1442 $CPAN::Frontend->myprint("\n");
1443 } elsif (!CPAN::HandleConfig->edit(@o_what)) {
1444 $CPAN::Frontend->myprint(qq{Type 'o conf' to view all configuration }.
1447 } elsif ($o_type eq 'debug') {
1449 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1452 my($what) = shift @o_what;
1453 if ($what =~ s/^-// && exists $CPAN::DEBUG{$what}) {
1454 $CPAN::DEBUG &= $CPAN::DEBUG ^ $CPAN::DEBUG{$what};
1457 if ( exists $CPAN::DEBUG{$what} ) {
1458 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1459 } elsif ($what =~ /^\d/) {
1460 $CPAN::DEBUG = $what;
1461 } elsif (lc $what eq 'all') {
1463 for (values %CPAN::DEBUG) {
1466 $CPAN::DEBUG = $max;
1469 for (keys %CPAN::DEBUG) {
1470 next unless lc($_) eq lc($what);
1471 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1474 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1479 my $raw = "Valid options for debug are ".
1480 join(", ",sort(keys %CPAN::DEBUG), 'all').
1481 qq{ or a number. Completion works on the options. }.
1482 qq{Case is ignored.};
1484 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
1485 $CPAN::Frontend->myprint("\n\n");
1488 $CPAN::Frontend->myprint("Options set for debugging ($CPAN::DEBUG):\n");
1490 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1491 $v = $CPAN::DEBUG{$k};
1492 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
1493 if $v & $CPAN::DEBUG;
1496 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1499 $CPAN::Frontend->myprint(qq{
1501 conf set or get configuration variables
1502 debug set or get debugging options
1507 # CPAN::Shell::paintdots_onreload
1508 sub paintdots_onreload {
1511 if ( $_[0] =~ /[Ss]ubroutine ([\w:]+) redefined/ ) {
1515 # $CPAN::Frontend->myprint(".($subr)");
1516 $CPAN::Frontend->myprint(".");
1517 if ($subr =~ /\bshell\b/i) {
1518 # warn "debug[$_[0]]";
1520 # It would be nice if we could detect that a
1521 # subroutine has actually changed, but for now we
1522 # practically always set the GOTOSHELL global
1532 #-> sub CPAN::Shell::reload ;
1534 my($self,$command,@arg) = @_;
1536 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1537 if ($command =~ /^cpan$/i) {
1539 chdir $CPAN::iCwd if $CPAN::iCwd; # may fail
1543 "CPAN/HandleConfig.pm",
1544 "CPAN/FirstTime.pm",
1551 MFILE: for my $f (@relo) {
1552 next unless exists $INC{$f};
1556 $CPAN::Frontend->myprint("($p");
1557 local($SIG{__WARN__}) = paintdots_onreload(\$redef);
1558 $self->reload_this($f) or $failed++;
1559 my $v = eval "$p\::->VERSION";
1560 $CPAN::Frontend->myprint("v$v)");
1562 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1564 my $errors = $failed == 1 ? "error" : "errors";
1565 $CPAN::Frontend->mywarn("\n$failed $errors during reload. You better quit ".
1568 } elsif ($command =~ /^index$/i) {
1569 CPAN::Index->force_reload;
1571 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN modules
1572 index re-reads the index files\n});
1576 # reload means only load again what we have loaded before
1577 #-> sub CPAN::Shell::reload_this ;
1579 my($self,$f,$args) = @_;
1580 CPAN->debug("f[$f]") if $CPAN::DEBUG;
1581 return 1 unless $INC{$f}; # we never loaded this, so we do not
1583 my $pwd = CPAN::anycwd();
1584 CPAN->debug("pwd[$pwd]") if $CPAN::DEBUG;
1586 for my $inc (@INC) {
1587 $file = File::Spec->catfile($inc,split /\//, $f);
1591 CPAN->debug("file[$file]") if $CPAN::DEBUG;
1593 unless ($file && -f $file) {
1594 # this thingie is not in the INC path, maybe CPAN/MyConfig.pm?
1596 @inc = substr($file,0,-length($f)); # bring in back to me!
1598 CPAN->debug("file[$file]inc[@inc]") if $CPAN::DEBUG;
1600 $CPAN::Frontend->mywarn("Found no file to reload for '$f'\n");
1603 my $mtime = (stat $file)[9];
1604 $reload->{$f} ||= $^T;
1605 my $must_reload = $mtime > $reload->{$f};
1607 $must_reload ||= $args->{force};
1609 my $fh = FileHandle->new($file) or
1610 $CPAN::Frontend->mydie("Could not open $file: $!");
1613 my $content = <$fh>;
1614 CPAN->debug(sprintf("reload file[%s] content[%s...]",$file,substr($content,0,128)))
1618 eval "require '$f'";
1623 $reload->{$f} = time;
1625 $CPAN::Frontend->myprint("__unchanged__");
1630 #-> sub CPAN::Shell::mkmyconfig ;
1632 my($self, $cpanpm, %args) = @_;
1633 require CPAN::FirstTime;
1634 my $home = CPAN::HandleConfig::home;
1635 $cpanpm = $INC{'CPAN/MyConfig.pm'} ||
1636 File::Spec->catfile(split /\//, "$home/.cpan/CPAN/MyConfig.pm");
1637 File::Path::mkpath(File::Basename::dirname($cpanpm)) unless -e $cpanpm;
1638 CPAN::HandleConfig::require_myconfig_or_config;
1639 $CPAN::Config ||= {};
1644 keep_source_where => undef,
1647 CPAN::FirstTime::init($cpanpm, %args);
1650 #-> sub CPAN::Shell::_binary_extensions ;
1651 sub _binary_extensions {
1652 my($self) = shift @_;
1653 my(@result,$module,%seen,%need,$headerdone);
1654 for $module ($self->expand('Module','/./')) {
1655 my $file = $module->cpan_file;
1656 next if $file eq "N/A";
1657 next if $file =~ /^Contact Author/;
1658 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
1659 next if $dist->isa_perl;
1660 next unless $module->xs_file;
1662 $CPAN::Frontend->myprint(".");
1663 push @result, $module;
1665 # print join " | ", @result;
1666 $CPAN::Frontend->myprint("\n");
1670 #-> sub CPAN::Shell::recompile ;
1672 my($self) = shift @_;
1673 my($module,@module,$cpan_file,%dist);
1674 @module = $self->_binary_extensions();
1675 for $module (@module){ # we force now and compile later, so we
1677 $cpan_file = $module->cpan_file;
1678 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1680 $dist{$cpan_file}++;
1682 for $cpan_file (sort keys %dist) {
1683 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1684 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1686 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1687 # stop a package from recompiling,
1688 # e.g. IO-1.12 when we have perl5.003_10
1692 #-> sub CPAN::Shell::scripts ;
1694 my($self, $arg) = @_;
1695 $CPAN::Frontend->mywarn(">>>> experimental command, currently unsupported <<<<\n\n");
1697 for my $req (qw( HTML::LinkExtor Sort::Versions List::Util )) {
1698 unless ($CPAN::META->has_inst($req)) {
1699 $CPAN::Frontend->mywarn(" $req not available\n");
1702 my $p = HTML::LinkExtor->new();
1703 my $indexfile = "/home/ftp/pub/PAUSE/scripts/new/index.html";
1704 unless (-f $indexfile) {
1705 $CPAN::Frontend->mydie("found no indexfile[$indexfile]\n");
1707 $p->parse_file($indexfile);
1710 if ($arg =~ s|^/(.+)/$|$1|) {
1711 $qrarg = eval 'qr/$arg/'; # hide construct from 5.004
1713 for my $l ($p->links) {
1714 my $tag = shift @$l;
1715 next unless $tag eq "a";
1717 my $href = $att{href};
1718 next unless $href =~ s|^\.\./authors/id/./../||;
1721 if ($href =~ $qrarg) {
1725 if ($href =~ /\Q$arg\E/) {
1733 # now filter for the latest version if there is more than one of a name
1739 $stems{$stem} ||= [];
1740 push @{$stems{$stem}}, $href;
1742 for (sort keys %stems) {
1744 if (@{$stems{$_}} > 1) {
1745 $highest = List::Util::reduce {
1746 Sort::Versions::versioncmp($a,$b) > 0 ? $a : $b
1749 $highest = $stems{$_}[0];
1751 $CPAN::Frontend->myprint("$highest\n");
1755 #-> sub CPAN::Shell::upgrade ;
1757 my($self,@args) = @_;
1758 $self->install($self->r(@args));
1761 #-> sub CPAN::Shell::_u_r_common ;
1763 my($self) = shift @_;
1764 my($what) = shift @_;
1765 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1766 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
1767 $what && $what =~ /^[aru]$/;
1769 @args = '/./' unless @args;
1770 my(@result,$module,%seen,%need,$headerdone,
1771 $version_undefs,$version_zeroes);
1772 $version_undefs = $version_zeroes = 0;
1773 my $sprintf = "%s%-25s%s %9s %9s %s\n";
1774 my @expand = $self->expand('Module',@args);
1775 my $expand = scalar @expand;
1776 if (0) { # Looks like noise to me, was very useful for debugging
1777 # for metadata cache
1778 $CPAN::Frontend->myprint(sprintf "%d matches in the database\n", $expand);
1780 MODULE: for $module (@expand) {
1781 my $file = $module->cpan_file;
1782 next MODULE unless defined $file; # ??
1783 $file =~ s|^./../||;
1784 my($latest) = $module->cpan_version;
1785 my($inst_file) = $module->inst_file;
1787 return if $CPAN::Signal;
1790 $have = $module->inst_version;
1791 } elsif ($what eq "r") {
1792 $have = $module->inst_version;
1794 if ($have eq "undef"){
1796 } elsif ($have == 0){
1799 next MODULE unless CPAN::Version->vgt($latest, $have);
1800 # to be pedantic we should probably say:
1801 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1802 # to catch the case where CPAN has a version 0 and we have a version undef
1803 } elsif ($what eq "u") {
1809 } elsif ($what eq "r") {
1811 } elsif ($what eq "u") {
1815 return if $CPAN::Signal; # this is sometimes lengthy
1818 push @result, sprintf "%s %s\n", $module->id, $have;
1819 } elsif ($what eq "r") {
1820 push @result, $module->id;
1821 next MODULE if $seen{$file}++;
1822 } elsif ($what eq "u") {
1823 push @result, $module->id;
1824 next MODULE if $seen{$file}++;
1825 next MODULE if $file =~ /^Contact/;
1827 unless ($headerdone++){
1828 $CPAN::Frontend->myprint("\n");
1829 $CPAN::Frontend->myprint(sprintf(
1832 "Package namespace",
1841 # $GLOBAL_AUTOLOAD_RECURSION = 12;
1845 $CPAN::META->has_inst("Term::ANSIColor")
1847 $module->description
1849 $color_on = Term::ANSIColor::color("green");
1850 $color_off = Term::ANSIColor::color("reset");
1852 $CPAN::Frontend->myprint(sprintf $sprintf,
1859 $need{$module->id}++;
1863 $CPAN::Frontend->myprint("No modules found for @args\n");
1864 } elsif ($what eq "r") {
1865 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1869 if ($version_zeroes) {
1870 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1871 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1872 qq{a version number of 0\n});
1874 if ($version_undefs) {
1875 my $s_has = $version_undefs > 1 ? "s have" : " has";
1876 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1877 qq{parseable version number\n});
1883 #-> sub CPAN::Shell::r ;
1885 shift->_u_r_common("r",@_);
1888 #-> sub CPAN::Shell::u ;
1890 shift->_u_r_common("u",@_);
1893 #-> sub CPAN::Shell::failed ;
1895 my($self,$only_id,$silent) = @_;
1897 DIST: for my $d ($CPAN::META->all_objects("CPAN::Distribution")) {
1899 NAY: for my $nosayer (
1907 next unless exists $d->{$nosayer};
1909 $d->{$nosayer}->can("failed") ?
1910 $d->{$nosayer}->failed :
1911 $d->{$nosayer} =~ /^NO/
1913 next NAY if $only_id && $only_id != (
1914 $d->{$nosayer}->can("commandid")
1916 $d->{$nosayer}->commandid
1918 $CPAN::CurrentCommandId
1923 next DIST unless $failed;
1927 # " %-45s: %s %s\n",
1930 $d->{$failed}->can("failed") ?
1932 $d->{$failed}->commandid,
1935 $d->{$failed}->text,
1945 my $scope = $only_id ? "command" : "session";
1947 my $print = join "",
1948 map { sprintf " %-45s: %s %s\n", @$_[1,2,3] }
1949 sort { $a->[0] <=> $b->[0] } @failed;
1950 $CPAN::Frontend->myprint("Failed during this $scope:\n$print");
1951 } elsif (!$only_id || !$silent) {
1952 $CPAN::Frontend->myprint("Nothing failed in this $scope\n");
1956 # XXX intentionally undocumented because completely bogus, unportable,
1959 #-> sub CPAN::Shell::status ;
1962 require Devel::Size;
1963 my $ps = FileHandle->new;
1964 open $ps, "/proc/$$/status";
1967 next unless /VmSize:\s+(\d+)/;
1971 $CPAN::Frontend->mywarn(sprintf(
1972 "%-27s %6d\n%-27s %6d\n",
1976 Devel::Size::total_size($CPAN::META)/1024,
1978 for my $k (sort keys %$CPAN::META) {
1979 next unless substr($k,0,4) eq "read";
1980 warn sprintf " %-26s %6d\n", $k, Devel::Size::total_size($CPAN::META->{$k})/1024;
1981 for my $k2 (sort keys %{$CPAN::META->{$k}}) {
1982 warn sprintf " %-25s %6d (keys: %6d)\n",
1984 Devel::Size::total_size($CPAN::META->{$k}{$k2})/1024,
1985 scalar keys %{$CPAN::META->{$k}{$k2}};
1990 #-> sub CPAN::Shell::autobundle ;
1993 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
1994 my(@bundle) = $self->_u_r_common("a",@_);
1995 my($todir) = File::Spec->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1996 File::Path::mkpath($todir);
1997 unless (-d $todir) {
1998 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
2001 my($y,$m,$d) = (localtime)[5,4,3];
2005 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
2006 my($to) = File::Spec->catfile($todir,"$me.pm");
2008 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
2009 $to = File::Spec->catfile($todir,"$me.pm");
2011 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
2013 "package Bundle::$me;\n\n",
2014 "\$VERSION = '0.01';\n\n",
2018 "Bundle::$me - Snapshot of installation on ",
2019 $Config::Config{'myhostname'},
2022 "\n\n=head1 SYNOPSIS\n\n",
2023 "perl -MCPAN -e 'install Bundle::$me'\n\n",
2024 "=head1 CONTENTS\n\n",
2025 join("\n", @bundle),
2026 "\n\n=head1 CONFIGURATION\n\n",
2028 "\n\n=head1 AUTHOR\n\n",
2029 "This Bundle has been generated automatically ",
2030 "by the autobundle routine in CPAN.pm.\n",
2033 $CPAN::Frontend->myprint("\nWrote bundle file
2037 #-> sub CPAN::Shell::expandany ;
2040 CPAN->debug("s[$s]") if $CPAN::DEBUG;
2041 if ($s =~ m|/|) { # looks like a file
2042 $s = CPAN::Distribution->normalize($s);
2043 return $CPAN::META->instance('CPAN::Distribution',$s);
2044 # Distributions spring into existence, not expand
2045 } elsif ($s =~ m|^Bundle::|) {
2046 $self->local_bundles; # scanning so late for bundles seems
2047 # both attractive and crumpy: always
2048 # current state but easy to forget
2050 return $self->expand('Bundle',$s);
2052 return $self->expand('Module',$s)
2053 if $CPAN::META->exists('CPAN::Module',$s);
2058 #-> sub CPAN::Shell::expand ;
2061 my($type,@args) = @_;
2062 CPAN->debug("type[$type]args[@args]") if $CPAN::DEBUG;
2063 my $class = "CPAN::$type";
2064 my $methods = ['id'];
2065 for my $meth (qw(name)) {
2066 next if $] < 5.00303; # no "can"
2067 next unless $class->can($meth);
2068 push @$methods, $meth;
2070 $self->expand_by_method($class,$methods,@args);
2073 sub expand_by_method {
2075 my($class,$methods,@args) = @_;
2078 my($regex,$command);
2079 if ($arg =~ m|^/(.*)/$|) {
2081 } elsif ($arg =~ m/=/) {
2085 CPAN->debug(sprintf "class[%s]regex[%s]command[%s]",
2087 defined $regex ? $regex : "UNDEFINED",
2088 defined $command ? $command : "UNDEFINED",
2090 if (defined $regex) {
2092 $CPAN::META->all_objects($class)
2095 # BUG, we got an empty object somewhere
2096 require Data::Dumper;
2097 CPAN->debug(sprintf(
2098 "Bug in CPAN: Empty id on obj[%s][%s]",
2100 Data::Dumper::Dumper($obj)
2104 for my $method (@$methods) {
2105 my $match = eval {$obj->$method() =~ /$regex/i};
2107 my($err) = $@ =~ /^(.+) at .+? line \d+\.$/;
2108 $err ||= $@; # if we were too restrictive above
2109 $CPAN::Frontend->mydie("$err\n");
2116 } elsif ($command) {
2117 die "equal sign in command disabled (immature interface), ".
2119 ! \$CPAN::Shell::ADVANCED_QUERY=1
2120 to enable it. But please note, this is HIGHLY EXPERIMENTAL code
2121 that may go away anytime.\n"
2122 unless $ADVANCED_QUERY;
2123 my($method,$criterion) = $arg =~ /(.+?)=(.+)/;
2124 my($matchcrit) = $criterion =~ m/^~(.+)/;
2128 $CPAN::META->all_objects($class)
2130 my $lhs = $self->$method() or next; # () for 5.00503
2132 push @m, $self if $lhs =~ m/$matchcrit/;
2134 push @m, $self if $lhs eq $criterion;
2139 if ( $class eq 'CPAN::Bundle' ) {
2140 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
2141 } elsif ($class eq "CPAN::Distribution") {
2142 $xarg = CPAN::Distribution->normalize($arg);
2146 if ($CPAN::META->exists($class,$xarg)) {
2147 $obj = $CPAN::META->instance($class,$xarg);
2148 } elsif ($CPAN::META->exists($class,$arg)) {
2149 $obj = $CPAN::META->instance($class,$arg);
2156 @m = sort {$a->id cmp $b->id} @m;
2157 if ( $CPAN::DEBUG ) {
2158 my $wantarray = wantarray;
2159 my $join_m = join ",", map {$_->id} @m;
2160 $self->debug("wantarray[$wantarray]join_m[$join_m]");
2162 return wantarray ? @m : $m[0];
2165 #-> sub CPAN::Shell::format_result ;
2168 my($type,@args) = @_;
2169 @args = '/./' unless @args;
2170 my(@result) = $self->expand($type,@args);
2171 my $result = @result == 1 ?
2172 $result[0]->as_string :
2174 "No objects of type $type found for argument @args\n" :
2176 (map {$_->as_glimpse} @result),
2177 scalar @result, " items found\n",
2182 #-> sub CPAN::Shell::report_fh ;
2184 my $installation_report_fh;
2185 my $previously_noticed = 0;
2188 return $installation_report_fh if $installation_report_fh;
2189 if ($CPAN::META->has_inst("File::Temp")) {
2190 $installation_report_fh
2192 template => 'cpan_install_XXXX',
2197 unless ( $installation_report_fh ) {
2198 warn("Couldn't open installation report file; " .
2199 "no report file will be generated."
2200 ) unless $previously_noticed++;
2206 # The only reason for this method is currently to have a reliable
2207 # debugging utility that reveals which output is going through which
2208 # channel. No, I don't like the colors ;-)
2210 # to turn colordebugging on, write
2211 # cpan> o conf colorize_output 1
2213 #-> sub CPAN::Shell::print_ornamented ;
2215 my $print_ornamented_have_warned = 0;
2216 sub colorize_output {
2217 my $colorize_output = $CPAN::Config->{colorize_output};
2218 if ($colorize_output && !$CPAN::META->has_inst("Term::ANSIColor")) {
2219 unless ($print_ornamented_have_warned++) {
2220 # no myprint/mywarn within myprint/mywarn!
2221 warn "Colorize_output is set to true but Term::ANSIColor is not
2222 installed. To activate colorized output, please install Term::ANSIColor.\n\n";
2224 $colorize_output = 0;
2226 return $colorize_output;
2231 sub print_ornamented {
2232 my($self,$what,$ornament) = @_;
2233 return unless defined $what;
2235 local $| = 1; # Flush immediately
2236 if ( $CPAN::Be_Silent ) {
2237 print {report_fh()} $what;
2240 my $swhat = "$what"; # stringify if it is an object
2241 if ($CPAN::Config->{term_is_latin}){
2244 =~ s{([\xC0-\xDF])([\x80-\xBF])}{chr(ord($1)<<6&0xC0|ord($2)&0x3F)}eg; #};
2246 if ($self->colorize_output) {
2247 if ( $CPAN::DEBUG && $swhat =~ /^Debug\(/ ) {
2248 # if you want to have this configurable, please file a bugreport
2249 $ornament = "black on_cyan";
2251 my $color_on = eval { Term::ANSIColor::color($ornament) } || "";
2253 print "Term::ANSIColor rejects color[$ornament]: $@\n
2254 Please choose a different color (Hint: try 'o conf init color.*')\n";
2258 Term::ANSIColor::color("reset");
2264 # where is myprint/mywarn/Frontend/etc. documented? We need guidelines
2265 # where to use what! I think, we send everything to STDOUT and use
2266 # print for normal/good news and warn for news that need more
2267 # attention. Yes, this is our working contract for now.
2269 my($self,$what) = @_;
2271 $self->print_ornamented($what, $CPAN::Config->{colorize_print}||'bold blue on_white');
2275 my($self,$what) = @_;
2276 $self->myprint($what);
2281 my($self,$what) = @_;
2282 $self->print_ornamented($what, $CPAN::Config->{colorize_warn}||'bold red on_white');
2285 # only to be used for shell commands
2287 my($self,$what) = @_;
2288 $self->print_ornamented($what, $CPAN::Config->{colorize_warn}||'bold red on_white');
2290 # If it is the shell, we want that the following die to be silent,
2291 # but if it is not the shell, we would need a 'die $what'. We need
2292 # to take care that only shell commands use mydie. Is this
2298 # sub CPAN::Shell::colorable_makemaker_prompt
2299 sub colorable_makemaker_prompt {
2301 if (CPAN::Shell->colorize_output) {
2302 my $ornament = $CPAN::Config->{colorize_print}||'bold blue on_white';
2303 my $color_on = eval { Term::ANSIColor::color($ornament); } || "";
2306 my $ans = ExtUtils::MakeMaker::prompt($foo,$bar);
2307 if (CPAN::Shell->colorize_output) {
2308 print Term::ANSIColor::color('reset');
2313 # use this only for unrecoverable errors!
2314 sub unrecoverable_error {
2315 my($self,$what) = @_;
2316 my @lines = split /\n/, $what;
2318 for my $l (@lines) {
2319 $longest = length $l if length $l > $longest;
2321 $longest = 62 if $longest > 62;
2322 for my $l (@lines) {
2328 if (length $l < 66) {
2329 $l = pack "A66 A*", $l, "<==";
2333 unshift @lines, "\n";
2334 $self->mydie(join "", @lines);
2338 my($self, $sleep) = @_;
2343 return if -t STDOUT;
2344 my $odef = select STDERR;
2351 #-> sub CPAN::Shell::rematein ;
2352 # RE-adme||MA-ke||TE-st||IN-stall
2355 my($meth,@some) = @_;
2357 while($meth =~ /^(force|notest)$/) {
2358 push @pragma, $meth;
2359 $meth = shift @some or
2360 $CPAN::Frontend->mydie("Pragma $pragma[-1] used without method: ".
2364 CPAN->debug("pragma[@pragma]meth[$meth]some[@some]") if $CPAN::DEBUG;
2366 # Here is the place to set "test_count" on all involved parties to
2367 # 0. We then can pass this counter on to the involved
2368 # distributions and those can refuse to test if test_count > X. In
2369 # the first stab at it we could use a 1 for "X".
2371 # But when do I reset the distributions to start with 0 again?
2372 # Jost suggested to have a random or cycling interaction ID that
2373 # we pass through. But the ID is something that is just left lying
2374 # around in addition to the counter, so I'd prefer to set the
2375 # counter to 0 now, and repeat at the end of the loop. But what
2376 # about dependencies? They appear later and are not reset, they
2377 # enter the queue but not its copy. How do they get a sensible
2380 # construct the queue
2382 STHING: foreach $s (@some) {
2385 CPAN->debug("s is an object[$s]") if $CPAN::DEBUG;
2387 } elsif ($s =~ m|[\$\@\%]|) { # looks like a perl variable
2388 } elsif ($s =~ m|^/|) { # looks like a regexp
2389 $CPAN::Frontend->mywarn("Sorry, $meth with a regular expression is ".
2390 "not supported.\nRejecting argument '$s'\n");
2391 $CPAN::Frontend->mysleep(2);
2393 } elsif ($meth eq "ls") {
2394 $self->globls($s,\@pragma);
2397 CPAN->debug("calling expandany [$s]") if $CPAN::DEBUG;
2398 $obj = CPAN::Shell->expandany($s);
2401 } elsif (ref $obj) {
2402 $obj->color_cmd_tmps(0,1);
2403 CPAN::Queue->new(qmod => $obj->id, reqtype => "c");
2405 } elsif ($CPAN::META->exists('CPAN::Author',uc($s))) {
2406 $obj = $CPAN::META->instance('CPAN::Author',uc($s));
2407 if ($meth =~ /^(dump|ls)$/) {
2410 $CPAN::Frontend->mywarn(
2412 "Don't be silly, you can't $meth ",
2416 $CPAN::Frontend->mysleep(2);
2418 } elsif ($s =~ m|[\$\@\%]| && $meth eq "dump") {
2419 CPAN::InfoObj->dump($s);
2422 ->mywarn(qq{Warning: Cannot $meth $s, }.
2423 qq{don't know what it is.
2428 to find objects with matching identifiers.
2430 $CPAN::Frontend->mysleep(2);
2434 # queuerunner (please be warned: when I started to change the
2435 # queue to hold objects instead of names, I made one or two
2436 # mistakes and never found which. I reverted back instead)
2437 while (my $q = CPAN::Queue->first) {
2439 my $s = $q->as_string;
2440 my $reqtype = $q->reqtype || "";
2441 $obj = CPAN::Shell->expandany($s);
2442 $obj->{reqtype} ||= "";
2443 CPAN->debug("obj-reqtype[$obj->{reqtype}]".
2444 "q-reqtype[$reqtype]") if $CPAN::DEBUG;
2445 if ($obj->{reqtype}) {
2446 if ($obj->{reqtype} eq "b" && $reqtype =~ /^[rc]$/) {
2447 $obj->{reqtype} = $reqtype;
2449 exists $obj->{install}
2452 $obj->{install}->can("failed") ?
2453 $obj->{install}->failed :
2454 $obj->{install} =~ /^NO/
2457 delete $obj->{install};
2458 $CPAN::Frontend->mywarn
2459 ("Promoting $obj->{ID} from 'build_requires' to 'requires'");
2463 $obj->{reqtype} = $reqtype;
2466 for my $pragma (@pragma) {
2469 ($] < 5.00303 || $obj->can($pragma))){
2470 ### compatibility with 5.003
2471 $obj->$pragma($meth); # the pragma "force" in
2472 # "CPAN::Distribution" must know
2473 # what we are intending
2476 if ($]>=5.00303 && $obj->can('called_for')) {
2477 $obj->called_for($s);
2479 CPAN->debug(qq{pragma[@pragma]meth[$meth]}.
2480 qq{ID[$obj->{ID}]}) if $CPAN::DEBUG;
2484 CPAN::Queue->delete($s);
2486 CPAN->debug("failed");
2490 CPAN::Queue->delete_first($s);
2492 for my $obj (@qcopy) {
2493 $obj->color_cmd_tmps(0,0);
2494 delete $obj->{incommandcolor};
2498 #-> sub CPAN::Shell::recent ;
2502 CPAN::Distribution::_display_url( $self, $CPAN::Defaultrecent );
2507 # set up the dispatching methods
2509 for my $command (qw(
2524 *$command = sub { shift->rematein($command, @_); };
2528 package CPAN::LWP::UserAgent;
2532 return if $SETUPDONE;
2533 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2534 require LWP::UserAgent;
2535 @ISA = qw(Exporter LWP::UserAgent);
2538 $CPAN::Frontend->mywarn(" LWP::UserAgent not available\n");
2542 sub get_basic_credentials {
2543 my($self, $realm, $uri, $proxy) = @_;
2544 if ($USER && $PASSWD) {
2545 return ($USER, $PASSWD);
2548 ($USER,$PASSWD) = $self->get_proxy_credentials();
2550 ($USER,$PASSWD) = $self->get_non_proxy_credentials();
2552 return($USER,$PASSWD);
2555 sub get_proxy_credentials {
2557 my ($user, $password);
2558 if ( defined $CPAN::Config->{proxy_user} &&
2559 defined $CPAN::Config->{proxy_pass}) {
2560 $user = $CPAN::Config->{proxy_user};
2561 $password = $CPAN::Config->{proxy_pass};
2562 return ($user, $password);
2564 my $username_prompt = "\nProxy authentication needed!
2565 (Note: to permanently configure username and password run
2566 o conf proxy_user your_username
2567 o conf proxy_pass your_password
2569 ($user, $password) =
2570 _get_username_and_password_from_user($username_prompt);
2571 return ($user,$password);
2574 sub get_non_proxy_credentials {
2576 my ($user,$password);
2577 if ( defined $CPAN::Config->{username} &&
2578 defined $CPAN::Config->{password}) {
2579 $user = $CPAN::Config->{username};
2580 $password = $CPAN::Config->{password};
2581 return ($user, $password);
2583 my $username_prompt = "\nAuthentication needed!
2584 (Note: to permanently configure username and password run
2585 o conf username your_username
2586 o conf password your_password
2589 ($user, $password) =
2590 _get_username_and_password_from_user($username_prompt);
2591 return ($user,$password);
2594 sub _get_username_and_password_from_user {
2596 my $username_message = shift;
2597 my ($username,$password);
2599 ExtUtils::MakeMaker->import(qw(prompt));
2600 $username = prompt($username_message);
2601 if ($CPAN::META->has_inst("Term::ReadKey")) {
2602 Term::ReadKey::ReadMode("noecho");
2605 $CPAN::Frontend->mywarn(
2606 "Warning: Term::ReadKey seems not to be available, your password will be echoed to the terminal!\n"
2609 $password = prompt("Password:");
2611 if ($CPAN::META->has_inst("Term::ReadKey")) {
2612 Term::ReadKey::ReadMode("restore");
2614 $CPAN::Frontend->myprint("\n\n");
2615 return ($username,$password);
2618 # mirror(): Its purpose is to deal with proxy authentication. When we
2619 # call SUPER::mirror, we relly call the mirror method in
2620 # LWP::UserAgent. LWP::UserAgent will then call
2621 # $self->get_basic_credentials or some equivalent and this will be
2622 # $self->dispatched to our own get_basic_credentials method.
2624 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
2626 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
2627 # although we have gone through our get_basic_credentials, the proxy
2628 # server refuses to connect. This could be a case where the username or
2629 # password has changed in the meantime, so I'm trying once again without
2630 # $USER and $PASSWD to give the get_basic_credentials routine another
2631 # chance to set $USER and $PASSWD.
2633 # mirror(): Its purpose is to deal with proxy authentication. When we
2634 # call SUPER::mirror, we relly call the mirror method in
2635 # LWP::UserAgent. LWP::UserAgent will then call
2636 # $self->get_basic_credentials or some equivalent and this will be
2637 # $self->dispatched to our own get_basic_credentials method.
2639 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
2641 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
2642 # although we have gone through our get_basic_credentials, the proxy
2643 # server refuses to connect. This could be a case where the username or
2644 # password has changed in the meantime, so I'm trying once again without
2645 # $USER and $PASSWD to give the get_basic_credentials routine another
2646 # chance to set $USER and $PASSWD.
2649 my($self,$url,$aslocal) = @_;
2650 my $result = $self->SUPER::mirror($url,$aslocal);
2651 if ($result->code == 407) {
2654 $result = $self->SUPER::mirror($url,$aslocal);
2662 #-> sub CPAN::FTP::ftp_get ;
2664 my($class,$host,$dir,$file,$target) = @_;
2666 qq[Going to fetch file [$file] from dir [$dir]
2667 on host [$host] as local [$target]\n]
2669 my $ftp = Net::FTP->new($host);
2671 $CPAN::Frontend->mywarn(" Could not connect to host '$host' with Net::FTP\n");
2674 return 0 unless defined $ftp;
2675 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
2676 $class->debug(qq[Going to login("anonymous","$Config::Config{cf_email}")]);
2677 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
2678 my $msg = $ftp->message;
2679 $CPAN::Frontend->mywarn(" Couldn't login on $host: $msg");
2682 unless ( $ftp->cwd($dir) ){
2683 my $msg = $ftp->message;
2684 $CPAN::Frontend->mywarn(" Couldn't cwd $dir: $msg");
2688 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
2689 unless ( $ftp->get($file,$target) ){
2690 my $msg = $ftp->message;
2691 $CPAN::Frontend->mywarn(" Couldn't fetch $file from $host: $msg");
2694 $ftp->quit; # it's ok if this fails
2698 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
2700 # > *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
2701 # > --- /tmp/cp Wed Sep 24 13:26:40 1997
2703 # > *** 1562,1567 ****
2704 # > --- 1562,1580 ----
2705 # > return 1 if substr($url,0,4) eq "file";
2706 # > return 1 unless $url =~ m|://([^/]+)|;
2708 # > + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
2710 # > + $proxy =~ m|://([^/:]+)|;
2712 # > + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
2713 # > + if ($noproxy) {
2714 # > + if ($host !~ /$noproxy$/) {
2715 # > + $host = $proxy;
2718 # > + $host = $proxy;
2721 # > require Net::Ping;
2722 # > return 1 unless $Net::Ping::VERSION >= 2;
2726 #-> sub CPAN::FTP::localize ;
2728 my($self,$file,$aslocal,$force) = @_;
2730 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
2731 unless defined $aslocal;
2732 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
2735 if ($^O eq 'MacOS') {
2736 # Comment by AK on 2000-09-03: Uniq short filenames would be
2737 # available in CHECKSUMS file
2738 my($name, $path) = File::Basename::fileparse($aslocal, '');
2739 if (length($name) > 31) {
2750 my $size = 31 - length($suf);
2751 while (length($name) > $size) {
2755 $aslocal = File::Spec->catfile($path, $name);
2759 if (-f $aslocal && -r _ && !($force & 1)){
2761 if ($size = -s $aslocal) {
2762 $self->debug("aslocal[$aslocal]size[$size]") if $CPAN::DEBUG;
2765 # empty file from a previous unsuccessful attempt to download it
2767 $CPAN::Frontend->mydie("Found a zero-length '$aslocal' that I ".
2768 "could not remove.");
2773 rename $aslocal, "$aslocal.bak";
2777 my($aslocal_dir) = File::Basename::dirname($aslocal);
2778 File::Path::mkpath($aslocal_dir);
2779 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
2780 qq{directory "$aslocal_dir".
2781 I\'ll continue, but if you encounter problems, they may be due
2782 to insufficient permissions.\n}) unless -w $aslocal_dir;
2784 # Inheritance is not easier to manage than a few if/else branches
2785 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2787 CPAN::LWP::UserAgent->config;
2788 eval {$Ua = CPAN::LWP::UserAgent->new;}; # Why is has_usable still not fit enough?
2790 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n")
2794 $Ua->proxy('ftp', $var)
2795 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
2796 $Ua->proxy('http', $var)
2797 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
2800 # >>>>> On Wed, 13 Dec 2000 09:21:34 -0500, "Robison, Jonathon (J.M.)" <jrobiso2@visteon.com> said:
2802 # > I note that although CPAN.pm can use proxies, it doesn't seem equipped to
2803 # > use ones that require basic autorization.
2805 # > Example of when I use it manually in my own stuff:
2807 # > $ua->proxy(['http','ftp'], http://my.proxy.server:83');
2808 # > $req->proxy_authorization_basic("username","password");
2809 # > $res = $ua->request($req);
2813 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
2817 for my $prx (qw(ftp_proxy http_proxy no_proxy)) {
2818 $ENV{$prx} = $CPAN::Config->{$prx} if $CPAN::Config->{$prx};
2821 # Try the list of urls for each single object. We keep a record
2822 # where we did get a file from
2823 my(@reordered,$last);
2824 $CPAN::Config->{urllist} ||= [];
2825 unless (ref $CPAN::Config->{urllist} eq 'ARRAY') {
2826 $CPAN::Frontend->mywarn("Malformed urllist; ignoring. Configuration file corrupt?\n");
2827 $CPAN::Config->{urllist} = [];
2829 $last = $#{$CPAN::Config->{urllist}};
2830 if ($force & 2) { # local cpans probably out of date, don't reorder
2831 @reordered = (0..$last);
2835 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
2837 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
2839 defined($ThesiteURL)
2841 ($CPAN::Config->{urllist}[$b] eq $ThesiteURL)
2843 ($CPAN::Config->{urllist}[$a] eq $ThesiteURL)
2848 $self->debug("Themethod[$Themethod]") if $CPAN::DEBUG;
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 if ($u->can("text")) {
2867 $u->{TEXT} .= "/" unless substr($u->{TEXT},-1) eq "/";
2869 $u .= "/" unless substr($u,-1) eq "/";
2870 $u = CPAN::URL->new(TEXT => $u, FROM => "USER");
2873 for my $u (@CPAN::Defaultsites) {
2874 push @urllist, $u unless grep { $_ eq $u } @urllist;
2876 $self->debug("synth. urllist[@urllist]") if $CPAN::DEBUG;
2877 my $ret = $self->$method(\@urllist,$file,$aslocal);
2879 $Themethod = $level;
2881 # utime $now, $now, $aslocal; # too bad, if we do that, we
2882 # might alter a local mirror
2883 $self->debug("level[$level]") if $CPAN::DEBUG;
2887 last if $CPAN::Signal; # need to cleanup
2890 unless ($CPAN::Signal) {
2893 if (@{$CPAN::Config->{urllist}}) {
2895 qq{Please check, if the URLs I found in your configuration file \(}.
2896 join(", ", @{$CPAN::Config->{urllist}}).
2899 push @mess, qq{Your urllist is empty!};
2901 push @mess, qq{The urllist can be edited.},
2902 qq{E.g. with 'o conf urllist push ftp://myurl/'};
2903 $CPAN::Frontend->mywarn(Text::Wrap::wrap("","","@mess"). "\n\n");
2904 $CPAN::Frontend->mywarn("Could not fetch $file\n");
2905 $CPAN::Frontend->mysleep(2);
2908 rename "$aslocal.bak", $aslocal;
2909 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
2910 $self->ls($aslocal));
2916 # package CPAN::FTP;
2918 my($self,$host_seq,$file,$aslocal) = @_;
2920 HOSTEASY: for $ro_url (@$host_seq) {
2921 my $url .= "$ro_url$file";
2922 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
2923 if ($url =~ /^file:/) {
2925 if ($CPAN::META->has_inst('URI::URL')) {
2926 my $u = URI::URL->new($url);
2928 } else { # works only on Unix, is poorly constructed, but
2929 # hopefully better than nothing.
2930 # RFC 1738 says fileurl BNF is
2931 # fileurl = "file://" [ host | "localhost" ] "/" fpath
2932 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
2934 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
2935 $l =~ s|^file:||; # assume they
2939 if ! -f $l && $l =~ m|^/\w:|; # e.g. /P:
2941 $self->debug("local file[$l]") if $CPAN::DEBUG;
2942 if ( -f $l && -r _) {
2943 $ThesiteURL = $ro_url;
2946 if ($l =~ /(.+)\.gz$/) {
2948 if ( -f $ungz && -r _) {
2949 $ThesiteURL = $ro_url;
2953 # Maybe mirror has compressed it?
2955 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
2956 CPAN::Tarzip->new("$l.gz")->gunzip($aslocal);
2958 $ThesiteURL = $ro_url;
2963 if ($CPAN::META->has_usable('LWP')) {
2964 $CPAN::Frontend->myprint("Fetching with LWP:
2968 CPAN::LWP::UserAgent->config;
2969 eval { $Ua = CPAN::LWP::UserAgent->new; };
2971 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n");
2974 my $res = $Ua->mirror($url, $aslocal);
2975 if ($res->is_success) {
2976 $ThesiteURL = $ro_url;
2978 utime $now, $now, $aslocal; # download time is more
2979 # important than upload
2982 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2983 my $gzurl = "$url.gz";
2984 $CPAN::Frontend->myprint("Fetching with LWP:
2987 $res = $Ua->mirror($gzurl, "$aslocal.gz");
2988 if ($res->is_success &&
2989 CPAN::Tarzip->new("$aslocal.gz")->gunzip($aslocal)
2991 $ThesiteURL = $ro_url;
2995 $CPAN::Frontend->myprint(sprintf(
2996 "LWP failed with code[%s] message[%s]\n",
3000 # Alan Burlison informed me that in firewall environments
3001 # Net::FTP can still succeed where LWP fails. So we do not
3002 # skip Net::FTP anymore when LWP is available.
3005 $ro_url->can("text")
3007 $ro_url->{FROM} eq "USER"
3009 my $ret = $self->hosthard([$ro_url],$file,$aslocal);
3010 return $ret if $ret;
3012 $CPAN::Frontend->mywarn(" LWP not available\n");
3014 return if $CPAN::Signal;
3015 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
3016 # that's the nice and easy way thanks to Graham
3017 my($host,$dir,$getfile) = ($1,$2,$3);
3018 if ($CPAN::META->has_usable('Net::FTP')) {
3020 $CPAN::Frontend->myprint("Fetching with Net::FTP:
3023 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
3024 "aslocal[$aslocal]") if $CPAN::DEBUG;
3025 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
3026 $ThesiteURL = $ro_url;
3029 if ($aslocal !~ /\.gz(?!\n)\Z/) {
3030 my $gz = "$aslocal.gz";
3031 $CPAN::Frontend->myprint("Fetching with Net::FTP
3034 if (CPAN::FTP->ftp_get($host,
3038 CPAN::Tarzip->new($gz)->gunzip($aslocal)
3040 $ThesiteURL = $ro_url;
3047 return if $CPAN::Signal;
3051 # package CPAN::FTP;
3053 my($self,$host_seq,$file,$aslocal) = @_;
3055 # Came back if Net::FTP couldn't establish connection (or
3056 # failed otherwise) Maybe they are behind a firewall, but they
3057 # gave us a socksified (or other) ftp program...
3060 my($devnull) = $CPAN::Config->{devnull} || "";
3062 my($aslocal_dir) = File::Basename::dirname($aslocal);
3063 File::Path::mkpath($aslocal_dir);
3064 HOSTHARD: for $ro_url (@$host_seq) {
3065 my $url = "$ro_url$file";
3066 my($proto,$host,$dir,$getfile);
3068 # Courtesy Mark Conty mark_conty@cargill.com change from
3069 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
3071 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
3072 # proto not yet used
3073 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
3075 next HOSTHARD; # who said, we could ftp anything except ftp?
3077 next HOSTHARD if $proto eq "file"; # file URLs would have had
3078 # success above. Likely a bogus URL
3080 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
3082 # Try the most capable first and leave ncftp* for last as it only
3084 DLPRG: for my $f (qw(curl wget lynx ncftpget ncftp)) {
3085 my $funkyftp = CPAN::HandleConfig->safe_quote($CPAN::Config->{$f});
3086 next unless defined $funkyftp;
3087 next if $funkyftp =~ /^\s*$/;
3089 my($asl_ungz, $asl_gz);
3090 ($asl_ungz = $aslocal) =~ s/\.gz//;
3091 $asl_gz = "$asl_ungz.gz";
3093 my($src_switch) = "";
3095 my($stdout_redir) = " > $asl_ungz";
3097 $src_switch = " -source";
3098 } elsif ($f eq "ncftp"){
3099 $src_switch = " -c";
3100 } elsif ($f eq "wget"){
3101 $src_switch = " -O $asl_ungz";
3103 } elsif ($f eq 'curl'){
3104 $src_switch = ' -L -f -s -S --netrc-optional';
3107 if ($f eq "ncftpget"){
3108 $chdir = "cd $aslocal_dir && ";
3111 $CPAN::Frontend->myprint(
3113 Trying with "$funkyftp$src_switch" to get
3117 "$chdir$funkyftp$src_switch \"$url\" $devnull$stdout_redir";
3118 $self->debug("system[$system]") if $CPAN::DEBUG;
3119 my($wstatus) = system($system);
3121 # lynx returns 0 when it fails somewhere
3123 my $content = do { local *FH; open FH, $asl_ungz or die; local $/; <FH> };
3124 if ($content =~ /^<.*<title>[45]/si) {
3125 $CPAN::Frontend->mywarn(qq{
3126 No success, the file that lynx has has downloaded looks like an error message:
3129 $CPAN::Frontend->mysleep(1);
3133 $CPAN::Frontend->myprint(qq{
3134 No success, the file that lynx has has downloaded is an empty file.
3139 if ($wstatus == 0) {
3142 } elsif ($asl_ungz ne $aslocal) {
3143 # test gzip integrity
3144 if (CPAN::Tarzip->new($asl_ungz)->gtest) {
3145 # e.g. foo.tar is gzipped --> foo.tar.gz
3146 rename $asl_ungz, $aslocal;
3148 CPAN::Tarzip->new($asl_gz)->gzip($asl_ungz);
3151 $ThesiteURL = $ro_url;
3153 } elsif ($url !~ /\.gz(?!\n)\Z/) {
3155 -f $asl_ungz && -s _ == 0;
3156 my $gz = "$aslocal.gz";
3157 my $gzurl = "$url.gz";
3158 $CPAN::Frontend->myprint(
3160 Trying with "$funkyftp$src_switch" to get
3163 my($system) = "$funkyftp$src_switch \"$url.gz\" $devnull > $asl_gz";
3164 $self->debug("system[$system]") if $CPAN::DEBUG;
3166 if (($wstatus = system($system)) == 0
3170 # test gzip integrity
3171 my $ct = CPAN::Tarzip->new($asl_gz);
3173 $ct->gunzip($aslocal);
3175 # somebody uncompressed file for us?
3176 rename $asl_ungz, $aslocal;
3178 $ThesiteURL = $ro_url;
3181 unlink $asl_gz if -f $asl_gz;
3184 my $estatus = $wstatus >> 8;
3185 my $size = -f $aslocal ?
3186 ", left\n$aslocal with size ".-s _ :
3187 "\nWarning: expected file [$aslocal] doesn't exist";
3188 $CPAN::Frontend->myprint(qq{
3189 System call "$system"
3190 returned status $estatus (wstat $wstatus)$size
3193 return if $CPAN::Signal;
3194 } # transfer programs
3198 # package CPAN::FTP;
3200 my($self,$host_seq,$file,$aslocal) = @_;
3203 my($aslocal_dir) = File::Basename::dirname($aslocal);
3204 File::Path::mkpath($aslocal_dir);
3205 my $ftpbin = $CPAN::Config->{ftp};
3206 unless (length $ftpbin && MM->maybe_command($ftpbin)) {
3207 $CPAN::Frontend->myprint("No external ftp command available\n\n");
3210 $CPAN::Frontend->mywarn(qq{
3211 As a last ressort we now switch to the external ftp command '$ftpbin'
3214 Doing so often leads to problems that are hard to diagnose.
3216 If you're victim of such problems, please consider unsetting the ftp
3217 config variable with
3223 $CPAN::Frontend->mysleep(2);
3224 HOSTHARDEST: for $ro_url (@$host_seq) {
3225 my $url = "$ro_url$file";
3226 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
3227 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
3230 my($host,$dir,$getfile) = ($1,$2,$3);
3232 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
3233 $ctime,$blksize,$blocks) = stat($aslocal);
3234 $timestamp = $mtime ||= 0;
3235 my($netrc) = CPAN::FTP::netrc->new;
3236 my($netrcfile) = $netrc->netrc;
3237 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
3238 my $targetfile = File::Basename::basename($aslocal);
3244 map("cd $_", split /\//, $dir), # RFC 1738
3246 "get $getfile $targetfile",
3250 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
3251 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
3252 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
3254 $netrc->contains($host))) if $CPAN::DEBUG;
3255 if ($netrc->protected) {
3256 my $dialog = join "", map { " $_\n" } @dialog;
3258 if ($netrc->contains($host)) {
3259 $netrc_explain = "Relying that your .netrc entry for '$host' ".
3260 "manages the login";
3262 $netrc_explain = "Relying that your default .netrc entry ".
3263 "manages the login";
3265 $CPAN::Frontend->myprint(qq{
3266 Trying with external ftp to get
3269 Going to send the dialog
3273 $self->talk_ftp("$ftpbin$verbose $host",
3275 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3276 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
3278 if ($mtime > $timestamp) {
3279 $CPAN::Frontend->myprint("GOT $aslocal\n");
3280 $ThesiteURL = $ro_url;
3283 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
3285 return if $CPAN::Signal;
3287 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
3288 qq{correctly protected.\n});
3291 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
3292 nor does it have a default entry\n");
3295 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
3296 # then and login manually to host, using e-mail as
3298 $CPAN::Frontend->myprint(qq{Issuing "$ftpbin$verbose -n"\n});
3302 "user anonymous $Config::Config{'cf_email'}"
3304 my $dialog = join "", map { " $_\n" } @dialog;
3305 $CPAN::Frontend->myprint(qq{
3306 Trying with external ftp to get
3308 Going to send the dialog
3312 $self->talk_ftp("$ftpbin$verbose -n", @dialog);
3313 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3314 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
3316 if ($mtime > $timestamp) {
3317 $CPAN::Frontend->myprint("GOT $aslocal\n");
3318 $ThesiteURL = $ro_url;
3321 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
3323 return if $CPAN::Signal;
3324 $CPAN::Frontend->mywarn("Can't access URL $url.\n\n");
3325 $CPAN::Frontend->mysleep(2);
3329 # package CPAN::FTP;
3331 my($self,$command,@dialog) = @_;
3332 my $fh = FileHandle->new;
3333 $fh->open("|$command") or die "Couldn't open ftp: $!";
3334 foreach (@dialog) { $fh->print("$_\n") }
3335 $fh->close; # Wait for process to complete
3337 my $estatus = $wstatus >> 8;
3338 $CPAN::Frontend->myprint(qq{
3339 Subprocess "|$command"
3340 returned status $estatus (wstat $wstatus)
3344 # find2perl needs modularization, too, all the following is stolen
3348 my($self,$name) = @_;
3349 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
3350 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
3352 my($perms,%user,%group);
3356 $blocks = int(($blocks + 1) / 2);
3359 $blocks = int(($sizemm + 1023) / 1024);
3362 if (-f _) { $perms = '-'; }
3363 elsif (-d _) { $perms = 'd'; }
3364 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
3365 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
3366 elsif (-p _) { $perms = 'p'; }
3367 elsif (-S _) { $perms = 's'; }
3368 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
3370 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
3371 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
3372 my $tmpmode = $mode;
3373 my $tmp = $rwx[$tmpmode & 7];
3375 $tmp = $rwx[$tmpmode & 7] . $tmp;
3377 $tmp = $rwx[$tmpmode & 7] . $tmp;
3378 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
3379 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
3380 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
3383 my $user = $user{$uid} || $uid; # too lazy to implement lookup
3384 my $group = $group{$gid} || $gid;
3386 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
3388 my($moname) = $moname[$mon];
3389 if (-M _ > 365.25 / 2) {
3390 $timeyear = $year + 1900;
3393 $timeyear = sprintf("%02d:%02d", $hour, $min);
3396 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
3410 package CPAN::FTP::netrc;
3413 # package CPAN::FTP::netrc;
3416 my $home = CPAN::HandleConfig::home;
3417 my $file = File::Spec->catfile($home,".netrc");
3419 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3420 $atime,$mtime,$ctime,$blksize,$blocks)
3425 my($fh,@machines,$hasdefault);
3427 $fh = FileHandle->new or die "Could not create a filehandle";
3429 if($fh->open($file)){
3430 $protected = ($mode & 077) == 0;
3432 NETRC: while (<$fh>) {
3433 my(@tokens) = split " ", $_;
3434 TOKEN: while (@tokens) {
3435 my($t) = shift @tokens;
3436 if ($t eq "default"){
3440 last TOKEN if $t eq "macdef";
3441 if ($t eq "machine") {
3442 push @machines, shift @tokens;
3447 $file = $hasdefault = $protected = "";
3451 'mach' => [@machines],
3453 'hasdefault' => $hasdefault,
3454 'protected' => $protected,
3458 # CPAN::FTP::netrc::hasdefault;
3459 sub hasdefault { shift->{'hasdefault'} }
3460 sub netrc { shift->{'netrc'} }
3461 sub protected { shift->{'protected'} }
3463 my($self,$mach) = @_;
3464 for ( @{$self->{'mach'}} ) {
3465 return 1 if $_ eq $mach;
3470 package CPAN::Complete;
3474 my($text, $line, $start, $end) = @_;
3475 my(@perlret) = cpl($text, $line, $start);
3476 # find longest common match. Can anybody show me how to peruse
3477 # T::R::Gnu to have this done automatically? Seems expensive.
3478 return () unless @perlret;
3479 my($newtext) = $text;
3480 for (my $i = length($text)+1;;$i++) {
3481 last unless length($perlret[0]) && length($perlret[0]) >= $i;
3482 my $try = substr($perlret[0],0,$i);
3483 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
3484 # warn "try[$try]tries[@tries]";
3485 if (@tries == @perlret) {
3491 ($newtext,@perlret);
3494 #-> sub CPAN::Complete::cpl ;
3496 my($word,$line,$pos) = @_;
3500 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3502 if ($line =~ s/^(force\s*)//) {
3507 @return = grep /^$word/, @CPAN::Complete::COMMANDS;
3508 } elsif ( $line !~ /^[\!abcdghimorutl]/ ) {
3510 } elsif ($line =~ /^(a|ls)\s/) {
3511 @return = cplx('CPAN::Author',uc($word));
3512 } elsif ($line =~ /^b\s/) {
3513 CPAN::Shell->local_bundles;
3514 @return = cplx('CPAN::Bundle',$word);
3515 } elsif ($line =~ /^d\s/) {
3516 @return = cplx('CPAN::Distribution',$word);
3517 } elsif ($line =~ m/^(
3518 [mru]|make|clean|dump|get|test|install|readme|look|cvs_import|perldoc|recent
3520 if ($word =~ /^Bundle::/) {
3521 CPAN::Shell->local_bundles;
3523 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
3524 } elsif ($line =~ /^i\s/) {
3525 @return = cpl_any($word);
3526 } elsif ($line =~ /^reload\s/) {
3527 @return = cpl_reload($word,$line,$pos);
3528 } elsif ($line =~ /^o\s/) {
3529 @return = cpl_option($word,$line,$pos);
3530 } elsif ($line =~ m/^\S+\s/ ) {
3531 # fallback for future commands and what we have forgotten above
3532 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
3539 #-> sub CPAN::Complete::cplx ;
3541 my($class, $word) = @_;
3542 # I believed for many years that this was sorted, today I
3543 # realized, it wasn't sorted anymore. Now (rev 1.301 / v 1.55) I
3544 # make it sorted again. Maybe sort was dropped when GNU-readline
3545 # support came in? The RCS file is difficult to read on that:-(
3546 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
3549 #-> sub CPAN::Complete::cpl_any ;
3553 cplx('CPAN::Author',$word),
3554 cplx('CPAN::Bundle',$word),
3555 cplx('CPAN::Distribution',$word),
3556 cplx('CPAN::Module',$word),
3560 #-> sub CPAN::Complete::cpl_reload ;
3562 my($word,$line,$pos) = @_;
3564 my(@words) = split " ", $line;
3565 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3566 my(@ok) = qw(cpan index);
3567 return @ok if @words == 1;
3568 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
3571 #-> sub CPAN::Complete::cpl_option ;
3573 my($word,$line,$pos) = @_;
3575 my(@words) = split " ", $line;
3576 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3577 my(@ok) = qw(conf debug);
3578 return @ok if @words == 1;
3579 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
3581 } elsif ($words[1] eq 'index') {
3583 } elsif ($words[1] eq 'conf') {
3584 return CPAN::HandleConfig::cpl(@_);
3585 } elsif ($words[1] eq 'debug') {
3586 return sort grep /^\Q$word\E/i,
3587 sort keys %CPAN::DEBUG, 'all';
3591 package CPAN::Index;
3594 #-> sub CPAN::Index::force_reload ;
3597 $CPAN::Index::LAST_TIME = 0;
3601 #-> sub CPAN::Index::reload ;
3603 my($cl,$force) = @_;
3606 # XXX check if a newer one is available. (We currently read it
3607 # from time to time)
3608 for ($CPAN::Config->{index_expire}) {
3609 $_ = 0.001 unless $_ && $_ > 0.001;
3611 unless (1 || $CPAN::Have_warned->{readmetadatacache}++) {
3612 # debug here when CPAN doesn't seem to read the Metadata
3614 Carp::cluck("META-PROTOCOL[$CPAN::META->{PROTOCOL}]");
3616 unless ($CPAN::META->{PROTOCOL}) {
3617 $cl->read_metadata_cache;
3618 $CPAN::META->{PROTOCOL} ||= "1.0";
3620 if ( $CPAN::META->{PROTOCOL} < PROTOCOL ) {
3621 # warn "Setting last_time to 0";
3622 $LAST_TIME = 0; # No warning necessary
3624 return if $LAST_TIME + $CPAN::Config->{index_expire}*86400 > $time
3627 # IFF we are developing, it helps to wipe out the memory
3628 # between reloads, otherwise it is not what a user expects.
3629 undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
3630 $CPAN::META = CPAN->new;
3634 local $LAST_TIME = $time;
3635 local $CPAN::META->{PROTOCOL} = PROTOCOL;
3637 my $needshort = $^O eq "dos";
3639 $cl->rd_authindex($cl
3641 "authors/01mailrc.txt.gz",
3643 File::Spec->catfile('authors', '01mailrc.gz') :
3644 File::Spec->catfile('authors', '01mailrc.txt.gz'),
3647 $debug = "timing reading 01[".($t2 - $time)."]";
3649 return if $CPAN::Signal; # this is sometimes lengthy
3650 $cl->rd_modpacks($cl
3652 "modules/02packages.details.txt.gz",
3654 File::Spec->catfile('modules', '02packag.gz') :
3655 File::Spec->catfile('modules', '02packages.details.txt.gz'),
3658 $debug .= "02[".($t2 - $time)."]";
3660 return if $CPAN::Signal; # this is sometimes lengthy
3663 "modules/03modlist.data.gz",
3665 File::Spec->catfile('modules', '03mlist.gz') :
3666 File::Spec->catfile('modules', '03modlist.data.gz'),
3668 $cl->write_metadata_cache;
3670 $debug .= "03[".($t2 - $time)."]";
3672 CPAN->debug($debug) if $CPAN::DEBUG;
3675 $CPAN::META->{PROTOCOL} = PROTOCOL;
3678 #-> sub CPAN::Index::reload_x ;
3680 my($cl,$wanted,$localname,$force) = @_;
3681 $force |= 2; # means we're dealing with an index here
3682 CPAN::HandleConfig->load; # we should guarantee loading wherever
3683 # we rely on Config XXX
3684 $localname ||= $wanted;
3685 my $abs_wanted = File::Spec->catfile($CPAN::Config->{'keep_source_where'},
3689 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
3692 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
3693 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
3694 qq{day$s. I\'ll use that.});
3697 $force |= 1; # means we're quite serious about it.
3699 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
3702 #-> sub CPAN::Index::rd_authindex ;
3704 my($cl, $index_target) = @_;
3706 return unless defined $index_target;
3707 $CPAN::Frontend->myprint("Going to read $index_target\n");
3709 tie *FH, 'CPAN::Tarzip', $index_target;
3712 push @lines, split /\012/ while <FH>;
3714 my $modulus = int(@lines/75) || 1;
3716 my($userid,$fullname,$email) =
3717 m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
3718 next unless $userid && $fullname && $email;
3720 # instantiate an author object
3721 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
3722 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
3723 $CPAN::Frontend->myprint(".") unless $i++ % $modulus;
3724 return if $CPAN::Signal;
3726 $CPAN::Frontend->myprint("DONE\n");
3730 my($self,$dist) = @_;
3731 $dist = $self->{'id'} unless defined $dist;
3732 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
3736 #-> sub CPAN::Index::rd_modpacks ;
3738 my($self, $index_target) = @_;
3739 return unless defined $index_target;
3740 $CPAN::Frontend->myprint("Going to read $index_target\n");
3741 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3743 CPAN->debug(sprintf "start[%d]", time) if $CPAN::DEBUG;
3746 while (my $bytes = $fh->READ(\$chunk,8192)) {
3749 my @lines = split /\012/, $slurp;
3750 CPAN->debug(sprintf "end[%d]", time) if $CPAN::DEBUG;
3753 my($line_count,$last_updated);
3755 my $shift = shift(@lines);
3756 last if $shift =~ /^\s*$/;
3757 $shift =~ /^Line-Count:\s+(\d+)/ and $line_count = $1;
3758 $shift =~ /^Last-Updated:\s+(.+)/ and $last_updated = $1;
3760 CPAN->debug("line_count[$line_count]last_updated[$last_updated]") if $CPAN::DEBUG;
3761 if (not defined $line_count) {
3763 $CPAN::Frontend->mywarn(qq{Warning: Your $index_target does not contain a Line-Count header.
3764 Please check the validity of the index file by comparing it to more
3765 than one CPAN mirror. I'll continue but problems seem likely to
3769 $CPAN::Frontend->mysleep(5);
3770 } elsif ($line_count != scalar @lines) {
3772 $CPAN::Frontend->mywarn(sprintf qq{Warning: Your %s
3773 contains a Line-Count header of %d but I see %d lines there. Please
3774 check the validity of the index file by comparing it to more than one
3775 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
3776 $index_target, $line_count, scalar(@lines));
3779 if (not defined $last_updated) {
3781 $CPAN::Frontend->mywarn(qq{Warning: Your $index_target does not contain a Last-Updated header.
3782 Please check the validity of the index file by comparing it to more
3783 than one CPAN mirror. I'll continue but problems seem likely to
3787 $CPAN::Frontend->mysleep(5);
3791 ->myprint(sprintf qq{ Database was generated on %s\n},
3793 $DATE_OF_02 = $last_updated;
3796 if ($CPAN::META->has_inst('HTTP::Date')) {
3798 $age -= HTTP::Date::str2time($last_updated);
3800 $CPAN::Frontend->mywarn(" HTTP::Date not available\n");
3801 require Time::Local;
3802 my(@d) = $last_updated =~ / (\d+) (\w+) (\d+) (\d+):(\d+):(\d+) /;
3803 $d[1] = index("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", $d[1])/4;
3804 $age -= $d[1]>=0 ? Time::Local::timegm(@d[5,4,3,0,1,2]) : 0;
3811 qq{Warning: This index file is %d days old.
3812 Please check the host you chose as your CPAN mirror for staleness.
3813 I'll continue but problems seem likely to happen.\a\n},
3816 } elsif ($age < -1) {
3820 qq{Warning: Your system date is %d days behind this index file!
3822 Timestamp index file: %s
3823 Please fix your system time, problems with the make command expected.\n},
3833 # A necessity since we have metadata_cache: delete what isn't
3835 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
3836 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
3839 my $modulus = int(@lines/75) || 1;
3841 # before 1.56 we split into 3 and discarded the rest. From
3842 # 1.57 we assign remaining text to $comment thus allowing to
3843 # influence isa_perl
3844 my($mod,$version,$dist,$comment) = split " ", $_, 4;
3845 my($bundle,$id,$userid);
3847 if ($mod eq 'CPAN' &&
3849 CPAN::Queue->exists('Bundle::CPAN') ||
3850 CPAN::Queue->exists('CPAN')
3854 if ($version > $CPAN::VERSION){
3855 $CPAN::Frontend->mywarn(qq{
3856 New CPAN.pm version (v$version) available.
3857 [Currently running version is v$CPAN::VERSION]
3858 You might want to try
3861 to both upgrade CPAN.pm and run the new version without leaving
3862 the current session.
3865 $CPAN::Frontend->mysleep(2);
3866 $CPAN::Frontend->myprint(qq{\n});
3868 last if $CPAN::Signal;
3869 } elsif ($mod =~ /^Bundle::(.*)/) {
3874 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
3875 # Let's make it a module too, because bundles have so much
3876 # in common with modules.
3878 # Changed in 1.57_63: seems like memory bloat now without
3879 # any value, so commented out
3881 # $CPAN::META->instance('CPAN::Module',$mod);
3885 # instantiate a module object
3886 $id = $CPAN::META->instance('CPAN::Module',$mod);
3890 # Although CPAN prohibits same name with different version the
3891 # indexer may have changed the version for the same distro
3892 # since the last time ("Force Reindexing" feature)
3893 if ($id->cpan_file ne $dist
3895 $id->cpan_version ne $version
3897 $userid = $id->userid || $self->userid($dist);
3899 'CPAN_USERID' => $userid,
3900 'CPAN_VERSION' => $version,
3901 'CPAN_FILE' => $dist,
3905 # instantiate a distribution object
3906 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
3907 # we do not need CONTAINSMODS unless we do something with
3908 # this dist, so we better produce it on demand.
3910 ## my $obj = $CPAN::META->instance(
3911 ## 'CPAN::Distribution' => $dist
3913 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
3915 $CPAN::META->instance(
3916 'CPAN::Distribution' => $dist
3918 'CPAN_USERID' => $userid,
3919 'CPAN_COMMENT' => $comment,
3923 for my $name ($mod,$dist) {
3924 # $self->debug("exists name[$name]") if $CPAN::DEBUG;
3925 $exists{$name} = undef;
3928 $CPAN::Frontend->myprint(".") unless $i++ % $modulus;
3929 return if $CPAN::Signal;
3931 $CPAN::Frontend->myprint("DONE\n");
3933 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
3934 for my $o ($CPAN::META->all_objects($class)) {
3935 next if exists $exists{$o->{ID}};
3936 $CPAN::META->delete($class,$o->{ID});
3937 # CPAN->debug("deleting ID[$o->{ID}] in class[$class]")
3944 #-> sub CPAN::Index::rd_modlist ;
3946 my($cl,$index_target) = @_;
3947 return unless defined $index_target;
3948 $CPAN::Frontend->myprint("Going to read $index_target\n");
3949 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3953 while (my $bytes = $fh->READ(\$chunk,8192)) {
3956 my @eval2 = split /\012/, $slurp;
3959 my $shift = shift(@eval2);
3960 if ($shift =~ /^Date:\s+(.*)/){
3961 if ($DATE_OF_03 eq $1){
3962 $CPAN::Frontend->myprint("Unchanged.\n");
3967 last if $shift =~ /^\s*$/;
3969 push @eval2, q{CPAN::Modulelist->data;};
3971 my($comp) = Safe->new("CPAN::Safe1");
3972 my($eval2) = join("\n", @eval2);
3973 CPAN->debug(sprintf "length of eval2[%d]", length $eval2) if $CPAN::DEBUG;
3974 my $ret = $comp->reval($eval2);
3975 Carp::confess($@) if $@;
3976 return if $CPAN::Signal;
3978 my $until = keys %$ret;
3979 my $modulus = int($until/75) || 1;
3980 CPAN->debug(sprintf "until[%d]", $until) if $CPAN::DEBUG;
3982 my $obj = $CPAN::META->instance("CPAN::Module",$_);
3983 delete $ret->{$_}{modid}; # not needed here, maybe elsewhere
3984 $obj->set(%{$ret->{$_}});
3985 $CPAN::Frontend->myprint(".") unless $i++ % $modulus;
3986 return if $CPAN::Signal;
3988 $CPAN::Frontend->myprint("DONE\n");
3991 #-> sub CPAN::Index::write_metadata_cache ;
3992 sub write_metadata_cache {
3994 return unless $CPAN::Config->{'cache_metadata'};
3995 return unless $CPAN::META->has_usable("Storable");
3997 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
3998 CPAN::Distribution)) {
3999 $cache->{$k} = $CPAN::META->{readonly}{$k}; # unsafe meta access, ok
4001 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
4002 $cache->{last_time} = $LAST_TIME;
4003 $cache->{DATE_OF_02} = $DATE_OF_02;
4004 $cache->{PROTOCOL} = PROTOCOL;
4005 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
4006 eval { Storable::nstore($cache, $metadata_file) };
4007 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
4010 #-> sub CPAN::Index::read_metadata_cache ;
4011 sub read_metadata_cache {
4013 return unless $CPAN::Config->{'cache_metadata'};
4014 return unless $CPAN::META->has_usable("Storable");
4015 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
4016 return unless -r $metadata_file and -f $metadata_file;
4017 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
4019 eval { $cache = Storable::retrieve($metadata_file) };
4020 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
4021 if (!$cache || !UNIVERSAL::isa($cache, 'HASH')){
4025 if (exists $cache->{PROTOCOL}) {
4026 if (PROTOCOL > $cache->{PROTOCOL}) {
4027 $CPAN::Frontend->mywarn(sprintf("Ignoring Metadata cache written ".
4028 "with protocol v%s, requiring v%s\n",
4035 $CPAN::Frontend->mywarn("Ignoring Metadata cache written ".
4036 "with protocol v1.0\n");
4041 while(my($class,$v) = each %$cache) {
4042 next unless $class =~ /^CPAN::/;
4043 $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok
4044 while (my($id,$ro) = each %$v) {
4045 $CPAN::META->{readwrite}{$class}{$id} ||=
4046 $class->new(ID=>$id, RO=>$ro);
4051 unless ($clcnt) { # sanity check
4052 $CPAN::Frontend->myprint("Warning: Found no data in $metadata_file\n");
4055 if ($idcnt < 1000) {
4056 $CPAN::Frontend->myprint("Warning: Found only $idcnt objects ".
4057 "in $metadata_file\n");
4060 $CPAN::META->{PROTOCOL} ||=
4061 $cache->{PROTOCOL}; # reading does not up or downgrade, but it
4062 # does initialize to some protocol
4063 $LAST_TIME = $cache->{last_time};
4064 $DATE_OF_02 = $cache->{DATE_OF_02};
4065 $CPAN::Frontend->myprint(" Database was generated on $DATE_OF_02\n")
4066 if defined $DATE_OF_02; # An old cache may not contain DATE_OF_02
4070 package CPAN::InfoObj;
4075 exists $self->{RO} and return $self->{RO};
4080 my $ro = $self->ro or return "N/A"; # N/A for bundles found locally
4081 return $ro->{CPAN_USERID} || "N/A";
4084 sub id { shift->{ID}; }
4086 #-> sub CPAN::InfoObj::new ;
4088 my $this = bless {}, shift;
4093 # The set method may only be used by code that reads index data or
4094 # otherwise "objective" data from the outside world. All session
4095 # related material may do anything else with instance variables but
4096 # must not touch the hash under the RO attribute. The reason is that
4097 # the RO hash gets written to Metadata file and is thus persistent.
4099 #-> sub CPAN::InfoObj::safe_chdir ;
4101 my($self,$todir) = @_;
4102 # we die if we cannot chdir and we are debuggable
4103 Carp::confess("safe_chdir called without todir argument")
4104 unless defined $todir and length $todir;
4106 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
4110 unless (-x $todir) {
4111 unless (chmod 0755, $todir) {
4112 my $cwd = CPAN::anycwd();
4113 $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
4114 "permission to change the permission; cannot ".
4115 "chdir to '$todir'\n");
4116 $CPAN::Frontend->mysleep(5);
4117 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
4118 qq{to todir[$todir]: $!});
4122 $CPAN::Frontend->mydie("Directory '$todir' has gone. Cannot continue.\n");
4125 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
4128 my $cwd = CPAN::anycwd();
4129 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
4130 qq{to todir[$todir] (a chmod has been issued): $!});
4135 #-> sub CPAN::InfoObj::set ;
4137 my($self,%att) = @_;
4138 my $class = ref $self;
4140 # This must be ||=, not ||, because only if we write an empty
4141 # reference, only then the set method will write into the readonly
4142 # area. But for Distributions that spring into existence, maybe
4143 # because of a typo, we do not like it that they are written into
4144 # the readonly area and made permanent (at least for a while) and
4145 # that is why we do not "allow" other places to call ->set.
4146 unless ($self->id) {
4147 CPAN->debug("Bug? Empty ID, rejecting");
4150 my $ro = $self->{RO} =
4151 $CPAN::META->{readonly}{$class}{$self->id} ||= {};
4153 while (my($k,$v) = each %att) {
4158 #-> sub CPAN::InfoObj::as_glimpse ;
4162 my $class = ref($self);
4163 $class =~ s/^CPAN:://;
4164 my $id = $self->can("pretty_id") ? $self->pretty_id : $self->{ID};
4165 push @m, sprintf "%-15s %s\n", $class, $id;
4169 #-> sub CPAN::InfoObj::as_string ;
4173 my $class = ref($self);
4174 $class =~ s/^CPAN:://;
4175 push @m, $class, " id = $self->{ID}\n";
4177 unless ($ro = $self->ro) {
4178 $CPAN::Frontend->mydie("Unknown object $self->{ID}");
4180 for (sort keys %$ro) {
4181 # next if m/^(ID|RO)$/;
4183 if ($_ eq "CPAN_USERID") {
4185 $extra .= $self->fullname;
4186 my $email; # old perls!
4187 if ($email = $CPAN::META->instance("CPAN::Author",
4190 $extra .= " <$email>";
4192 $extra .= " <no email>";
4195 } elsif ($_ eq "FULLNAME") { # potential UTF-8 conversion
4196 push @m, sprintf " %-12s %s\n", $_, $self->fullname;
4199 next unless defined $ro->{$_};
4200 push @m, sprintf " %-12s %s%s\n", $_, $ro->{$_}, $extra;
4202 for (sort keys %$self) {
4203 next if m/^(ID|RO)$/;
4204 if (ref($self->{$_}) eq "ARRAY") {
4205 push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
4206 } elsif (ref($self->{$_}) eq "HASH") {
4210 join(" ",sort keys %{$self->{$_}}),
4213 push @m, sprintf " %-12s %s\n", $_, $self->{$_};
4219 #-> sub CPAN::InfoObj::fullname ;
4222 $CPAN::META->instance("CPAN::Author",$self->cpan_userid)->fullname;
4225 #-> sub CPAN::InfoObj::dump ;
4227 my($self, $what) = @_;
4228 unless ($CPAN::META->has_inst("Data::Dumper")) {
4229 $CPAN::Frontend->mydie("dump command requires Data::Dumper installed");
4231 local $Data::Dumper::Sortkeys;
4232 $Data::Dumper::Sortkeys = 1;
4233 my $out = Data::Dumper::Dumper($what ? eval $what : $self);
4234 if (length $out > 100000) {
4235 my $fh_pager = FileHandle->new;
4236 local($SIG{PIPE}) = "IGNORE";
4237 my $pager = $CPAN::Config->{'pager'} || "cat";
4238 $fh_pager->open("|$pager")
4239 or die "Could not open pager $pager\: $!";
4240 $fh_pager->print($out);
4243 $CPAN::Frontend->myprint($out);
4247 package CPAN::Author;
4250 #-> sub CPAN::Author::force
4256 #-> sub CPAN::Author::force
4259 delete $self->{force};
4262 #-> sub CPAN::Author::id
4265 my $id = $self->{ID};
4266 $CPAN::Frontend->mydie("Illegal author id[$id]") unless $id =~ /^[A-Z]/;
4270 #-> sub CPAN::Author::as_glimpse ;
4274 my $class = ref($self);
4275 $class =~ s/^CPAN:://;
4276 push @m, sprintf(qq{%-15s %s ("%s" <%s>)\n},
4284 #-> sub CPAN::Author::fullname ;
4286 shift->ro->{FULLNAME};
4290 #-> sub CPAN::Author::email ;
4291 sub email { shift->ro->{EMAIL}; }
4293 #-> sub CPAN::Author::ls ;
4296 my $glob = shift || "";
4297 my $silent = shift || 0;
4300 # adapted from CPAN::Distribution::verifyCHECKSUM ;
4301 my(@csf); # chksumfile
4302 @csf = $self->id =~ /(.)(.)(.*)/;
4303 $csf[1] = join "", @csf[0,1];
4304 $csf[2] = join "", @csf[1,2]; # ("A","AN","ANDK")
4306 @dl = $self->dir_listing([$csf[0],"CHECKSUMS"], 0, 1);
4307 unless (grep {$_->[2] eq $csf[1]} @dl) {
4308 $CPAN::Frontend->myprint("Directory $csf[1]/ does not exist\n") unless $silent ;
4311 @dl = $self->dir_listing([@csf[0,1],"CHECKSUMS"], 0, 1);
4312 unless (grep {$_->[2] eq $csf[2]} @dl) {
4313 $CPAN::Frontend->myprint("Directory $id/ does not exist\n") unless $silent;
4316 @dl = $self->dir_listing([@csf,"CHECKSUMS"], 1, 1);
4318 if ($CPAN::META->has_inst("Text::Glob")) {
4319 my $rglob = Text::Glob::glob_to_regex($glob);
4320 @dl = grep { $_->[2] =~ /$rglob/ } @dl;
4322 $CPAN::Frontend->mydie("Text::Glob not installed, cannot proceed");
4325 $CPAN::Frontend->myprint(join "", map {
4326 sprintf("%8d %10s %s/%s\n", $_->[0], $_->[1], $id, $_->[2])
4327 } sort { $a->[2] cmp $b->[2] } @dl);
4331 # returns an array of arrays, the latter contain (size,mtime,filename)
4332 #-> sub CPAN::Author::dir_listing ;
4335 my $chksumfile = shift;
4336 my $recursive = shift;
4337 my $may_ftp = shift;
4340 File::Spec->catfile($CPAN::Config->{keep_source_where},
4341 "authors", "id", @$chksumfile);
4345 # Purge and refetch old (pre-PGP) CHECKSUMS; they are a security
4346 # hazard. (Without GPG installed they are not that much better,
4348 $fh = FileHandle->new;
4349 if (open($fh, $lc_want)) {
4350 my $line = <$fh>; close $fh;
4351 unlink($lc_want) unless $line =~ /PGP/;
4355 # connect "force" argument with "index_expire".
4356 my $force = $self->{force};
4357 if (my @stat = stat $lc_want) {
4358 $force ||= $stat[9] + $CPAN::Config->{index_expire}*86400 <= time;
4362 $lc_file = CPAN::FTP->localize(
4363 "authors/id/@$chksumfile",
4368 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
4369 $chksumfile->[-1] .= ".gz";
4370 $lc_file = CPAN::FTP->localize("authors/id/@$chksumfile",
4373 $lc_file =~ s{\.gz(?!\n)\Z}{}; #};
4374 CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file);
4380 $lc_file = $lc_want;
4381 # we *could* second-guess and if the user has a file: URL,
4382 # then we could look there. But on the other hand, if they do
4383 # have a file: URL, wy did they choose to set
4384 # $CPAN::Config->{show_upload_date} to false?
4387 # adapted from CPAN::Distribution::CHECKSUM_check_file ;
4388 $fh = FileHandle->new;
4390 if (open $fh, $lc_file){
4393 $eval =~ s/\015?\012/\n/g;
4395 my($comp) = Safe->new();
4396 $cksum = $comp->reval($eval);
4398 rename $lc_file, "$lc_file.bad";
4399 Carp::confess($@) if $@;
4401 } elsif ($may_ftp) {
4402 Carp::carp "Could not open '$lc_file' for reading.";
4404 # Maybe should warn: "You may want to set show_upload_date to a true value"
4408 for $f (sort keys %$cksum) {
4409 if (exists $cksum->{$f}{isdir}) {
4411 my(@dir) = @$chksumfile;
4413 push @dir, $f, "CHECKSUMS";
4415 [$_->[0], $_->[1], "$f/$_->[2]"]
4416 } $self->dir_listing(\@dir,1,$may_ftp);
4418 push @result, [ 0, "-", $f ];
4422 ($cksum->{$f}{"size"}||0),
4423 $cksum->{$f}{"mtime"}||"---",
4431 package CPAN::Distribution;
4437 my $ro = $self->ro or return;
4441 # CPAN::Distribution::undelay
4444 delete $self->{later};
4447 # add the A/AN/ stuff
4448 # CPAN::Distribution::normalize
4451 $s = $self->id unless defined $s;
4455 $s !~ m|[A-Z]/[A-Z-]{2}/[A-Z-]{2,}/|
4457 return $s if $s =~ m:^N/A|^Contact Author: ;
4458 $s =~ s|^(.)(.)([^/]*/)(.+)$|$1/$1$2/$1$2$3$4| or
4459 $CPAN::Frontend->mywarn("Strange distribution name [$s]\n");
4460 CPAN->debug("s[$s]") if $CPAN::DEBUG;
4465 #-> sub CPAN::Distribution::author ;
4468 my($authorid) = $self->pretty_id =~ /^([\w\-]+)/;
4469 CPAN::Shell->expand("Author",$authorid);
4472 # tries to get the yaml from CPAN instead of the distro itself:
4473 # EXPERIMENTAL, UNDOCUMENTED AND UNTESTED, for Tels
4476 my $meta = $self->pretty_id;
4477 $meta =~ s/\.(tar.gz|tgz|zip|tar.bz2)/.meta/;
4478 my(@ls) = CPAN::Shell->globls($meta);
4479 my $norm = $self->normalize($meta);
4483 File::Spec->catfile(
4484 $CPAN::Config->{keep_source_where},
4489 $self->debug("Doing localize") if $CPAN::DEBUG;
4490 unless ($local_file =
4491 CPAN::FTP->localize("authors/id/$norm",
4493 $CPAN::Frontend->mydie("Giving up on downloading yaml file '$local_wanted'\n");
4495 if ($CPAN::META->has_inst("YAML")) {
4496 my $yaml = YAML::LoadFile($local_file);
4499 $CPAN::Frontend->mydie("Yaml not installed, cannot parse '$local_file'\n");
4503 #-> sub CPAN::Distribution::pretty_id
4507 return $id unless $id =~ m|^./../|;
4511 # mark as dirty/clean
4512 #-> sub CPAN::Distribution::color_cmd_tmps ;
4513 sub color_cmd_tmps {
4515 my($depth) = shift || 0;
4516 my($color) = shift || 0;
4517 my($ancestors) = shift || [];
4518 # a distribution needs to recurse into its prereq_pms
4520 return if exists $self->{incommandcolor}
4521 && $self->{incommandcolor}==$color;
4523 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
4525 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
4526 my $prereq_pm = $self->prereq_pm;
4527 if (defined $prereq_pm) {
4528 PREREQ: for my $pre (keys %{$prereq_pm->{requires}||{}},
4529 keys %{$prereq_pm->{build_requires}||{}}) {
4530 next PREREQ if $pre eq "perl";
4532 unless ($premo = CPAN::Shell->expand("Module",$pre)) {
4533 $CPAN::Frontend->mywarn("prerequisite module[$pre] not known\n");
4534 $CPAN::Frontend->mysleep(2);
4537 $premo->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
4541 delete $self->{sponsored_mods};
4542 delete $self->{badtestcnt};
4544 $self->{incommandcolor} = $color;
4547 #-> sub CPAN::Distribution::as_string ;
4550 $self->containsmods;
4552 $self->SUPER::as_string(@_);
4555 #-> sub CPAN::Distribution::containsmods ;
4558 return keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
4559 my $dist_id = $self->{ID};
4560 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
4561 my $mod_file = $mod->cpan_file or next;
4562 my $mod_id = $mod->{ID} or next;
4563 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
4565 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
4567 keys %{$self->{CONTAINSMODS}};
4570 #-> sub CPAN::Distribution::upload_date ;
4573 return $self->{UPLOAD_DATE} if exists $self->{UPLOAD_DATE};
4574 my(@local_wanted) = split(/\//,$self->id);
4575 my $filename = pop @local_wanted;
4576 push @local_wanted, "CHECKSUMS";
4577 my $author = CPAN::Shell->expand("Author",$self->cpan_userid);
4578 return unless $author;
4579 my @dl = $author->dir_listing(\@local_wanted,0,$CPAN::Config->{show_upload_date});
4581 my($dirent) = grep { $_->[2] eq $filename } @dl;
4582 # warn sprintf "dirent[%s]id[%s]", $dirent, $self->id;
4583 return unless $dirent->[1];
4584 return $self->{UPLOAD_DATE} = $dirent->[1];
4587 #-> sub CPAN::Distribution::uptodate ;
4591 foreach $c ($self->containsmods) {
4592 my $obj = CPAN::Shell->expandany($c);
4593 unless ($obj->uptodate){
4594 my $id = $self->pretty_id;
4595 $self->debug("$id not uptodate due to $c") if $CPAN::DEBUG;
4602 #-> sub CPAN::Distribution::called_for ;
4605 $self->{CALLED_FOR} = $id if defined $id;
4606 return $self->{CALLED_FOR};
4609 #-> sub CPAN::Distribution::get ;
4614 exists $self->{'build_dir'} and push @e,
4615 "Is already unwrapped into directory $self->{'build_dir'}";
4616 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4618 my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
4621 # Get the file on local disk
4626 File::Spec->catfile(
4627 $CPAN::Config->{keep_source_where},
4630 split(/\//,$self->id)
4633 $self->debug("Doing localize") if $CPAN::DEBUG;
4634 unless ($local_file =
4635 CPAN::FTP->localize("authors/id/$self->{ID}",
4638 if ($CPAN::Index::DATE_OF_02) {
4639 $note = "Note: Current database in memory was generated ".
4640 "on $CPAN::Index::DATE_OF_02\n";
4642 $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n$note");
4644 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
4645 $self->{localfile} = $local_file;
4646 return if $CPAN::Signal;
4651 if ($CPAN::META->has_inst("Digest::SHA")) {
4652 $self->debug("Digest::SHA is installed, verifying");
4653 $self->verifyCHECKSUM;
4655 $self->debug("Digest::SHA is NOT installed");
4657 return if $CPAN::Signal;
4660 # Create a clean room and go there
4662 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
4663 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
4664 $self->safe_chdir($builddir);
4665 $self->debug("Removing tmp") if $CPAN::DEBUG;
4666 File::Path::rmtree("tmp");
4667 unless (mkdir "tmp", 0755) {
4668 $CPAN::Frontend->unrecoverable_error(<<EOF);
4669 Couldn't mkdir '$builddir/tmp': $!
4671 Cannot continue: Please find the reason why I cannot make the
4674 and fix the problem, then retry.
4679 $self->safe_chdir($sub_wd);
4682 $self->safe_chdir("tmp");
4687 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
4688 my $ct = CPAN::Tarzip->new($local_file);
4689 if ($local_file =~ /(\.tar\.(bz2|gz|Z)|\.tgz)(?!\n)\Z/i){
4690 $self->{was_uncompressed}++ unless $ct->gtest();
4691 $self->untar_me($ct);
4692 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
4693 $self->unzip_me($ct);
4695 $self->{was_uncompressed}++ unless $ct->gtest();
4696 $self->debug("calling pm2dir for local_file[$local_file]")
4698 $local_file = $self->handle_singlefile($local_file);
4700 # $self->{archived} = "NO";
4701 # $self->safe_chdir($sub_wd);
4705 # we are still in the tmp directory!
4706 # Let's check if the package has its own directory.
4707 my $dh = DirHandle->new(File::Spec->curdir)
4708 or Carp::croak("Couldn't opendir .: $!");
4709 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
4711 my ($distdir,$packagedir);
4712 if (@readdir == 1 && -d $readdir[0]) {
4713 $distdir = $readdir[0];
4714 $packagedir = File::Spec->catdir($builddir,$distdir);
4715 $self->debug("packagedir[$packagedir]builddir[$builddir]distdir[$distdir]")
4717 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
4719 File::Path::rmtree($packagedir);
4720 unless (File::Copy::move($distdir,$packagedir)) {
4721 $CPAN::Frontend->unrecoverable_error(<<EOF);
4722 Couldn't move '$distdir' to '$packagedir': $!
4724 Cannot continue: Please find the reason why I cannot move
4725 $builddir/tmp/$distdir
4728 and fix the problem, then retry
4732 $self->debug(sprintf("moved distdir[%s] to packagedir[%s] -e[%s]-d[%s]",
4739 my $userid = $self->cpan_userid;
4741 CPAN->debug("no userid? self[$self]");
4744 my $pragmatic_dir = $userid . '000';
4745 $pragmatic_dir =~ s/\W_//g;
4746 $pragmatic_dir++ while -d "../$pragmatic_dir";
4747 $packagedir = File::Spec->catdir($builddir,$pragmatic_dir);
4748 $self->debug("packagedir[$packagedir]") if $CPAN::DEBUG;
4749 File::Path::mkpath($packagedir);
4751 for $f (@readdir) { # is already without "." and ".."
4752 my $to = File::Spec->catdir($packagedir,$f);
4753 File::Copy::move($f,$to) or Carp::confess("Couldn't move $f to $to: $!");
4757 $self->safe_chdir($sub_wd);
4761 $self->{'build_dir'} = $packagedir;
4762 $self->safe_chdir($builddir);
4763 File::Path::rmtree("tmp");
4765 $self->safe_chdir($packagedir);
4766 if ($CPAN::Config->{check_sigs}) {
4767 if ($CPAN::META->has_inst("Module::Signature")) {
4768 if (-f "SIGNATURE") {
4769 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
4770 my $rv = Module::Signature::verify();
4771 if ($rv != Module::Signature::SIGNATURE_OK() and
4772 $rv != Module::Signature::SIGNATURE_MISSING()) {
4773 $CPAN::Frontend->myprint(
4774 qq{\nSignature invalid for }.
4775 qq{distribution file. }.
4776 qq{Please investigate.\n\n}.
4778 $CPAN::META->instance(
4785 sprintf(qq{I'd recommend removing %s. Its signature
4786 is invalid. Maybe you have configured your 'urllist' with
4787 a bad URL. Please check this array with 'o conf urllist', and
4788 retry. For more information, try opening a subshell with
4796 $self->{signature_verify} = CPAN::Distrostatus->new("NO");
4797 $CPAN::Frontend->mywarn(Text::Wrap::wrap("","",$wrap));
4798 $CPAN::Frontend->mysleep(5) if $CPAN::Frontend->can("mysleep");
4800 $self->{signature_verify} = CPAN::Distrostatus->new("YES");
4801 $self->debug("Module::Signature has verified") if $CPAN::DEBUG;
4804 $CPAN::Frontend->mywarn(qq{Package came without SIGNATURE\n\n});
4807 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
4810 $self->safe_chdir($builddir);
4811 return if $CPAN::Signal;
4814 my($mpl) = File::Spec->catfile($packagedir,"Makefile.PL");
4815 my($mpl_exists) = -f $mpl;
4816 unless ($mpl_exists) {
4817 # NFS has been reported to have racing problems after the
4818 # renaming of a directory in some environments.
4820 $CPAN::Frontend->mysleep(1);
4821 my $mpldh = DirHandle->new($packagedir)
4822 or Carp::croak("Couldn't opendir $packagedir: $!");
4823 $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read;
4826 my $prefer_installer = "eumm"; # eumm|mb
4827 if (-f File::Spec->catfile($packagedir,"Build.PL")) {
4828 if ($mpl_exists) { # they *can* choose
4829 if ($CPAN::META->has_inst("Module::Build")) {
4830 $prefer_installer = $CPAN::Config->{prefer_installer};
4833 $prefer_installer = "mb";
4836 if (lc($prefer_installer) eq "mb") {
4837 $self->{modulebuild} = 1;
4838 } elsif (! $mpl_exists) {
4839 $self->debug(sprintf("makefilepl[%s]anycwd[%s]",
4843 my($configure) = File::Spec->catfile($packagedir,"Configure");
4844 if (-f $configure) {
4845 # do we have anything to do?
4846 $self->{'configure'} = $configure;
4847 } elsif (-f File::Spec->catfile($packagedir,"Makefile")) {
4848 $CPAN::Frontend->mywarn(qq{
4849 Package comes with a Makefile and without a Makefile.PL.
4850 We\'ll try to build it with that Makefile then.
4852 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
4853 $CPAN::Frontend->mysleep(2);
4855 my $cf = $self->called_for || "unknown";
4860 $cf =~ s|[/\\:]||g; # risk of filesystem damage
4861 $cf = "unknown" unless length($cf);
4862 $CPAN::Frontend->mywarn(qq{Package seems to come without Makefile.PL.
4863 (The test -f "$mpl" returned false.)
4864 Writing one on our own (setting NAME to $cf)\a\n});
4865 $self->{had_no_makefile_pl}++;
4866 $CPAN::Frontend->mysleep(3);
4868 # Writing our own Makefile.PL
4871 if ($self->{archived} eq "maybe_pl"){
4872 my $fh = FileHandle->new;
4873 my $script_file = File::Spec->catfile($packagedir,$local_file);
4874 $fh->open($script_file)
4875 or Carp::croak("Could not open $script_file: $!");
4877 # name parsen und prereq
4878 my($state) = "poddir";
4879 my($name, $prereq) = ("", "");
4881 if ($state eq "poddir" && /^=head\d\s+(\S+)/) {
4884 } elsif ($1 eq 'PREREQUISITES') {
4887 } elsif ($state =~ m{^(name|prereq)$}) {
4892 } elsif ($state eq "name") {
4897 } elsif ($state eq "prereq") {
4900 } elsif (/^=cut\b/) {
4907 s{.*<}{}; # strip X<...>
4911 $prereq = join " ", split /\s+/, $prereq;
4912 my($PREREQ_PM) = join("\n", map {
4913 s{.*<}{}; # strip X<...>
4915 if (/[\s\'\"]/) { # prose?
4917 s/[^\w:]$//; # period?
4918 " "x28 . "'$_' => 0,";
4920 } split /\s*,\s*/, $prereq);
4923 EXE_FILES => ['$name'],
4929 my $to_file = File::Spec->catfile($packagedir, $name);
4930 rename $script_file, $to_file
4931 or die "Can't rename $script_file to $to_file: $!";
4934 my $fh = FileHandle->new;
4936 or Carp::croak("Could not open >$mpl: $!");
4938 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
4939 # because there was no Makefile.PL supplied.
4940 # Autogenerated on: }.scalar localtime().qq{
4942 use ExtUtils::MakeMaker;
4944 NAME => q[$cf],$script
4954 # CPAN::Distribution::untar_me ;
4957 $self->{archived} = "tar";
4959 $self->{unwrapped} = "YES";
4961 $self->{unwrapped} = "NO";
4965 # CPAN::Distribution::unzip_me ;
4968 $self->{archived} = "zip";
4970 $self->{unwrapped} = "YES";
4972 $self->{unwrapped} = "NO";
4977 sub handle_singlefile {
4978 my($self,$local_file) = @_;
4980 if ( $local_file =~ /\.pm(\.(gz|Z))?(?!\n)\Z/ ){
4981 $self->{archived} = "pm";
4983 $self->{archived} = "maybe_pl";
4986 my $to = File::Basename::basename($local_file);
4987 if ($to =~ s/\.(gz|Z)(?!\n)\Z//) {
4988 if (CPAN::Tarzip->new($local_file)->gunzip($to)) {
4989 $self->{unwrapped} = "YES";
4991 $self->{unwrapped} = "NO";
4994 File::Copy::cp($local_file,".");
4995 $self->{unwrapped} = "YES";
5000 #-> sub CPAN::Distribution::new ;
5002 my($class,%att) = @_;
5004 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
5006 my $this = { %att };
5007 return bless $this, $class;
5010 #-> sub CPAN::Distribution::look ;
5014 if ($^O eq 'MacOS') {
5015 $self->Mac::BuildTools::look;
5019 if ( $CPAN::Config->{'shell'} ) {
5020 $CPAN::Frontend->myprint(qq{
5021 Trying to open a subshell in the build directory...
5024 $CPAN::Frontend->myprint(qq{
5025 Your configuration does not define a value for subshells.
5026 Please define it with "o conf shell <your shell>"
5030 my $dist = $self->id;
5032 unless ($dir = $self->dir) {
5035 unless ($dir ||= $self->dir) {
5036 $CPAN::Frontend->mywarn(qq{
5037 Could not determine which directory to use for looking at $dist.
5041 my $pwd = CPAN::anycwd();
5042 $self->safe_chdir($dir);
5043 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
5045 local $ENV{CPAN_SHELL_LEVEL} = $ENV{CPAN_SHELL_LEVEL}||0;
5046 $ENV{CPAN_SHELL_LEVEL} += 1;
5047 my $shell = CPAN::HandleConfig->safe_quote($CPAN::Config->{'shell'});
5048 unless (system($shell) == 0) {
5050 $CPAN::Frontend->mywarn("Subprocess shell exit code $code\n");
5053 $self->safe_chdir($pwd);
5056 # CPAN::Distribution::cvs_import ;
5060 my $dir = $self->dir;
5062 my $package = $self->called_for;
5063 my $module = $CPAN::META->instance('CPAN::Module', $package);
5064 my $version = $module->cpan_version;
5066 my $userid = $self->cpan_userid;
5068 my $cvs_dir = (split /\//, $dir)[-1];
5069 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
5071 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
5073 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
5074 if ($cvs_site_perl) {
5075 $cvs_dir = "$cvs_site_perl/$cvs_dir";
5077 my $cvs_log = qq{"imported $package $version sources"};
5078 $version =~ s/\./_/g;
5079 # XXX cvs: undocumented and unclear how it was meant to work
5080 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
5081 "$cvs_dir", $userid, "v$version");
5083 my $pwd = CPAN::anycwd();
5084 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
5086 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
5088 $CPAN::Frontend->myprint(qq{@cmd\n});
5089 system(@cmd) == 0 or
5091 $CPAN::Frontend->mydie("cvs import failed");
5092 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
5095 #-> sub CPAN::Distribution::readme ;
5098 my($dist) = $self->id;
5099 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
5100 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
5103 File::Spec->catfile(
5104 $CPAN::Config->{keep_source_where},
5107 split(/\//,"$sans.readme"),
5109 $self->debug("Doing localize") if $CPAN::DEBUG;
5110 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
5112 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
5114 if ($^O eq 'MacOS') {
5115 Mac::BuildTools::launch_file($local_file);
5119 my $fh_pager = FileHandle->new;
5120 local($SIG{PIPE}) = "IGNORE";
5121 my $pager = $CPAN::Config->{'pager'} || "cat";
5122 $fh_pager->open("|$pager")
5123 or die "Could not open pager $pager\: $!";
5124 my $fh_readme = FileHandle->new;
5125 $fh_readme->open($local_file)
5126 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
5127 $CPAN::Frontend->myprint(qq{
5132 $fh_pager->print(<$fh_readme>);
5136 #-> sub CPAN::Distribution::verifyCHECKSUM ;
5137 sub verifyCHECKSUM {
5141 $self->{CHECKSUM_STATUS} ||= "";
5142 $self->{CHECKSUM_STATUS} eq "OK" and push @e, "Checksum was ok";
5143 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5145 my($lc_want,$lc_file,@local,$basename);
5146 @local = split(/\//,$self->id);
5148 push @local, "CHECKSUMS";
5150 File::Spec->catfile($CPAN::Config->{keep_source_where},
5151 "authors", "id", @local);
5153 if (my $size = -s $lc_want) {
5154 $self->debug("lc_want[$lc_want]size[$size]") if $CPAN::DEBUG;
5155 if ($self->CHECKSUM_check_file($lc_want,1)) {
5156 return $self->{CHECKSUM_STATUS} = "OK";
5159 $lc_file = CPAN::FTP->localize("authors/id/@local",
5162 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
5163 $local[-1] .= ".gz";
5164 $lc_file = CPAN::FTP->localize("authors/id/@local",
5167 $lc_file =~ s/\.gz(?!\n)\Z//;
5168 CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file);
5173 if ($self->CHECKSUM_check_file($lc_file)) {
5174 return $self->{CHECKSUM_STATUS} = "OK";
5178 #-> sub CPAN::Distribution::SIG_check_file ;
5179 sub SIG_check_file {
5180 my($self,$chk_file) = @_;
5181 my $rv = eval { Module::Signature::_verify($chk_file) };
5183 if ($rv == Module::Signature::SIGNATURE_OK()) {
5184 $CPAN::Frontend->myprint("Signature for $chk_file ok\n");
5185 return $self->{SIG_STATUS} = "OK";
5187 $CPAN::Frontend->myprint(qq{\nSignature invalid for }.
5188 qq{distribution file. }.
5189 qq{Please investigate.\n\n}.
5191 $CPAN::META->instance(
5196 my $wrap = qq{I\'d recommend removing $chk_file. Its signature
5197 is invalid. Maybe you have configured your 'urllist' with
5198 a bad URL. Please check this array with 'o conf urllist', and
5201 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
5205 #-> sub CPAN::Distribution::CHECKSUM_check_file ;
5207 # sloppy is 1 when we have an old checksums file that maybe is good
5210 sub CHECKSUM_check_file {
5211 my($self,$chk_file,$sloppy) = @_;
5212 my($cksum,$file,$basename);
5215 $self->debug("chk_file[$chk_file]sloppy[$sloppy]") if $CPAN::DEBUG;
5216 if ($CPAN::Config->{check_sigs}) {
5217 if ($CPAN::META->has_inst("Module::Signature") and Module::Signature->VERSION >= 0.26) {
5218 $self->debug("Module::Signature is installed, verifying");
5219 $self->SIG_check_file($chk_file);
5221 $self->debug("Module::Signature is NOT installed");
5225 $file = $self->{localfile};
5226 $basename = File::Basename::basename($file);
5227 my $fh = FileHandle->new;
5228 if (open $fh, $chk_file){
5231 $eval =~ s/\015?\012/\n/g;
5233 my($comp) = Safe->new();
5234 $cksum = $comp->reval($eval);
5236 rename $chk_file, "$chk_file.bad";
5237 Carp::confess($@) if $@;
5240 Carp::carp "Could not open $chk_file for reading";
5243 if (! ref $cksum or ref $cksum ne "HASH") {
5244 $CPAN::Frontend->mywarn(qq{
5245 Warning: checksum file '$chk_file' broken.
5247 When trying to read that file I expected to get a hash reference
5248 for further processing, but got garbage instead.
5250 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed nonetheless?", "no");
5251 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
5252 $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS file broken";
5254 } elsif (exists $cksum->{$basename}{sha256}) {
5255 $self->debug("Found checksum for $basename:" .
5256 "$cksum->{$basename}{sha256}\n") if $CPAN::DEBUG;
5260 my $eq = $self->eq_CHECKSUM($fh,$cksum->{$basename}{sha256});
5262 $fh = CPAN::Tarzip->TIEHANDLE($file);
5265 my $dg = Digest::SHA->new(256);
5268 while ($fh->READ($ref, 4096) > 0){
5271 my $hexdigest = $dg->hexdigest;
5272 $eq += $hexdigest eq $cksum->{$basename}{'sha256-ungz'};
5276 $CPAN::Frontend->myprint("Checksum for $file ok\n");
5277 return $self->{CHECKSUM_STATUS} = "OK";
5279 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
5280 qq{distribution file. }.
5281 qq{Please investigate.\n\n}.
5283 $CPAN::META->instance(
5288 my $wrap = qq{I\'d recommend removing $file. Its
5289 checksum is incorrect. Maybe you have configured your 'urllist' with
5290 a bad URL. Please check this array with 'o conf urllist', and
5293 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
5295 # former versions just returned here but this seems a
5296 # serious threat that deserves a die
5298 # $CPAN::Frontend->myprint("\n\n");
5302 # close $fh if fileno($fh);
5305 unless ($self->{CHECKSUM_STATUS}) {
5306 $CPAN::Frontend->mywarn(qq{
5307 Warning: No checksum for $basename in $chk_file.
5309 The cause for this may be that the file is very new and the checksum
5310 has not yet been calculated, but it may also be that something is
5311 going awry right now.
5313 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed?", "yes");
5314 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
5316 $self->{CHECKSUM_STATUS} = "NIL -- distro not in CHECKSUMS file";
5321 #-> sub CPAN::Distribution::eq_CHECKSUM ;
5323 my($self,$fh,$expect) = @_;
5324 if ($CPAN::META->has_inst("Digest::SHA")) {
5325 my $dg = Digest::SHA->new(256);
5327 while (read($fh, $data, 4096)){
5330 my $hexdigest = $dg->hexdigest;
5331 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
5332 return $hexdigest eq $expect;
5337 #-> sub CPAN::Distribution::force ;
5339 # Both CPAN::Modules and CPAN::Distributions know if "force" is in
5340 # effect by autoinspection, not by inspecting a global variable. One
5341 # of the reason why this was chosen to work that way was the treatment
5342 # of dependencies. They should not automatically inherit the force
5343 # status. But this has the downside that ^C and die() will return to
5344 # the prompt but will not be able to reset the force_update
5345 # attributes. We try to correct for it currently in the read_metadata
5346 # routine, and immediately before we check for a Signal. I hope this
5347 # works out in one of v1.57_53ff
5349 # "Force get forgets previous error conditions"
5351 #-> sub CPAN::Distribution::force ;
5353 my($self, $method) = @_;
5355 CHECKSUM_STATUS archived build_dir localfile make install unwrapped
5356 writemakefile modulebuild make_test signature_verify
5358 delete $self->{$att};
5360 if ($method && $method =~ /make|test|install/) {
5361 $self->{"force_update"}++; # name should probably have been force_install
5366 my($self, $method) = @_;
5367 # warn "XDEBUG: set notest for $self $method";
5368 $self->{"notest"}++; # name should probably have been force_install
5373 # warn "XDEBUG: deleting notest";
5374 delete $self->{'notest'};
5377 #-> sub CPAN::Distribution::unforce ;
5380 delete $self->{'force_update'};
5383 #-> sub CPAN::Distribution::isa_perl ;
5386 my $file = File::Basename::basename($self->id);
5387 if ($file =~ m{ ^ perl
5400 } elsif ($self->cpan_comment
5402 $self->cpan_comment =~ /isa_perl\(.+?\)/){
5408 #-> sub CPAN::Distribution::perl ;
5413 carp __PACKAGE__ . "::perl was called without parameters.";
5415 return CPAN::HandleConfig->safe_quote($CPAN::Perl);
5419 #-> sub CPAN::Distribution::make ;
5422 my $make = $self->{modulebuild} ? "Build" : "make";
5423 # Emergency brake if they said install Pippi and get newest perl
5424 if ($self->isa_perl) {
5426 $self->called_for ne $self->id &&
5427 ! $self->{force_update}
5429 # if we die here, we break bundles
5432 qq{The most recent version "%s" of the module "%s"
5433 is part of the perl-%s distribution. To install that, you need to run
5434 force install %s --or--
5437 $CPAN::META->instance(
5446 $self->{make} = CPAN::Distrostatus->new("NO isa perl");
5447 $CPAN::Frontend->mysleep(1);
5451 $CPAN::Frontend->myprint(sprintf "Running %s for %s\n", $make, $self->id);
5454 delete $self->{force_update};
5459 !$self->{archived} || $self->{archived} eq "NO" and push @e,
5460 "Is neither a tar nor a zip archive.";
5462 !$self->{unwrapped} || $self->{unwrapped} eq "NO" and push @e,
5463 "Had problems unarchiving. Please build manually";
5465 unless ($self->{force_update}) {
5466 exists $self->{signature_verify} and (
5467 $self->{signature_verify}->can("failed") ?
5468 $self->{signature_verify}->failed :
5469 $self->{signature_verify} =~ /^NO/
5471 and push @e, "Did not pass the signature test.";
5474 if (exists $self->{writemakefile} &&
5476 $self->{writemakefile}->can("failed") ?
5477 $self->{writemakefile}->failed :
5478 $self->{writemakefile} =~ /^NO/
5480 # XXX maybe a retry would be in order?
5481 my $err = $self->{writemakefile}->can("text") ?
5482 $self->{writemakefile}->text :
5483 $self->{writemakefile};
5485 $err ||= "Had some problem writing Makefile";
5486 $err .= ", won't make";
5490 defined $self->{make} and push @e,
5491 "Has already been processed within this session";
5493 if (exists $self->{later} and length($self->{later})) {
5494 if ($self->unsat_prereq) {
5495 push @e, $self->{later};
5496 # RT ticket 18438 raises doubts if the deletion of {later} is valid.
5497 # YAML-0.53 triggered the later hodge-podge here, but my margin notes
5498 # are not sufficient to be sure if we really must/may do the delete
5499 # here. SO I accept the suggested patch for now. If we trigger a bug
5500 # again, I must go into deep contemplation about the {later} flag.
5503 # delete $self->{later};
5507 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5510 delete $self->{force_update};
5513 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
5514 my $builddir = $self->dir or
5515 $CPAN::Frontend->mydie("PANIC: Cannot determine build directory\n");
5516 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
5517 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
5519 if ($^O eq 'MacOS') {
5520 Mac::BuildTools::make($self);
5525 if ($self->{'configure'}) {
5526 $system = $self->{'configure'};
5527 } elsif ($self->{modulebuild}) {
5528 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
5529 $system = "$perl Build.PL $CPAN::Config->{mbuildpl_arg}";
5531 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
5533 # This needs a handler that can be turned on or off:
5534 # $switch = "-MExtUtils::MakeMaker ".
5535 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
5537 $system = sprintf("%s%s Makefile.PL%s",
5539 $switch ? " $switch" : "",
5540 $CPAN::Config->{makepl_arg} ? " $CPAN::Config->{makepl_arg}" : "",
5543 unless (exists $self->{writemakefile}) {
5544 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
5548 if ($CPAN::Config->{inactivity_timeout}) {
5550 if ($Config::Config{d_alarm}
5552 $Config::Config{d_alarm} eq "define"
5556 $CPAN::Frontend->mywarn("Warning: you have configured the config ".
5557 "variable 'inactivity_timeout' to ".
5558 "'$CPAN::Config->{inactivity_timeout}'. But ".
5559 "on this machine the system call 'alarm' ".
5560 "isn't available. This means that we cannot ".
5561 "provide the feature of intercepting long ".
5562 "waiting code and will turn this feature off.\n"
5564 $CPAN::Config->{inactivity_timeout} = 0;
5567 if ($go_via_alarm) {
5569 alarm $CPAN::Config->{inactivity_timeout};
5570 local $SIG{CHLD}; # = sub { wait };
5571 if (defined($pid = fork)) {
5576 # note, this exec isn't necessary if
5577 # inactivity_timeout is 0. On the Mac I'd
5578 # suggest, we set it always to 0.
5582 $CPAN::Frontend->myprint("Cannot fork: $!");
5591 $CPAN::Frontend->myprint($err);
5592 $self->{writemakefile} = CPAN::Distrostatus->new("NO $err");
5597 $ret = system($system);
5599 $self->{writemakefile} = CPAN::Distrostatus
5600 ->new("NO '$system' returned status $ret");
5601 $CPAN::Frontend->mywarn("Warning: No success on command[$system]\n");
5605 if (-f "Makefile" || -f "Build") {
5606 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
5607 delete $self->{make_clean}; # if cleaned before, enable next
5609 $self->{writemakefile} = CPAN::Distrostatus
5610 ->new(qq{NO -- Unknown reason.});
5614 delete $self->{force_update};
5617 if (my @prereq = $self->unsat_prereq){
5618 if ($prereq[0][0] eq "perl") {
5619 my $need = "requires perl '$prereq[0][1]'";
5620 my $id = $self->pretty_id;
5621 $CPAN::Frontend->mywarn("$id $need; you have only $]; giving up\n");
5622 $self->{make} = CPAN::Distrostatus->new("NO $need");
5625 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
5628 if ($self->{modulebuild}) {
5629 unless (-f "Build") {
5631 $CPAN::Frontend->mywarn("Alert: no Build file available for 'make $self->{id}'".
5632 " in cwd[$cwd]. Danger, Will Robinson!");
5633 $CPAN::Frontend->mysleep(5);
5635 $system = sprintf "%s %s", $self->_build_command(), $CPAN::Config->{mbuild_arg};
5637 $system = join " ", $self->_make_command(), $CPAN::Config->{make_arg};
5639 if (system($system) == 0) {
5640 $CPAN::Frontend->myprint(" $system -- OK\n");
5641 $self->{make} = CPAN::Distrostatus->new("YES");
5643 $self->{writemakefile} ||= CPAN::Distrostatus->new("YES");
5644 $self->{make} = CPAN::Distrostatus->new("NO");
5645 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
5655 $CPAN::Config->{make} || $Config::Config{make} || 'make'
5658 # Old style call, without object. Deprecated
5659 Carp::confess("CPAN::_make_command() used as function. Don't Do That.");
5661 safe_quote(undef, $CPAN::Config->{make} || $Config::Config{make} || 'make');
5665 #-> sub CPAN::Distribution::follow_prereqs ;
5666 sub follow_prereqs {
5668 my(@prereq_tuples) = grep {$_->[0] ne "perl"} @_;
5669 return unless @prereq_tuples;
5670 my @prereq = map { $_->[0] } @prereq_tuples;
5673 b => "build_requires",
5678 myprint("---- Unsatisfied dependencies detected during\n".
5680 join("", map {" $_->[0] \[$map{$_->[1]}]\n"} @prereq_tuples),
5683 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
5685 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
5686 my $answer = CPAN::Shell::colorable_makemaker_prompt(
5687 "Shall I follow them and prepend them to the queue
5688 of modules we are processing right now?", "yes");
5689 $follow = $answer =~ /^\s*y/i;
5693 myprint(" Ignoring dependencies on modules @prereq\n");
5696 # color them as dirty
5697 for my $p (@prereq) {
5698 # warn "calling color_cmd_tmps(0,1)";
5699 CPAN::Shell->expandany($p)->color_cmd_tmps(0,1);
5701 # queue them and re-queue yourself
5702 CPAN::Queue->jumpqueue([$id,$self->{reqtype}],
5703 reverse @prereq_tuples);
5704 $self->{later} = "Delayed until after prerequisites";
5705 return 1; # signal success to the queuerunner
5709 #-> sub CPAN::Distribution::unsat_prereq ;
5710 # return ([Foo=>1],[Bar=>1.2]) for normal modules
5711 # return ([perl=>5.008]) if we need a newer perl than we are running under
5714 my $prereq_pm = $self->prereq_pm or return;
5716 my %merged = (%{$prereq_pm->{requires}||{}},%{$prereq_pm->{build_requires}||{}});
5717 NEED: while (my($need_module, $need_version) = each %merged) {
5718 my($have_version,$inst_file);
5719 if ($need_module eq "perl") {
5723 my $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
5724 next if $nmo->uptodate;
5725 $inst_file = $nmo->inst_file;
5727 # if they have not specified a version, we accept any installed one
5728 if (not defined $need_version or
5729 $need_version eq "0" or
5730 $need_version eq "undef") {
5731 next if defined $inst_file;
5734 $have_version = $nmo->inst_version;
5737 # We only want to install prereqs if either they're not installed
5738 # or if the installed version is too old. We cannot omit this
5739 # check, because if 'force' is in effect, nobody else will check.
5740 if (defined $inst_file) {
5741 my(@all_requirements) = split /\s*,\s*/, $need_version;
5744 RQ: for my $rq (@all_requirements) {
5745 if ($rq =~ s|>=\s*||) {
5746 } elsif ($rq =~ s|>\s*||) {
5748 if (CPAN::Version->vgt($have_version,$rq)){
5752 } elsif ($rq =~ s|!=\s*||) {
5754 if (CPAN::Version->vcmp($have_version,$rq)){
5760 } elsif ($rq =~ m|<=?\s*|) {
5762 $CPAN::Frontend->mywarn("Downgrading not supported (rq[$rq])");
5766 if (! CPAN::Version->vgt($rq, $have_version)){
5769 CPAN->debug(sprintf("need_module[%s]inst_file[%s]".
5770 "inst_version[%s]rq[%s]ok[%d]",
5774 CPAN::Version->readable($rq),
5778 next NEED if $ok == @all_requirements;
5781 if ($need_module eq "perl") {
5782 return ["perl", $need_version];
5784 if ($self->{sponsored_mods}{$need_module}++){
5785 # We have already sponsored it and for some reason it's still
5786 # not available. So we do nothing. Or what should we do?
5787 # if we push it again, we have a potential infinite loop
5790 my $needed_as = exists $prereq_pm->{requires}{$need_module} ? "r" : "b";
5791 push @need, [$need_module,$needed_as];
5796 #-> sub CPAN::Distribution::read_yaml ;
5799 return $self->{yaml_content} if exists $self->{yaml_content};
5800 my $build_dir = $self->{build_dir};
5801 my $yaml = File::Spec->catfile($build_dir,"META.yml");
5802 $self->debug("yaml[$yaml]") if $CPAN::DEBUG;
5803 return unless -f $yaml;
5804 if ($CPAN::META->has_inst("YAML")) {
5805 eval { $self->{yaml_content} = YAML::LoadFile($yaml); };
5807 $CPAN::Frontend->mywarn("Error while parsing META.yml: $@");
5810 if (not exists $self->{yaml_content}{dynamic_config}
5811 or $self->{yaml_content}{dynamic_config}
5813 $self->{yaml_content} = undef;
5816 $self->debug(sprintf "yaml_content[%s]", $self->{yaml_content} || "UNDEF")
5818 return $self->{yaml_content};
5821 #-> sub CPAN::Distribution::prereq_pm ;
5824 return $self->{prereq_pm} if
5825 exists $self->{prereq_pm_detected} && $self->{prereq_pm_detected};
5826 return unless $self->{writemakefile} # no need to have succeeded
5827 # but we must have run it
5828 || $self->{modulebuild};
5830 if (my $yaml = $self->read_yaml) { # often dynamic_config prevents a result here
5831 $req = $yaml->{requires} || {};
5832 $breq = $yaml->{build_requires} || {};
5833 undef $req unless ref $req eq "HASH" && %$req;
5835 if ($yaml->{generated_by} =~ /ExtUtils::MakeMaker version ([\d\._]+)/) {
5836 my $eummv = do { local $^W = 0; $1+0; };
5837 if ($eummv < 6.2501) {
5838 # thanks to Slaven for digging that out: MM before
5839 # that could be wrong because it could reflect a
5846 while (my($k,$v) = each %{$req||{}}) {
5849 } elsif ($k =~ /[A-Za-z]/ &&
5851 $CPAN::META->exists("Module",$v)
5853 $CPAN::Frontend->mywarn("Suspicious key-value pair in META.yml's ".
5854 "requires hash: $k => $v; I'll take both ".
5855 "key and value as a module name\n");
5856 $CPAN::Frontend->mysleep(1);
5862 $req = $areq if $do_replace;
5865 unless ($req || $breq) {
5866 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
5867 my $makefile = File::Spec->catfile($build_dir,"Makefile");
5871 $fh = FileHandle->new("<$makefile\0")) {
5874 last if /MakeMaker post_initialize section/;
5876 \s+PREREQ_PM\s+=>\s+(.+)
5879 # warn "Found prereq expr[$p]";
5881 # Regexp modified by A.Speer to remember actual version of file
5882 # PREREQ_PM hash key wants, then add to
5883 while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
5884 # In case a prereq is mentioned twice, complain.
5885 if ( defined $req->{$1} ) {
5886 warn "Warning: PREREQ_PM mentions $1 more than once, ".
5887 "last mention wins";
5893 } elsif (-f "Build") {
5894 if ($CPAN::META->has_inst("Module::Build")) {
5896 $req = Module::Build->current->requires();
5897 $breq = Module::Build->current->build_requires();
5900 # HTML::Mason prompted for this with bleadperl@28900 or so
5903 sprintf("Warning: while trying to determine ".
5904 "prerequisites for %s with the help of ".
5905 "Module::Build the following error ".
5906 "occurred: '%s'\n\nCannot care for prerequisites\n",
5910 $self->{prereq_pm_detected}++;
5911 return $self->{prereq_pm} = {requires=>{},build_requires=>{}};
5917 && ! -f "Makefile.PL"
5918 && ! exists $req->{"Module::Build"}
5919 && ! $CPAN::META->has_inst("Module::Build")) {
5920 $CPAN::Frontend->mywarn(" Warning: CPAN.pm discovered Module::Build as ".
5921 "undeclared prerequisite.\n".
5922 " Adding it now as such.\n"
5924 $CPAN::Frontend->mysleep(5);
5925 $req->{"Module::Build"} = 0;
5926 delete $self->{writemakefile};
5928 $self->{prereq_pm_detected}++;
5929 return $self->{prereq_pm} = { requires => $req, build_requires => $breq };
5932 #-> sub CPAN::Distribution::test ;
5937 delete $self->{force_update};
5940 # warn "XDEBUG: checking for notest: $self->{notest} $self";
5941 if ($self->{notest}) {
5942 $CPAN::Frontend->myprint("Skipping test because of notest pragma\n");
5946 my $make = $self->{modulebuild} ? "Build" : "make";
5947 $CPAN::Frontend->myprint("Running $make test\n");
5948 if (my @prereq = $self->unsat_prereq){
5949 unless ($prereq[0][0] eq "perl") {
5950 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
5955 unless (exists $self->{make} or exists $self->{later}) {
5957 "Make had some problems, won't test";
5960 exists $self->{make} and
5962 $self->{make}->can("failed") ?
5963 $self->{make}->failed :
5964 $self->{make} =~ /^NO/
5965 ) and push @e, "Can't test without successful make";
5967 $self->{badtestcnt} ||= 0;
5968 $self->{badtestcnt} > 0 and
5969 push @e, "Won't repeat unsuccessful test during this command";
5971 exists $self->{later} and length($self->{later}) and
5972 push @e, $self->{later};
5974 if (exists $self->{build_dir}) {
5975 if ($CPAN::META->{is_tested}{$self->{build_dir}}
5977 exists $self->{make_test}
5980 $self->{make_test}->can("failed") ?
5981 $self->{make_test}->failed :
5982 $self->{make_test} =~ /^NO/
5985 push @e, "Already tested successfully";
5988 push @e, "Has no own directory";
5991 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5993 chdir $self->{'build_dir'} or
5994 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
5995 $self->debug("Changed directory to $self->{'build_dir'}")
5998 if ($^O eq 'MacOS') {
5999 Mac::BuildTools::make_test($self);
6003 if ($self->{modulebuild}) {
6004 my $v = CPAN::Shell->expand("Module","Test::Harness")->inst_version;
6005 if (CPAN::Version->vlt($v,2.62)) {
6006 $CPAN::Frontend->mywarn(qq{The version of your Test::Harness is only
6007 '$v', you need at least '2.62'. Please upgrade your Test::Harness.\n});
6008 $self->{make_test} = CPAN::Distrostatus->new("NO Test::Harness too old");
6013 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
6015 : ($ENV{PERLLIB} || "");
6017 $CPAN::META->set_perl5lib;
6018 local $ENV{MAKEFLAGS}; # protect us from outer make calls
6021 if ($self->{modulebuild}) {
6022 $system = sprintf "%s test", $self->_build_command();
6024 $system = join " ", $self->_make_command(), "test";
6027 if ( $CPAN::Config->{test_report} &&
6028 $CPAN::META->has_inst("CPAN::Reporter") ) {
6029 $tests_ok = CPAN::Reporter::test($self, $system);
6031 $tests_ok = system($system) == 0;
6036 for my $m (keys %{$self->{sponsored_mods}}) {
6037 my $m_obj = CPAN::Shell->expand("Module",$m);
6038 if (!$m_obj->distribution->{make_test}
6040 $m_obj->distribution->{make_test}->failed){
6047 my $which = join ",", @prereq;
6048 my $verb = $cnt == 1 ? "one dependency not OK ($which)" :
6049 "$cnt dependencies missing ($which)";
6050 $CPAN::Frontend->mywarn("Tests succeeded but $verb\n");
6051 $self->{make_test} = CPAN::Distrostatus->new("NO -- $verb");
6056 $CPAN::Frontend->myprint(" $system -- OK\n");
6057 $CPAN::META->is_tested($self->{'build_dir'});
6058 $self->{make_test} = CPAN::Distrostatus->new("YES");
6060 $self->{make_test} = CPAN::Distrostatus->new("NO");
6061 $self->{badtestcnt}++;
6062 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
6066 #-> sub CPAN::Distribution::clean ;
6069 my $make = $self->{modulebuild} ? "Build" : "make";
6070 $CPAN::Frontend->myprint("Running $make clean\n");
6071 unless (exists $self->{archived}) {
6072 $CPAN::Frontend->mywarn("Distribution seems to have never been unzipped".
6073 "/untarred, nothing done\n");
6076 unless (exists $self->{build_dir}) {
6077 $CPAN::Frontend->mywarn("Distribution has no own directory, nothing to do.\n");
6082 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
6083 push @e, "make clean already called once";
6084 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
6086 chdir $self->{'build_dir'} or
6087 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
6088 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
6090 if ($^O eq 'MacOS') {
6091 Mac::BuildTools::make_clean($self);
6096 if ($self->{modulebuild}) {
6097 unless (-f "Build") {
6099 $CPAN::Frontend->mywarn("Alert: no Build file available for 'clean $self->{id}".
6100 " in cwd[$cwd]. Danger, Will Robinson!");
6101 $CPAN::Frontend->mysleep(5);
6103 $system = sprintf "%s clean", $self->_build_command();
6105 $system = join " ", $self->_make_command(), "clean";
6107 if (system($system) == 0) {
6108 $CPAN::Frontend->myprint(" $system -- OK\n");
6112 # Jost Krieger pointed out that this "force" was wrong because
6113 # it has the effect that the next "install" on this distribution
6114 # will untar everything again. Instead we should bring the
6115 # object's state back to where it is after untarring.
6126 $self->{make_clean} = CPAN::Distrostatus->new("YES");
6129 # Hmmm, what to do if make clean failed?
6131 $self->{make_clean} = CPAN::Distrostatus->new("NO");
6132 $CPAN::Frontend->mywarn(qq{ $system -- NOT OK\n});
6134 # 2006-02-27: seems silly to me to force a make now
6135 # $self->force("make"); # so that this directory won't be used again
6140 #-> sub CPAN::Distribution::install ;
6145 delete $self->{force_update};
6148 my $make = $self->{modulebuild} ? "Build" : "make";
6149 $CPAN::Frontend->myprint("Running $make install\n");
6152 unless (exists $self->{make} or exists $self->{later}) {
6154 "Make had some problems, won't install";
6157 exists $self->{make} and
6159 $self->{make}->can("failed") ?
6160 $self->{make}->failed :
6161 $self->{make} =~ /^NO/
6163 push @e, "Make had returned bad status, install seems impossible";
6165 if (exists $self->{build_dir}) {
6167 push @e, "Has no own directory";
6170 if (exists $self->{make_test} and
6172 $self->{make_test}->can("failed") ?
6173 $self->{make_test}->failed :
6174 $self->{make_test} =~ /^NO/
6176 if ($self->{force_update}) {
6177 $self->{make_test}->text("FAILED but failure ignored because ".
6178 "'force' in effect");
6180 push @e, "make test had returned bad status, ".
6181 "won't install without force"
6184 if (exists $self->{'install'}) {
6185 if ($self->{'install'}->can("text") ?
6186 $self->{'install'}->text eq "YES" :
6187 $self->{'install'} =~ /^YES/
6189 push @e, "Already done";
6191 # comment in Todo on 2006-02-11; maybe retry?
6192 push @e, "Already tried without success";
6196 exists $self->{later} and length($self->{later}) and
6197 push @e, $self->{later};
6199 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
6201 chdir $self->{'build_dir'} or
6202 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
6203 $self->debug("Changed directory to $self->{'build_dir'}")
6206 if ($^O eq 'MacOS') {
6207 Mac::BuildTools::make_install($self);
6212 if ($self->{modulebuild}) {
6213 my($mbuild_install_build_command) =
6214 exists $CPAN::HandleConfig::keys{mbuild_install_build_command} &&
6215 $CPAN::Config->{mbuild_install_build_command} ?
6216 $CPAN::Config->{mbuild_install_build_command} :
6217 $self->_build_command();
6218 $system = sprintf("%s install %s",
6219 $mbuild_install_build_command,
6220 $CPAN::Config->{mbuild_install_arg},
6223 my($make_install_make_command) = $CPAN::Config->{make_install_make_command} ||
6224 $self->_make_command();
6225 $system = sprintf("%s install %s",
6226 $make_install_make_command,
6227 $CPAN::Config->{make_install_arg},
6231 my($stderr) = $^O eq "MSWin32" ? "" : " 2>&1 ";
6232 $CPAN::Config->{build_requires_install_policy}||="ask/yes";
6234 my $reqtype = $self->{reqtype} ||= "c"; # in doubt it was a command
6235 my $want_install = "yes";
6236 if ($reqtype eq "b") {
6237 if ($CPAN::Config->{build_requires_install_policy} eq "no") {
6238 $want_install = "no";
6239 } elsif ($CPAN::Config->{build_requires_install_policy} =~ m|^ask/(.+)|) {
6241 $default = "yes" unless $default =~ /^(y|n)/i;
6243 CPAN::Shell::colorable_makemaker_prompt
6244 ("$id is just needed temporarily during building or testing. ".
6245 "Do you want to install it permanently? (Y/n)",
6249 unless ($want_install =~ /^y/i) {
6250 my $is_only = "is only 'build_requires'";
6251 $CPAN::Frontend->mywarn("Not installing because $is_only\n");
6252 $self->{install} = CPAN::Distrostatus->new("NO -- $is_only");
6253 delete $self->{force_update};
6256 my($pipe) = FileHandle->new("$system $stderr |");
6259 print $_; # intentionally NOT use Frontend->myprint because it
6260 # looks irritating when we markup in color what we
6261 # just pass through from an external program
6266 $CPAN::Frontend->myprint(" $system -- OK\n");
6267 $CPAN::META->is_installed($self->{build_dir});
6268 return $self->{install} = CPAN::Distrostatus->new("YES");
6270 $self->{install} = CPAN::Distrostatus->new("NO");
6271 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
6273 $makeout =~ /permission/s
6276 ! $CPAN::Config->{make_install_make_command}
6277 || $CPAN::Config->{make_install_make_command} eq $CPAN::Config->{make}
6280 $CPAN::Frontend->myprint(
6282 qq{ You may have to su }.
6283 qq{to root to install the package\n}.
6284 qq{ (Or you may want to run something like\n}.
6285 qq{ o conf make_install_make_command 'sudo make'\n}.
6286 qq{ to raise your permissions.}
6290 delete $self->{force_update};
6293 #-> sub CPAN::Distribution::dir ;
6295 shift->{'build_dir'};
6298 #-> sub CPAN::Distribution::perldoc ;
6302 my($dist) = $self->id;
6303 my $package = $self->called_for;
6305 $self->_display_url( $CPAN::Defaultdocs . $package );
6308 #-> sub CPAN::Distribution::_check_binary ;
6310 my ($dist,$shell,$binary) = @_;
6313 $CPAN::Frontend->myprint(qq{ + _check_binary($binary)\n})
6317 $pid = open README, "which $binary|"
6318 or $CPAN::Frontend->mydie(qq{Could not fork 'which $binary': $!});
6322 close README or die "Could not run 'which $binary': $!";
6324 $CPAN::Frontend->myprint(qq{ + $out \n})
6325 if $CPAN::DEBUG && $out;
6330 #-> sub CPAN::Distribution::_display_url ;
6332 my($self,$url) = @_;
6333 my($res,$saved_file,$pid,$out);
6335 $CPAN::Frontend->myprint(qq{ + _display_url($url)\n})
6338 # should we define it in the config instead?
6339 my $html_converter = "html2text";
6341 my $web_browser = $CPAN::Config->{'lynx'} || undef;
6342 my $web_browser_out = $web_browser
6343 ? CPAN::Distribution->_check_binary($self,$web_browser)
6346 if ($web_browser_out) {
6347 # web browser found, run the action
6348 my $browser = CPAN::HandleConfig->safe_quote($CPAN::Config->{'lynx'});
6349 $CPAN::Frontend->myprint(qq{system[$browser $url]})
6351 $CPAN::Frontend->myprint(qq{
6354 with browser $browser
6356 $CPAN::Frontend->mysleep(1);
6357 system("$browser $url");
6358 if ($saved_file) { 1 while unlink($saved_file) }
6360 # web browser not found, let's try text only
6361 my $html_converter_out =
6362 CPAN::Distribution->_check_binary($self,$html_converter);
6363 $html_converter_out = CPAN::HandleConfig->safe_quote($html_converter_out);
6365 if ($html_converter_out ) {
6366 # html2text found, run it
6367 $saved_file = CPAN::Distribution->_getsave_url( $self, $url );
6368 $CPAN::Frontend->mydie(qq{ERROR: problems while getting $url\n})
6369 unless defined($saved_file);
6372 $pid = open README, "$html_converter $saved_file |"
6373 or $CPAN::Frontend->mydie(qq{
6374 Could not fork '$html_converter $saved_file': $!});
6376 if ($CPAN::META->has_inst("File::Temp")) {
6377 $fh = File::Temp->new(
6378 template => 'cpan_htmlconvert_XXXX',
6382 $filename = $fh->filename;
6384 $filename = "cpan_htmlconvert_$$.txt";
6385 $fh = FileHandle->new();
6386 open $fh, ">$filename" or die;
6392 $CPAN::Frontend->mydie(qq{Could not run '$html_converter $saved_file': $!});
6393 my $tmpin = $fh->filename;
6394 $CPAN::Frontend->myprint(sprintf(qq{
6396 saved output to %s\n},
6404 or $CPAN::Frontend->mydie(qq{Could not open "$tmpin": $!});
6405 my $fh_pager = FileHandle->new;
6406 local($SIG{PIPE}) = "IGNORE";
6407 my $pager = $CPAN::Config->{'pager'} || "cat";
6408 $fh_pager->open("|$pager")
6409 or $CPAN::Frontend->mydie(qq{
6410 Could not open pager '$pager': $!});
6411 $CPAN::Frontend->myprint(qq{
6416 $CPAN::Frontend->mysleep(1);
6417 $fh_pager->print(<FH>);
6420 # coldn't find the web browser or html converter
6421 $CPAN::Frontend->myprint(qq{
6422 You need to install lynx or $html_converter to use this feature.});
6427 #-> sub CPAN::Distribution::_getsave_url ;
6429 my($dist, $shell, $url) = @_;
6431 $CPAN::Frontend->myprint(qq{ + _getsave_url($url)\n})
6435 if ($CPAN::META->has_inst("File::Temp")) {
6436 $fh = File::Temp->new(
6437 template => "cpan_getsave_url_XXXX",
6441 $filename = $fh->filename;
6443 $fh = FileHandle->new;
6444 $filename = "cpan_getsave_url_$$.html";
6446 my $tmpin = $filename;
6447 if ($CPAN::META->has_usable('LWP')) {
6448 $CPAN::Frontend->myprint("Fetching with LWP:
6452 CPAN::LWP::UserAgent->config;
6453 eval { $Ua = CPAN::LWP::UserAgent->new; };
6455 $CPAN::Frontend->mywarn("ERROR: CPAN::LWP::UserAgent->new dies with $@\n");
6459 $Ua->proxy('http', $var)
6460 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
6462 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
6465 my $req = HTTP::Request->new(GET => $url);
6466 $req->header('Accept' => 'text/html');
6467 my $res = $Ua->request($req);
6468 if ($res->is_success) {
6469 $CPAN::Frontend->myprint(" + request successful.\n")
6471 print $fh $res->content;
6473 $CPAN::Frontend->myprint(qq{ + saved content to $tmpin \n})
6477 $CPAN::Frontend->myprint(sprintf(
6478 "LWP failed with code[%s], message[%s]\n",
6485 $CPAN::Frontend->mywarn(" LWP not available\n");
6490 # sub CPAN::Distribution::_build_command
6491 sub _build_command {
6493 if ($^O eq "MSWin32") { # special code needed at least up to
6494 # Module::Build 0.2611 and 0.2706; a fix
6495 # in M:B has been promised 2006-01-30
6496 my($perl) = $self->perl or $CPAN::Frontend->mydie("Couldn't find executable perl\n");
6497 return "$perl ./Build";
6502 package CPAN::Bundle;
6507 $CPAN::Frontend->myprint($self->as_string);
6512 delete $self->{later};
6513 for my $c ( $self->contains ) {
6514 my $obj = CPAN::Shell->expandany($c) or next;
6519 # mark as dirty/clean
6520 #-> sub CPAN::Bundle::color_cmd_tmps ;
6521 sub color_cmd_tmps {
6523 my($depth) = shift || 0;
6524 my($color) = shift || 0;
6525 my($ancestors) = shift || [];
6526 # a module needs to recurse to its cpan_file, a distribution needs
6527 # to recurse into its prereq_pms, a bundle needs to recurse into its modules
6529 return if exists $self->{incommandcolor}
6530 && $self->{incommandcolor}==$color;
6532 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
6534 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
6536 for my $c ( $self->contains ) {
6537 my $obj = CPAN::Shell->expandany($c) or next;
6538 CPAN->debug("c[$c]obj[$obj]") if $CPAN::DEBUG;
6539 $obj->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
6542 delete $self->{badtestcnt};
6544 $self->{incommandcolor} = $color;
6547 #-> sub CPAN::Bundle::as_string ;
6551 # following line must be "=", not "||=" because we have a moving target
6552 $self->{INST_VERSION} = $self->inst_version;
6553 return $self->SUPER::as_string;
6556 #-> sub CPAN::Bundle::contains ;
6559 my($inst_file) = $self->inst_file || "";
6560 my($id) = $self->id;
6561 $self->debug("inst_file[$inst_file]id[$id]") if $CPAN::DEBUG;
6562 if ($inst_file && CPAN::Version->vlt($self->inst_version,$self->cpan_version)) {
6565 unless ($inst_file) {
6566 # Try to get at it in the cpan directory
6567 $self->debug("no inst_file") if $CPAN::DEBUG;
6569 $CPAN::Frontend->mydie("I don't know a bundle with ID $id\n") unless
6570 $cpan_file = $self->cpan_file;
6571 if ($cpan_file eq "N/A") {
6572 $CPAN::Frontend->mydie("Bundle $id not found on disk and not on CPAN.
6573 Maybe stale symlink? Maybe removed during session? Giving up.\n");
6575 my $dist = $CPAN::META->instance('CPAN::Distribution',
6578 $self->debug("id[$dist->{ID}]") if $CPAN::DEBUG;
6579 my($todir) = $CPAN::Config->{'cpan_home'};
6580 my(@me,$from,$to,$me);
6581 @me = split /::/, $self->id;
6583 $me = File::Spec->catfile(@me);
6584 $from = $self->find_bundle_file($dist->{'build_dir'},join('/',@me));
6585 $to = File::Spec->catfile($todir,$me);
6586 File::Path::mkpath(File::Basename::dirname($to));
6587 File::Copy::copy($from, $to)
6588 or Carp::confess("Couldn't copy $from to $to: $!");
6592 my $fh = FileHandle->new;
6594 open($fh,$inst_file) or die "Could not open '$inst_file': $!";
6596 $self->debug("inst_file[$inst_file]") if $CPAN::DEBUG;
6598 $in_cont = m/^=(?!head1\s+CONTENTS)/ ? 0 :
6599 m/^=head1\s+CONTENTS/ ? 1 : $in_cont;
6600 next unless $in_cont;
6605 push @result, (split " ", $_, 2)[0];
6608 delete $self->{STATUS};
6609 $self->{CONTAINS} = \@result;
6610 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
6612 $CPAN::Frontend->mywarn(qq{
6613 The bundle file "$inst_file" may be a broken
6614 bundlefile. It seems not to contain any bundle definition.
6615 Please check the file and if it is bogus, please delete it.
6616 Sorry for the inconvenience.
6622 #-> sub CPAN::Bundle::find_bundle_file
6623 # $where is in local format, $what is in unix format
6624 sub find_bundle_file {
6625 my($self,$where,$what) = @_;
6626 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
6627 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
6628 ### my $bu = File::Spec->catfile($where,$what);
6629 ### return $bu if -f $bu;
6630 my $manifest = File::Spec->catfile($where,"MANIFEST");
6631 unless (-f $manifest) {
6632 require ExtUtils::Manifest;
6633 my $cwd = CPAN::anycwd();
6634 $self->safe_chdir($where);
6635 ExtUtils::Manifest::mkmanifest();
6636 $self->safe_chdir($cwd);
6638 my $fh = FileHandle->new($manifest)
6639 or Carp::croak("Couldn't open $manifest: $!");
6641 my $bundle_filename = $what;
6642 $bundle_filename =~ s|Bundle.*/||;
6643 my $bundle_unixpath;
6646 my($file) = /(\S+)/;
6647 if ($file =~ m|\Q$what\E$|) {
6648 $bundle_unixpath = $file;
6649 # return File::Spec->catfile($where,$bundle_unixpath); # bad
6652 # retry if she managed to have no Bundle directory
6653 $bundle_unixpath = $file if $file =~ m|\Q$bundle_filename\E$|;
6655 return File::Spec->catfile($where, split /\//, $bundle_unixpath)
6656 if $bundle_unixpath;
6657 Carp::croak("Couldn't find a Bundle file in $where");
6660 # needs to work quite differently from Module::inst_file because of
6661 # cpan_home/Bundle/ directory and the possibility that we have
6662 # shadowing effect. As it makes no sense to take the first in @INC for
6663 # Bundles, we parse them all for $VERSION and take the newest.
6665 #-> sub CPAN::Bundle::inst_file ;
6670 @me = split /::/, $self->id;
6673 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
6674 my $bfile = File::Spec->catfile($incdir, @me);
6675 CPAN->debug("bfile[$bfile]") if $CPAN::DEBUG;
6676 next unless -f $bfile;
6677 my $foundv = MM->parse_version($bfile);
6678 if (!$bestv || CPAN::Version->vgt($foundv,$bestv)) {
6679 $self->{INST_FILE} = $bfile;
6680 $self->{INST_VERSION} = $bestv = $foundv;
6686 #-> sub CPAN::Bundle::inst_version ;
6689 $self->inst_file; # finds INST_VERSION as side effect
6690 $self->{INST_VERSION};
6693 #-> sub CPAN::Bundle::rematein ;
6695 my($self,$meth) = @_;
6696 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
6697 my($id) = $self->id;
6698 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
6699 unless $self->inst_file || $self->cpan_file;
6701 for $s ($self->contains) {
6702 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
6703 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
6704 if ($type eq 'CPAN::Distribution') {
6705 $CPAN::Frontend->mywarn(qq{
6706 The Bundle }.$self->id.qq{ contains
6707 explicitly a file $s.
6709 $CPAN::Frontend->mysleep(3);
6711 # possibly noisy action:
6712 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
6713 my $obj = $CPAN::META->instance($type,$s);
6714 $obj->{reqtype} = $self->{reqtype};
6716 if ($obj->isa('CPAN::Bundle')
6718 exists $obj->{install_failed}
6720 ref($obj->{install_failed}) eq "HASH"
6722 for (keys %{$obj->{install_failed}}) {
6723 $self->{install_failed}{$_} = undef; # propagate faiure up
6726 $fail{$s} = 1; # the bundle itself may have succeeded but
6731 $success = $obj->can("uptodate") ? $obj->uptodate : 0;
6732 $success ||= $obj->{'install'} && $obj->{'install'} eq "YES";
6734 delete $self->{install_failed}{$s};
6741 # recap with less noise
6742 if ( $meth eq "install" ) {
6745 my $raw = sprintf(qq{Bundle summary:
6746 The following items in bundle %s had installation problems:},
6749 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
6750 $CPAN::Frontend->myprint("\n");
6753 for $s ($self->contains) {
6755 $paragraph .= "$s ";
6756 $self->{install_failed}{$s} = undef;
6757 $reported{$s} = undef;
6760 my $report_propagated;
6761 for $s (sort keys %{$self->{install_failed}}) {
6762 next if exists $reported{$s};
6763 $paragraph .= "and the following items had problems
6764 during recursive bundle calls: " unless $report_propagated++;
6765 $paragraph .= "$s ";
6767 $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
6768 $CPAN::Frontend->myprint("\n");
6770 $self->{'install'} = 'YES';
6775 # If a bundle contains another that contains an xs_file we have here,
6776 # we just don't bother I suppose
6777 #-> sub CPAN::Bundle::xs_file
6782 #-> sub CPAN::Bundle::force ;
6783 sub force { shift->rematein('force',@_); }
6784 #-> sub CPAN::Bundle::notest ;
6785 sub notest { shift->rematein('notest',@_); }
6786 #-> sub CPAN::Bundle::get ;
6787 sub get { shift->rematein('get',@_); }
6788 #-> sub CPAN::Bundle::make ;
6789 sub make { shift->rematein('make',@_); }
6790 #-> sub CPAN::Bundle::test ;
6793 $self->{badtestcnt} ||= 0;
6794 $self->rematein('test',@_);
6796 #-> sub CPAN::Bundle::install ;
6799 $self->rematein('install',@_);
6801 #-> sub CPAN::Bundle::clean ;
6802 sub clean { shift->rematein('clean',@_); }
6804 #-> sub CPAN::Bundle::uptodate ;
6807 return 0 unless $self->SUPER::uptodate; # we mut have the current Bundle def
6809 foreach $c ($self->contains) {
6810 my $obj = CPAN::Shell->expandany($c);
6811 return 0 unless $obj->uptodate;
6816 #-> sub CPAN::Bundle::readme ;
6819 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
6820 No File found for bundle } . $self->id . qq{\n}), return;
6821 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
6822 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
6825 package CPAN::Module;
6829 # sub CPAN::Module::userid
6834 return $ro->{userid} || $ro->{CPAN_USERID};
6836 # sub CPAN::Module::description
6839 my $ro = $self->ro or return "";
6845 CPAN::Shell->expand("Distribution",$self->cpan_file);
6848 # sub CPAN::Module::undelay
6851 delete $self->{later};
6852 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
6857 # mark as dirty/clean
6858 #-> sub CPAN::Module::color_cmd_tmps ;
6859 sub color_cmd_tmps {
6861 my($depth) = shift || 0;
6862 my($color) = shift || 0;
6863 my($ancestors) = shift || [];
6864 # a module needs to recurse to its cpan_file
6866 return if exists $self->{incommandcolor}
6867 && $self->{incommandcolor}==$color;
6868 return if $depth>=1 && $self->uptodate;
6870 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
6872 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
6874 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
6875 $dist->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
6878 delete $self->{badtestcnt};
6880 $self->{incommandcolor} = $color;
6883 #-> sub CPAN::Module::as_glimpse ;
6887 my $class = ref($self);
6888 $class =~ s/^CPAN:://;
6892 $CPAN::Shell::COLOR_REGISTERED
6894 $CPAN::META->has_inst("Term::ANSIColor")
6898 $color_on = Term::ANSIColor::color("green");
6899 $color_off = Term::ANSIColor::color("reset");
6901 my $uptodateness = " ";
6902 if ($class eq "Bundle") {
6903 } elsif ($self->uptodate) {
6904 $uptodateness = "=";
6905 } elsif ($self->inst_version) {
6906 $uptodateness = "<";
6908 push @m, sprintf("%-7s %1s %s%-22s%s (%s)\n",
6914 ($self->distribution ?
6915 $self->distribution->pretty_id :
6922 #-> sub CPAN::Module::dslip_status
6926 @{$stat->{D}}{qw,i c a b R M S,} = qw,idea
6927 pre-alpha alpha beta released
6929 @{$stat->{S}}{qw,m d u n a,} = qw,mailing-list
6930 developer comp.lang.perl.*
6932 @{$stat->{L}}{qw,p c + o h,} = qw,perl C C++ other hybrid,;
6933 @{$stat->{I}}{qw,f r O p h n,} = qw,functions
6935 object-oriented pragma
6937 @{$stat->{P}}{qw,p g l b a o d r n,} = qw,Standard-Perl
6941 distribution_allowed
6942 restricted_distribution
6944 for my $x (qw(d s l i p)) {
6945 $stat->{$x}{' '} = 'unknown';
6946 $stat->{$x}{'?'} = 'unknown';
6949 return +{} unless $ro && $ro->{statd};
6956 DV => $stat->{D}{$ro->{statd}},
6957 SV => $stat->{S}{$ro->{stats}},
6958 LV => $stat->{L}{$ro->{statl}},
6959 IV => $stat->{I}{$ro->{stati}},
6960 PV => $stat->{P}{$ro->{statp}},
6964 #-> sub CPAN::Module::as_string ;
6968 CPAN->debug("$self entering as_string") if $CPAN::DEBUG;
6969 my $class = ref($self);
6970 $class =~ s/^CPAN:://;
6972 push @m, $class, " id = $self->{ID}\n";
6973 my $sprintf = " %-12s %s\n";
6974 push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
6975 if $self->description;
6976 my $sprintf2 = " %-12s %s (%s)\n";
6978 $userid = $self->userid;
6981 if ($author = CPAN::Shell->expand('Author',$userid)) {
6984 if ($m = $author->email) {
6991 $author->fullname . $email
6995 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
6996 if $self->cpan_version;
6997 if (my $cpan_file = $self->cpan_file){
6998 push @m, sprintf($sprintf, 'CPAN_FILE', $cpan_file);
6999 if (my $dist = CPAN::Shell->expand("Distribution",$cpan_file)) {
7000 my $upload_date = $dist->upload_date;
7002 push @m, sprintf($sprintf, 'UPLOAD_DATE', $upload_date);
7006 my $sprintf3 = " %-12s %1s%1s%1s%1s%1s (%s,%s,%s,%s,%s)\n";
7007 my $dslip = $self->dslip_status;
7011 @{$dslip}{qw(D S L I P DV SV LV IV PV)},
7013 my $local_file = $self->inst_file;
7014 unless ($self->{MANPAGE}) {
7017 $manpage = $self->manpage_headline($local_file);
7019 # If we have already untarred it, we should look there
7020 my $dist = $CPAN::META->instance('CPAN::Distribution',
7022 # warn "dist[$dist]";
7023 # mff=manifest file; mfh=manifest handle
7028 (-f ($mff = File::Spec->catfile($dist->{build_dir}, "MANIFEST")))
7030 $mfh = FileHandle->new($mff)
7032 CPAN->debug("mff[$mff]") if $CPAN::DEBUG;
7033 my $lfre = $self->id; # local file RE
7036 my($lfl); # local file file
7038 my(@mflines) = <$mfh>;
7043 while (length($lfre)>5 and !$lfl) {
7044 ($lfl) = grep /$lfre/, @mflines;
7045 CPAN->debug("lfl[$lfl]lfre[$lfre]") if $CPAN::DEBUG;
7048 $lfl =~ s/\s.*//; # remove comments
7049 $lfl =~ s/\s+//g; # chomp would maybe be too system-specific
7050 my $lfl_abs = File::Spec->catfile($dist->{build_dir},$lfl);
7051 # warn "lfl_abs[$lfl_abs]";
7053 $manpage = $self->manpage_headline($lfl_abs);
7057 $self->{MANPAGE} = $manpage if $manpage;
7060 for $item (qw/MANPAGE/) {
7061 push @m, sprintf($sprintf, $item, $self->{$item})
7062 if exists $self->{$item};
7064 for $item (qw/CONTAINS/) {
7065 push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
7066 if exists $self->{$item} && @{$self->{$item}};
7068 push @m, sprintf($sprintf, 'INST_FILE',
7069 $local_file || "(not installed)");
7070 push @m, sprintf($sprintf, 'INST_VERSION',
7071 $self->inst_version) if $local_file;
7075 sub manpage_headline {
7076 my($self,$local_file) = @_;
7077 my(@local_file) = $local_file;
7078 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
7079 push @local_file, $local_file;
7081 for $locf (@local_file) {
7082 next unless -f $locf;
7083 my $fh = FileHandle->new($locf)
7084 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
7088 $inpod = m/^=(?!head1\s+NAME\s*$)/ ? 0 :
7089 m/^=head1\s+NAME\s*$/ ? 1 : $inpod;
7106 #-> sub CPAN::Module::cpan_file ;
7107 # Note: also inherited by CPAN::Bundle
7110 CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
7111 unless ($self->ro) {
7112 CPAN::Index->reload;
7115 if ($ro && defined $ro->{CPAN_FILE}){
7116 return $ro->{CPAN_FILE};
7118 my $userid = $self->userid;
7120 if ($CPAN::META->exists("CPAN::Author",$userid)) {
7121 my $author = $CPAN::META->instance("CPAN::Author",
7123 my $fullname = $author->fullname;
7124 my $email = $author->email;
7125 unless (defined $fullname && defined $email) {
7126 return sprintf("Contact Author %s",
7130 return "Contact Author $fullname <$email>";
7132 return "Contact Author $userid (Email address not available)";
7140 #-> sub CPAN::Module::cpan_version ;
7146 # Can happen with modules that are not on CPAN
7149 $ro->{CPAN_VERSION} = 'undef'
7150 unless defined $ro->{CPAN_VERSION};
7151 $ro->{CPAN_VERSION};
7154 #-> sub CPAN::Module::force ;
7157 $self->{'force_update'}++;
7162 # warn "XDEBUG: set notest for Module";
7163 $self->{'notest'}++;
7166 #-> sub CPAN::Module::rematein ;
7168 my($self,$meth) = @_;
7169 $CPAN::Frontend->myprint(sprintf("Running %s for module '%s'\n",
7172 my $cpan_file = $self->cpan_file;
7173 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
7174 $CPAN::Frontend->mywarn(sprintf qq{
7175 The module %s isn\'t available on CPAN.
7177 Either the module has not yet been uploaded to CPAN, or it is
7178 temporary unavailable. Please contact the author to find out
7179 more about the status. Try 'i %s'.
7186 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
7187 $pack->called_for($self->id);
7188 $pack->force($meth) if exists $self->{'force_update'};
7189 $pack->notest($meth) if exists $self->{'notest'};
7191 $pack->{reqtype} ||= "";
7192 CPAN->debug("dist-reqtype[$pack->{reqtype}]".
7193 "self-reqtype[$self->{reqtype}]") if $CPAN::DEBUG;
7194 if ($pack->{reqtype}) {
7195 if ($pack->{reqtype} eq "b" && $self->{reqtype} =~ /^[rc]$/) {
7196 $pack->{reqtype} = $self->{reqtype};
7198 exists $pack->{install}
7201 $pack->{install}->can("failed") ?
7202 $pack->{install}->failed :
7203 $pack->{install} =~ /^NO/
7206 delete $pack->{install};
7207 $CPAN::Frontend->mywarn
7208 ("Promoting $pack->{ID} from 'build_requires' to 'requires'");
7212 $pack->{reqtype} = $self->{reqtype};
7219 $pack->unforce if $pack->can("unforce") && exists $self->{'force_update'};
7220 $pack->unnotest if $pack->can("unnotest") && exists $self->{'notest'};
7221 delete $self->{'force_update'};
7222 delete $self->{'notest'};
7228 #-> sub CPAN::Module::perldoc ;
7229 sub perldoc { shift->rematein('perldoc') }
7230 #-> sub CPAN::Module::readme ;
7231 sub readme { shift->rematein('readme') }
7232 #-> sub CPAN::Module::look ;
7233 sub look { shift->rematein('look') }
7234 #-> sub CPAN::Module::cvs_import ;
7235 sub cvs_import { shift->rematein('cvs_import') }
7236 #-> sub CPAN::Module::get ;
7237 sub get { shift->rematein('get',@_) }
7238 #-> sub CPAN::Module::make ;
7239 sub make { shift->rematein('make') }
7240 #-> sub CPAN::Module::test ;
7243 $self->{badtestcnt} ||= 0;
7244 $self->rematein('test',@_);
7246 #-> sub CPAN::Module::uptodate ;
7249 local($_); # protect against a bug in MakeMaker 6.17
7250 my($latest) = $self->cpan_version;
7252 my($inst_file) = $self->inst_file;
7254 if (defined $inst_file) {
7255 $have = $self->inst_version;
7260 ! CPAN::Version->vgt($latest, $have)
7262 CPAN->debug("returning uptodate. inst_file[$inst_file] ".
7263 "latest[$latest] have[$have]") if $CPAN::DEBUG;
7268 #-> sub CPAN::Module::install ;
7274 not exists $self->{'force_update'}
7276 $CPAN::Frontend->myprint(sprintf("%s is up to date (%s).\n",
7278 $self->inst_version,
7284 if ($ro && $ro->{stats} && $ro->{stats} eq "a") {
7285 $CPAN::Frontend->mywarn(qq{
7286 \n\n\n ***WARNING***
7287 The module $self->{ID} has no active maintainer.\n\n\n
7289 $CPAN::Frontend->mysleep(5);
7291 $self->rematein('install') if $doit;
7293 #-> sub CPAN::Module::clean ;
7294 sub clean { shift->rematein('clean') }
7296 #-> sub CPAN::Module::inst_file ;
7300 @packpath = split /::/, $self->{ID};
7301 $packpath[-1] .= ".pm";
7302 if (@packpath == 1 && $packpath[0] eq "readline.pm") {
7303 unshift @packpath, "Term", "ReadLine"; # historical reasons
7305 foreach $dir (@INC) {
7306 my $pmfile = File::Spec->catfile($dir,@packpath);
7314 #-> sub CPAN::Module::xs_file ;
7318 @packpath = split /::/, $self->{ID};
7319 push @packpath, $packpath[-1];
7320 $packpath[-1] .= "." . $Config::Config{'dlext'};
7321 foreach $dir (@INC) {
7322 my $xsfile = File::Spec->catfile($dir,'auto',@packpath);
7330 #-> sub CPAN::Module::inst_version ;
7333 my $parsefile = $self->inst_file or return;
7334 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
7337 $have = MM->parse_version($parsefile) || "undef";
7338 $have =~ s/^ //; # since the %vd hack these two lines here are needed
7339 $have =~ s/ $//; # trailing whitespace happens all the time
7341 # My thoughts about why %vd processing should happen here
7343 # Alt1 maintain it as string with leading v:
7344 # read index files do nothing
7345 # compare it use utility for compare
7346 # print it do nothing
7348 # Alt2 maintain it as what it is
7349 # read index files convert
7350 # compare it use utility because there's still a ">" vs "gt" issue
7351 # print it use CPAN::Version for print
7353 # Seems cleaner to hold it in memory as a string starting with a "v"
7355 # If the author of this module made a mistake and wrote a quoted
7356 # "v1.13" instead of v1.13, we simply leave it at that with the
7357 # effect that *we* will treat it like a v-tring while the rest of
7358 # perl won't. Seems sensible when we consider that any action we
7359 # could take now would just add complexity.
7361 $have = CPAN::Version->readable($have);
7363 $have =~ s/\s*//g; # stringify to float around floating point issues
7364 $have; # no stringify needed, \s* above matches always
7377 CPAN - query, download and build perl modules from CPAN sites
7383 perl -MCPAN -e shell;
7391 $mod = "Acme::Meta";
7393 CPAN::Shell->install($mod); # same thing
7394 CPAN::Shell->expandany($mod)->install; # same thing
7395 CPAN::Shell->expand("Module",$mod)->install; # same thing
7396 CPAN::Shell->expand("Module",$mod)
7397 ->distribution->install; # same thing
7401 $distro = "NWCLARK/Acme-Meta-0.01.tar.gz";
7402 install $distro; # same thing
7403 CPAN::Shell->install($distro); # same thing
7404 CPAN::Shell->expandany($distro)->install; # same thing
7405 CPAN::Shell->expand("Distribution",$distro)->install; # same thing
7409 This module and its competitor, the CPANPLUS module, are both much
7410 cooler than the other.
7412 =head1 COMPATIBILITY
7414 CPAN.pm is regularly tested to run under 5.004, 5.005, and assorted
7415 newer versions. It is getting more and more difficult to get the
7416 minimal prerequisites working on older perls. It is close to
7417 impossible to get the whole Bundle::CPAN working there. If you're in
7418 the position to have only these old versions, be advised that CPAN is
7419 designed to work fine without the Bundle::CPAN installed.
7421 To get things going, note that GBARR/Scalar-List-Utils-1.18.tar.gz is
7422 compatible with ancient perls and that File::Temp is listed as a
7423 prerequisite but CPAN has reasonable workarounds if it is missing.
7427 The CPAN module is designed to automate the make and install of perl
7428 modules and extensions. It includes some primitive searching
7429 capabilities and knows how to use Net::FTP or LWP (or some external
7430 download clients) to fetch the raw data from the net.
7432 Modules are fetched from one or more of the mirrored CPAN
7433 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
7436 The CPAN module also supports the concept of named and versioned
7437 I<bundles> of modules. Bundles simplify the handling of sets of
7438 related modules. See Bundles below.
7440 The package contains a session manager and a cache manager. There is
7441 no status retained between sessions. The session manager keeps track
7442 of what has been fetched, built and installed in the current
7443 session. The cache manager keeps track of the disk space occupied by
7444 the make processes and deletes excess space according to a simple FIFO
7447 All methods provided are accessible in a programmer style and in an
7448 interactive shell style.
7450 =head2 CPAN::shell([$prompt, $command]) Starting Interactive Mode
7452 The interactive mode is entered by running
7454 perl -MCPAN -e shell
7456 which puts you into a readline interface. You will have the most fun if
7457 you install Term::ReadKey and Term::ReadLine to enjoy both history and
7460 Once you are on the command line, type 'h' and the rest should be
7463 The function call C<shell> takes two optional arguments, one is the
7464 prompt, the second is the default initial command line (the latter
7465 only works if a real ReadLine interface module is installed).
7467 The most common uses of the interactive modes are
7471 =item Searching for authors, bundles, distribution files and modules
7473 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
7474 for each of the four categories and another, C<i> for any of the
7475 mentioned four. Each of the four entities is implemented as a class
7476 with slightly differing methods for displaying an object.
7478 Arguments you pass to these commands are either strings exactly matching
7479 the identification string of an object or regular expressions that are
7480 then matched case-insensitively against various attributes of the
7481 objects. The parser recognizes a regular expression only if you
7482 enclose it between two slashes.
7484 The principle is that the number of found objects influences how an
7485 item is displayed. If the search finds one item, the result is
7486 displayed with the rather verbose method C<as_string>, but if we find
7487 more than one, we display each object with the terse method
7490 =item make, test, install, clean modules or distributions
7492 These commands take any number of arguments and investigate what is
7493 necessary to perform the action. If the argument is a distribution
7494 file name (recognized by embedded slashes), it is processed. If it is
7495 a module, CPAN determines the distribution file in which this module
7496 is included and processes that, following any dependencies named in
7497 the module's META.yml or Makefile.PL (this behavior is controlled by
7498 the configuration parameter C<prerequisites_policy>.)
7500 Any C<make> or C<test> are run unconditionally. An
7502 install <distribution_file>
7504 also is run unconditionally. But for
7508 CPAN checks if an install is actually needed for it and prints
7509 I<module up to date> in the case that the distribution file containing
7510 the module doesn't need to be updated.
7512 CPAN also keeps track of what it has done within the current session
7513 and doesn't try to build a package a second time regardless if it
7514 succeeded or not. The C<force> pragma may precede another command
7515 (currently: C<make>, C<test>, or C<install>) and executes the
7516 command from scratch and tries to continue in case of some errors.
7520 cpan> install OpenGL
7521 OpenGL is up to date.
7522 cpan> force install OpenGL
7525 OpenGL-0.4/COPYRIGHT
7528 The C<notest> pragma may be set to skip the test part in the build
7533 cpan> notest install Tk
7535 A C<clean> command results in a
7539 being executed within the distribution file's working directory.
7541 =item get, readme, perldoc, look module or distribution
7543 C<get> downloads a distribution file without further action. C<readme>
7544 displays the README file of the associated distribution. C<Look> gets
7545 and untars (if not yet done) the distribution file, changes to the
7546 appropriate directory and opens a subshell process in that directory.
7547 C<perldoc> displays the pod documentation of the module in html or
7552 =item ls globbing_expression
7554 The first form lists all distribution files in and below an author's
7555 CPAN directory as they are stored in the CHECKUMS files distributed on
7556 CPAN. The listing goes recursive into all subdirectories.
7558 The second form allows to limit or expand the output with shell
7559 globbing as in the following examples:
7565 The last example is very slow and outputs extra progress indicators
7566 that break the alignment of the result.
7568 Note that globbing only lists directories explicitly asked for, for
7569 example FOO/* will not list FOO/bar/Acme-Sthg-n.nn.tar.gz. This may be
7570 regarded as a bug and may be changed in future versions.
7574 The C<failed> command reports all distributions that failed on one of
7575 C<make>, C<test> or C<install> for some reason in the currently
7576 running shell session.
7580 Interactive sessions maintain a lockfile, per default C<~/.cpan/.lock>
7581 (but the directory can be configured via the C<cpan_home> config
7582 variable). The shell is a bit picky if you try to start another CPAN
7583 session. It dies immediately if there is a lockfile and the lock seems
7584 to belong to a running process. In case you want to run a second shell
7585 session, it is probably safest to maintain another directory, say
7586 C<~/.cpan-for-X/> and a C<~/.cpan-for-X/CPAN/MyConfig.pm> that
7587 contains the configuration options. Then you can start the second
7590 perl -I ~/.cpan-for-X -MCPAN::MyConfig -MCPAN -e shell
7594 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
7595 in the cpan-shell it is intended that you can press C<^C> anytime and
7596 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
7597 to clean up and leave the shell loop. You can emulate the effect of a
7598 SIGTERM by sending two consecutive SIGINTs, which usually means by
7599 pressing C<^C> twice.
7601 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
7602 SIGALRM is used during the run of the C<perl Makefile.PL> or C<perl
7603 Build.PL> subprocess.
7609 The commands that are available in the shell interface are methods in
7610 the package CPAN::Shell. If you enter the shell command, all your
7611 input is split by the Text::ParseWords::shellwords() routine which
7612 acts like most shells do. The first word is being interpreted as the
7613 method to be called and the rest of the words are treated as arguments
7614 to this method. Continuation lines are supported if a line ends with a
7619 C<autobundle> writes a bundle file into the
7620 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
7621 a list of all modules that are both available from CPAN and currently
7622 installed within @INC. The name of the bundle file is based on the
7623 current date and a counter.
7627 recompile() is a very special command in that it takes no argument and
7628 runs the make/test/install cycle with brute force over all installed
7629 dynamically loadable extensions (aka XS modules) with 'force' in
7630 effect. The primary purpose of this command is to finish a network
7631 installation. Imagine, you have a common source tree for two different
7632 architectures. You decide to do a completely independent fresh
7633 installation. You start on one architecture with the help of a Bundle
7634 file produced earlier. CPAN installs the whole Bundle for you, but
7635 when you try to repeat the job on the second architecture, CPAN
7636 responds with a C<"Foo up to date"> message for all modules. So you
7637 invoke CPAN's recompile on the second architecture and you're done.
7639 Another popular use for C<recompile> is to act as a rescue in case your
7640 perl breaks binary compatibility. If one of the modules that CPAN uses
7641 is in turn depending on binary compatibility (so you cannot run CPAN
7642 commands), then you should try the CPAN::Nox module for recovery.
7644 =head2 upgrade [Module|/Regex/]...
7646 The C<upgrade> command first runs an C<r> command with the given
7647 arguments and then installs the newest versions of all modules that
7648 were listed by that.
7652 mkmyconfig() writes your own CPAN::MyConfig file into your ~/.cpan/
7653 directory so that you can save your own preferences instead of the
7656 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
7658 Although it may be considered internal, the class hierarchy does matter
7659 for both users and programmer. CPAN.pm deals with above mentioned four
7660 classes, and all those classes share a set of methods. A classical
7661 single polymorphism is in effect. A metaclass object registers all
7662 objects of all kinds and indexes them with a string. The strings
7663 referencing objects have a separated namespace (well, not completely
7668 words containing a "/" (slash) Distribution
7669 words starting with Bundle:: Bundle
7670 everything else Module or Author
7672 Modules know their associated Distribution objects. They always refer
7673 to the most recent official release. Developers may mark their releases
7674 as unstable development versions (by inserting an underbar into the
7675 module version number which will also be reflected in the distribution
7676 name when you run 'make dist'), so the really hottest and newest
7677 distribution is not always the default. If a module Foo circulates
7678 on CPAN in both version 1.23 and 1.23_90, CPAN.pm offers a convenient
7679 way to install version 1.23 by saying
7683 This would install the complete distribution file (say
7684 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
7685 like to install version 1.23_90, you need to know where the
7686 distribution file resides on CPAN relative to the authors/id/
7687 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
7688 so you would have to say
7690 install BAR/Foo-1.23_90.tar.gz
7692 The first example will be driven by an object of the class
7693 CPAN::Module, the second by an object of class CPAN::Distribution.
7695 =head1 PROGRAMMER'S INTERFACE
7697 If you do not enter the shell, the available shell commands are both
7698 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
7699 functions in the calling package (C<install(...)>).
7701 There's currently only one class that has a stable interface -
7702 CPAN::Shell. All commands that are available in the CPAN shell are
7703 methods of the class CPAN::Shell. Each of the commands that produce
7704 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
7705 the IDs of all modules within the list.
7709 =item expand($type,@things)
7711 The IDs of all objects available within a program are strings that can
7712 be expanded to the corresponding real objects with the
7713 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
7714 list of CPAN::Module objects according to the C<@things> arguments
7715 given. In scalar context it only returns the first element of the
7718 =item expandany(@things)
7720 Like expand, but returns objects of the appropriate type, i.e.
7721 CPAN::Bundle objects for bundles, CPAN::Module objects for modules and
7722 CPAN::Distribution objects for distributions. Note: it does not expand
7723 to CPAN::Author objects.
7725 =item Programming Examples
7727 This enables the programmer to do operations that combine
7728 functionalities that are available in the shell.
7730 # install everything that is outdated on my disk:
7731 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
7733 # install my favorite programs if necessary:
7734 for $mod (qw(Net::FTP Digest::SHA Data::Dumper)){
7735 my $obj = CPAN::Shell->expand('Module',$mod);
7739 # list all modules on my disk that have no VERSION number
7740 for $mod (CPAN::Shell->expand("Module","/./")){
7741 next unless $mod->inst_file;
7742 # MakeMaker convention for undefined $VERSION:
7743 next unless $mod->inst_version eq "undef";
7744 print "No VERSION in ", $mod->id, "\n";
7747 # find out which distribution on CPAN contains a module:
7748 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
7750 Or if you want to write a cronjob to watch The CPAN, you could list
7751 all modules that need updating. First a quick and dirty way:
7753 perl -e 'use CPAN; CPAN::Shell->r;'
7755 If you don't want to get any output in the case that all modules are
7756 up to date, you can parse the output of above command for the regular
7757 expression //modules are up to date// and decide to mail the output
7758 only if it doesn't match. Ick?
7760 If you prefer to do it more in a programmer style in one single
7761 process, maybe something like this suits you better:
7763 # list all modules on my disk that have newer versions on CPAN
7764 for $mod (CPAN::Shell->expand("Module","/./")){
7765 next unless $mod->inst_file;
7766 next if $mod->uptodate;
7767 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
7768 $mod->id, $mod->inst_version, $mod->cpan_version;
7771 If that gives you too much output every day, you maybe only want to
7772 watch for three modules. You can write
7774 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")){
7776 as the first line instead. Or you can combine some of the above
7779 # watch only for a new mod_perl module
7780 $mod = CPAN::Shell->expand("Module","mod_perl");
7781 exit if $mod->uptodate;
7782 # new mod_perl arrived, let me know all update recommendations
7787 =head2 Methods in the other Classes
7789 The programming interface for the classes CPAN::Module,
7790 CPAN::Distribution, CPAN::Bundle, and CPAN::Author is still considered
7791 beta and partially even alpha. In the following paragraphs only those
7792 methods are documented that have proven useful over a longer time and
7793 thus are unlikely to change.
7797 =item CPAN::Author::as_glimpse()
7799 Returns a one-line description of the author
7801 =item CPAN::Author::as_string()
7803 Returns a multi-line description of the author
7805 =item CPAN::Author::email()
7807 Returns the author's email address
7809 =item CPAN::Author::fullname()
7811 Returns the author's name
7813 =item CPAN::Author::name()
7815 An alias for fullname
7817 =item CPAN::Bundle::as_glimpse()
7819 Returns a one-line description of the bundle
7821 =item CPAN::Bundle::as_string()
7823 Returns a multi-line description of the bundle
7825 =item CPAN::Bundle::clean()
7827 Recursively runs the C<clean> method on all items contained in the bundle.
7829 =item CPAN::Bundle::contains()
7831 Returns a list of objects' IDs contained in a bundle. The associated
7832 objects may be bundles, modules or distributions.
7834 =item CPAN::Bundle::force($method,@args)
7836 Forces CPAN to perform a task that normally would have failed. Force
7837 takes as arguments a method name to be called and any number of
7838 additional arguments that should be passed to the called method. The
7839 internals of the object get the needed changes so that CPAN.pm does
7840 not refuse to take the action. The C<force> is passed recursively to
7841 all contained objects.
7843 =item CPAN::Bundle::get()
7845 Recursively runs the C<get> method on all items contained in the bundle
7847 =item CPAN::Bundle::inst_file()
7849 Returns the highest installed version of the bundle in either @INC or
7850 C<$CPAN::Config->{cpan_home}>. Note that this is different from
7851 CPAN::Module::inst_file.
7853 =item CPAN::Bundle::inst_version()
7855 Like CPAN::Bundle::inst_file, but returns the $VERSION
7857 =item CPAN::Bundle::uptodate()
7859 Returns 1 if the bundle itself and all its members are uptodate.
7861 =item CPAN::Bundle::install()
7863 Recursively runs the C<install> method on all items contained in the bundle
7865 =item CPAN::Bundle::make()
7867 Recursively runs the C<make> method on all items contained in the bundle
7869 =item CPAN::Bundle::readme()
7871 Recursively runs the C<readme> method on all items contained in the bundle
7873 =item CPAN::Bundle::test()
7875 Recursively runs the C<test> method on all items contained in the bundle
7877 =item CPAN::Distribution::as_glimpse()
7879 Returns a one-line description of the distribution
7881 =item CPAN::Distribution::as_string()
7883 Returns a multi-line description of the distribution
7885 =item CPAN::Distribution::author
7887 Returns the CPAN::Author object of the maintainer who uploaded this
7890 =item CPAN::Distribution::clean()
7892 Changes to the directory where the distribution has been unpacked and
7893 runs C<make clean> there.
7895 =item CPAN::Distribution::containsmods()
7897 Returns a list of IDs of modules contained in a distribution file.
7898 Only works for distributions listed in the 02packages.details.txt.gz
7899 file. This typically means that only the most recent version of a
7900 distribution is covered.
7902 =item CPAN::Distribution::cvs_import()
7904 Changes to the directory where the distribution has been unpacked and
7907 cvs -d $cvs_root import -m $cvs_log $cvs_dir $userid v$version
7911 =item CPAN::Distribution::dir()
7913 Returns the directory into which this distribution has been unpacked.
7915 =item CPAN::Distribution::force($method,@args)
7917 Forces CPAN to perform a task that normally would have failed. Force
7918 takes as arguments a method name to be called and any number of
7919 additional arguments that should be passed to the called method. The
7920 internals of the object get the needed changes so that CPAN.pm does
7921 not refuse to take the action.
7923 =item CPAN::Distribution::get()
7925 Downloads the distribution from CPAN and unpacks it. Does nothing if
7926 the distribution has already been downloaded and unpacked within the
7929 =item CPAN::Distribution::install()
7931 Changes to the directory where the distribution has been unpacked and
7932 runs the external command C<make install> there. If C<make> has not
7933 yet been run, it will be run first. A C<make test> will be issued in
7934 any case and if this fails, the install will be canceled. The
7935 cancellation can be avoided by letting C<force> run the C<install> for
7938 Note that install() gives no meaningful return value. See uptodate().
7940 =item CPAN::Distribution::isa_perl()
7942 Returns 1 if this distribution file seems to be a perl distribution.
7943 Normally this is derived from the file name only, but the index from
7944 CPAN can contain a hint to achieve a return value of true for other
7947 =item CPAN::Distribution::look()
7949 Changes to the directory where the distribution has been unpacked and
7950 opens a subshell there. Exiting the subshell returns.
7952 =item CPAN::Distribution::make()
7954 First runs the C<get> method to make sure the distribution is
7955 downloaded and unpacked. Changes to the directory where the
7956 distribution has been unpacked and runs the external commands C<perl
7957 Makefile.PL> or C<perl Build.PL> and C<make> there.
7959 =item CPAN::Distribution::perldoc()
7961 Downloads the pod documentation of the file associated with a
7962 distribution (in html format) and runs it through the external
7963 command lynx specified in C<$CPAN::Config->{lynx}>. If lynx
7964 isn't available, it converts it to plain text with external
7965 command html2text and runs it through the pager specified
7966 in C<$CPAN::Config->{pager}>
7968 =item CPAN::Distribution::prereq_pm()
7970 Returns the hash reference that has been announced by a distribution
7971 as the merge of the C<requires> element and the C<build_requires>
7972 element of the META.yml or the C<PREREQ_PM> hash in the
7973 C<Makefile.PL>. Note: works only after an attempt has been made to
7974 C<make> the distribution. Returns undef otherwise.
7976 =item CPAN::Distribution::readme()
7978 Downloads the README file associated with a distribution and runs it
7979 through the pager specified in C<$CPAN::Config->{pager}>.
7981 =item CPAN::Distribution::read_yaml()
7983 Returns the content of the META.yml of this distro as a hashref. Note:
7984 works only after an attempt has been made to C<make> the distribution.
7985 Returns undef otherwise.
7987 =item CPAN::Distribution::test()
7989 Changes to the directory where the distribution has been unpacked and
7990 runs C<make test> there.
7992 =item CPAN::Distribution::uptodate()
7994 Returns 1 if all the modules contained in the distribution are
7995 uptodate. Relies on containsmods.
7997 =item CPAN::Index::force_reload()
7999 Forces a reload of all indices.
8001 =item CPAN::Index::reload()
8003 Reloads all indices if they have not been read for more than
8004 C<$CPAN::Config->{index_expire}> days.
8006 =item CPAN::InfoObj::dump()
8008 CPAN::Author, CPAN::Bundle, CPAN::Module, and CPAN::Distribution
8009 inherit this method. It prints the data structure associated with an
8010 object. Useful for debugging. Note: the data structure is considered
8011 internal and thus subject to change without notice.
8013 =item CPAN::Module::as_glimpse()
8015 Returns a one-line description of the module in four columns: The
8016 first column contains the word C<Module>, the second column consists
8017 of one character: an equals sign if this module is already installed
8018 and uptodate, a less-than sign if this module is installed but can be
8019 upgraded, and a space if the module is not installed. The third column
8020 is the name of the module and the fourth column gives maintainer or
8021 distribution information.
8023 =item CPAN::Module::as_string()
8025 Returns a multi-line description of the module
8027 =item CPAN::Module::clean()
8029 Runs a clean on the distribution associated with this module.
8031 =item CPAN::Module::cpan_file()
8033 Returns the filename on CPAN that is associated with the module.
8035 =item CPAN::Module::cpan_version()
8037 Returns the latest version of this module available on CPAN.
8039 =item CPAN::Module::cvs_import()
8041 Runs a cvs_import on the distribution associated with this module.
8043 =item CPAN::Module::description()
8045 Returns a 44 character description of this module. Only available for
8046 modules listed in The Module List (CPAN/modules/00modlist.long.html
8047 or 00modlist.long.txt.gz)
8049 =item CPAN::Module::distribution()
8051 Returns the CPAN::Distribution object that contains the current
8052 version of this module.
8054 =item CPAN::Module::dslip_status()
8056 Returns a hash reference. The keys of the hash are the letters C<D>,
8057 C<S>, C<L>, C<I>, and <P>, for development status, support level,
8058 language, interface and public licence respectively. The data for the
8059 DSLIP status are collected by pause.perl.org when authors register
8060 their namespaces. The values of the 5 hash elements are one-character
8061 words whose meaning is described in the table below. There are also 5
8062 hash elements C<DV>, C<SV>, C<LV>, C<IV>, and <PV> that carry a more
8063 verbose value of the 5 status variables.
8065 Where the 'DSLIP' characters have the following meanings:
8067 D - Development Stage (Note: *NO IMPLIED TIMESCALES*):
8068 i - Idea, listed to gain consensus or as a placeholder
8069 c - under construction but pre-alpha (not yet released)
8070 a/b - Alpha/Beta testing
8072 M - Mature (no rigorous definition)
8073 S - Standard, supplied with Perl 5
8078 u - Usenet newsgroup comp.lang.perl.modules
8079 n - None known, try comp.lang.perl.modules
8080 a - abandoned; volunteers welcome to take over maintainance
8083 p - Perl-only, no compiler needed, should be platform independent
8084 c - C and perl, a C compiler will be needed
8085 h - Hybrid, written in perl with optional C code, no compiler needed
8086 + - C++ and perl, a C++ compiler will be needed
8087 o - perl and another language other than C or C++
8090 f - plain Functions, no references used
8091 h - hybrid, object and function interfaces available
8092 n - no interface at all (huh?)
8093 r - some use of unblessed References or ties
8094 O - Object oriented using blessed references and/or inheritance
8097 p - Standard-Perl: user may choose between GPL and Artistic
8098 g - GPL: GNU General Public License
8099 l - LGPL: "GNU Lesser General Public License" (previously known as
8100 "GNU Library General Public License")
8101 b - BSD: The BSD License
8102 a - Artistic license alone
8103 o - open source: appoved by www.opensource.org
8104 d - allows distribution without restrictions
8105 r - restricted distribtion
8106 n - no license at all
8108 =item CPAN::Module::force($method,@args)
8110 Forces CPAN to perform a task that normally would have failed. Force
8111 takes as arguments a method name to be called and any number of
8112 additional arguments that should be passed to the called method. The
8113 internals of the object get the needed changes so that CPAN.pm does
8114 not refuse to take the action.
8116 =item CPAN::Module::get()
8118 Runs a get on the distribution associated with this module.
8120 =item CPAN::Module::inst_file()
8122 Returns the filename of the module found in @INC. The first file found
8123 is reported just like perl itself stops searching @INC when it finds a
8126 =item CPAN::Module::inst_version()
8128 Returns the version number of the module in readable format.
8130 =item CPAN::Module::install()
8132 Runs an C<install> on the distribution associated with this module.
8134 =item CPAN::Module::look()
8136 Changes to the directory where the distribution associated with this
8137 module has been unpacked and opens a subshell there. Exiting the
8140 =item CPAN::Module::make()
8142 Runs a C<make> on the distribution associated with this module.
8144 =item CPAN::Module::manpage_headline()
8146 If module is installed, peeks into the module's manpage, reads the
8147 headline and returns it. Moreover, if the module has been downloaded
8148 within this session, does the equivalent on the downloaded module even
8149 if it is not installed.
8151 =item CPAN::Module::perldoc()
8153 Runs a C<perldoc> on this module.
8155 =item CPAN::Module::readme()
8157 Runs a C<readme> on the distribution associated with this module.
8159 =item CPAN::Module::test()
8161 Runs a C<test> on the distribution associated with this module.
8163 =item CPAN::Module::uptodate()
8165 Returns 1 if the module is installed and up-to-date.
8167 =item CPAN::Module::userid()
8169 Returns the author's ID of the module.
8173 =head2 Cache Manager
8175 Currently the cache manager only keeps track of the build directory
8176 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
8177 deletes complete directories below C<build_dir> as soon as the size of
8178 all directories there gets bigger than $CPAN::Config->{build_cache}
8179 (in MB). The contents of this cache may be used for later
8180 re-installations that you intend to do manually, but will never be
8181 trusted by CPAN itself. This is due to the fact that the user might
8182 use these directories for building modules on different architectures.
8184 There is another directory ($CPAN::Config->{keep_source_where}) where
8185 the original distribution files are kept. This directory is not
8186 covered by the cache manager and must be controlled by the user. If
8187 you choose to have the same directory as build_dir and as
8188 keep_source_where directory, then your sources will be deleted with
8189 the same fifo mechanism.
8193 A bundle is just a perl module in the namespace Bundle:: that does not
8194 define any functions or methods. It usually only contains documentation.
8196 It starts like a perl module with a package declaration and a $VERSION
8197 variable. After that the pod section looks like any other pod with the
8198 only difference being that I<one special pod section> exists starting with
8203 In this pod section each line obeys the format
8205 Module_Name [Version_String] [- optional text]
8207 The only required part is the first field, the name of a module
8208 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
8209 of the line is optional. The comment part is delimited by a dash just
8210 as in the man page header.
8212 The distribution of a bundle should follow the same convention as
8213 other distributions.
8215 Bundles are treated specially in the CPAN package. If you say 'install
8216 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
8217 the modules in the CONTENTS section of the pod. You can install your
8218 own Bundles locally by placing a conformant Bundle file somewhere into
8219 your @INC path. The autobundle() command which is available in the
8220 shell interface does that for you by including all currently installed
8221 modules in a snapshot bundle file.
8223 =head1 PREREQUISITES
8225 If you have a local mirror of CPAN and can access all files with
8226 "file:" URLs, then you only need a perl better than perl5.003 to run
8227 this module. Otherwise Net::FTP is strongly recommended. LWP may be
8228 required for non-UNIX systems or if your nearest CPAN site is
8229 associated with a URL that is not C<ftp:>.
8231 If you have neither Net::FTP nor LWP, there is a fallback mechanism
8232 implemented for an external ftp command or for an external lynx
8237 =head2 Finding packages and VERSION
8239 This module presumes that all packages on CPAN
8245 declare their $VERSION variable in an easy to parse manner. This
8246 prerequisite can hardly be relaxed because it consumes far too much
8247 memory to load all packages into the running program just to determine
8248 the $VERSION variable. Currently all programs that are dealing with
8249 version use something like this
8251 perl -MExtUtils::MakeMaker -le \
8252 'print MM->parse_version(shift)' filename
8254 If you are author of a package and wonder if your $VERSION can be
8255 parsed, please try the above method.
8259 come as compressed or gzipped tarfiles or as zip files and contain a
8260 C<Makefile.PL> or C<Build.PL> (well, we try to handle a bit more, but
8261 without much enthusiasm).
8267 The debugging of this module is a bit complex, because we have
8268 interferences of the software producing the indices on CPAN, of the
8269 mirroring process on CPAN, of packaging, of configuration, of
8270 synchronicity, and of bugs within CPAN.pm.
8272 For debugging the code of CPAN.pm itself in interactive mode some more
8273 or less useful debugging aid can be turned on for most packages within
8278 =item o debug package...
8280 sets debug mode for packages.
8282 =item o debug -package...
8284 unsets debug mode for packages.
8288 turns debugging on for all packages.
8290 =item o debug number
8294 which sets the debugging packages directly. Note that C<o debug 0>
8295 turns debugging off.
8297 What seems quite a successful strategy is the combination of C<reload
8298 cpan> and the debugging switches. Add a new debug statement while
8299 running in the shell and then issue a C<reload cpan> and see the new
8300 debugging messages immediately without losing the current context.
8302 C<o debug> without an argument lists the valid package names and the
8303 current set of packages in debugging mode. C<o debug> has built-in
8306 For debugging of CPAN data there is the C<dump> command which takes
8307 the same arguments as make/test/install and outputs each object's
8308 Data::Dumper dump. If an argument looks like a perl variable and
8309 contains one of C<$>, C<@> or C<%>, it is eval()ed and fed to
8310 Data::Dumper directly.
8312 =head2 Floppy, Zip, Offline Mode
8314 CPAN.pm works nicely without network too. If you maintain machines
8315 that are not networked at all, you should consider working with file:
8316 URLs. Of course, you have to collect your modules somewhere first. So
8317 you might use CPAN.pm to put together all you need on a networked
8318 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
8319 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
8320 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
8321 with this floppy. See also below the paragraph about CD-ROM support.
8323 =head2 Basic Utilities for Programmers
8327 =item has_inst($module)
8329 Returns true if the module is installed. See the source for details.
8331 =item has_usable($module)
8333 Returns true if the module is installed and several and is in a usable
8334 state. Only useful for a handful of modules that are used internally.
8335 See the source for details.
8337 =item instance($module)
8339 The constructor for all the singletons used to represent modules,
8340 distributions, authors and bundles. If the object already exists, this
8341 method returns the object, otherwise it calls the constructor.
8345 =head1 CONFIGURATION
8347 When the CPAN module is used for the first time, a configuration
8348 dialog tries to determine a couple of site specific options. The
8349 result of the dialog is stored in a hash reference C< $CPAN::Config >
8350 in a file CPAN/Config.pm.
8352 The default values defined in the CPAN/Config.pm file can be
8353 overridden in a user specific file: CPAN/MyConfig.pm. Such a file is
8354 best placed in $HOME/.cpan/CPAN/MyConfig.pm, because $HOME/.cpan is
8355 added to the search path of the CPAN module before the use() or
8356 require() statements.
8358 The configuration dialog can be started any time later again by
8359 issuing the command C< o conf init > in the CPAN shell. A subset of
8360 the configuration dialog can be run by issuing C<o conf init WORD>
8361 where WORD is any valid config variable or a regular expression.
8363 Currently the following keys in the hash reference $CPAN::Config are
8366 build_cache size of cache for directories to build modules
8367 build_dir locally accessible directory to build modules
8368 build_requires_install_policy
8369 to install or not to install: when a module is
8370 only needed for building. yes|no|ask/yes|ask/no
8371 bzip2 path to external prg
8372 cache_metadata use serializer to cache metadata
8373 commands_quote prefered character to use for quoting external
8374 commands when running them. Defaults to double
8375 quote on Windows, single tick everywhere else;
8376 can be set to space to disable quoting
8377 check_sigs if signatures should be verified
8378 colorize_output boolean if Term::ANSIColor should colorize output
8379 colorize_print Term::ANSIColor attributes for normal output
8380 colorize_warn Term::ANSIColor attributes for warnings
8381 commandnumber_in_prompt
8382 boolean if you want to see current command number
8383 cpan_home local directory reserved for this package
8384 curl path to external prg
8385 dontload_hash DEPRECATED
8386 dontload_list arrayref: modules in the list will not be
8387 loaded by the CPAN::has_inst() routine
8388 ftp path to external prg
8389 ftp_passive if set, the envariable FTP_PASSIVE is set for downloads
8390 ftp_proxy proxy host for ftp requests
8392 gpg path to external prg
8393 gzip location of external program gzip
8394 histfile file to maintain history between sessions
8395 histsize maximum number of lines to keep in histfile
8396 http_proxy proxy host for http requests
8397 inactivity_timeout breaks interactive Makefile.PLs or Build.PLs
8398 after this many seconds inactivity. Set to 0 to
8400 index_expire after this many days refetch index files
8401 inhibit_startup_message
8402 if true, does not print the startup message
8403 keep_source_where directory in which to keep the source (if we do)
8404 lynx path to external prg
8405 make location of external make program
8406 make_arg arguments that should always be passed to 'make'
8407 make_install_make_command
8408 the make command for running 'make install', for
8410 make_install_arg same as make_arg for 'make install'
8411 makepl_arg arguments passed to 'perl Makefile.PL'
8412 mbuild_arg arguments passed to './Build'
8413 mbuild_install_arg arguments passed to './Build install'
8414 mbuild_install_build_command
8415 command to use instead of './Build' when we are
8416 in the install stage, for example 'sudo ./Build'
8417 mbuildpl_arg arguments passed to 'perl Build.PL'
8418 ncftp path to external prg
8419 ncftpget path to external prg
8420 no_proxy don't proxy to these hosts/domains (comma separated list)
8421 pager location of external program more (or any pager)
8422 password your password if you CPAN server wants one
8423 prefer_installer legal values are MB and EUMM: if a module comes
8424 with both a Makefile.PL and a Build.PL, use the
8425 former (EUMM) or the latter (MB); if the module
8426 comes with only one of the two, that one will be
8428 prerequisites_policy
8429 what to do if you are missing module prerequisites
8430 ('follow' automatically, 'ask' me, or 'ignore')
8431 proxy_user username for accessing an authenticating proxy
8432 proxy_pass password for accessing an authenticating proxy
8433 scan_cache controls scanning of cache ('atstart' or 'never')
8434 shell your favorite shell
8435 show_upload_date boolean if commands should try to determine upload date
8436 tar location of external program tar
8437 term_is_latin if true internal UTF-8 is translated to ISO-8859-1
8438 (and nonsense for characters outside latin range)
8439 term_ornaments boolean to turn ReadLine ornamenting on/off
8440 test_report email test reports (if CPAN::Reporter is installed)
8441 unzip location of external program unzip
8442 urllist arrayref to nearby CPAN sites (or equivalent locations)
8443 username your username if you CPAN server wants one
8444 wait_list arrayref to a wait server to try (See CPAN::WAIT)
8445 wget path to external prg
8447 You can set and query each of these options interactively in the cpan
8448 shell with the command set defined within the C<o conf> command:
8452 =item C<o conf E<lt>scalar optionE<gt>>
8454 prints the current value of the I<scalar option>
8456 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
8458 Sets the value of the I<scalar option> to I<value>
8460 =item C<o conf E<lt>list optionE<gt>>
8462 prints the current value of the I<list option> in MakeMaker's
8465 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
8467 shifts or pops the array in the I<list option> variable
8469 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
8471 works like the corresponding perl commands.
8475 =head2 CPAN::anycwd($path): Note on config variable getcwd
8477 CPAN.pm changes the current working directory often and needs to
8478 determine its own current working directory. Per default it uses
8479 Cwd::cwd but if this doesn't work on your system for some reason,
8480 alternatives can be configured according to the following table:
8498 Calls the external command cwd.
8502 =head2 Note on urllist parameter's format
8504 urllist parameters are URLs according to RFC 1738. We do a little
8505 guessing if your URL is not compliant, but if you have problems with
8506 file URLs, please try the correct format. Either:
8508 file://localhost/whatever/ftp/pub/CPAN/
8512 file:///home/ftp/pub/CPAN/
8514 =head2 urllist parameter has CD-ROM support
8516 The C<urllist> parameter of the configuration table contains a list of
8517 URLs that are to be used for downloading. If the list contains any
8518 C<file> URLs, CPAN always tries to get files from there first. This
8519 feature is disabled for index files. So the recommendation for the
8520 owner of a CD-ROM with CPAN contents is: include your local, possibly
8521 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
8523 o conf urllist push file://localhost/CDROM/CPAN
8525 CPAN.pm will then fetch the index files from one of the CPAN sites
8526 that come at the beginning of urllist. It will later check for each
8527 module if there is a local copy of the most recent version.
8529 Another peculiarity of urllist is that the site that we could
8530 successfully fetch the last file from automatically gets a preference
8531 token and is tried as the first site for the next request. So if you
8532 add a new site at runtime it may happen that the previously preferred
8533 site will be tried another time. This means that if you want to disallow
8534 a site for the next transfer, it must be explicitly removed from
8539 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
8540 install foreign, unmasked, unsigned code on your machine. We compare
8541 to a checksum that comes from the net just as the distribution file
8542 itself. But we try to make it easy to add security on demand:
8544 =head2 Cryptographically signed modules
8546 Since release 1.77 CPAN.pm has been able to verify cryptographically
8547 signed module distributions using Module::Signature. The CPAN modules
8548 can be signed by their authors, thus giving more security. The simple
8549 unsigned MD5 checksums that were used before by CPAN protect mainly
8550 against accidental file corruption.
8552 You will need to have Module::Signature installed, which in turn
8553 requires that you have at least one of Crypt::OpenPGP module or the
8554 command-line F<gpg> tool installed.
8556 You will also need to be able to connect over the Internet to the public
8557 keyservers, like pgp.mit.edu, and their port 11731 (the HKP protocol).
8559 The configuration parameter check_sigs is there to turn signature
8564 Most functions in package CPAN are exported per default. The reason
8565 for this is that the primary use is intended for the cpan shell or for
8570 When the CPAN shell enters a subshell via the look command, it sets
8571 the environment CPAN_SHELL_LEVEL to 1 or increments it if it is
8574 When the config variable ftp_passive is set, all downloads will be run
8575 with the environment variable FTP_PASSIVE set to this value. This is
8576 in general a good idea as it influences both Net::FTP and LWP based
8577 connections. The same effect can be achieved by starting the cpan
8578 shell with this environment variable set. For Net::FTP alone, one can
8579 also always set passive mode by running libnetcfg.
8581 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
8583 Populating a freshly installed perl with my favorite modules is pretty
8584 easy if you maintain a private bundle definition file. To get a useful
8585 blueprint of a bundle definition file, the command autobundle can be used
8586 on the CPAN shell command line. This command writes a bundle definition
8587 file for all modules that are installed for the currently running perl
8588 interpreter. It's recommended to run this command only once and from then
8589 on maintain the file manually under a private name, say
8590 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
8592 cpan> install Bundle::my_bundle
8594 then answer a few questions and then go out for a coffee.
8596 Maintaining a bundle definition file means keeping track of two
8597 things: dependencies and interactivity. CPAN.pm sometimes fails on
8598 calculating dependencies because not all modules define all MakeMaker
8599 attributes correctly, so a bundle definition file should specify
8600 prerequisites as early as possible. On the other hand, it's a bit
8601 annoying that many distributions need some interactive configuring. So
8602 what I try to accomplish in my private bundle file is to have the
8603 packages that need to be configured early in the file and the gentle
8604 ones later, so I can go out after a few minutes and leave CPAN.pm
8607 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
8609 Thanks to Graham Barr for contributing the following paragraphs about
8610 the interaction between perl, and various firewall configurations. For
8611 further information on firewalls, it is recommended to consult the
8612 documentation that comes with the ncftp program. If you are unable to
8613 go through the firewall with a simple Perl setup, it is very likely
8614 that you can configure ncftp so that it works for your firewall.
8616 =head2 Three basic types of firewalls
8618 Firewalls can be categorized into three basic types.
8624 This is where the firewall machine runs a web server and to access the
8625 outside world you must do it via the web server. If you set environment
8626 variables like http_proxy or ftp_proxy to a values beginning with http://
8627 or in your web browser you have to set proxy information then you know
8628 you are running an http firewall.
8630 To access servers outside these types of firewalls with perl (even for
8631 ftp) you will need to use LWP.
8635 This where the firewall machine runs an ftp server. This kind of
8636 firewall will only let you access ftp servers outside the firewall.
8637 This is usually done by connecting to the firewall with ftp, then
8638 entering a username like "user@outside.host.com"
8640 To access servers outside these type of firewalls with perl you
8641 will need to use Net::FTP.
8643 =item One way visibility
8645 I say one way visibility as these firewalls try to make themselves look
8646 invisible to the users inside the firewall. An FTP data connection is
8647 normally created by sending the remote server your IP address and then
8648 listening for the connection. But the remote server will not be able to
8649 connect to you because of the firewall. So for these types of firewall
8650 FTP connections need to be done in a passive mode.
8652 There are two that I can think off.
8658 If you are using a SOCKS firewall you will need to compile perl and link
8659 it with the SOCKS library, this is what is normally called a 'socksified'
8660 perl. With this executable you will be able to connect to servers outside
8661 the firewall as if it is not there.
8665 This is the firewall implemented in the Linux kernel, it allows you to
8666 hide a complete network behind one IP address. With this firewall no
8667 special compiling is needed as you can access hosts directly.
8669 For accessing ftp servers behind such firewalls you usually need to
8670 set the environment variable C<FTP_PASSIVE> or the config variable
8671 ftp_passive to a true value.
8677 =head2 Configuring lynx or ncftp for going through a firewall
8679 If you can go through your firewall with e.g. lynx, presumably with a
8682 /usr/local/bin/lynx -pscott:tiger
8684 then you would configure CPAN.pm with the command
8686 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
8688 That's all. Similarly for ncftp or ftp, you would configure something
8691 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
8693 Your mileage may vary...
8701 I installed a new version of module X but CPAN keeps saying,
8702 I have the old version installed
8704 Most probably you B<do> have the old version installed. This can
8705 happen if a module installs itself into a different directory in the
8706 @INC path than it was previously installed. This is not really a
8707 CPAN.pm problem, you would have the same problem when installing the
8708 module manually. The easiest way to prevent this behaviour is to add
8709 the argument C<UNINST=1> to the C<make install> call, and that is why
8710 many people add this argument permanently by configuring
8712 o conf make_install_arg UNINST=1
8716 So why is UNINST=1 not the default?
8718 Because there are people who have their precise expectations about who
8719 may install where in the @INC path and who uses which @INC array. In
8720 fine tuned environments C<UNINST=1> can cause damage.
8724 I want to clean up my mess, and install a new perl along with
8725 all modules I have. How do I go about it?
8727 Run the autobundle command for your old perl and optionally rename the
8728 resulting bundle file (e.g. Bundle/mybundle.pm), install the new perl
8729 with the Configure option prefix, e.g.
8731 ./Configure -Dprefix=/usr/local/perl-5.6.78.9
8733 Install the bundle file you produced in the first step with something like
8735 cpan> install Bundle::mybundle
8741 When I install bundles or multiple modules with one command
8742 there is too much output to keep track of.
8744 You may want to configure something like
8746 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
8747 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
8749 so that STDOUT is captured in a file for later inspection.
8754 I am not root, how can I install a module in a personal directory?
8756 First of all, you will want to use your own configuration, not the one
8757 that your root user installed. If you do not have permission to write
8758 in the cpan directory that root has configured, you will be asked if
8759 you want to create your own config. Answering "yes" will bring you into
8760 CPAN's configuration stage, using the system config for all defaults except
8761 things that have to do with CPAN's work directory, saving your choices to
8762 your MyConfig.pm file.
8764 You can also manually initiate this process with the following command:
8766 % perl -MCPAN -e 'mkmyconfig'
8772 from the CPAN shell.
8774 You will most probably also want to configure something like this:
8776 o conf makepl_arg "LIB=~/myperl/lib \
8777 INSTALLMAN1DIR=~/myperl/man/man1 \
8778 INSTALLMAN3DIR=~/myperl/man/man3"
8780 You can make this setting permanent like all C<o conf> settings with
8783 You will have to add ~/myperl/man to the MANPATH environment variable
8784 and also tell your perl programs to look into ~/myperl/lib, e.g. by
8787 use lib "$ENV{HOME}/myperl/lib";
8789 or setting the PERL5LIB environment variable.
8791 While we're speaking about $ENV{HOME}, it might be worth mentioning,
8792 that for Windows we use the File::HomeDir module that provides an
8793 equivalent to the concept of the home directory on Unix.
8795 Another thing you should bear in mind is that the UNINST parameter can
8796 be dnagerous when you are installing into a private area because you
8797 might accidentally remove modules that other people depend on that are
8798 not using the private area.
8802 How to get a package, unwrap it, and make a change before building it?
8804 Have a look at the C<look> (!) command.
8808 I installed a Bundle and had a couple of fails. When I
8809 retried, everything resolved nicely. Can this be fixed to work
8812 The reason for this is that CPAN does not know the dependencies of all
8813 modules when it starts out. To decide about the additional items to
8814 install, it just uses data found in the META.yml file or the generated
8815 Makefile. An undetected missing piece breaks the process. But it may
8816 well be that your Bundle installs some prerequisite later than some
8817 depending item and thus your second try is able to resolve everything.
8818 Please note, CPAN.pm does not know the dependency tree in advance and
8819 cannot sort the queue of things to install in a topologically correct
8820 order. It resolves perfectly well IF all modules declare the
8821 prerequisites correctly with the PREREQ_PM attribute to MakeMaker or
8822 the C<requires> stanza of Module::Build. For bundles which fail and
8823 you need to install often, it is recommended to sort the Bundle
8824 definition file manually.
8828 In our intranet we have many modules for internal use. How
8829 can I integrate these modules with CPAN.pm but without uploading
8830 the modules to CPAN?
8832 Have a look at the CPAN::Site module.
8836 When I run CPAN's shell, I get an error message about things in my
8837 /etc/inputrc (or ~/.inputrc) file.
8839 These are readline issues and can only be fixed by studying readline
8840 configuration on your architecture and adjusting the referenced file
8841 accordingly. Please make a backup of the /etc/inputrc or ~/.inputrc
8842 and edit them. Quite often harmless changes like uppercasing or
8843 lowercasing some arguments solves the problem.
8847 Some authors have strange characters in their names.
8849 Internally CPAN.pm uses the UTF-8 charset. If your terminal is
8850 expecting ISO-8859-1 charset, a converter can be activated by setting
8851 term_is_latin to a true value in your config file. One way of doing so
8854 cpan> o conf term_is_latin 1
8856 If other charset support is needed, please file a bugreport against
8857 CPAN.pm at rt.cpan.org and describe your needs. Maybe we can extend
8858 the support or maybe UTF-8 terminals become widely available.
8862 When an install fails for some reason and then I correct the error
8863 condition and retry, CPAN.pm refuses to install the module, saying
8864 C<Already tried without success>.
8866 Use the force pragma like so
8868 force install Foo::Bar
8870 This does a bit more than really needed because it untars the
8871 distribution again and runs make and test and only then install.
8873 Or, if you find this is too fast and you would prefer to do smaller
8878 first and then continue as always. C<Force get> I<forgets> previous
8885 and then 'make install' directly in the subshell.
8887 Or you leave the CPAN shell and start it again.
8889 For the really curious, by accessing internals directly, you I<could>
8891 !delete CPAN::Shell->expandany("Foo::Bar")->distribution->{install}
8893 but this is neither guaranteed to work in the future nor is it a
8898 How do I install a "DEVELOPER RELEASE" of a module?
8900 By default, CPAN will install the latest non-developer release of a
8901 module. If you want to install a dev release, you have to specify the
8902 partial path starting with the author id to the tarball you wish to
8905 cpan> install KWILLIAMS/Module-Build-0.27_07.tar.gz
8907 Note that you can use the C<ls> command to get this path listed.
8911 How do I install a module and all its dependencies from the commandline,
8912 without being prompted for anything, despite my CPAN configuration
8915 CPAN uses ExtUtils::MakeMaker's prompt() function to ask its questions, so
8916 if you set the PERL_MM_USE_DEFAULT environment variable, you shouldn't be
8917 asked any questions at all (assuming the modules you are installing are
8918 nice about obeying that variable as well):
8920 % PERL_MM_USE_DEFAULT=1 perl -MCPAN -e 'install My::Module'
8924 How do I create a Module::Build based Build.PL derived from an
8925 ExtUtils::MakeMaker focused Makefile.PL?
8927 http://search.cpan.org/search?query=Module::Build::Convert
8929 http://accognoscere.org/papers/perl-module-build-convert/module-build-convert.html
8936 Please report bugs via http://rt.cpan.org/
8938 Before submitting a bug, please make sure that the traditional method
8939 of building a Perl module package from a shell by following the
8940 installation instructions of that package still works in your
8943 =head1 SECURITY ADVICE
8945 This software enables you to upgrade software on your computer and so
8946 is inherently dangerous because the newly installed software may
8947 contain bugs and may alter the way your computer works or even make it
8948 unusable. Please consider backing up your data before every upgrade.
8952 Andreas Koenig C<< <andk@cpan.org> >>
8956 This program is free software; you can redistribute it and/or
8957 modify it under the same terms as Perl itself.
8959 See L<http://www.perl.com/perl/misc/Artistic.html>
8963 Kawai,Takanori provides a Japanese translation of this manpage at
8964 http://member.nifty.ne.jp/hippo2000/perltips/CPAN.htm
8968 cpan(1), CPAN::Nox(3pm), CPAN::Version(3pm)