2 use vars qw{$Try_autoload $Revision
3 $META $Signal $Cwd $End
4 $Suppress_readline %Dontload
10 # $Id: CPAN.pm,v 1.239 1998/07/24 16:37:04 k Exp $
12 # only used during development:
14 # $Revision = "[".substr(q$Revision: 1.239 $, 10)."]";
21 use ExtUtils::MakeMaker (); # $SelfLoader::DEBUG=1;
22 use File::Basename ();
28 use Text::ParseWords ();
31 END { $End++; &cleanup; }
52 $CPAN::Frontend ||= "CPAN::Shell";
53 $CPAN::Defaultsite ||= "ftp://ftp.perl.org/pub/CPAN";
56 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $term);
59 @CPAN::ISA = qw(CPAN::Debug Exporter);
62 autobundle bundle expand force get
63 install make readme recompile shell test clean
66 #-> sub CPAN::AUTOLOAD ;
71 @EXPORT{@EXPORT} = '';
72 if (exists $EXPORT{$l}){
75 my $ok = CPAN::Shell->try_dot_al($AUTOLOAD);
79 # $CPAN::Frontend->mywarn("Could not autoload $AUTOLOAD");
81 $CPAN::Frontend->mywarn(qq{Unknown command "$AUTOLOAD". }.
89 $Suppress_readline ||= ! -t STDIN;
91 my $prompt = "cpan> ";
93 unless ($Suppress_readline) {
94 require Term::ReadLine;
95 # import Term::ReadLine;
96 $term = Term::ReadLine->new('CPAN Monitor');
97 $readline::rl_completion_function =
98 $readline::rl_completion_function = 'CPAN::Complete::cpl';
104 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
105 my $cwd = CPAN->$getcwd();
106 my $rl_avail = $Suppress_readline ? "suppressed" :
107 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
108 "available (try ``install Bundle::CPAN'')";
110 $CPAN::Frontend->myprint(
112 cpan shell -- CPAN exploration and modules installation (v$CPAN::VERSION$CPAN::Revision)
113 ReadLine support $rl_avail
115 }) unless $CPAN::Config->{'inhibit_startup_message'} ;
116 my($continuation) = "";
118 if ($Suppress_readline) {
120 last unless defined ($_ = <> );
123 last unless defined ($_ = $term->readline($prompt));
125 $_ = "$continuation$_" if $continuation;
128 $_ = 'h' if /^\s*\?/;
129 if (/^(?:q(?:uit)?|bye|exit)$/i) {
139 use vars qw($import_done);
140 CPAN->import(':DEFAULT') unless $import_done++;
141 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
148 if ($] < 5.00322) { # parsewords had a bug until recently
151 eval { @line = Text::ParseWords::shellwords($_) };
152 warn($@), next if $@;
154 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
155 my $command = shift @line;
156 eval { CPAN::Shell->$command(@line) };
159 $CPAN::Frontend->myprint("\n");
168 package CPAN::CacheMgr;
169 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
172 package CPAN::Config;
173 import ExtUtils::MakeMaker 'neatvalue';
174 use vars qw(%can $dot_cpan);
177 'commit' => "Commit changes to disk",
178 'defaults' => "Reload defaults from disk",
179 'init' => "Interactive setting of all options",
183 use vars qw($Ua $Thesite $Themethod);
184 @CPAN::FTP::ISA = qw(CPAN::Debug);
186 package CPAN::Complete;
187 @CPAN::Complete::ISA = qw(CPAN::Debug);
190 use vars qw($last_time $date_of_03);
191 @CPAN::Index::ISA = qw(CPAN::Debug);
195 package CPAN::InfoObj;
196 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
198 package CPAN::Author;
199 @CPAN::Author::ISA = qw(CPAN::InfoObj);
201 package CPAN::Distribution;
202 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
204 package CPAN::Bundle;
205 @CPAN::Bundle::ISA = qw(CPAN::Module);
207 package CPAN::Module;
208 @CPAN::Module::ISA = qw(CPAN::InfoObj);
211 use vars qw($AUTOLOAD $redef @ISA);
212 @CPAN::Shell::ISA = qw(CPAN::Debug);
214 #-> sub CPAN::Shell::AUTOLOAD ;
216 my($autoload) = $AUTOLOAD;
217 my $class = shift(@_);
218 # warn "autoload[$autoload] class[$class]";
219 $autoload =~ s/.*:://;
220 if ($autoload =~ /^w/) {
221 if ($CPAN::META->has_inst('CPAN::WAIT')) {
222 CPAN::WAIT->$autoload(@_);
224 $CPAN::Frontend->mywarn(qq{
225 Commands starting with "w" require CPAN::WAIT to be installed.
226 Please consider installing CPAN::WAIT to use the fulltext index.
227 For this you just need to type
232 my $ok = CPAN::Shell->try_dot_al($AUTOLOAD);
236 # $CPAN::Frontend->mywarn("Could not autoload $autoload");
238 $CPAN::Frontend->mywarn(qq{Unknown command '$autoload'. }.
244 #-> CPAN::Shell::try_dot_al
246 my($class,$autoload) = @_;
247 return unless $CPAN::Try_autoload;
248 # I don't see how to re-use that from the AutoLoader...
250 # Braces used to preserve $1 et al.
252 my ($pkg,$func) = $autoload =~ /(.*)::([^:]+)$/;
254 if (defined($name=$INC{"$pkg.pm"}))
256 $name =~ s|^(.*)$pkg\.pm$|$1auto/$pkg/$func.al|;
257 $name = undef unless (-r $name);
259 unless (defined $name)
261 $name = "auto/$autoload.al";
266 eval {local $SIG{__DIE__};require $name};
268 if (substr($autoload,-9) eq '::DESTROY') {
272 if ($name =~ s/(\w{12,})\.al$/substr($1,0,11).".al"/e){
273 eval {local $SIG{__DIE__};require $name};
288 # my $lm = Carp::longmess();
289 # warn "ok[$ok] autoload[$autoload] longmess[$lm]"; # debug
293 #### autoloader is experimental
294 #### to try it we have to set $Try_autoload and uncomment
295 #### the use statement and uncomment the __END__ below
296 #### You also need AutoSplit 1.01 available. MakeMaker will
297 #### then build CPAN with all the AutoLoad stuff.
301 if ($CPAN::Try_autoload) {
304 CPAN::Author CPAN::Bundle CPAN::CacheMgr CPAN::Complete
305 CPAN::Config CPAN::Debug CPAN::Distribution CPAN::FTP
306 CPAN::FTP::netrc CPAN::Index CPAN::InfoObj CPAN::Module
308 *{"$p\::AUTOLOAD"} = \&AutoLoader::AUTOLOAD;
312 package CPAN::Tarzip;
313 use vars qw($AUTOLOAD @ISA);
314 @CPAN::Tarzip::ISA = qw(CPAN::Debug);
317 # currently only used to determine if we should or shouldn't announce
318 # the availability of a new CPAN module
320 my($class,$mod) = @_;
321 # warn "Queue object for mod[$mod]";
322 bless {mod => $mod}, $class;
327 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
329 # Do this after you have set up the whole inheritance
330 CPAN::Config->load unless defined $CPAN::No_Config_is_ok;
334 # __END__ # uncomment this and AutoSplit version 1.01 will split it
336 #-> sub CPAN::autobundle ;
338 #-> sub CPAN::bundle ;
340 #-> sub CPAN::expand ;
342 #-> sub CPAN::force ;
344 #-> sub CPAN::install ;
348 #-> sub CPAN::clean ;
355 my($mgr,$class) = @_;
356 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
358 values %{ $META->{$class} };
361 # Called by shell, not in batch mode. Not clean XXX
362 #-> sub CPAN::checklock ;
365 my $lockfile = MM->catfile($CPAN::Config->{cpan_home},".lock");
366 if (-f $lockfile && -M _ > 0) {
367 my $fh = FileHandle->new($lockfile);
370 if (defined $other && $other) {
372 return if $$==$other; # should never happen
373 $CPAN::Frontend->mywarn(
375 There seems to be running another CPAN process ($other). Contacting...
377 if (kill 0, $other) {
378 $CPAN::Frontend->mydie(qq{Other job is running.
379 You may want to kill it and delete the lockfile, maybe. On UNIX try:
383 } elsif (-w $lockfile) {
385 ExtUtils::MakeMaker::prompt
386 (qq{Other job not responding. Shall I overwrite }.
387 qq{the lockfile? (Y/N)},"y");
388 $CPAN::Frontend->myexit("Ok, bye\n")
389 unless $ans =~ /^y/i;
392 qq{Lockfile $lockfile not writeable by you. }.
393 qq{Cannot proceed.\n}.
396 qq{ and then rerun us.\n}
401 File::Path::mkpath($CPAN::Config->{cpan_home});
403 unless ($fh = FileHandle->new(">$lockfile")) {
404 if ($! =~ /Permission/) {
405 my $incc = $INC{'CPAN/Config.pm'};
406 my $myincc = MM->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
407 $CPAN::Frontend->myprint(qq{
409 Your configuration suggests that CPAN.pm should use a working
411 $CPAN::Config->{cpan_home}
412 Unfortunately we could not create the lock file
414 due to permission problems.
416 Please make sure that the configuration variable
417 \$CPAN::Config->{cpan_home}
418 points to a directory where you can write a .lock file. You can set
419 this variable in either
426 $CPAN::Frontend->mydie("Could not open >$lockfile: $!");
428 $fh->print($$, "\n");
429 $self->{LOCK} = $lockfile;
433 $CPAN::Frontend->mydie("Got SIGTERM, leaving");
438 $CPAN::Frontend->mydie("Got another SIGINT") if $Signal;
439 print "Caught SIGINT\n";
442 $SIG{'__DIE__'} = \&cleanup;
443 $self->debug("Signal handler set.") if $CPAN::DEBUG;
446 #-> sub CPAN::DESTROY ;
448 &cleanup; # need an eval?
452 sub cwd {Cwd::cwd();}
454 #-> sub CPAN::getcwd ;
455 sub getcwd {Cwd::getcwd();}
457 #-> sub CPAN::exists ;
459 my($mgr,$class,$id) = @_;
461 ### Carp::croak "exists called without class argument" unless $class;
463 exists $META->{$class}{$id};
466 #-> sub CPAN::delete ;
468 my($mgr,$class,$id) = @_;
469 delete $META->{$class}{$id};
472 #-> sub CPAN::has_inst
474 my($self,$mod,$message) = @_;
475 Carp::croak("CPAN->has_inst() called without an argument")
477 if (defined $message && $message eq "no") {
480 } elsif (exists $Dontload{$mod}) {
486 $file =~ s|/|\\|g if $^O eq 'MSWin32';
489 # warn "$file in %INC"; #debug
491 } elsif (eval { require $file }) {
492 # eval is good: if we haven't yet read the database it's
493 # perfect and if we have installed the module in the meantime,
494 # it tries again. The second require is only a NOOP returning
495 # 1 if we had success, otherwise it's retrying
496 $CPAN::Frontend->myprint("CPAN: $mod loaded ok\n");
497 if ($mod eq "CPAN::WAIT") {
498 push @CPAN::Shell::ISA, CPAN::WAIT;
501 } elsif ($mod eq "Net::FTP") {
503 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
505 install Bundle::libnet
509 } elsif ($mod eq "MD5"){
510 $CPAN::Frontend->myprint(qq{
511 CPAN: MD5 security checks disabled because MD5 not installed.
512 Please consider installing the MD5 module.
520 #-> sub CPAN::instance ;
522 my($mgr,$class,$id) = @_;
525 $META->{$class}{$id} ||= $class->new(ID => $id );
533 #-> sub CPAN::cleanup ;
535 # warn "cleanup called with arg[@_] End[$End] Signal[$Signal]";
536 local $SIG{__DIE__} = '';
541 0 && # disabled, try reload cpan with it
542 $] > 5.004_60 # thereabouts
547 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
549 $subroutine eq '(eval)';
552 return if $ineval && !$End;
553 return unless defined $META->{'LOCK'};
554 return unless -f $META->{'LOCK'};
555 unlink $META->{'LOCK'};
557 # Carp::cluck("DEBUGGING");
558 $CPAN::Frontend->mywarn("Lockfile removed.\n");
561 package CPAN::CacheMgr;
563 #-> sub CPAN::CacheMgr::as_string ;
565 eval { require Data::Dumper };
567 return shift->SUPER::as_string;
569 return Data::Dumper::Dumper(shift);
573 #-> sub CPAN::CacheMgr::cachesize ;
580 return unless -d $self->{ID};
581 while ($self->{DU} > $self->{'MAX'} ) {
582 my($toremove) = shift @{$self->{FIFO}};
583 $CPAN::Frontend->myprint(sprintf(
584 "Deleting from cache".
585 ": $toremove (%.1f>%.1f MB)\n",
586 $self->{DU}, $self->{'MAX'})
588 return if $CPAN::Signal;
589 $self->force_clean_cache($toremove);
590 return if $CPAN::Signal;
594 #-> sub CPAN::CacheMgr::dir ;
599 #-> sub CPAN::CacheMgr::entries ;
602 return unless defined $dir;
603 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
604 $dir ||= $self->{ID};
606 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
607 my($cwd) = CPAN->$getcwd();
608 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
609 my $dh = DirHandle->new(".") or Carp::croak("Couldn't opendir $dir: $!");
612 next if $_ eq "." || $_ eq "..";
614 push @entries, MM->catfile($dir,$_);
616 push @entries, MM->catdir($dir,$_);
618 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
621 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
622 sort { -M $b <=> -M $a} @entries;
625 #-> sub CPAN::CacheMgr::disk_usage ;
628 return if exists $self->{SIZE}{$dir};
629 return if $CPAN::Signal;
633 $File::Find::prune++ if $CPAN::Signal;
639 return if $CPAN::Signal;
640 $self->{SIZE}{$dir} = $Du/1024/1024;
641 push @{$self->{FIFO}}, $dir;
642 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
643 $self->{DU} += $Du/1024/1024;
647 #-> sub CPAN::CacheMgr::force_clean_cache ;
648 sub force_clean_cache {
650 return unless -e $dir;
651 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
653 File::Path::rmtree($dir);
654 $self->{DU} -= $self->{SIZE}{$dir};
655 delete $self->{SIZE}{$dir};
658 #-> sub CPAN::CacheMgr::new ;
665 ID => $CPAN::Config->{'build_dir'},
666 MAX => $CPAN::Config->{'build_cache'},
669 File::Path::mkpath($self->{ID});
670 my $dh = DirHandle->new($self->{ID});
673 $CPAN::Frontend->myprint(
674 sprintf("Scanning cache %s for sizes\n",
676 for $e ($self->entries($self->{ID})) {
677 next if $e eq ".." || $e eq ".";
678 $self->disk_usage($e);
679 return if $CPAN::Signal;
683 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
685 CPAN->debug($debug) if $CPAN::DEBUG;
691 #-> sub CPAN::Debug::debug ;
694 my($caller,$func,$line,@rest) = caller(1); # caller(0) eg
695 # Complete, caller(1)
697 ($caller) = caller(0);
699 $arg = "" unless defined $arg;
700 my $rest = join "|", map { defined $_ ? $_ : "UNDEF" } @rest;
701 if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
702 if ($arg and ref $arg) {
703 eval { require Data::Dumper };
705 $CPAN::Frontend->myprint($arg->as_string);
707 $CPAN::Frontend->myprint(Data::Dumper::Dumper($arg));
710 $CPAN::Frontend->myprint("Debug($caller:$func,$line,[$rest]): $arg\n");
715 package CPAN::Config;
717 #-> sub CPAN::Config::edit ;
719 my($class,@args) = @_;
721 CPAN->debug("class[$class]args[".join(" | ",@args)."]");
722 my($o,$str,$func,$args,$key_exists);
728 if (ref($CPAN::Config->{$o}) eq ARRAY) {
731 # Let's avoid eval, it's easier to comprehend without.
732 if ($func eq "push") {
733 push @{$CPAN::Config->{$o}}, @args;
734 } elsif ($func eq "pop") {
735 pop @{$CPAN::Config->{$o}};
736 } elsif ($func eq "shift") {
737 shift @{$CPAN::Config->{$o}};
738 } elsif ($func eq "unshift") {
739 unshift @{$CPAN::Config->{$o}}, @args;
740 } elsif ($func eq "splice") {
741 splice @{$CPAN::Config->{$o}}, @args;
743 $CPAN::Config->{$o} = [@args];
745 $CPAN::Frontend->myprint(
748 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$o}),
753 $CPAN::Config->{$o} = $args[0] if defined $args[0];
754 $CPAN::Frontend->myprint(" $o " .
755 (defined $CPAN::Config->{$o} ?
756 $CPAN::Config->{$o} : "UNDEFINED"));
761 #-> sub CPAN::Config::commit ;
763 my($self,$configpm) = @_;
764 unless (defined $configpm){
765 $configpm ||= $INC{"CPAN/MyConfig.pm"};
766 $configpm ||= $INC{"CPAN/Config.pm"};
767 $configpm || Carp::confess(q{
768 CPAN::Config::commit called without an argument.
769 Please specify a filename where to save the configuration or try
770 "o conf init" to have an interactive course through configing.
775 $mode = (stat $configpm)[2];
776 if ($mode && ! -w _) {
777 Carp::confess("$configpm is not writable");
781 my $msg = <<EOF unless $configpm =~ /MyConfig/;
783 # This is CPAN.pm's systemwide configuration file. This file provides
784 # defaults for users, and the values can be changed in a per-user
785 # configuration file. The user-config file is being looked for as
786 # ~/.cpan/CPAN/MyConfig.pm.
790 my($fh) = FileHandle->new;
791 open $fh, ">$configpm" or warn "Couldn't open >$configpm: $!";
792 $fh->print(qq[$msg\$CPAN::Config = \{\n]);
793 foreach (sort keys %$CPAN::Config) {
796 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}),
801 $fh->print("};\n1;\n__END__\n");
804 #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
805 #chmod $mode, $configpm;
806 ###why was that so? $self->defaults;
807 $CPAN::Frontend->myprint("commit: wrote $configpm\n");
811 *default = \&defaults;
812 #-> sub CPAN::Config::defaults ;
822 undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
831 #-> sub CPAN::Config::load ;
835 eval {require CPAN::Config;}; # We eval because of some
837 unless ($dot_cpan++){
838 unshift @INC, MM->catdir($ENV{HOME},".cpan");
839 eval {require CPAN::MyConfig;}; # where you can override
840 # system wide settings
843 return unless @miss = $self->not_loaded;
844 # XXX better check for arrayrefs too
845 require CPAN::FirstTime;
846 my($configpm,$fh,$redo,$theycalled);
848 $theycalled++ if @miss==1 && $miss[0] eq 'inhibit_startup_message';
849 if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
850 $configpm = $INC{"CPAN/Config.pm"};
852 } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
853 $configpm = $INC{"CPAN/MyConfig.pm"};
856 my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
857 my($configpmdir) = MM->catdir($path_to_cpan,"CPAN");
858 my($configpmtest) = MM->catfile($configpmdir,"Config.pm");
859 if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
860 if (-w $configpmtest) {
861 $configpm = $configpmtest;
862 } elsif (-w $configpmdir) {
863 #_#_# following code dumped core on me with 5.003_11, a.k.
864 unlink "$configpmtest.bak" if -f "$configpmtest.bak";
865 rename $configpmtest, "$configpmtest.bak" if -f $configpmtest;
866 my $fh = FileHandle->new;
867 if ($fh->open(">$configpmtest")) {
869 $configpm = $configpmtest;
871 # Should never happen
872 Carp::confess("Cannot open >$configpmtest");
877 $configpmdir = MM->catdir($ENV{HOME},".cpan","CPAN");
878 File::Path::mkpath($configpmdir);
879 $configpmtest = MM->catfile($configpmdir,"MyConfig.pm");
880 if (-w $configpmtest) {
881 $configpm = $configpmtest;
882 } elsif (-w $configpmdir) {
883 #_#_# following code dumped core on me with 5.003_11, a.k.
884 my $fh = FileHandle->new;
885 if ($fh->open(">$configpmtest")) {
887 $configpm = $configpmtest;
889 # Should never happen
890 Carp::confess("Cannot open >$configpmtest");
893 Carp::confess(qq{WARNING: CPAN.pm is unable to }.
894 qq{create a configuration file.});
899 $CPAN::Frontend->myprint(qq{
900 We have to reconfigure CPAN.pm due to following uninitialized parameters:
903 }) if $redo && ! $theycalled;
904 $CPAN::Frontend->myprint(qq{
905 $configpm initialized.
908 CPAN::FirstTime::init($configpm);
911 #-> sub CPAN::Config::not_loaded ;
915 cpan_home keep_source_where build_dir build_cache index_expire
916 gzip tar unzip make pager makepl_arg make_arg make_install_arg
917 urllist inhibit_startup_message ftp_proxy http_proxy no_proxy
919 push @miss, $_ unless defined $CPAN::Config->{$_};
924 #-> sub CPAN::Config::unload ;
926 delete $INC{'CPAN/MyConfig.pm'};
927 delete $INC{'CPAN/Config.pm'};
930 #-> sub CPAN::Config::help ;
932 $CPAN::Frontend->myprint(q[
934 defaults reload default config values from disk
935 commit commit session changes to disk
936 init go through a dialog to set all parameters
938 You may edit key values in the follow fashion:
940 o conf build_cache 15
942 o conf build_dir "/foo/bar"
946 o conf urllist unshift ftp://ftp.foo.bar/
949 undef; #don't reprint CPAN::Config
952 #-> sub CPAN::Config::cpl ;
954 my($word,$line,$pos) = @_;
956 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
957 my(@words) = split " ", substr($line,0,$pos+1);
962 $words[2] =~ /list$/ && @words == 3
964 $words[2] =~ /list$/ && @words == 4 && length($word)
967 return grep /^\Q$word\E/, qw(splice shift unshift pop push);
968 } elsif (@words >= 4) {
971 my(@o_conf) = (keys %CPAN::Config::can, keys %$CPAN::Config);
972 return grep /^\Q$word\E/, @o_conf;
977 #-> sub CPAN::Shell::h ;
979 my($class,$about) = @_;
980 if (defined $about) {
981 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
983 $CPAN::Frontend->myprint(q{
984 command arguments description
987 d /regex/ info distributions
989 i none anything of above
991 r as reinstall recommendations
992 u above uninstalled distributions
993 See manpage for autobundle, recompile, force, look, etc.
996 test modules, make test (implies make)
997 install dists, bundles, make install (implies test)
998 clean "r" or "u" make clean
999 readme display the README file
1001 reload index|cpan load most recent indices/CPAN.pm
1002 h or ? display this menu
1003 o various set and query options
1004 ! perl-code eval a perl command
1005 q quit the shell subroutine
1012 #-> sub CPAN::Shell::a ;
1013 sub a { $CPAN::Frontend->myprint(shift->format_result('Author',@_));}
1014 #-> sub CPAN::Shell::b ;
1016 my($self,@which) = @_;
1017 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1018 my($incdir,$bdir,$dh);
1019 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1020 $bdir = MM->catdir($incdir,"Bundle");
1021 if ($dh = DirHandle->new($bdir)) { # may fail
1023 for $entry ($dh->read) {
1024 next if -d MM->catdir($bdir,$entry);
1025 next unless $entry =~ s/\.pm$//;
1026 $CPAN::META->instance('CPAN::Bundle',"Bundle::$entry");
1030 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1032 #-> sub CPAN::Shell::d ;
1033 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1034 #-> sub CPAN::Shell::m ;
1035 sub m { $CPAN::Frontend->myprint(shift->format_result('Module',@_));}
1037 #-> sub CPAN::Shell::i ;
1042 @type = qw/Author Bundle Distribution Module/;
1043 @args = '/./' unless @args;
1046 push @result, $self->expand($type,@args);
1048 my $result = @result == 1 ?
1049 $result[0]->as_string :
1050 join "", map {$_->as_glimpse} @result;
1051 $result ||= "No objects found of any type for argument @args\n";
1052 $CPAN::Frontend->myprint($result);
1055 #-> sub CPAN::Shell::o ;
1057 my($self,$o_type,@o_what) = @_;
1059 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1060 if ($o_type eq 'conf') {
1061 shift @o_what if @o_what && $o_what[0] eq 'help';
1064 $CPAN::Frontend->myprint("CPAN::Config options");
1065 if (exists $INC{'CPAN/Config.pm'}) {
1066 $CPAN::Frontend->myprint(" from $INC{'CPAN/Config.pm'}");
1068 if (exists $INC{'CPAN/MyConfig.pm'}) {
1069 $CPAN::Frontend->myprint(" and $INC{'CPAN/MyConfig.pm'}");
1071 $CPAN::Frontend->myprint(":\n");
1072 for $k (sort keys %CPAN::Config::can) {
1073 $v = $CPAN::Config::can{$k};
1074 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1076 $CPAN::Frontend->myprint("\n");
1077 for $k (sort keys %$CPAN::Config) {
1078 $v = $CPAN::Config->{$k};
1080 $CPAN::Frontend->myprint(
1087 map {"\t$_\n"} @{$v}
1091 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1094 $CPAN::Frontend->myprint("\n");
1095 } elsif (!CPAN::Config->edit(@o_what)) {
1096 $CPAN::Frontend->myprint(qq[Type 'o conf' to view configuration edit options\n\n]);
1098 } elsif ($o_type eq 'debug') {
1100 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1103 my($what) = shift @o_what;
1104 if ( exists $CPAN::DEBUG{$what} ) {
1105 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1106 } elsif ($what =~ /^\d/) {
1107 $CPAN::DEBUG = $what;
1108 } elsif (lc $what eq 'all') {
1110 for (values %CPAN::DEBUG) {
1113 $CPAN::DEBUG = $max;
1116 for (keys %CPAN::DEBUG) {
1117 next unless lc($_) eq lc($what);
1118 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1121 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1126 $CPAN::Frontend->myprint("Valid options for debug are ".
1127 join(", ",sort(keys %CPAN::DEBUG), 'all').
1128 qq{ or a number. Completion works on the options. }.
1129 qq{Case is ignored.\n\n});
1132 $CPAN::Frontend->myprint("Options set for debugging:\n");
1134 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1135 $v = $CPAN::DEBUG{$k};
1136 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v) if $v & $CPAN::DEBUG;
1139 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1142 $CPAN::Frontend->myprint(qq{
1144 conf set or get configuration variables
1145 debug set or get debugging options
1150 #-> sub CPAN::Shell::reload ;
1152 my($self,$command,@arg) = @_;
1154 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1155 if ($command =~ /cpan/i) {
1156 CPAN->debug("reloading the whole CPAN.pm") if $CPAN::DEBUG;
1157 my $fh = FileHandle->new($INC{'CPAN.pm'});
1160 local($SIG{__WARN__})
1162 if ( $_[0] =~ /Subroutine (\w+) redefined/ ) {
1166 # $CPAN::Frontend->myprint(".($subr)");
1167 $CPAN::Frontend->myprint(".");
1174 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1175 } elsif ($command =~ /index/) {
1176 CPAN::Index->force_reload;
1178 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN.pm file
1179 index re-reads the index files
1184 #-> sub CPAN::Shell::_binary_extensions ;
1185 sub _binary_extensions {
1186 my($self) = shift @_;
1187 my(@result,$module,%seen,%need,$headerdone);
1188 my $isaperl = q{perl5[._-]\\d{3}(_[0-4][0-9])?\\.tar[._-]gz$};
1189 for $module ($self->expand('Module','/./')) {
1190 my $file = $module->cpan_file;
1191 next if $file eq "N/A";
1192 next if $file =~ /^Contact Author/;
1193 next if $file =~ / $isaperl /xo;
1194 next unless $module->xs_file;
1196 $CPAN::Frontend->myprint(".");
1197 push @result, $module;
1199 # print join " | ", @result;
1200 $CPAN::Frontend->myprint("\n");
1204 #-> sub CPAN::Shell::recompile ;
1206 my($self) = shift @_;
1207 my($module,@module,$cpan_file,%dist);
1208 @module = $self->_binary_extensions();
1209 for $module (@module){ # we force now and compile later, so we
1211 $cpan_file = $module->cpan_file;
1212 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1214 $dist{$cpan_file}++;
1216 for $cpan_file (sort keys %dist) {
1217 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1218 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1220 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1221 # stop a package from recompiling,
1222 # e.g. IO-1.12 when we have perl5.003_10
1226 #-> sub CPAN::Shell::_u_r_common ;
1228 my($self) = shift @_;
1229 my($what) = shift @_;
1230 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1231 Carp::croak "Usage: \$obj->_u_r_common($what)" unless defined $what;
1232 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless $what =~ /^[aru]$/;
1234 @args = '/./' unless @args;
1235 my(@result,$module,%seen,%need,$headerdone,
1236 $version_undefs,$version_zeroes);
1237 $version_undefs = $version_zeroes = 0;
1238 my $sprintf = "%-25s %9s %9s %s\n";
1239 for $module ($self->expand('Module',@args)) {
1240 my $file = $module->cpan_file;
1241 next unless defined $file; # ??
1242 my($latest) = $module->cpan_version;
1243 my($inst_file) = $module->inst_file;
1245 return if $CPAN::Signal;
1248 $have = $module->inst_version;
1249 } elsif ($what eq "r") {
1250 $have = $module->inst_version;
1252 if ($have eq "undef"){
1254 } elsif ($have == 0){
1257 next if $have >= $latest;
1258 # to be pedantic we should probably say:
1259 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1260 # to catch the case where CPAN has a version 0 and we have a version undef
1261 } elsif ($what eq "u") {
1267 } elsif ($what eq "r") {
1269 } elsif ($what eq "u") {
1273 return if $CPAN::Signal; # this is sometimes lengthy
1276 push @result, sprintf "%s %s\n", $module->id, $have;
1277 } elsif ($what eq "r") {
1278 push @result, $module->id;
1279 next if $seen{$file}++;
1280 } elsif ($what eq "u") {
1281 push @result, $module->id;
1282 next if $seen{$file}++;
1283 next if $file =~ /^Contact/;
1285 unless ($headerdone++){
1286 $CPAN::Frontend->myprint("\n");
1287 $CPAN::Frontend->myprint(sprintf(
1289 "Package namespace",
1295 $latest = substr($latest,0,8) if length($latest) > 8;
1296 $have = substr($have,0,8) if length($have) > 8;
1297 $CPAN::Frontend->myprint(sprintf $sprintf, $module->id, $have, $latest, $file);
1298 $need{$module->id}++;
1302 $CPAN::Frontend->myprint("No modules found for @args\n");
1303 } elsif ($what eq "r") {
1304 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1308 if ($version_zeroes) {
1309 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1310 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1311 qq{a version number of 0\n});
1313 if ($version_undefs) {
1314 my $s_has = $version_undefs > 1 ? "s have" : " has";
1315 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1316 qq{parseable version number\n});
1322 #-> sub CPAN::Shell::r ;
1324 shift->_u_r_common("r",@_);
1327 #-> sub CPAN::Shell::u ;
1329 shift->_u_r_common("u",@_);
1332 #-> sub CPAN::Shell::autobundle ;
1335 my(@bundle) = $self->_u_r_common("a",@_);
1336 my($todir) = MM->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1337 File::Path::mkpath($todir);
1338 unless (-d $todir) {
1339 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
1342 my($y,$m,$d) = (localtime)[5,4,3];
1346 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1347 my($to) = MM->catfile($todir,"$me.pm");
1349 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1350 $to = MM->catfile($todir,"$me.pm");
1352 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1354 "package Bundle::$me;\n\n",
1355 "\$VERSION = '0.01';\n\n",
1359 "Bundle::$me - Snapshot of installation on ",
1360 $Config::Config{'myhostname'},
1363 "\n\n=head1 SYNOPSIS\n\n",
1364 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1365 "=head1 CONTENTS\n\n",
1366 join("\n", @bundle),
1367 "\n\n=head1 CONFIGURATION\n\n",
1369 "\n\n=head1 AUTHOR\n\n",
1370 "This Bundle has been generated automatically ",
1371 "by the autobundle routine in CPAN.pm.\n",
1374 $CPAN::Frontend->myprint("\nWrote bundle file
1378 #-> sub CPAN::Shell::expand ;
1381 my($type,@args) = @_;
1385 if ($arg =~ m|^/(.*)/$|) {
1388 my $class = "CPAN::$type";
1390 if (defined $regex) {
1391 for $obj ( sort {$a->id cmp $b->id} $CPAN::META->all($class)) {
1394 $obj->id =~ /$regex/i
1398 $] < 5.00303 ### provide sort of compatibility with 5.003
1403 $obj->name =~ /$regex/i
1408 if ( $type eq 'Bundle' ) {
1409 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
1411 if ($CPAN::META->exists($class,$xarg)) {
1412 $obj = $CPAN::META->instance($class,$xarg);
1413 } elsif ($CPAN::META->exists($class,$arg)) {
1414 $obj = $CPAN::META->instance($class,$arg);
1421 return wantarray ? @m : $m[0];
1424 #-> sub CPAN::Shell::format_result ;
1427 my($type,@args) = @_;
1428 @args = '/./' unless @args;
1429 my(@result) = $self->expand($type,@args);
1430 my $result = @result == 1 ?
1431 $result[0]->as_string :
1432 join "", map {$_->as_glimpse} @result;
1433 $result ||= "No objects of type $type found for argument @args\n";
1437 # The only reason for this method is currently to have a reliable
1438 # debugging utility that reveals which output is going through which
1439 # channel. No, I don't like the colors ;-)
1440 sub print_ornamented {
1441 my($self,$what,$ornament) = @_;
1443 my $ornamenting = 0; # turn the colors on
1446 unless (defined &color) {
1447 if ($CPAN::META->has_inst("Term::ANSIColor")) {
1448 import Term::ANSIColor "color";
1450 *color = sub { return "" };
1454 for $line (split /\n/, $what) {
1455 $longest = length($line) if length($line) > $longest;
1457 my $sprintf = "%-" . $longest . "s";
1459 $what =~ s/(.*\n?)//m;
1462 my($nl) = chomp $line ? "\n" : "";
1463 # print "line[$line]ornament[$ornament]sprintf[$sprintf]\n";
1464 print color($ornament), sprintf($sprintf,$line), color("reset"), $nl;
1472 my($self,$what) = @_;
1473 $self->print_ornamented($what, 'bold blue on_yellow');
1477 my($self,$what) = @_;
1478 $self->myprint($what);
1483 my($self,$what) = @_;
1484 $self->print_ornamented($what, 'bold red on_yellow');
1488 my($self,$what) = @_;
1489 $self->print_ornamented($what, 'bold red on_white');
1490 Carp::confess "died";
1494 my($self,$what) = @_;
1495 $self->print_ornamented($what, 'bold red on_white');
1499 #-> sub CPAN::Shell::rematein ;
1500 # RE-adme||MA-ke||TE-st||IN-stall
1503 my($meth,@some) = @_;
1505 if ($meth eq 'force') {
1507 $meth = shift @some;
1509 CPAN->debug("pragma[$pragma]meth[$meth] some[@some]") if $CPAN::DEBUG;
1511 foreach $s (@some) {
1515 } elsif ($s =~ m|/|) { # looks like a file
1516 $obj = $CPAN::META->instance('CPAN::Distribution',$s);
1517 } elsif ($s =~ m|^Bundle::|) {
1518 $CPAN::META->{'CPAN::Queue'}{$s} ||= CPAN::Queue->new($s);
1519 $obj = $CPAN::META->instance('CPAN::Bundle',$s);
1521 $CPAN::META->{'CPAN::Queue'}{$s} ||= CPAN::Queue->new($s);
1522 $obj = $CPAN::META->instance('CPAN::Module',$s)
1523 if $CPAN::META->exists('CPAN::Module',$s);
1527 qq{pragma[$pragma] meth[$meth] obj[$obj] as_string\[}.
1535 ($] < 5.00303 || $obj->can($pragma)); ###
1539 if ($]>=5.00303 && $obj->can('called_for')) {
1540 $obj->called_for($s);
1543 } elsif ($CPAN::META->exists('CPAN::Author',$s)) {
1544 $obj = $CPAN::META->instance('CPAN::Author',$s);
1545 $CPAN::Frontend->myprint(
1547 "Don't be silly, you can't $meth ",
1552 $CPAN::Frontend->myprint(qq{Warning: Cannot $meth $s, don\'t know what it is.
1557 to find objects with similar identifiers.
1563 #-> sub CPAN::Shell::force ;
1564 sub force { shift->rematein('force',@_); }
1565 #-> sub CPAN::Shell::get ;
1566 sub get { shift->rematein('get',@_); }
1567 #-> sub CPAN::Shell::readme ;
1568 sub readme { shift->rematein('readme',@_); }
1569 #-> sub CPAN::Shell::make ;
1570 sub make { shift->rematein('make',@_); }
1571 #-> sub CPAN::Shell::test ;
1572 sub test { shift->rematein('test',@_); }
1573 #-> sub CPAN::Shell::install ;
1574 sub install { shift->rematein('install',@_); }
1575 #-> sub CPAN::Shell::clean ;
1576 sub clean { shift->rematein('clean',@_); }
1577 #-> sub CPAN::Shell::look ;
1578 sub look { shift->rematein('look',@_); }
1582 #-> sub CPAN::FTP::ftp_get ;
1584 my($class,$host,$dir,$file,$target) = @_;
1586 qq[Going to fetch file [$file] from dir [$dir]
1587 on host [$host] as local [$target]\n]
1589 my $ftp = Net::FTP->new($host);
1590 return 0 unless defined $ftp;
1591 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
1592 $class->debug(qq[Going to ->login("anonymous","$Config::Config{'cf_email'}")\n]);
1593 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
1594 warn "Couldn't login on $host";
1597 unless ( $ftp->cwd($dir) ){
1598 warn "Couldn't cwd $dir";
1602 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
1603 unless ( $ftp->get($file,$target) ){
1604 warn "Couldn't fetch $file from $host\n";
1607 $ftp->quit; # it's ok if this fails
1611 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
1613 # leach,> *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
1614 # leach,> --- /tmp/cp Wed Sep 24 13:26:40 1997
1615 # leach,> ***************
1616 # leach,> *** 1562,1567 ****
1617 # leach,> --- 1562,1580 ----
1618 # leach,> return 1 if substr($url,0,4) eq "file";
1619 # leach,> return 1 unless $url =~ m|://([^/]+)|;
1620 # leach,> my $host = $1;
1621 # leach,> + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
1622 # leach,> + if ($proxy) {
1623 # leach,> + $proxy =~ m|://([^/:]+)|;
1624 # leach,> + $proxy = $1;
1625 # leach,> + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
1626 # leach,> + if ($noproxy) {
1627 # leach,> + if ($host !~ /$noproxy$/) {
1628 # leach,> + $host = $proxy;
1630 # leach,> + } else {
1631 # leach,> + $host = $proxy;
1634 # leach,> require Net::Ping;
1635 # leach,> return 1 unless $Net::Ping::VERSION >= 2;
1639 # this is quite optimistic and returns one on several occasions where
1640 # inappropriate. But this does no harm. It would do harm if we were
1641 # too pessimistic (as I was before the http_proxy
1643 my($self,$url) = @_;
1644 return 1; # we can't simply roll our own, firewalls may break ping
1645 return 0 unless $url;
1646 return 1 if substr($url,0,4) eq "file";
1647 return 1 unless $url =~ m|^(\w+)://([^/]+)|;
1648 my $proxytype = $1 . "_proxy"; # ftp_proxy or http_proxy
1650 return 1 if $CPAN::Config->{$proxytype} || $ENV{$proxytype};
1652 return 1 unless $Net::Ping::VERSION >= 2;
1654 # 1.3101 had it different: only if the first eval raised an
1655 # exception we tried it with TCP. Now we are happy if icmp wins
1656 # the order and return, we don't even check for $@. Thanks to
1657 # thayer@uis.edu for the suggestion.
1658 eval {$p = Net::Ping->new("icmp");};
1659 return 1 if $p && ref($p) && $p->ping($host, 10);
1660 eval {$p = Net::Ping->new("tcp");};
1661 $CPAN::Frontend->mydie($@) if $@;
1662 return $p->ping($host, 10);
1665 #-> sub CPAN::FTP::localize ;
1666 # sorry for the ugly code here, I'll clean it up as soon as Net::FTP
1669 my($self,$file,$aslocal,$force) = @_;
1671 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
1672 unless defined $aslocal;
1673 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
1676 return $aslocal if -f $aslocal && -r _ && !($force & 1);
1679 rename $aslocal, "$aslocal.bak";
1683 my($aslocal_dir) = File::Basename::dirname($aslocal);
1684 File::Path::mkpath($aslocal_dir);
1685 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
1686 qq{directory "$aslocal_dir".
1687 I\'ll continue, but if you encounter problems, they may be due
1688 to insufficient permissions.\n}) unless -w $aslocal_dir;
1690 # Inheritance is not easier to manage than a few if/else branches
1691 if ($CPAN::META->has_inst('LWP')) {
1692 require LWP::UserAgent;
1694 $Ua = LWP::UserAgent->new;
1696 $Ua->proxy('ftp', $var)
1697 if $var = $CPAN::Config->{'ftp_proxy'} || $ENV{'ftp_proxy'};
1698 $Ua->proxy('http', $var)
1699 if $var = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
1701 if $var = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
1705 # Try the list of urls for each single object. We keep a record
1706 # where we did get a file from
1707 my(@reordered,$last);
1708 $CPAN::Config->{urllist} ||= [];
1709 $last = $#{$CPAN::Config->{urllist}};
1710 if ($force & 2) { # local cpans probably out of date, don't reorder
1711 @reordered = (0..$last);
1715 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
1717 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
1728 @levels = ($Themethod, grep {$_ ne $Themethod} qw/easy hard hardest/);
1730 @levels = qw/easy hard hardest/;
1732 for $level (@levels) {
1733 my $method = "host$level";
1734 my @host_seq = $level eq "easy" ?
1735 @reordered : 0..$last; # reordered has CDROM up front
1736 @host_seq = (0) unless @host_seq;
1737 my $ret = $self->$method(\@host_seq,$file,$aslocal);
1739 $Themethod = $level;
1740 $self->debug("level[$level]") if $CPAN::DEBUG;
1748 qq{Please check, if the URLs I found in your configuration file \(}.
1749 join(", ", @{$CPAN::Config->{urllist}}).
1750 qq{\) are valid. The urllist can be edited.},
1751 qq{E.g. with ``o conf urllist push ftp://myurl/''};
1752 $CPAN::Frontend->myprint(Text::Wrap::wrap("","",@mess). "\n\n");
1754 $CPAN::Frontend->myprint("Cannot fetch $file\n\n");
1756 rename "$aslocal.bak", $aslocal;
1757 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
1758 $self->ls($aslocal));
1765 my($self,$host_seq,$file,$aslocal) = @_;
1767 HOSTEASY: for $i (@$host_seq) {
1768 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
1769 unless ($self->is_reachable($url)) {
1770 $CPAN::Frontend->myprint("Skipping $url (seems to be not reachable)\n");
1774 $url .= "/" unless substr($url,-1) eq "/";
1776 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
1777 if ($url =~ /^file:/) {
1779 if ($CPAN::META->has_inst('LWP')) {
1781 my $u = URI::URL->new($url);
1783 } else { # works only on Unix, is poorly constructed, but
1784 # hopefully better than nothing.
1785 # RFC 1738 says fileurl BNF is
1786 # fileurl = "file://" [ host | "localhost" ] "/" fpath
1787 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
1789 ($l = $url) =~ s,^file://[^/]+,,; # discard the host part
1790 $l =~ s/^file://; # assume they meant file://localhost
1792 if ( -f $l && -r _) {
1796 # Maybe mirror has compressed it?
1798 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
1799 CPAN::Tarzip->gunzip("$l.gz", $aslocal);
1806 if ($CPAN::META->has_inst('LWP')) {
1807 $CPAN::Frontend->myprint("Fetching with LWP:
1810 my $res = $Ua->mirror($url, $aslocal);
1811 if ($res->is_success) {
1814 } elsif ($url !~ /\.gz$/) {
1815 my $gzurl = "$url.gz";
1816 $CPAN::Frontend->myprint("Fetching with LWP:
1819 $res = $Ua->mirror($gzurl, "$aslocal.gz");
1820 if ($res->is_success &&
1821 CPAN::Tarzip->gunzip("$aslocal.gz",$aslocal)
1829 # Alan Burlison informed me that in firewall envs Net::FTP
1830 # can still succeed where LWP fails. So we do not skip
1831 # Net::FTP anymore when LWP is available.
1835 $self->debug("LWP not installed") if $CPAN::DEBUG;
1837 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
1838 # that's the nice and easy way thanks to Graham
1839 my($host,$dir,$getfile) = ($1,$2,$3);
1840 if ($CPAN::META->has_inst('Net::FTP')) {
1842 $CPAN::Frontend->myprint("Fetching with Net::FTP:
1845 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
1846 "aslocal[$aslocal]") if $CPAN::DEBUG;
1847 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
1851 if ($aslocal !~ /\.gz$/) {
1852 my $gz = "$aslocal.gz";
1853 $CPAN::Frontend->myprint("Fetching with Net::FTP
1856 if (CPAN::FTP->ftp_get($host,
1860 CPAN::Tarzip->gunzip($gz,$aslocal)
1873 my($self,$host_seq,$file,$aslocal) = @_;
1875 # Came back if Net::FTP couldn't establish connection (or
1876 # failed otherwise) Maybe they are behind a firewall, but they
1877 # gave us a socksified (or other) ftp program...
1880 my($devnull) = $CPAN::Config->{devnull} || "";
1882 my($aslocal_dir) = File::Basename::dirname($aslocal);
1883 File::Path::mkpath($aslocal_dir);
1884 HOSTHARD: for $i (@$host_seq) {
1885 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
1886 unless ($self->is_reachable($url)) {
1887 $CPAN::Frontend->myprint("Skipping $url (not reachable)\n");
1890 $url .= "/" unless substr($url,-1) eq "/";
1892 my($proto,$host,$dir,$getfile);
1894 # Courtesy Mark Conty mark_conty@cargill.com change from
1895 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
1897 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
1898 # proto not yet used
1899 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
1901 next HOSTHARD; # who said, we could ftp anything except ftp?
1903 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
1905 for $f ('lynx','ncftpget','ncftp') {
1906 next unless exists $CPAN::Config->{$f};
1907 $funkyftp = $CPAN::Config->{$f};
1908 next unless defined $funkyftp;
1909 next if $funkyftp =~ /^\s*$/;
1910 my($want_compressed);
1911 my $aslocal_uncompressed;
1912 ($aslocal_uncompressed = $aslocal) =~ s/\.gz//;
1913 my($source_switch) = "";
1914 $source_switch = " -source" if $funkyftp =~ /\blynx$/;
1915 $source_switch = " -c" if $funkyftp =~ /\bncftp$/;
1916 $CPAN::Frontend->myprint(
1918 Trying with "$funkyftp$source_switch" to get
1921 my($system) = "$funkyftp$source_switch '$url' $devnull > ".
1922 "$aslocal_uncompressed";
1923 $self->debug("system[$system]") if $CPAN::DEBUG;
1925 if (($wstatus = system($system)) == 0
1927 -s $aslocal_uncompressed # lynx returns 0 on my
1928 # system even if it fails
1930 if ($aslocal_uncompressed ne $aslocal) {
1931 # test gzip integrity
1933 CPAN::Tarzip->gtest($aslocal_uncompressed)
1935 rename $aslocal_uncompressed, $aslocal;
1937 CPAN::Tarzip->gzip($aslocal_uncompressed,
1938 "$aslocal_uncompressed.gz");
1943 } elsif ($url !~ /\.gz$/) {
1944 unlink $aslocal_uncompressed if
1945 -f $aslocal_uncompressed && -s _ == 0;
1946 my $gz = "$aslocal.gz";
1947 my $gzurl = "$url.gz";
1948 $CPAN::Frontend->myprint(
1950 Trying with "$funkyftp$source_switch" to get
1953 my($system) = "$funkyftp$source_switch '$url.gz' $devnull > ".
1954 "$aslocal_uncompressed.gz";
1955 $self->debug("system[$system]") if $CPAN::DEBUG;
1957 if (($wstatus = system($system)) == 0
1959 -s "$aslocal_uncompressed.gz"
1961 # test gzip integrity
1962 if (CPAN::Tarzip->gtest("$aslocal_uncompressed.gz")) {
1963 CPAN::Tarzip->gunzip("$aslocal_uncompressed.gz",
1966 rename $aslocal_uncompressed, $aslocal;
1971 unlink "$aslocal_uncompressed.gz" if
1972 -f "$aslocal_uncompressed.gz";
1975 my $estatus = $wstatus >> 8;
1976 my $size = -f $aslocal ? ", left\n$aslocal with size ".-s _ : "";
1977 $CPAN::Frontend->myprint(qq{
1978 System call "$system"
1979 returned status $estatus (wstat $wstatus)$size
1987 my($self,$host_seq,$file,$aslocal) = @_;
1990 my($aslocal_dir) = File::Basename::dirname($aslocal);
1991 File::Path::mkpath($aslocal_dir);
1992 HOSTHARDEST: for $i (@$host_seq) {
1993 unless (length $CPAN::Config->{'ftp'}) {
1994 $CPAN::Frontend->myprint("No external ftp command available\n\n");
1997 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
1998 unless ($self->is_reachable($url)) {
1999 $CPAN::Frontend->myprint("Skipping $url (not reachable)\n");
2002 $url .= "/" unless substr($url,-1) eq "/";
2004 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
2005 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2008 my($host,$dir,$getfile) = ($1,$2,$3);
2011 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
2012 $ctime,$blksize,$blocks) = stat($aslocal);
2013 $timestamp = $mtime ||= 0;
2014 my($netrc) = CPAN::FTP::netrc->new;
2015 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
2016 my $targetfile = File::Basename::basename($aslocal);
2022 map("cd $_", split "/", $dir), # RFC 1738
2024 "get $getfile $targetfile",
2027 if (! $netrc->netrc) {
2028 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
2029 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
2030 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
2032 $netrc->contains($host))) if $CPAN::DEBUG;
2033 if ($netrc->protected) {
2034 $CPAN::Frontend->myprint(qq{
2035 Trying with external ftp to get
2037 As this requires some features that are not thoroughly tested, we\'re
2038 not sure, that we get it right....
2042 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose $host",
2044 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2045 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2047 if ($mtime > $timestamp) {
2048 $CPAN::Frontend->myprint("GOT $aslocal\n");
2052 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
2055 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
2056 qq{correctly protected.\n});
2059 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
2060 nor does it have a default entry\n");
2063 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
2064 # then and login manually to host, using e-mail as
2066 $CPAN::Frontend->myprint(qq{Issuing "$CPAN::Config->{'ftp'}$verbose -n"\n});
2070 "user anonymous $Config::Config{'cf_email'}"
2072 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose -n", @dialog);
2073 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2074 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2076 if ($mtime > $timestamp) {
2077 $CPAN::Frontend->myprint("GOT $aslocal\n");
2081 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
2083 $CPAN::Frontend->myprint("Can't access URL $url.\n\n");
2089 my($self,$command,@dialog) = @_;
2090 my $fh = FileHandle->new;
2091 $fh->open("|$command") or die "Couldn't open ftp: $!";
2092 foreach (@dialog) { $fh->print("$_\n") }
2093 $fh->close; # Wait for process to complete
2095 my $estatus = $wstatus >> 8;
2096 $CPAN::Frontend->myprint(qq{
2097 Subprocess "|$command"
2098 returned status $estatus (wstat $wstatus)
2103 # find2perl needs modularization, too, all the following is stolen
2107 my($self,$name) = @_;
2108 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
2109 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
2111 my($perms,%user,%group);
2115 $blocks = int(($blocks + 1) / 2);
2118 $blocks = int(($sizemm + 1023) / 1024);
2121 if (-f _) { $perms = '-'; }
2122 elsif (-d _) { $perms = 'd'; }
2123 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
2124 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
2125 elsif (-p _) { $perms = 'p'; }
2126 elsif (-S _) { $perms = 's'; }
2127 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
2129 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
2130 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
2131 my $tmpmode = $mode;
2132 my $tmp = $rwx[$tmpmode & 7];
2134 $tmp = $rwx[$tmpmode & 7] . $tmp;
2136 $tmp = $rwx[$tmpmode & 7] . $tmp;
2137 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
2138 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
2139 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
2142 my $user = $user{$uid} || $uid; # too lazy to implement lookup
2143 my $group = $group{$gid} || $gid;
2145 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
2147 my($moname) = $moname[$mon];
2148 if (-M _ > 365.25 / 2) {
2149 $timeyear = $year + 1900;
2152 $timeyear = sprintf("%02d:%02d", $hour, $min);
2155 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
2169 package CPAN::FTP::netrc;
2173 my $file = MM->catfile($ENV{HOME},".netrc");
2175 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2176 $atime,$mtime,$ctime,$blksize,$blocks)
2181 my($fh,@machines,$hasdefault);
2183 $fh = FileHandle->new or die "Could not create a filehandle";
2185 if($fh->open($file)){
2186 $protected = ($mode & 077) == 0;
2188 NETRC: while (<$fh>) {
2189 my(@tokens) = split " ", $_;
2190 TOKEN: while (@tokens) {
2191 my($t) = shift @tokens;
2192 if ($t eq "default"){
2196 last TOKEN if $t eq "macdef";
2197 if ($t eq "machine") {
2198 push @machines, shift @tokens;
2203 $file = $hasdefault = $protected = "";
2207 'mach' => [@machines],
2209 'hasdefault' => $hasdefault,
2210 'protected' => $protected,
2214 sub hasdefault { shift->{'hasdefault'} }
2215 sub netrc { shift->{'netrc'} }
2216 sub protected { shift->{'protected'} }
2218 my($self,$mach) = @_;
2219 for ( @{$self->{'mach'}} ) {
2220 return 1 if $_ eq $mach;
2225 package CPAN::Complete;
2227 #-> sub CPAN::Complete::cpl ;
2229 my($word,$line,$pos) = @_;
2233 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2235 if ($line =~ s/^(force\s*)//) {
2243 ! a b d h i m o q r u autobundle clean
2244 make test install force reload look
2247 } elsif ( $line !~ /^[\!abdhimorutl]/ ) {
2249 } elsif ($line =~ /^a\s/) {
2250 @return = cplx('CPAN::Author',$word);
2251 } elsif ($line =~ /^b\s/) {
2252 @return = cplx('CPAN::Bundle',$word);
2253 } elsif ($line =~ /^d\s/) {
2254 @return = cplx('CPAN::Distribution',$word);
2255 } elsif ($line =~ /^([mru]|make|clean|test|install|readme|look)\s/ ) {
2256 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
2257 } elsif ($line =~ /^i\s/) {
2258 @return = cpl_any($word);
2259 } elsif ($line =~ /^reload\s/) {
2260 @return = cpl_reload($word,$line,$pos);
2261 } elsif ($line =~ /^o\s/) {
2262 @return = cpl_option($word,$line,$pos);
2269 #-> sub CPAN::Complete::cplx ;
2271 my($class, $word) = @_;
2272 grep /^\Q$word\E/, map { $_->id } $CPAN::META->all($class);
2275 #-> sub CPAN::Complete::cpl_any ;
2279 cplx('CPAN::Author',$word),
2280 cplx('CPAN::Bundle',$word),
2281 cplx('CPAN::Distribution',$word),
2282 cplx('CPAN::Module',$word),
2286 #-> sub CPAN::Complete::cpl_reload ;
2288 my($word,$line,$pos) = @_;
2290 my(@words) = split " ", $line;
2291 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2292 my(@ok) = qw(cpan index);
2293 return @ok if @words == 1;
2294 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
2297 #-> sub CPAN::Complete::cpl_option ;
2299 my($word,$line,$pos) = @_;
2301 my(@words) = split " ", $line;
2302 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2303 my(@ok) = qw(conf debug);
2304 return @ok if @words == 1;
2305 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
2307 } elsif ($words[1] eq 'index') {
2309 } elsif ($words[1] eq 'conf') {
2310 return CPAN::Config::cpl(@_);
2311 } elsif ($words[1] eq 'debug') {
2312 return sort grep /^\Q$word\E/, sort keys %CPAN::DEBUG, 'all';
2316 package CPAN::Index;
2318 #-> sub CPAN::Index::force_reload ;
2321 $CPAN::Index::last_time = 0;
2325 #-> sub CPAN::Index::reload ;
2327 my($cl,$force) = @_;
2330 # XXX check if a newer one is available. (We currently read it
2331 # from time to time)
2332 for ($CPAN::Config->{index_expire}) {
2333 $_ = 0.001 unless $_ > 0.001;
2335 return if $last_time + $CPAN::Config->{index_expire}*86400 > $time
2340 my $needshort = $^O eq "dos";
2342 $cl->rd_authindex($cl->reload_x(
2343 "authors/01mailrc.txt.gz",
2344 $needshort ? "01mailrc.gz" : "",
2347 $debug = "timing reading 01[".($t2 - $time)."]";
2349 return if $CPAN::Signal; # this is sometimes lengthy
2350 $cl->rd_modpacks($cl->reload_x(
2351 "modules/02packages.details.txt.gz",
2352 $needshort ? "02packag.gz" : "",
2355 $debug .= "02[".($t2 - $time)."]";
2357 return if $CPAN::Signal; # this is sometimes lengthy
2358 $cl->rd_modlist($cl->reload_x(
2359 "modules/03modlist.data.gz",
2360 $needshort ? "03mlist.gz" : "",
2363 $debug .= "03[".($t2 - $time)."]";
2365 CPAN->debug($debug) if $CPAN::DEBUG;
2368 #-> sub CPAN::Index::reload_x ;
2370 my($cl,$wanted,$localname,$force) = @_;
2371 $force |= 2; # means we're dealing with an index here
2372 CPAN::Config->load; # we should guarantee loading wherever we rely
2374 $localname ||= $wanted;
2375 my $abs_wanted = MM->catfile($CPAN::Config->{'keep_source_where'},
2379 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
2382 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
2383 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
2384 qq{day$s. I\'ll use that.});
2387 $force |= 1; # means we're quite serious about it.
2389 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
2392 #-> sub CPAN::Index::rd_authindex ;
2394 my($cl,$index_target) = @_;
2395 return unless defined $index_target;
2396 $CPAN::Frontend->myprint("Going to read $index_target\n");
2397 # my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
2398 # while ($_ = $fh->READLINE) {
2401 tie *FH, CPAN::Tarzip, $index_target;
2405 my($userid,$fullname,$email) =
2406 /alias\s+(\S+)\s+\"([^\"\<]+)\s+<([^\>]+)\>\"/;
2407 next unless $userid && $fullname && $email;
2409 # instantiate an author object
2410 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
2411 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
2412 return if $CPAN::Signal;
2417 my($self,$dist) = @_;
2418 $dist = $self->{'id'} unless defined $dist;
2419 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
2423 #-> sub CPAN::Index::rd_modpacks ;
2425 my($cl,$index_target) = @_;
2426 return unless defined $index_target;
2427 $CPAN::Frontend->myprint("Going to read $index_target\n");
2428 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
2430 while ($_ = $fh->READLINE) {
2433 while ($_ = $fh->READLINE) {
2435 my($mod,$version,$dist) = split;
2436 ### $version =~ s/^\+//;
2438 # if it is a bundle, instatiate a bundle object
2439 my($bundle,$id,$userid);
2441 if ($mod eq 'CPAN' &&
2443 $CPAN::META->exists('CPAN::Queue','Bundle::CPAN') ||
2444 $CPAN::META->exists('CPAN::Queue','CPAN')
2448 if ($version > $CPAN::VERSION){
2449 $CPAN::Frontend->myprint(qq{
2450 There\'s a new CPAN.pm version (v$version) available!
2451 You might want to try
2452 install Bundle::CPAN
2454 without quitting the current session. It should be a seamless upgrade
2455 while we are running...
2458 $CPAN::Frontend->myprint(qq{\n});
2460 last if $CPAN::Signal;
2461 } elsif ($mod =~ /^Bundle::(.*)/) {
2466 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
2467 # warn "made mod[$mod]a bundle";
2468 # Let's make it a module too, because bundles have so much
2469 # in common with modules
2470 $CPAN::META->instance('CPAN::Module',$mod);
2471 # warn "made mod[$mod]a module";
2473 # This "next" makes us faster but if the job is running long, we ignore
2474 # rereads which is bad. So we have to be a bit slower again.
2475 # } elsif ($CPAN::META->exists('CPAN::Module',$mod)) {
2480 # instantiate a module object
2481 $id = $CPAN::META->instance('CPAN::Module',$mod);
2484 if ($id->cpan_file ne $dist){
2485 $userid = $cl->userid($dist);
2487 'CPAN_USERID' => $userid,
2488 'CPAN_VERSION' => $version,
2489 'CPAN_FILE' => $dist
2493 # instantiate a distribution object
2494 unless ($CPAN::META->exists('CPAN::Distribution',$dist)) {
2495 $CPAN::META->instance(
2496 'CPAN::Distribution' => $dist
2498 'CPAN_USERID' => $userid
2502 return if $CPAN::Signal;
2507 #-> sub CPAN::Index::rd_modlist ;
2509 my($cl,$index_target) = @_;
2510 return unless defined $index_target;
2511 $CPAN::Frontend->myprint("Going to read $index_target\n");
2512 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
2515 while ($_ = $fh->READLINE) {
2516 if (/^Date:\s+(.*)/){
2517 return if $date_of_03 eq $1;
2522 push @eval, $_ while $_ = $fh->READLINE;
2524 push @eval, q{CPAN::Modulelist->data;};
2526 my($comp) = Safe->new("CPAN::Safe1");
2527 my($eval) = join("", @eval);
2528 my $ret = $comp->reval($eval);
2529 Carp::confess($@) if $@;
2530 return if $CPAN::Signal;
2532 my $obj = $CPAN::META->instance(CPAN::Module,$_);
2533 $obj->set(%{$ret->{$_}});
2534 return if $CPAN::Signal;
2538 package CPAN::InfoObj;
2540 #-> sub CPAN::InfoObj::new ;
2541 sub new { my $this = bless {}, shift; %$this = @_; $this }
2543 #-> sub CPAN::InfoObj::set ;
2545 my($self,%att) = @_;
2546 my(%oldatt) = %$self;
2547 %$self = (%oldatt, %att);
2550 #-> sub CPAN::InfoObj::id ;
2551 sub id { shift->{'ID'} }
2553 #-> sub CPAN::InfoObj::as_glimpse ;
2557 my $class = ref($self);
2558 $class =~ s/^CPAN:://;
2559 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
2563 #-> sub CPAN::InfoObj::as_string ;
2567 my $class = ref($self);
2568 $class =~ s/^CPAN:://;
2569 push @m, $class, " id = $self->{ID}\n";
2570 for (sort keys %$self) {
2573 if ($_ eq "CPAN_USERID") {
2574 $extra .= " (".$self->author;
2575 my $email; # old perls!
2576 if ($email = $CPAN::META->instance(CPAN::Author,
2579 $extra .= " <$email>";
2581 $extra .= " <no email>";
2585 if (ref($self->{$_}) eq "ARRAY") { # language interface? XXX
2586 push @m, sprintf " %-12s %s%s\n", $_, "@{$self->{$_}}", $extra;
2588 push @m, sprintf " %-12s %s%s\n", $_, $self->{$_}, $extra;
2594 #-> sub CPAN::InfoObj::author ;
2597 $CPAN::META->instance(CPAN::Author,$self->{CPAN_USERID})->fullname;
2600 package CPAN::Author;
2602 #-> sub CPAN::Author::as_glimpse ;
2606 my $class = ref($self);
2607 $class =~ s/^CPAN:://;
2608 push @m, sprintf "%-15s %s (%s)\n", $class, $self->{ID}, $self->fullname;
2612 # Dead code, I would have liked to have,,, but it was never reached,,,
2615 # return "Don't be silly, you can't make $self->{FULLNAME} ;-)\n";
2618 #-> sub CPAN::Author::fullname ;
2619 sub fullname { shift->{'FULLNAME'} }
2621 #-> sub CPAN::Author::email ;
2622 sub email { shift->{'EMAIL'} }
2624 package CPAN::Distribution;
2626 #-> sub CPAN::Distribution::called_for ;
2629 $self->{'CALLED_FOR'} = $id if defined $id;
2630 return $self->{'CALLED_FOR'};
2633 #-> sub CPAN::Distribution::get ;
2638 exists $self->{'build_dir'} and push @e,
2639 "Unwrapped into directory $self->{'build_dir'}";
2640 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
2645 $CPAN::Config->{keep_source_where},
2648 split("/",$self->{ID})
2651 $self->debug("Doing localize") if $CPAN::DEBUG;
2653 CPAN::FTP->localize("authors/id/$self->{ID}", $local_wanted)
2654 or $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n");
2655 $self->{localfile} = $local_file;
2656 my $builddir = $CPAN::META->{cachemgr}->dir;
2657 $self->debug("doing chdir $builddir") if $CPAN::DEBUG;
2658 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
2661 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
2662 if ($CPAN::META->has_inst('MD5')) {
2663 $self->debug("MD5 is installed, verifying");
2666 $self->debug("MD5 is NOT installed");
2668 $self->debug("Removing tmp") if $CPAN::DEBUG;
2669 File::Path::rmtree("tmp");
2670 mkdir "tmp", 0755 or Carp::croak "Couldn't mkdir tmp: $!";
2672 $self->debug("Changed directory to tmp") if $CPAN::DEBUG;
2673 if (! $local_file) {
2674 Carp::croak "bad download, can't do anything :-(\n";
2675 } elsif ($local_file =~ /(\.tar\.(gz|Z)|\.tgz)$/i){
2676 $self->untar_me($local_file);
2677 } elsif ( $local_file =~ /\.zip$/i ) {
2678 $self->unzip_me($local_file);
2679 } elsif ( $local_file =~ /\.pm\.(gz|Z)$/) {
2680 $self->pm2dir_me($local_file);
2682 $self->{archived} = "NO";
2685 if ($self->{archived} ne 'NO') {
2687 # Let's check if the package has its own directory.
2688 my $dh = DirHandle->new(".") or Carp::croak("Couldn't opendir .: $!");
2689 my @readdir = grep $_ !~ /^\.\.?$/, $dh->read; ### MAC??
2691 my ($distdir,$packagedir);
2692 if (@readdir == 1 && -d $readdir[0]) {
2693 $distdir = $readdir[0];
2694 $packagedir = MM->catdir($builddir,$distdir);
2695 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used $packagedir\n");
2696 File::Path::rmtree($packagedir);
2697 rename($distdir,$packagedir) or Carp::confess("Couldn't rename $distdir to $packagedir: $!");
2699 my $pragmatic_dir = $self->{'CPAN_USERID'} . '000';
2700 $pragmatic_dir =~ s/\W_//g;
2701 $pragmatic_dir++ while -d "../$pragmatic_dir";
2702 $packagedir = MM->catdir($builddir,$pragmatic_dir);
2703 File::Path::mkpath($packagedir);
2705 for $f (@readdir) { # is already without "." and ".."
2706 my $to = MM->catdir($packagedir,$f);
2707 rename($f,$to) or Carp::confess("Couldn't rename $f to $to: $!");
2710 $self->{'build_dir'} = $packagedir;
2713 $self->debug("Changed directory to .. (self is $self [".$self->as_string."])")
2715 File::Path::rmtree("tmp");
2716 if ($CPAN::Config->{keep_source_where} =~ /^no/i ){
2717 $CPAN::Frontend->myprint("Going to unlink $local_file\n");
2718 unlink $local_file or Carp::carp "Couldn't unlink $local_file";
2720 my($makefilepl) = MM->catfile($packagedir,"Makefile.PL");
2721 unless (-f $makefilepl) {
2722 my($configure) = MM->catfile($packagedir,"Configure");
2723 if (-f $configure) {
2724 # do we have anything to do?
2725 $self->{'configure'} = $configure;
2726 } elsif (-f MM->catfile($packagedir,"Makefile")) {
2727 $CPAN::Frontend->myprint(qq{
2728 Package comes with a Makefile and without a Makefile.PL.
2729 We\'ll try to build it with that Makefile then.
2731 $self->{writemakefile} = "YES";
2734 my $fh = FileHandle->new(">$makefilepl")
2735 or Carp::croak("Could not open >$makefilepl");
2736 my $cf = $self->called_for || "unknown";
2738 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
2739 # because there was no Makefile.PL supplied.
2740 # Autogenerated on: }.scalar localtime().qq{
2742 use ExtUtils::MakeMaker;
2743 WriteMakefile(NAME => q[$cf]);
2746 $CPAN::Frontend->myprint(qq{Package comes without Makefile.PL.
2747 Writing one on our own (calling it $cf)\n});
2755 my($self,$local_file) = @_;
2756 $self->{archived} = "tar";
2757 if (CPAN::Tarzip->untar($local_file)) {
2758 $self->{unwrapped} = "YES";
2760 $self->{unwrapped} = "NO";
2765 my($self,$local_file) = @_;
2766 $self->{archived} = "zip";
2767 my $system = "$CPAN::Config->{unzip} $local_file";
2768 if (system($system) == 0) {
2769 $self->{unwrapped} = "YES";
2771 $self->{unwrapped} = "NO";
2776 my($self,$local_file) = @_;
2777 $self->{archived} = "pm";
2778 my $to = File::Basename::basename($local_file);
2779 $to =~ s/\.(gz|Z)$//;
2780 if (CPAN::Tarzip->gunzip($local_file,$to)) {
2781 $self->{unwrapped} = "YES";
2783 $self->{unwrapped} = "NO";
2787 #-> sub CPAN::Distribution::new ;
2789 my($class,%att) = @_;
2791 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
2793 my $this = { %att };
2794 return bless $this, $class;
2797 #-> sub CPAN::Distribution::look ;
2800 if ( $CPAN::Config->{'shell'} ) {
2801 $CPAN::Frontend->myprint(qq{
2802 Trying to open a subshell in the build directory...
2805 $CPAN::Frontend->myprint(qq{
2806 Your configuration does not define a value for subshells.
2807 Please define it with "o conf shell <your shell>"
2811 my $dist = $self->id;
2812 my $dir = $self->dir or $self->get;
2815 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
2816 my $pwd = CPAN->$getcwd();
2818 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
2819 system($CPAN::Config->{'shell'}) == 0
2820 or $CPAN::Frontend->mydie("Subprocess shell error");
2824 #-> sub CPAN::Distribution::readme ;
2827 my($dist) = $self->id;
2828 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
2829 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
2833 $CPAN::Config->{keep_source_where},
2836 split("/","$sans.readme"),
2838 $self->debug("Doing localize") if $CPAN::DEBUG;
2839 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
2841 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
2842 my $fh_pager = FileHandle->new;
2843 local($SIG{PIPE}) = "IGNORE";
2844 $fh_pager->open("|$CPAN::Config->{'pager'}")
2845 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
2846 my $fh_readme = FileHandle->new;
2847 $fh_readme->open($local_file)
2848 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
2849 $CPAN::Frontend->myprint(qq{
2852 with pager "$CPAN::Config->{'pager'}"
2855 $fh_pager->print(<$fh_readme>);
2858 #-> sub CPAN::Distribution::verifyMD5 ;
2863 $self->{MD5_STATUS} ||= "";
2864 $self->{MD5_STATUS} eq "OK" and push @e, "MD5 Checksum was ok";
2865 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
2867 my($lc_want,$lc_file,@local,$basename);
2868 @local = split("/",$self->{ID});
2870 push @local, "CHECKSUMS";
2872 MM->catfile($CPAN::Config->{keep_source_where},
2873 "authors", "id", @local);
2878 $self->MD5_check_file($lc_want)
2880 return $self->{MD5_STATUS} = "OK";
2882 $lc_file = CPAN::FTP->localize("authors/id/@local",
2885 $local[-1] .= ".gz";
2886 $lc_file = CPAN::FTP->localize("authors/id/@local",
2889 $lc_file =~ s/\.gz$//;
2890 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
2895 $self->MD5_check_file($lc_file);
2898 #-> sub CPAN::Distribution::MD5_check_file ;
2899 sub MD5_check_file {
2900 my($self,$chk_file) = @_;
2901 my($cksum,$file,$basename);
2902 $file = $self->{localfile};
2903 $basename = File::Basename::basename($file);
2904 my $fh = FileHandle->new;
2905 if (open $fh, $chk_file){
2909 my($comp) = Safe->new();
2910 $cksum = $comp->reval($eval);
2912 rename $chk_file, "$chk_file.bad";
2913 Carp::confess($@) if $@;
2916 Carp::carp "Could not open $chk_file for reading";
2919 if (exists $cksum->{$basename}{md5}) {
2920 $self->debug("Found checksum for $basename:" .
2921 "$cksum->{$basename}{md5}\n") if $CPAN::DEBUG;
2925 my $eq = $self->eq_MD5($fh,$cksum->{$basename}{'md5'});
2927 $fh = CPAN::Tarzip->TIEHANDLE($file);
2930 # had to inline it, when I tied it, the tiedness got lost on
2931 # the call to eq_MD5. (Jan 1998)
2935 while ($fh->READ($ref, 4096)){
2938 my $hexdigest = $md5->hexdigest;
2939 $eq += $hexdigest eq $cksum->{$basename}{'md5-ungz'};
2943 $CPAN::Frontend->myprint("Checksum for $file ok\n");
2944 return $self->{MD5_STATUS} = "OK";
2946 $CPAN::Frontend->myprint(qq{Checksum mismatch for }.
2947 qq{distribution file. }.
2948 qq{Please investigate.\n\n}.
2950 $CPAN::META->instance(
2952 $self->{CPAN_USERID}
2954 my $wrap = qq{I\'d recommend removing $file. It seems to
2955 be a bogus file. Maybe you have configured your \`urllist\' with a
2956 bad URL. Please check this array with \`o conf urllist\', and
2958 $CPAN::Frontend->myprint(Text::Wrap::wrap("","",$wrap));
2959 $CPAN::Frontend->myprint("\n\n");
2963 # close $fh if fileno($fh);
2965 $self->{MD5_STATUS} ||= "";
2966 if ($self->{MD5_STATUS} eq "NIL") {
2967 $CPAN::Frontend->myprint(qq{
2968 No md5 checksum for $basename in local $chk_file.
2971 unlink $chk_file or $CPAN::Frontend->myprint("Could not unlink: $!");
2974 $self->{MD5_STATUS} = "NIL";
2979 #-> sub CPAN::Distribution::eq_MD5 ;
2981 my($self,$fh,$expectMD5) = @_;
2984 while (read($fh, $data, 4096)){
2987 # $md5->addfile($fh);
2988 my $hexdigest = $md5->hexdigest;
2989 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
2990 $hexdigest eq $expectMD5;
2993 #-> sub CPAN::Distribution::force ;
2996 $self->{'force_update'}++;
2997 delete $self->{'MD5_STATUS'};
2998 delete $self->{'archived'};
2999 delete $self->{'build_dir'};
3000 delete $self->{'localfile'};
3001 delete $self->{'make'};
3002 delete $self->{'install'};
3003 delete $self->{'unwrapped'};
3004 delete $self->{'writemakefile'};
3009 my $file = File::Basename::basename($self->id);
3010 return unless $file =~ m{ ^ perl
3013 (\d{3}(_[0-4][0-9])?)
3020 #-> sub CPAN::Distribution::perl ;
3023 my($perl) = MM->file_name_is_absolute($^X) ? $^X : "";
3024 my $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
3025 my $pwd = CPAN->$getcwd();
3026 my $candidate = MM->catfile($pwd,$^X);
3027 $perl ||= $candidate if MM->maybe_command($candidate);
3029 my ($component,$perl_name);
3030 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
3031 PATH_COMPONENT: foreach $component (MM->path(),
3032 $Config::Config{'binexp'}) {
3033 next unless defined($component) && $component;
3034 my($abs) = MM->catfile($component,$perl_name);
3035 if (MM->maybe_command($abs)) {
3045 #-> sub CPAN::Distribution::make ;
3048 $CPAN::Frontend->myprint(sprintf "Running make for %s\n", $self->id);
3049 # Emergency brake if they said install Pippi and get newest perl
3050 if ($self->isa_perl) {
3052 $self->called_for ne $self->id && ! $self->{'force_update'}
3054 $CPAN::Frontend->mydie(sprintf qq{
3055 The most recent version "%s" of the module "%s"
3056 comes with the current version of perl (%s).
3057 I\'ll build that only if you ask for something like
3062 $CPAN::META->instance(
3075 $self->{archived} eq "NO" and push @e,
3076 "Is neither a tar nor a zip archive.";
3078 $self->{unwrapped} eq "NO" and push @e,
3079 "had problems unarchiving. Please build manually";
3081 exists $self->{writemakefile} &&
3082 $self->{writemakefile} eq "NO" and push @e,
3083 "Had some problem writing Makefile";
3085 defined $self->{'make'} and push @e,
3086 "Has already been processed within this session";
3088 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3090 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
3091 my $builddir = $self->dir;
3092 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
3093 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
3096 if ($self->{'configure'}) {
3097 $system = $self->{'configure'};
3099 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
3101 # This needs a handler that can be turned on or off:
3102 # $switch = "-MExtUtils::MakeMaker ".
3103 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
3105 $system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}";
3107 unless (exists $self->{writemakefile}) {
3108 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
3111 if ($CPAN::Config->{inactivity_timeout}) {
3113 alarm $CPAN::Config->{inactivity_timeout};
3114 local $SIG{CHLD} = sub { wait };
3115 if (defined($pid = fork)) {
3119 # note, this exec isn't necessary if
3120 # inactivity_timeout is 0. On the Mac I'd
3121 # suggest, we set it always to 0.
3125 $CPAN::Frontend->myprint("Cannot fork: $!");
3133 $CPAN::Frontend->myprint($@);
3134 $self->{writemakefile} = "NO - $@";
3139 $ret = system($system);
3141 $self->{writemakefile} = "NO";
3145 $self->{writemakefile} = "YES";
3147 return if $CPAN::Signal;
3148 $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
3149 if (system($system) == 0) {
3150 $CPAN::Frontend->myprint(" $system -- OK\n");
3151 $self->{'make'} = "YES";
3153 $self->{writemakefile} = "YES";
3154 $self->{'make'} = "NO";
3155 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
3159 #-> sub CPAN::Distribution::test ;
3163 return if $CPAN::Signal;
3164 $CPAN::Frontend->myprint("Running make test\n");
3167 exists $self->{'make'} or push @e,
3168 "Make had some problems, maybe interrupted? Won't test";
3170 exists $self->{'make'} and
3171 $self->{'make'} eq 'NO' and
3172 push @e, "Oops, make had returned bad status";
3174 exists $self->{'build_dir'} or push @e, "Has no own directory";
3175 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3177 chdir $self->{'build_dir'} or
3178 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
3179 $self->debug("Changed directory to $self->{'build_dir'}")
3181 my $system = join " ", $CPAN::Config->{'make'}, "test";
3182 if (system($system) == 0) {
3183 $CPAN::Frontend->myprint(" $system -- OK\n");
3184 $self->{'make_test'} = "YES";
3186 $self->{'make_test'} = "NO";
3187 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
3191 #-> sub CPAN::Distribution::clean ;
3194 $CPAN::Frontend->myprint("Running make clean\n");
3197 exists $self->{'build_dir'} or push @e, "Has no own directory";
3198 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3200 chdir $self->{'build_dir'} or
3201 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
3202 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
3203 my $system = join " ", $CPAN::Config->{'make'}, "clean";
3204 if (system($system) == 0) {
3205 $CPAN::Frontend->myprint(" $system -- OK\n");
3208 # Hmmm, what to do if make clean failed?
3212 #-> sub CPAN::Distribution::install ;
3216 return if $CPAN::Signal;
3217 $CPAN::Frontend->myprint("Running make install\n");
3220 exists $self->{'build_dir'} or push @e, "Has no own directory";
3222 exists $self->{'make'} or push @e,
3223 "Make had some problems, maybe interrupted? Won't install";
3225 exists $self->{'make'} and
3226 $self->{'make'} eq 'NO' and
3227 push @e, "Oops, make had returned bad status";
3229 push @e, "make test had returned bad status, ".
3230 "won't install without force"
3231 if exists $self->{'make_test'} and
3232 $self->{'make_test'} eq 'NO' and
3233 ! $self->{'force_update'};
3235 exists $self->{'install'} and push @e,
3236 $self->{'install'} eq "YES" ?
3237 "Already done" : "Already tried without success";
3239 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3241 chdir $self->{'build_dir'} or
3242 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
3243 $self->debug("Changed directory to $self->{'build_dir'}")
3245 my $system = join(" ", $CPAN::Config->{'make'},
3246 "install", $CPAN::Config->{make_install_arg});
3247 my($pipe) = FileHandle->new("$system 2>&1 |");
3250 $CPAN::Frontend->myprint($_);
3255 $CPAN::Frontend->myprint(" $system -- OK\n");
3256 $self->{'install'} = "YES";
3258 $self->{'install'} = "NO";
3259 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
3260 if ($makeout =~ /permission/s && $> > 0) {
3261 $CPAN::Frontend->myprint(qq{ You may have to su }.
3262 qq{to root to install the package\n});
3267 #-> sub CPAN::Distribution::dir ;
3269 shift->{'build_dir'};
3272 package CPAN::Bundle;
3274 #-> sub CPAN::Bundle::as_string ;
3278 $self->{INST_VERSION} = $self->inst_version;
3279 return $self->SUPER::as_string;
3282 #-> sub CPAN::Bundle::contains ;
3285 my($parsefile) = $self->inst_file;
3286 my($id) = $self->id;
3287 $self->debug("parsefile[$parsefile]id[$id]") if $CPAN::DEBUG;
3288 unless ($parsefile) {
3289 # Try to get at it in the cpan directory
3290 $self->debug("no parsefile") if $CPAN::DEBUG;
3291 Carp::confess "I don't know a $id" unless $self->{CPAN_FILE};
3292 my $dist = $CPAN::META->instance('CPAN::Distribution',
3293 $self->{CPAN_FILE});
3295 $self->debug($dist->as_string) if $CPAN::DEBUG;
3296 my($todir) = $CPAN::Config->{'cpan_home'};
3297 my(@me,$from,$to,$me);
3298 @me = split /::/, $self->id;
3300 $me = MM->catfile(@me);
3301 $from = $self->find_bundle_file($dist->{'build_dir'},$me);
3302 $to = MM->catfile($todir,$me);
3303 File::Path::mkpath(File::Basename::dirname($to));
3304 File::Copy::copy($from, $to)
3305 or Carp::confess("Couldn't copy $from to $to: $!");
3309 my $fh = FileHandle->new;
3311 open($fh,$parsefile) or die "Could not open '$parsefile': $!";
3313 $self->debug("parsefile[$parsefile]") if $CPAN::DEBUG;
3315 $inpod = m/^=(?!head1\s+CONTENTS)/ ? 0 :
3316 m/^=head1\s+CONTENTS/ ? 1 : $inpod;
3321 push @result, (split " ", $_, 2)[0];
3324 delete $self->{STATUS};
3325 $self->{CONTAINS} = join ", ", @result;
3326 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
3328 $CPAN::Frontend->mywarn(qq{
3329 The bundle file "$parsefile" may be a broken
3330 bundlefile. It seems not to contain any bundle definition.
3331 Please check the file and if it is bogus, please delete it.
3332 Sorry for the inconvenience.
3338 #-> sub CPAN::Bundle::find_bundle_file
3339 sub find_bundle_file {
3340 my($self,$where,$what) = @_;
3341 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
3342 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
3343 ### my $bu = MM->catfile($where,$what);
3344 ### return $bu if -f $bu;
3346 my $manifest = MM->catfile($where,"MANIFEST");
3347 unless (-f $manifest) {
3348 require ExtUtils::Manifest;
3349 my $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
3350 my $cwd = CPAN->$getcwd();
3352 ExtUtils::Manifest::mkmanifest();
3355 my $fh = FileHandle->new($manifest)
3356 or Carp::croak("Couldn't open $manifest: $!");
3360 my($file) = /(\S+)/;
3361 if ($file =~ m|\Q$what\E$|) {
3363 return MM->catfile($where,$bu);
3364 } elsif ($what =~ s|Bundle/||) { # retry if she managed to
3365 # have no Bundle directory
3366 if ($file =~ m|\Q$what\E$|) {
3368 return MM->catfile($where,$bu);
3372 Carp::croak("Couldn't find a Bundle file in $where");
3375 #-> sub CPAN::Bundle::inst_file ;
3379 ($me = $self->id) =~ s/.*://;
3380 ## my(@me,$inst_file);
3381 ## @me = split /::/, $self->id;
3382 ## $me[-1] .= ".pm";
3383 $inst_file = MM->catfile($CPAN::Config->{'cpan_home'},
3384 "Bundle", "$me.pm");
3386 return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
3388 $self->SUPER::inst_file;
3389 # return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
3390 # return $self->{'INST_FILE'}; # even if undefined?
3393 #-> sub CPAN::Bundle::rematein ;
3395 my($self,$meth) = @_;
3396 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
3397 my($id) = $self->id;
3398 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
3399 unless $self->inst_file || $self->{CPAN_FILE};
3401 for $s ($self->contains) {
3402 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
3403 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
3404 if ($type eq 'CPAN::Distribution') {
3405 $CPAN::Frontend->mywarn(qq{
3406 The Bundle }.$self->id.qq{ contains
3407 explicitly a file $s.
3411 $CPAN::META->instance($type,$s)->$meth();
3415 #sub CPAN::Bundle::xs_file
3417 # If a bundle contains another that contains an xs_file we have
3418 # here, we just don't bother I suppose
3422 #-> sub CPAN::Bundle::force ;
3423 sub force { shift->rematein('force',@_); }
3424 #-> sub CPAN::Bundle::get ;
3425 sub get { shift->rematein('get',@_); }
3426 #-> sub CPAN::Bundle::make ;
3427 sub make { shift->rematein('make',@_); }
3428 #-> sub CPAN::Bundle::test ;
3429 sub test { shift->rematein('test',@_); }
3430 #-> sub CPAN::Bundle::install ;
3433 $self->rematein('install',@_);
3434 $CPAN::META->delete('CPAN::Queue',$self->id);
3436 #-> sub CPAN::Bundle::clean ;
3437 sub clean { shift->rematein('clean',@_); }
3439 #-> sub CPAN::Bundle::readme ;
3442 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
3443 No File found for bundle } . $self->id . qq{\n}), return;
3444 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
3445 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
3448 package CPAN::Module;
3450 #-> sub CPAN::Module::as_glimpse ;
3454 my $class = ref($self);
3455 $class =~ s/^CPAN:://;
3456 push @m, sprintf("%-15s %-15s (%s)\n", $class, $self->{ID},
3461 #-> sub CPAN::Module::as_string ;
3465 CPAN->debug($self) if $CPAN::DEBUG;
3466 my $class = ref($self);
3467 $class =~ s/^CPAN:://;
3469 push @m, $class, " id = $self->{ID}\n";
3470 my $sprintf = " %-12s %s\n";
3471 push @m, sprintf($sprintf, 'DESCRIPTION', $self->{description})
3472 if $self->{description};
3473 my $sprintf2 = " %-12s %s (%s)\n";
3475 if ($userid = $self->{'CPAN_USERID'} || $self->{'userid'}){
3477 if ($author = CPAN::Shell->expand('Author',$userid)) {
3480 if ($m = $author->email) {
3487 $author->fullname . $email
3491 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->{CPAN_VERSION})
3492 if $self->{CPAN_VERSION};
3493 push @m, sprintf($sprintf, 'CPAN_FILE', $self->{CPAN_FILE})
3494 if $self->{CPAN_FILE};
3495 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
3496 my(%statd,%stats,%statl,%stati);
3497 @statd{qw,? i c a b R M S,} = qw,unknown idea
3498 pre-alpha alpha beta released mature standard,;
3499 @stats{qw,? m d u n,} = qw,unknown mailing-list
3500 developer comp.lang.perl.* none,;
3501 @statl{qw,? p c + o h,} = qw,unknown perl C C++ other hybrid,;
3502 @stati{qw,? f r O h,} = qw,unknown functions
3503 references+ties object-oriented hybrid,;
3504 $statd{' '} = 'unknown';
3505 $stats{' '} = 'unknown';
3506 $statl{' '} = 'unknown';
3507 $stati{' '} = 'unknown';
3515 $statd{$self->{statd}},
3516 $stats{$self->{stats}},
3517 $statl{$self->{statl}},
3518 $stati{$self->{stati}}
3519 ) if $self->{statd};
3520 my $local_file = $self->inst_file;
3522 $self->{MANPAGE} ||= $self->manpage_headline($local_file);
3525 for $item (qw/MANPAGE CONTAINS/) {
3526 push @m, sprintf($sprintf, $item, $self->{$item})
3527 if exists $self->{$item};
3529 push @m, sprintf($sprintf, 'INST_FILE',
3530 $local_file || "(not installed)");
3531 push @m, sprintf($sprintf, 'INST_VERSION',
3532 $self->inst_version) if $local_file;
3536 sub manpage_headline {
3537 my($self,$local_file) = @_;
3538 my(@local_file) = $local_file;
3539 $local_file =~ s/\.pm$/.pod/;
3540 push @local_file, $local_file;
3542 for $locf (@local_file) {
3543 next unless -f $locf;
3544 my $fh = FileHandle->new($locf)
3545 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
3549 $inpod = m/^=(?!head1\s+NAME)/ ? 0 :
3550 m/^=head1\s+NAME/ ? 1 : $inpod;
3563 #-> sub CPAN::Module::cpan_file ;
3566 CPAN->debug($self->id) if $CPAN::DEBUG;
3567 unless (defined $self->{'CPAN_FILE'}) {
3568 CPAN::Index->reload;
3570 if (exists $self->{'CPAN_FILE'} && defined $self->{'CPAN_FILE'}){
3571 return $self->{'CPAN_FILE'};
3572 } elsif (exists $self->{'userid'} && defined $self->{'userid'}) {
3573 my $fullname = $CPAN::META->instance(CPAN::Author,
3574 $self->{'userid'})->fullname;
3575 my $email = $CPAN::META->instance(CPAN::Author,
3576 $self->{'userid'})->email;
3577 unless (defined $fullname && defined $email) {
3578 return "Contact Author $self->{userid} (Try ``a $self->{userid}'')";
3580 return "Contact Author $fullname <$email>";
3586 *name = \&cpan_file;
3588 #-> sub CPAN::Module::cpan_version ;
3591 $self->{'CPAN_VERSION'} = 'undef'
3592 unless defined $self->{'CPAN_VERSION'}; # I believe this is
3593 # always a bug in the
3594 # index and should be
3596 # but usually I find
3598 # and do not want to
3601 $self->{'CPAN_VERSION'};
3604 #-> sub CPAN::Module::force ;
3607 $self->{'force_update'}++;
3610 #-> sub CPAN::Module::rematein ;
3612 my($self,$meth) = @_;
3613 $self->debug($self->id) if $CPAN::DEBUG;
3614 my $cpan_file = $self->cpan_file;
3615 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
3616 $CPAN::Frontend->mywarn(sprintf qq{
3617 The module %s isn\'t available on CPAN.
3619 Either the module has not yet been uploaded to CPAN, or it is
3620 temporary unavailable. Please contact the author to find out
3621 more about the status. Try ``i %s''.
3628 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
3629 $pack->called_for($self->id);
3630 $pack->force if exists $self->{'force_update'};
3632 delete $self->{'force_update'};
3635 #-> sub CPAN::Module::readme ;
3636 sub readme { shift->rematein('readme') }
3637 #-> sub CPAN::Module::look ;
3638 sub look { shift->rematein('look') }
3639 #-> sub CPAN::Module::get ;
3640 sub get { shift->rematein('get',@_); }
3641 #-> sub CPAN::Module::make ;
3642 sub make { shift->rematein('make') }
3643 #-> sub CPAN::Module::test ;
3644 sub test { shift->rematein('test') }
3645 #-> sub CPAN::Module::install ;
3649 my($latest) = $self->cpan_version;
3651 my($inst_file) = $self->inst_file;
3653 if (defined $inst_file) {
3654 $have = $self->inst_version;
3656 if (1){ # A block for scoping $^W, the if is just for the visual
3663 not exists $self->{'force_update'}
3665 $CPAN::Frontend->myprint( $self->id. " is up to date.\n");
3670 $self->rematein('install') if $doit;
3671 $CPAN::META->delete('CPAN::Queue',$self->id);
3673 #-> sub CPAN::Module::clean ;
3674 sub clean { shift->rematein('clean') }
3676 #-> sub CPAN::Module::inst_file ;
3680 @packpath = split /::/, $self->{ID};
3681 $packpath[-1] .= ".pm";
3682 foreach $dir (@INC) {
3683 my $pmfile = MM->catfile($dir,@packpath);
3691 #-> sub CPAN::Module::xs_file ;
3695 @packpath = split /::/, $self->{ID};
3696 push @packpath, $packpath[-1];
3697 $packpath[-1] .= "." . $Config::Config{'dlext'};
3698 foreach $dir (@INC) {
3699 my $xsfile = MM->catfile($dir,'auto',@packpath);
3707 #-> sub CPAN::Module::inst_version ;
3710 my $parsefile = $self->inst_file or return;
3711 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
3713 my $have = MM->parse_version($parsefile) || "undef";
3718 package CPAN::Tarzip;
3721 my($class,$read,$write) = @_;
3722 if ($CPAN::META->has_inst("Compress::Zlib")) {
3724 $fhw = FileHandle->new($read)
3725 or $CPAN::Frontend->mydie("Could not open $read: $!");
3726 my $gz = Compress::Zlib::gzopen($write, "wb")
3727 or $CPAN::Frontend->mydie("Cannot gzopen $write: $!\n");
3728 $gz->gzwrite($buffer)
3729 while read($fhw,$buffer,4096) > 0 ;
3734 system("$CPAN::Config->{'gzip'} -c $read > $write")==0;
3739 my($class,$read,$write) = @_;
3740 if ($CPAN::META->has_inst("Compress::Zlib")) {
3742 $fhw = FileHandle->new(">$write")
3743 or $CPAN::Frontend->mydie("Could not open >$write: $!");
3744 my $gz = Compress::Zlib::gzopen($read, "rb")
3745 or $CPAN::Frontend->mydie("Cannot gzopen $read: $!\n");
3746 $fhw->print($buffer)
3747 while $gz->gzread($buffer) > 0 ;
3748 $CPAN::Frontend->mydie("Error reading from $read: $!\n")
3749 if $gz->gzerror != Compress::Zlib::Z_STREAM_END();
3754 system("$CPAN::Config->{'gzip'} -dc $read > $write")==0;
3759 my($class,$read) = @_;
3760 if ($CPAN::META->has_inst("Compress::Zlib")) {
3762 my $gz = Compress::Zlib::gzopen($read, "rb")
3763 or $CPAN::Frontend->mydie("Cannot open $read: $!\n");
3764 1 while $gz->gzread($buffer) > 0 ;
3765 $CPAN::Frontend->mydie("Error reading from $read: $!\n")
3766 if $gz->gzerror != Compress::Zlib::Z_STREAM_END();
3770 return system("$CPAN::Config->{'gzip'} -dt $read")==0;
3775 my($class,$file) = @_;
3777 $class->debug("file[$file]");
3778 if ($CPAN::META->has_inst("Compress::Zlib")) {
3779 my $gz = Compress::Zlib::gzopen($file,"rb") or
3780 die "Could not gzopen $file";
3781 $ret = bless {GZ => $gz}, $class;
3783 my $pipe = "$CPAN::Config->{'gzip'} --decompress --stdout $file |";
3784 my $fh = FileHandle->new($pipe) or die "Could pipe[$pipe]: $!";
3786 $ret = bless {FH => $fh}, $class;
3793 if (exists $self->{GZ}) {
3794 my $gz = $self->{GZ};
3795 my($line,$bytesread);
3796 $bytesread = $gz->gzreadline($line);
3797 return undef if $bytesread == 0;
3800 my $fh = $self->{FH};
3801 return scalar <$fh>;
3806 my($self,$ref,$length,$offset) = @_;
3807 die "read with offset not implemented" if defined $offset;
3808 if (exists $self->{GZ}) {
3809 my $gz = $self->{GZ};
3810 my $byteread = $gz->gzread($$ref,$length);# 30eaf79e8b446ef52464b5422da328a8
3813 my $fh = $self->{FH};
3814 return read($fh,$$ref,$length);
3820 if (exists $self->{GZ}) {
3821 my $gz = $self->{GZ};
3824 my $fh = $self->{FH};
3831 my($class,$file) = @_;
3832 # had to disable, because version 0.07 seems to be buggy
3833 if (MM->maybe_command($CPAN::Config->{'gzip'})
3835 MM->maybe_command($CPAN::Config->{'tar'})) {
3836 my $system = "$CPAN::Config->{'gzip'} --decompress --stdout " .
3837 "$file | $CPAN::Config->{tar} xvf -";
3838 return system($system) == 0;
3839 } elsif ($CPAN::META->has_inst("Archive::Tar")
3841 $CPAN::META->has_inst("Compress::Zlib") ) {
3842 my $tar = Archive::Tar->new($file,1);
3843 $tar->extract($tar->list_files); # I'm pretty sure we have nothing
3844 # that isn't compressed
3847 $CPAN::Frontend->mydie(qq{
3848 CPAN.pm needs either both external programs tar and gzip installed or
3849 both the modules Archive::Tar and Compress::Zlib. Neither prerequisite
3850 is available. Can\'t continue.
3863 CPAN - query, download and build perl modules from CPAN sites
3869 perl -MCPAN -e shell;
3875 autobundle, clean, install, make, recompile, test
3879 The CPAN module is designed to automate the make and install of perl
3880 modules and extensions. It includes some searching capabilities and
3881 knows how to use Net::FTP or LWP (or lynx or an external ftp client)
3882 to fetch the raw data from the net.
3884 Modules are fetched from one or more of the mirrored CPAN
3885 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
3888 The CPAN module also supports the concept of named and versioned
3889 'bundles' of modules. Bundles simplify the handling of sets of
3890 related modules. See BUNDLES below.
3892 The package contains a session manager and a cache manager. There is
3893 no status retained between sessions. The session manager keeps track
3894 of what has been fetched, built and installed in the current
3895 session. The cache manager keeps track of the disk space occupied by
3896 the make processes and deletes excess space according to a simple FIFO
3899 For extended searching capabilities there's a plugin for CPAN available,
3900 L<CPAN::WAIT>. C<CPAN::WAIT> is a full-text search engine that indexes
3901 all documents available in CPAN authors directories. If C<CPAN::WAIT>
3902 is installed on your system, the interactive shell of <CPAN.pm> will
3903 enable the C<wq>, C<wr>, C<wd>, C<wl>, and C<wh> commands which send
3904 queries to the WAIT server that has been configured for your
3907 All other methods provided are accessible in a programmer style and in an
3908 interactive shell style.
3910 =head2 Interactive Mode
3912 The interactive mode is entered by running
3914 perl -MCPAN -e shell
3916 which puts you into a readline interface. You will have the most fun if
3917 you install Term::ReadKey and Term::ReadLine to enjoy both history and
3920 Once you are on the command line, type 'h' and the rest should be
3923 The most common uses of the interactive modes are
3927 =item Searching for authors, bundles, distribution files and modules
3929 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
3930 for each of the four categories and another, C<i> for any of the
3931 mentioned four. Each of the four entities is implemented as a class
3932 with slightly differing methods for displaying an object.
3934 Arguments you pass to these commands are either strings exactly matching
3935 the identification string of an object or regular expressions that are
3936 then matched case-insensitively against various attributes of the
3937 objects. The parser recognizes a regular expression only if you
3938 enclose it between two slashes.
3940 The principle is that the number of found objects influences how an
3941 item is displayed. If the search finds one item, the result is displayed
3942 as object-E<gt>as_string, but if we find more than one, we display
3943 each as object-E<gt>as_glimpse. E.g.
3947 EMAIL a.koenig@franz.ww.TU-Berlin.DE
3948 FULLNAME Andreas König
3953 EMAIL a.koenig@franz.ww.TU-Berlin.DE
3954 FULLNAME Andreas König
3958 Author ANDYD (Andy Dougherty)
3959 Author MERLYN (Randal L. Schwartz)
3961 =item make, test, install, clean modules or distributions
3963 These commands take any number of arguments and investigate what is
3964 necessary to perform the action. If the argument is a distribution
3965 file name (recognized by embedded slashes), it is processed. If it is a
3966 module, CPAN determines the distribution file in which this module is
3967 included and processes that.
3969 Any C<make> or C<test> are run unconditionally. An
3971 install <distribution_file>
3973 also is run unconditionally. But for
3977 CPAN checks if an install is actually needed for it and prints
3978 I<module up to date> in the case that the distribution file containing
3979 the module doesnE<39>t need to be updated.
3981 CPAN also keeps track of what it has done within the current session
3982 and doesnE<39>t try to build a package a second time regardless if it
3983 succeeded or not. The C<force> command takes as a first argument the
3984 method to invoke (currently: C<make>, C<test>, or C<install>) and executes the
3985 command from scratch.
3989 cpan> install OpenGL
3990 OpenGL is up to date.
3991 cpan> force install OpenGL
3994 OpenGL-0.4/COPYRIGHT
3997 A C<clean> command results in a
4001 being executed within the distribution file's working directory.
4003 =item readme, look module or distribution
4005 These two commands take only one argument, be it a module or a
4006 distribution file. C<readme> unconditionally runs, displaying the
4007 README of the associated distribution file. C<Look> gets and
4008 untars (if not yet done) the distribution file, changes to the
4009 appropriate directory and opens a subshell process in that directory.
4013 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
4014 in the cpan-shell it is intended that you can press C<^C> anytime and
4015 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
4016 to clean up and leave the shell loop. You can emulate the effect of a
4017 SIGTERM by sending two consecutive SIGINTs, which usually means by
4018 pressing C<^C> twice.
4020 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
4021 SIGALRM is used during the run of the C<perl Makefile.PL> subprocess.
4027 The commands that are available in the shell interface are methods in
4028 the package CPAN::Shell. If you enter the shell command, all your
4029 input is split by the Text::ParseWords::shellwords() routine which
4030 acts like most shells do. The first word is being interpreted as the
4031 method to be called and the rest of the words are treated as arguments
4032 to this method. Continuation lines are supported if a line ends with a
4037 C<autobundle> writes a bundle file into the
4038 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
4039 a list of all modules that are both available from CPAN and currently
4040 installed within @INC. The name of the bundle file is based on the
4041 current date and a counter.
4045 recompile() is a very special command in that it takes no argument and
4046 runs the make/test/install cycle with brute force over all installed
4047 dynamically loadable extensions (aka XS modules) with 'force' in
4048 effect. The primary purpose of this command is to finish a network
4049 installation. Imagine, you have a common source tree for two different
4050 architectures. You decide to do a completely independent fresh
4051 installation. You start on one architecture with the help of a Bundle
4052 file produced earlier. CPAN installs the whole Bundle for you, but
4053 when you try to repeat the job on the second architecture, CPAN
4054 responds with a C<"Foo up to date"> message for all modules. So you
4055 invoke CPAN's recompile on the second architecture and youE<39>re done.
4057 Another popular use for C<recompile> is to act as a rescue in case your
4058 perl breaks binary compatibility. If one of the modules that CPAN uses
4059 is in turn depending on binary compatibility (so you cannot run CPAN
4060 commands), then you should try the CPAN::Nox module for recovery.
4062 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
4064 Although it may be considered internal, the class hierarchy does matter
4065 for both users and programmer. CPAN.pm deals with above mentioned four
4066 classes, and all those classes share a set of methods. A classical
4067 single polymorphism is in effect. A metaclass object registers all
4068 objects of all kinds and indexes them with a string. The strings
4069 referencing objects have a separated namespace (well, not completely
4074 words containing a "/" (slash) Distribution
4075 words starting with Bundle:: Bundle
4076 everything else Module or Author
4078 Modules know their associated Distribution objects. They always refer
4079 to the most recent official release. Developers may mark their releases
4080 as unstable development versions (by inserting an underbar into the
4081 visible version number), so the really hottest and newest distribution
4082 file is not always the default. If a module Foo circulates on CPAN in
4083 both version 1.23 and 1.23_90, CPAN.pm offers a convenient way to
4084 install version 1.23 by saying
4088 This would install the complete distribution file (say
4089 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
4090 like to install version 1.23_90, you need to know where the
4091 distribution file resides on CPAN relative to the authors/id/
4092 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
4093 so you would have to say
4095 install BAR/Foo-1.23_90.tar.gz
4097 The first example will be driven by an object of the class
4098 CPAN::Module, the second by an object of class CPAN::Distribution.
4100 =head2 ProgrammerE<39>s interface
4102 If you do not enter the shell, the available shell commands are both
4103 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
4104 functions in the calling package (C<install(...)>).
4106 There's currently only one class that has a stable interface -
4107 CPAN::Shell. All commands that are available in the CPAN shell are
4108 methods of the class CPAN::Shell. Each of the commands that produce
4109 listings of modules (C<r>, C<autobundle>, C<u>) returns a list of the
4110 IDs of all modules within the list.
4114 =item expand($type,@things)
4116 The IDs of all objects available within a program are strings that can
4117 be expanded to the corresponding real objects with the
4118 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
4119 list of CPAN::Module objects according to the C<@things> arguments
4120 given. In scalar context it only returns the first element of the
4123 =item Programming Examples
4125 This enables the programmer to do operations that combine
4126 functionalities that are available in the shell.
4128 # install everything that is outdated on my disk:
4129 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
4131 # install my favorite programs if necessary:
4132 for $mod (qw(Net::FTP MD5 Data::Dumper)){
4133 my $obj = CPAN::Shell->expand('Module',$mod);
4137 # list all modules on my disk that have no VERSION number
4138 for $mod (CPAN::Shell->expand("Module","/./")){
4139 next unless $mod->inst_file;
4140 # MakeMaker convention for undefined $VERSION:
4141 next unless $mod->inst_version eq "undef";
4142 print "No VERSION in ", $mod->id, "\n";
4147 =head2 Methods in the four
4149 =head2 Cache Manager
4151 Currently the cache manager only keeps track of the build directory
4152 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
4153 deletes complete directories below C<build_dir> as soon as the size of
4154 all directories there gets bigger than $CPAN::Config->{build_cache}
4155 (in MB). The contents of this cache may be used for later
4156 re-installations that you intend to do manually, but will never be
4157 trusted by CPAN itself. This is due to the fact that the user might
4158 use these directories for building modules on different architectures.
4160 There is another directory ($CPAN::Config->{keep_source_where}) where
4161 the original distribution files are kept. This directory is not
4162 covered by the cache manager and must be controlled by the user. If
4163 you choose to have the same directory as build_dir and as
4164 keep_source_where directory, then your sources will be deleted with
4165 the same fifo mechanism.
4169 A bundle is just a perl module in the namespace Bundle:: that does not
4170 define any functions or methods. It usually only contains documentation.
4172 It starts like a perl module with a package declaration and a $VERSION
4173 variable. After that the pod section looks like any other pod with the
4174 only difference being that I<one special pod section> exists starting with
4179 In this pod section each line obeys the format
4181 Module_Name [Version_String] [- optional text]
4183 The only required part is the first field, the name of a module
4184 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
4185 of the line is optional. The comment part is delimited by a dash just
4186 as in the man page header.
4188 The distribution of a bundle should follow the same convention as
4189 other distributions.
4191 Bundles are treated specially in the CPAN package. If you say 'install
4192 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
4193 the modules in the CONTENTS section of the pod. You can install your
4194 own Bundles locally by placing a conformant Bundle file somewhere into
4195 your @INC path. The autobundle() command which is available in the
4196 shell interface does that for you by including all currently installed
4197 modules in a snapshot bundle file.
4199 =head2 Prerequisites
4201 If you have a local mirror of CPAN and can access all files with
4202 "file:" URLs, then you only need a perl better than perl5.003 to run
4203 this module. Otherwise Net::FTP is strongly recommended. LWP may be
4204 required for non-UNIX systems or if your nearest CPAN site is
4205 associated with an URL that is not C<ftp:>.
4207 If you have neither Net::FTP nor LWP, there is a fallback mechanism
4208 implemented for an external ftp command or for an external lynx
4211 =head2 Finding packages and VERSION
4213 This module presumes that all packages on CPAN
4219 declare their $VERSION variable in an easy to parse manner. This
4220 prerequisite can hardly be relaxed because it consumes far too much
4221 memory to load all packages into the running program just to determine
4222 the $VERSION variable. Currently all programs that are dealing with
4223 version use something like this
4225 perl -MExtUtils::MakeMaker -le \
4226 'print MM->parse_version(shift)' filename
4228 If you are author of a package and wonder if your $VERSION can be
4229 parsed, please try the above method.
4233 come as compressed or gzipped tarfiles or as zip files and contain a
4234 Makefile.PL (well, we try to handle a bit more, but without much
4241 The debugging of this module is pretty difficult, because we have
4242 interferences of the software producing the indices on CPAN, of the
4243 mirroring process on CPAN, of packaging, of configuration, of
4244 synchronicity, and of bugs within CPAN.pm.
4246 In interactive mode you can try "o debug" which will list options for
4247 debugging the various parts of the package. The output may not be very
4248 useful for you as it's just a by-product of my own testing, but if you
4249 have an idea which part of the package may have a bug, it's sometimes
4250 worth to give it a try and send me more specific output. You should
4251 know that "o debug" has built-in completion support.
4253 =head2 Floppy, Zip, and all that Jazz
4255 CPAN.pm works nicely without network too. If you maintain machines
4256 that are not networked at all, you should consider working with file:
4257 URLs. Of course, you have to collect your modules somewhere first. So
4258 you might use CPAN.pm to put together all you need on a networked
4259 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
4260 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
4261 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
4264 =head1 CONFIGURATION
4266 When the CPAN module is installed, a site wide configuration file is
4267 created as CPAN/Config.pm. The default values defined there can be
4268 overridden in another configuration file: CPAN/MyConfig.pm. You can
4269 store this file in $HOME/.cpan/CPAN/MyConfig.pm if you want, because
4270 $HOME/.cpan is added to the search path of the CPAN module before the
4271 use() or require() statements.
4273 Currently the following keys in the hash reference $CPAN::Config are
4276 build_cache size of cache for directories to build modules
4277 build_dir locally accessible directory to build modules
4278 index_expire after this many days refetch index files
4279 cpan_home local directory reserved for this package
4280 gzip location of external program gzip
4281 inactivity_timeout breaks interactive Makefile.PLs after this
4282 many seconds inactivity. Set to 0 to never break.
4283 inhibit_startup_message
4284 if true, does not print the startup message
4285 keep_source keep the source in a local directory?
4286 keep_source_where directory in which to keep the source (if we do)
4287 make location of external make program
4288 make_arg arguments that should always be passed to 'make'
4289 make_install_arg same as make_arg for 'make install'
4290 makepl_arg arguments passed to 'perl Makefile.PL'
4291 pager location of external program more (or any pager)
4292 tar location of external program tar
4293 unzip location of external program unzip
4294 urllist arrayref to nearby CPAN sites (or equivalent locations)
4295 wait_list arrayref to a wait server to try (See CPAN::WAIT)
4297 You can set and query each of these options interactively in the cpan
4298 shell with the command set defined within the C<o conf> command:
4302 =item o conf E<lt>scalar optionE<gt>
4304 prints the current value of the I<scalar option>
4306 =item o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>
4308 Sets the value of the I<scalar option> to I<value>
4310 =item o conf E<lt>list optionE<gt>
4312 prints the current value of the I<list option> in MakeMaker's
4315 =item o conf E<lt>list optionE<gt> [shift|pop]
4317 shifts or pops the array in the I<list option> variable
4319 =item o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>
4321 works like the corresponding perl commands.
4325 =head2 urllist parameter has CD-ROM support
4327 The C<urllist> parameter of the configuration table contains a list of
4328 URLs that are to be used for downloading. If the list contains any
4329 C<file> URLs, CPAN always tries to get files from there first. This
4330 feature is disabled for index files. So the recommendation for the
4331 owner of a CD-ROM with CPAN contents is: include your local, possibly
4332 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
4334 o conf urllist push file://localhost/CDROM/CPAN
4336 CPAN.pm will then fetch the index files from one of the CPAN sites
4337 that come at the beginning of urllist. It will later check for each
4338 module if there is a local copy of the most recent version.
4340 Another peculiarity of urllist is that the site that we could
4341 successfully fetch the last file from automatically gets a preference
4342 token and is tried as the first site for the next request. So if you
4343 add a new site at runtime it may happen that the previously preferred
4344 site will be tried another time. This means that if you want to disallow
4345 a site for the next transfer, it must be explicitly removed from
4350 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
4351 install foreign, unmasked, unsigned code on your machine. We compare
4352 to a checksum that comes from the net just as the distribution file
4353 itself. If somebody has managed to tamper with the distribution file,
4354 they may have as well tampered with the CHECKSUMS file. Future
4355 development will go towards strong authentification.
4359 Most functions in package CPAN are exported per default. The reason
4360 for this is that the primary use is intended for the cpan shell or for
4365 We should give coverage for _all_ of the CPAN and not just the PAUSE
4366 part, right? In this discussion CPAN and PAUSE have become equal --
4367 but they are not. PAUSE is authors/ and modules/. CPAN is PAUSE plus
4368 the clpa/, doc/, misc/, ports/, src/, scripts/.
4370 Future development should be directed towards a better integration of
4373 If a Makefile.PL requires special customization of libraries, prompts
4374 the user for special input, etc. then you may find CPAN is not able to
4375 build the distribution. In that case, you should attempt the
4376 traditional method of building a Perl module package from a shell.
4380 Andreas König E<lt>a.koenig@kulturbox.deE<gt>
4384 perl(1), CPAN::Nox(3)