2 use vars qw{$META $Signal $Cwd $End $Suppress_readline};
6 # $Id: CPAN.pm,v 1.121 1997/02/03 09:08:23 k Exp $
8 # my $version = substr q$Revision: 1.121 $, 10; # only used during development
15 use ExtUtils::MakeMaker ();
16 use File::Basename ();
22 use Text::ParseWords ();
27 END { $End++; &cleanup; }
49 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $term);
52 @CPAN::ISA = qw(CPAN::Debug Exporter MM); # the MM class from
56 $META ||= new CPAN; # In case we reeval ourselves we
59 CPAN::Config->load unless defined $CPAN::No_Config_is_ok;
62 autobundle bundle expand force get
63 install make readme recompile shell test clean
68 #-> sub CPAN::autobundle ;
70 #-> sub CPAN::bundle ;
72 #-> sub CPAN::expand ;
76 #-> sub CPAN::install ;
87 #-> sub CPAN::AUTOLOAD ;
92 @EXPORT{@EXPORT} = '';
93 if (exists $EXPORT{$l}){
96 warn "CPAN doesn't know how to autoload $AUTOLOAD :-(
105 my($mgr,$class) = @_;
106 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
108 values %{ $META->{$class} };
111 # Called by shell, not in batch mode. Not clean XXX
112 #-> sub CPAN::checklock ;
115 my $lockfile = CPAN->catfile($CPAN::Config->{cpan_home},".lock");
116 if (-f $lockfile && -M _ > 0) {
117 my $fh = FileHandle->new($lockfile);
120 if (defined $other && $other) {
122 return if $$==$other; # should never happen
123 print qq{There seems to be running another CPAN process }.
124 qq{($other). Trying to contact...\n};
125 if (kill 0, $other) {
126 Carp::croak qq{Other job is running.\n}.
127 qq{You may want to kill it and delete the lockfile, }.
128 qq{maybe. On UNIX try:\n}.
131 } elsif (-w $lockfile) {
133 ExtUtils::MakeMaker::prompt
134 (qq{Other job not responding. Shall I overwrite }.
135 qq{the lockfile? (Y/N)},"y");
136 print("Ok, bye\n"), exit unless $ans =~ /^y/i;
139 qq{Lockfile $lockfile not writeable by you. }.
140 qq{Cannot proceed.\n}.
143 qq{ and then rerun us.\n}
148 File::Path::mkpath($CPAN::Config->{cpan_home});
150 unless ($fh = FileHandle->new(">$lockfile")) {
151 if ($! =~ /Permission/) {
152 my $incc = $INC{'CPAN/Config.pm'};
153 my $myincc = MM->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
156 Your configuration suggests that CPAN.pm should use a working
158 $CPAN::Config->{cpan_home}
159 Unfortunately we could not create the lock file
161 due to permission problems.
163 Please make sure that the configuration variable
164 \$CPAN::Config->{cpan_home}
165 points to a directory where you can write a .lock file. You can set
166 this variable in either
173 Carp::croak "Could not open >$lockfile: $!";
176 $self->{LOCK} = $lockfile;
178 $SIG{'TERM'} = sub { &cleanup; die "Got SIGTERM, leaving"; };
180 my $s = $Signal == 2 ? "a second" : "another";
181 &cleanup, die "Got $s SIGINT" if $Signal;
184 $SIG{'__DIE__'} = \&cleanup;
185 print STDERR "Signal handler set.\n"
186 unless $CPAN::Config->{'inhibit_startup_message'};
189 #-> sub CPAN::DESTROY ;
191 &cleanup; # need an eval?
194 #-> sub CPAN::exists ;
196 my($mgr,$class,$id) = @_;
198 Carp::croak "exists called without class argument" unless $class;
200 exists $META->{$class}{$id};
203 #-> sub CPAN::hasFTP ;
207 return $self->{'hasFTP'} = $arg;
208 } elsif (not defined $self->{'hasFTP'}) {
209 eval {require Net::FTP;};
210 $self->{'hasFTP'} = $@ ? 0 : 1;
212 return $self->{'hasFTP'};
215 #-> sub CPAN::hasLWP ;
219 return $self->{'hasLWP'} = $arg;
220 } elsif (not defined $self->{'hasLWP'}) {
223 $self->{'hasLWP'} = $LWP::VERSION >= 4.98;
225 return $self->{'hasLWP'};
228 #-> sub CPAN::hasMD5 ;
232 $self->{'hasMD5'} = $arg;
233 } elsif (not defined $self->{'hasMD5'}) {
236 print "MD5 security checks disabled because MD5 not installed.
237 Please consider installing MD5\n";
238 $self->{'hasMD5'} = 0;
243 return $self->{'hasMD5'};
246 #-> sub CPAN::hasWAIT ;
250 $self->{'hasWAIT'} = $arg;
251 } elsif (not defined $self->{'hasWAIT'}) {
252 eval {require CPAN::WAIT;};
254 $self->{'hasWAIT'} = 0;
256 $self->{'hasWAIT'} = 1;
259 return $self->{'hasWAIT'};
262 #-> sub CPAN::instance ;
264 my($mgr,$class,$id) = @_;
266 Carp::croak "instance called without class argument" unless $class;
268 $META->{$class}{$id} ||= $class->new(ID => $id );
276 #-> sub CPAN::cleanup ;
278 local $SIG{__DIE__} = '';
279 my $i = 0; my $ineval = 0; my $sub;
280 while ((undef,undef,undef,$sub) = caller(++$i)) {
281 $ineval = 1, last if $sub eq '(eval)';
283 return if $ineval && !$End;
284 return unless defined $META->{'LOCK'};
285 return unless -f $META->{'LOCK'};
286 unlink $META->{'LOCK'};
287 print STDERR "Lockfile removed.\n";
288 # my $mess = Carp::longmess(@_);
292 #-> sub CPAN::shell ;
294 $Suppress_readline ||= ! -t STDIN;
296 my $prompt = "cpan> ";
298 unless ($Suppress_readline) {
299 require Term::ReadLine;
300 import Term::ReadLine;
301 $term = new Term::ReadLine 'CPAN Monitor';
302 $readline::rl_completion_function =
303 $readline::rl_completion_function = 'CPAN::Complete::complete';
308 my $cwd = Cwd::cwd();
309 # How should we determine if we have more than stub ReadLine enabled?
310 my $rl_avail = $Suppress_readline ? "suppressed" :
311 defined &Term::ReadLine::Perl::readline ? "enabled" :
312 "available (get Term::ReadKey and Term::ReadLine::Perl)";
315 cpan shell -- CPAN exploration and modules installation (v$CPAN::VERSION)
316 Readline support $rl_avail
318 } unless $CPAN::Config->{'inhibit_startup_message'} ;
320 if ($Suppress_readline) {
322 last unless defined ($_ = <>);
325 # if ($CPAN::DEBUG) {
328 # for $item (qw/ReadLine IN OUT MinLine findConsole Features/) {
329 # $report .= sprintf "%-15s", $item;
330 # $report .= $term->$item() || "";
333 # CPAN->debug($report);
335 last unless defined ($_ = $term->readline($prompt));
339 $_ = 'h' if $_ eq '?';
344 use vars qw($import_done);
345 CPAN->import(':DEFAULT') unless $import_done++;
346 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
349 } elsif (/^q(?:uit)?$/i) {
353 if ($] < 5.00322) { # parsewords had a bug until recently
356 eval { @line = Text::ParseWords::shellwords($_) };
357 warn($@), next if $@;
359 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
360 my $command = shift @line;
361 eval { CPAN::Shell->$command(@line) };
365 &cleanup, die if $Signal;
371 package CPAN::CacheMgr;
373 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj);
376 #-> sub CPAN::CacheMgr::as_string ;
378 eval { require Data::Dumper };
380 return shift->SUPER::as_string;
382 return Data::Dumper::Dumper(shift);
386 #-> sub CPAN::CacheMgr::cachesize ;
392 # my($self,@dirs) = @_;
393 # return unless -d $self->{ID};
395 # @dirs = $self->dirs unless @dirs;
397 # $self->disk_usage($dir);
401 #-> sub CPAN::CacheMgr::clean_cache ;
405 while ($self->{DU} > $self->{'MAX'} and $dir = shift @{$self->{FIFO}}) {
406 $self->force_clean_cache($dir);
408 $self->debug("leaving clean_cache with $self->{DU}") if $CPAN::DEBUG;
411 #-> sub CPAN::CacheMgr::dir ;
416 #-> sub CPAN::CacheMgr::entries ;
419 $dir ||= $self->{ID};
420 my($cwd) = Cwd::cwd();
421 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
422 my $dh = DirHandle->new(".") or Carp::croak("Couldn't opendir $dir: $!");
425 next if $_ eq "." || $_ eq "..";
427 push @entries, $CPAN::META->catfile($dir,$_);
429 push @entries, $CPAN::META->catdir($dir,$_);
431 print STDERR "Warning: weird direntry in $dir: $_\n";
434 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
435 sort {-M $b <=> -M $a} @entries;
438 #-> sub CPAN::CacheMgr::disk_usage ;
441 if (! defined $dir or $dir eq "") {
442 $self->debug("Cannot determine disk usage for some reason") if $CPAN::DEBUG;
445 return if defined $self->{SIZE}{$dir};
454 $self->{SIZE}{$dir} = $Du/1024/1024;
455 push @{$self->{FIFO}}, $dir;
456 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
457 $self->{DU} += $Du/1024/1024;
458 if ($self->{DU} > $self->{'MAX'} ) {
459 my($toremove) = $self->{FIFO}[0];
460 printf "...Hold on a sec... cleaning from cache (%.1f>%.1f MB): $toremove\n",
461 $self->{DU}, $self->{'MAX'};
464 $self->debug("NOT have to clean the cache: $self->{DU} <= $self->{'MAX'}")
466 $self->debug($self->as_string) if $CPAN::DEBUG;
471 #-> sub CPAN::CacheMgr::force_clean_cache ;
472 sub force_clean_cache {
474 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
476 File::Path::rmtree($dir);
477 $self->{DU} -= $self->{SIZE}{$dir};
478 delete $self->{SIZE}{$dir};
481 #-> sub CPAN::CacheMgr::new ;
485 ID => $CPAN::Config->{'build_dir'},
486 MAX => $CPAN::Config->{'build_cache'},
489 File::Path::mkpath($self->{ID});
490 my $dh = DirHandle->new($self->{ID});
492 $self->debug("dir [$self->{ID}]") if $CPAN::DEBUG;
494 for $e ($self->entries) {
495 next if $e eq ".." || $e eq ".";
496 $self->debug("Have to check size $e") if $CPAN::DEBUG;
497 $self->disk_usage($e);
504 #-> sub CPAN::Debug::debug ;
507 my($caller,$func,$line,@rest) = caller(1); # caller(0) eg
508 # Complete, caller(1)
510 ($caller) = caller(0);
512 # print "caller[$caller]func[$func]line[$line]rest[@rest]\n";
513 # print "CPAN::DEBUG{caller}[$CPAN::DEBUG{$caller}]CPAN::DEBUG[$CPAN::DEBUG]\n";
514 if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
516 eval { require Data::Dumper };
518 print $arg->as_string;
520 print Data::Dumper::Dumper($arg);
523 print "Debug($caller:$func,$line,@rest): $arg\n"
528 package CPAN::Config;
529 import ExtUtils::MakeMaker 'neatvalue';
533 'commit' => "Commit changes to disk",
534 'defaults' => "Reload defaults from disk",
535 'init' => "Interactive setting of all options",
538 #-> sub CPAN::Config::edit ;
540 my($class,@args) = @_;
542 CPAN->debug("class[$class]args[".join(" | ",@args)."]");
543 my($o,$str,$func,$args,$key_exists);
549 if (ref($CPAN::Config->{$o}) eq ARRAY) {
552 # Let's avoid eval, it's easier to comprehend without.
553 if ($func eq "push") {
554 push @{$CPAN::Config->{$o}}, @args;
555 } elsif ($func eq "pop") {
556 pop @{$CPAN::Config->{$o}};
557 } elsif ($func eq "shift") {
558 shift @{$CPAN::Config->{$o}};
559 } elsif ($func eq "unshift") {
560 unshift @{$CPAN::Config->{$o}}, @args;
561 } elsif ($func eq "splice") {
562 splice @{$CPAN::Config->{$o}}, @args;
564 $CPAN::Config->{$o} = [@args];
568 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$o}),
573 $CPAN::Config->{$o} = $args[0] if defined $args[0];
575 print defined $CPAN::Config->{$o} ? $CPAN::Config->{$o} : "UNDEFINED";
580 #-> sub CPAN::Config::commit ;
582 my($self,$configpm) = @_;
583 unless (defined $configpm){
584 $configpm ||= $INC{"CPAN/MyConfig.pm"};
585 $configpm ||= $INC{"CPAN/Config.pm"};
586 $configpm || Carp::confess(qq{
587 CPAN::Config::commit called without an argument.
588 Please specify a filename where to save the configuration or try
589 "o conf init" to have an interactive course through configing.
594 $mode = (stat $configpm)[2];
595 if ($mode && ! -w _) {
596 Carp::confess("$configpm is not writable");
600 my $msg = <<EOF unless $configpm =~ /MyConfig/;
602 # This is CPAN.pm's systemwide configuration file. This file provides
603 # defaults for users, and the values can be changed in a per-user configuration
604 # file. The user-config file is being looked for as ~/.cpan/CPAN/MyConfig.pm.
608 my($fh) = FileHandle->new;
609 open $fh, ">$configpm" or warn "Couldn't open >$configpm: $!";
610 print $fh qq[$msg\$CPAN::Config = \{\n];
611 foreach (sort keys %$CPAN::Config) {
614 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}),
619 print $fh "};\n1;\n__END__\n";
622 #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
623 #chmod $mode, $configpm;
625 print "commit: wrote $configpm\n";
629 *default = \&defaults;
630 #-> sub CPAN::Config::defaults ;
640 undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
650 #-> sub CPAN::Config::load ;
653 eval {require CPAN::Config;}; # We eval, because of some MakeMaker problems
654 unshift @INC, $CPAN::META->catdir($ENV{HOME},".cpan") unless $dot_cpan++;
655 eval {require CPAN::MyConfig;}; # where you can override system wide settings
656 unless ( $self->load_succeeded ) {
657 require CPAN::FirstTime;
659 if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
660 $configpm = $INC{"CPAN/Config.pm"};
661 } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
662 $configpm = $INC{"CPAN/MyConfig.pm"};
664 my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
665 my($configpmdir) = MM->catdir($path_to_cpan,"CPAN");
666 my($configpmtest) = MM->catfile($configpmdir,"Config.pm");
667 if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
668 if (-w $configpmtest) {
669 $configpm = $configpmtest;
670 } elsif (-w $configpmdir) {
671 #_#_# following code dumped core on me with 5.003_11, a.k.
672 unlink "$configpmtest.bak" if -f "$configpmtest.bak";
673 rename $configpmtest, "$configpmtest.bak" if -f $configpmtest;
674 my $fh = FileHandle->new;
675 if ($fh->open(">$configpmtest")) {
677 $configpm = $configpmtest;
679 # Should never happen
680 Carp::confess("Cannot open >$configpmtest");
685 $configpmdir = MM->catdir($ENV{HOME},".cpan","CPAN");
686 File::Path::mkpath($configpmdir);
687 $configpmtest = MM->catfile($configpmdir,"MyConfig.pm");
688 if (-w $configpmtest) {
689 $configpm = $configpmtest;
690 } elsif (-w $configpmdir) {
691 #_#_# following code dumped core on me with 5.003_11, a.k.
692 my $fh = FileHandle->new;
693 if ($fh->open(">$configpmtest")) {
695 $configpm = $configpmtest;
697 # Should never happen
698 Carp::confess("Cannot open >$configpmtest");
701 Carp::confess(qq{WARNING: CPAN.pm is unable to }.
702 qq{create a configuration file.});
706 CPAN->debug(qq{Calling CPAN::FirstTime::init("$configpm")})
710 $configpm initialized.
712 CPAN::FirstTime::init($configpm);
716 #-> sub CPAN::Config::load_succeeded ;
720 cpan_home keep_source_where build_dir build_cache index_expire
721 gzip tar unzip make pager makepl_arg make_arg make_install_arg
722 urllist inhibit_startup_message ftp_proxy http_proxy no_proxy
724 unless (defined $CPAN::Config->{$_}){
726 CPAN->debug("undefined configuration parameter $_") if $CPAN::DEBUG;
732 #-> sub CPAN::Config::unload ;
734 delete $INC{'CPAN/MyConfig.pm'};
735 delete $INC{'CPAN/Config.pm'};
739 #-> sub CPAN::Config::help ;
743 defaults reload default config values from disk
744 commit commit session changes to disk
745 init go through a dialog to set all parameters
747 You may edit key values in the follow fashion:
749 o conf build_cache 15
751 o conf build_dir "/foo/bar"
755 o conf urllist unshift ftp://ftp.foo.bar/
758 undef; #don't reprint CPAN::Config
761 #-> sub CPAN::Config::complete ;
763 my($word,$line,$pos) = @_;
765 my(@o_conf) = (keys %CPAN::Config::can, keys %$CPAN::Config);
766 return grep /^\Q$word\E/, @o_conf;
770 use vars qw($AUTOLOAD $redef @ISA);
771 @CPAN::Shell::ISA = qw(CPAN::Debug);
772 if ($CPAN::META->hasWAIT) {
773 unshift @ISA, "CPAN::WAIT";
775 # private function ro re-eval this module (handy during development)
776 #-> sub CPAN::Shell::AUTOLOAD ;
778 my($autoload) = $AUTOLOAD;
779 $autoload =~ s/.*:://;
780 if ($autoload =~ /^w/) {
781 if ($CPAN::META->hasWAIT) {
786 Commands starting with "w" require CPAN::WAIT to be installed.
787 Please consider installing CPAN::WAIT to use the fulltext index.
788 Type "install CPAN::WAIT" and restart CPAN.pm.
792 warn "CPAN::Shell doesn't know how to autoload $autoload :-(
799 #-> sub CPAN::Shell::h ;
801 my($class,$about) = @_;
802 if (defined $about) {
803 print "Detailed help not yet implemented\n";
806 command arguments description
809 d /regex/ info distributions
811 i none anything of above
813 r as reinstall recommendations
814 u above uninstalled distributions
815 See manpage for autobundle, recompile, force, look, etc.
818 test modules, make test (implies make)
819 install dists, bundles, make install (implies test)
820 clean "r" or "u" make clean
821 readme display the README file
823 reload index|cpan load most recent indices/CPAN.pm
824 h or ? display this menu
825 o various set and query options
826 ! perl-code eval a perl command
827 q quit the shell subroutine
832 #-> sub CPAN::Shell::a ;
833 sub a { print shift->format_result('Author',@_);}
834 #-> sub CPAN::Shell::b ;
836 my($self,@which) = @_;
837 CPAN->debug("which[@which]") if $CPAN::DEBUG;
838 my($incdir,$bdir,$dh);
839 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
840 $bdir = $CPAN::META->catdir($incdir,"Bundle");
841 if ($dh = DirHandle->new($bdir)) { # may fail
843 for $entry ($dh->read) {
844 next if -d $CPAN::META->catdir($bdir,$entry);
845 next unless $entry =~ s/\.pm$//;
846 $CPAN::META->instance('CPAN::Bundle',"Bundle::$entry");
850 print $self->format_result('Bundle',@which);
852 #-> sub CPAN::Shell::d ;
853 sub d { print shift->format_result('Distribution',@_);}
854 #-> sub CPAN::Shell::m ;
855 sub m { print shift->format_result('Module',@_);}
857 #-> sub CPAN::Shell::i ;
862 @type = qw/Author Bundle Distribution Module/;
863 @args = '/./' unless @args;
866 push @result, $self->expand($type,@args);
868 my $result = @result==1 ?
869 $result[0]->as_string :
870 join "", map {$_->as_glimpse} @result;
871 $result ||= "No objects found of any type for argument @args\n";
875 #-> sub CPAN::Shell::o ;
877 my($self,$o_type,@o_what) = @_;
879 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
880 if ($o_type eq 'conf') {
881 shift @o_what if @o_what && $o_what[0] eq 'help';
884 print "CPAN::Config options:\n";
885 for $k (sort keys %CPAN::Config::can) {
886 $v = $CPAN::Config::can{$k};
887 printf " %-18s %s\n", $k, $v;
890 for $k (sort keys %$CPAN::Config) {
891 $v = $CPAN::Config->{$k};
893 printf " %-18s\n", $k;
894 print map {"\t$_\n"} @{$v};
896 printf " %-18s %s\n", $k, $v;
900 } elsif (!CPAN::Config->edit(@o_what)) {
901 print qq[Type 'o conf' to view configuration edit options\n\n];
903 } elsif ($o_type eq 'debug') {
905 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
908 my($what) = shift @o_what;
909 if ( exists $CPAN::DEBUG{$what} ) {
910 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
911 } elsif ($what =~ /^\d/) {
912 $CPAN::DEBUG = $what;
913 } elsif (lc $what eq 'all') {
915 for (values %CPAN::DEBUG) {
920 for (keys %CPAN::DEBUG) {
921 next unless lc($_) eq lc($what);
922 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
924 print "unknown argument [$what]\n";
928 print "Valid options for debug are ".
929 join(", ",sort(keys %CPAN::DEBUG), 'all').
930 qq{ or a number. Completion works on the options. }.
931 qq{Case is ignored.\n\n};
934 print "Options set for debugging:\n";
936 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
937 $v = $CPAN::DEBUG{$k};
938 printf " %-14s(%s)\n", $k, $v if $v & $CPAN::DEBUG;
941 print "Debugging turned off completely.\n";
946 conf set or get configuration variables
947 debug set or get debugging options
952 #-> sub CPAN::Shell::reload ;
954 if ($_[1] =~ /cpan/i) {
955 CPAN->debug("reloading the whole CPAN.pm") if $CPAN::DEBUG;
956 my $fh = FileHandle->new($INC{'CPAN.pm'});
960 local($SIG{__WARN__})
962 if ( $_[0] =~ /Subroutine \w+ redefined/ ) {
972 print "\n$redef subroutines redefined\n";
973 } elsif ($_[1] =~ /index/) {
974 CPAN::Index->force_reload;
978 #-> sub CPAN::Shell::_binary_extensions ;
979 sub _binary_extensions {
980 my($self) = shift @_;
981 my(@result,$module,%seen,%need,$headerdone);
982 for $module ($self->expand('Module','/./')) {
983 my $file = $module->cpan_file;
984 next if $file eq "N/A";
985 next if $file =~ /^Contact Author/;
986 next if $file =~ /perl5[._-]\d{3}(?:[\d_]+)?\.tar[._-]gz$/;
987 next unless $module->xs_file;
990 push @result, $module;
992 # print join " | ", @result;
997 #-> sub CPAN::Shell::recompile ;
999 my($self) = shift @_;
1000 my($module,@module,$cpan_file,%dist);
1001 @module = $self->_binary_extensions();
1002 for $module (@module){ # we force now and compile later, so we don't do it twice
1003 $cpan_file = $module->cpan_file;
1004 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1006 $dist{$cpan_file}++;
1008 for $cpan_file (sort keys %dist) {
1009 print " CPAN: Recompiling $cpan_file\n\n";
1010 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1012 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1013 # stop a package from recompiling,
1014 # e.g. IO-1.12 when we have perl5.003_10
1018 #-> sub CPAN::Shell::_u_r_common ;
1020 my($self) = shift @_;
1021 my($what) = shift @_;
1022 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1023 Carp::croak "Usage: \$obj->_u_r_common($what)" unless defined $what;
1024 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless $what =~ /^[aru]$/;
1026 @args = '/./' unless @args;
1027 my(@result,$module,%seen,%need,$headerdone,$version_zeroes);
1028 $version_zeroes = 0;
1029 my $sprintf = "%-25s %9s %9s %s\n";
1030 for $module ($self->expand('Module',@args)) {
1031 my $file = $module->cpan_file;
1032 next unless defined $file; # ??
1033 my($latest) = $module->cpan_version || 0;
1034 my($inst_file) = $module->inst_file;
1038 $have = $module->inst_version;
1039 } elsif ($what eq "r") {
1040 $have = $module->inst_version;
1042 $version_zeroes++ unless $have;
1043 next if $have >= $latest;
1044 } elsif ($what eq "u") {
1050 } elsif ($what eq "r") {
1052 } elsif ($what eq "u") {
1056 return if $CPAN::Signal; # this is sometimes lengthy
1059 push @result, sprintf "%s %s\n", $module->id, $have;
1060 } elsif ($what eq "r") {
1061 push @result, $module->id;
1062 next if $seen{$file}++;
1063 } elsif ($what eq "u") {
1064 push @result, $module->id;
1065 next if $seen{$file}++;
1066 next if $file =~ /^Contact/;
1068 unless ($headerdone++){
1072 "Package namespace",
1078 $latest = substr($latest,0,8) if length($latest) > 8;
1079 $have = substr($have,0,8) if length($have) > 8;
1080 printf $sprintf, $module->id, $have, $latest, $file;
1081 $need{$module->id}++;
1085 print "No modules found for @args\n";
1086 } elsif ($what eq "r") {
1087 print "All modules are up to date for @args\n";
1090 if ($what eq "r" && $version_zeroes) {
1091 my $s = $version_zeroes>1 ? "s have" : " has";
1092 print qq{$version_zeroes installed module$s no version number to compare\n};
1097 #-> sub CPAN::Shell::r ;
1099 shift->_u_r_common("r",@_);
1102 #-> sub CPAN::Shell::u ;
1104 shift->_u_r_common("u",@_);
1107 #-> sub CPAN::Shell::autobundle ;
1110 my(@bundle) = $self->_u_r_common("a",@_);
1111 my($todir) = $CPAN::META->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1112 File::Path::mkpath($todir);
1113 unless (-d $todir) {
1114 print "Couldn't mkdir $todir for some reason\n";
1117 my($y,$m,$d) = (localtime)[5,4,3];
1121 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1122 my($to) = $CPAN::META->catfile($todir,"$me.pm");
1124 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1125 $to = $CPAN::META->catfile($todir,"$me.pm");
1127 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1129 "package Bundle::$me;\n\n",
1130 "\$VERSION = '0.01';\n\n",
1134 "Bundle::$me - Snapshot of installation on ",
1135 $Config::Config{'myhostname'},
1138 "\n\n=head1 SYNOPSIS\n\n",
1139 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1140 "=head1 CONTENTS\n\n",
1141 join("\n", @bundle),
1142 "\n\n=head1 CONFIGURATION\n\n",
1144 "\n\n=head1 AUTHOR\n\n",
1145 "This Bundle has been generated automatically ",
1146 "by the autobundle routine in CPAN.pm.\n",
1149 print "\nWrote bundle file
1153 #-> sub CPAN::Shell::expand ;
1156 my($type,@args) = @_;
1160 if ($arg =~ m|^/(.*)/$|) {
1163 my $class = "CPAN::$type";
1165 if (defined $regex) {
1166 for $obj ( sort {$a->id cmp $b->id} $CPAN::META->all($class)) {
1169 $obj->id =~ /$regex/i
1173 $] < 5.00303 ### provide sort of compatibility with 5.003
1178 $obj->name =~ /$regex/i
1183 if ( $type eq 'Bundle' ) {
1184 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
1186 if ($CPAN::META->exists($class,$xarg)) {
1187 $obj = $CPAN::META->instance($class,$xarg);
1188 } elsif ($CPAN::META->exists($class,$arg)) {
1189 $obj = $CPAN::META->instance($class,$arg);
1199 #-> sub CPAN::Shell::format_result ;
1202 my($type,@args) = @_;
1203 @args = '/./' unless @args;
1204 my(@result) = $self->expand($type,@args);
1205 my $result = @result==1 ?
1206 $result[0]->as_string :
1207 join "", map {$_->as_glimpse} @result;
1208 $result ||= "No objects of type $type found for argument @args\n";
1212 #-> sub CPAN::Shell::rematein ;
1215 my($meth,@some) = @_;
1217 if ($meth eq 'force') {
1219 $meth = shift @some;
1221 CPAN->debug("pragma[$pragma]meth[$meth] some[@some]") if $CPAN::DEBUG;
1223 foreach $s (@some) {
1227 } elsif ($s =~ m|/|) { # looks like a file
1228 $obj = $CPAN::META->instance('CPAN::Distribution',$s);
1229 } elsif ($s =~ m|^Bundle::|) {
1230 $obj = $CPAN::META->instance('CPAN::Bundle',$s);
1232 $obj = $CPAN::META->instance('CPAN::Module',$s)
1233 if $CPAN::META->exists('CPAN::Module',$s);
1237 qq{pragma[$pragma] meth[$meth] obj[$obj] as_string\[}.
1245 ($] < 5.00303 || $obj->can($pragma)); ### compatibility with 5.003
1247 } elsif ($CPAN::META->exists('CPAN::Author',$s)) {
1248 $obj = $CPAN::META->instance('CPAN::Author',$s);
1249 print "Don't be silly, you can't $meth ", $obj->fullname, " ;-)\n";
1251 print "Warning: Cannot $meth $s, don't know what it is\n";
1256 #-> sub CPAN::Shell::force ;
1257 sub force { shift->rematein('force',@_); }
1258 #-> sub CPAN::Shell::get ;
1259 sub get { shift->rematein('get',@_); }
1260 #-> sub CPAN::Shell::readme ;
1261 sub readme { shift->rematein('readme',@_); }
1262 #-> sub CPAN::Shell::make ;
1263 sub make { shift->rematein('make',@_); }
1264 #-> sub CPAN::Shell::test ;
1265 sub test { shift->rematein('test',@_); }
1266 #-> sub CPAN::Shell::install ;
1267 sub install { shift->rematein('install',@_); }
1268 #-> sub CPAN::Shell::clean ;
1269 sub clean { shift->rematein('clean',@_); }
1270 #-> sub CPAN::Shell::look ;
1271 sub look { shift->rematein('look',@_); }
1275 @CPAN::FTP::ISA = qw(CPAN::Debug);
1277 #-> sub CPAN::FTP::ftp_get ;
1279 my($class,$host,$dir,$file,$target) = @_;
1281 qq[Going to fetch file [$file] from dir [$dir]
1282 on host [$host] as local [$target]\n]
1284 my $ftp = Net::FTP->new($host);
1285 return 0 unless defined $ftp;
1286 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
1287 $class->debug(qq[Going to ->login("anonymous","$Config::Config{'cf_email'}")\n]);
1288 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
1289 warn "Couldn't login on $host";
1292 # print qq[Going to ->cwd("$dir")\n];
1293 unless ( $ftp->cwd($dir) ){
1294 warn "Couldn't cwd $dir";
1298 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
1299 unless ( $ftp->get($file,$target) ){
1300 warn "Couldn't fetch $file from $host\n";
1303 $ftp->quit; # it's ok if this fails
1307 #-> sub CPAN::FTP::localize ;
1309 my($self,$file,$aslocal,$force) = @_;
1311 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
1312 unless defined $aslocal;
1313 $self->debug("file [$file] aslocal [$aslocal]") if $CPAN::DEBUG;
1315 return $aslocal if -f $aslocal && -r _ && ! $force;
1317 my($aslocal_dir) = File::Basename::dirname($aslocal);
1318 File::Path::mkpath($aslocal_dir);
1319 print STDERR qq{Warning: You are not allowed to write into }.
1320 qq{directory "$aslocal_dir".
1321 I\'ll continue, but if you face any problems, they may be due
1322 to insufficient permissions.\n} unless -w $aslocal_dir;
1324 # Inheritance is not easier to manage than a few if/else branches
1325 if ($CPAN::META->hasLWP) {
1326 require LWP::UserAgent;
1328 $Ua = new LWP::UserAgent;
1330 $Ua->proxy('ftp', $var)
1331 if $var = $CPAN::Config->{'ftp_proxy'} || $ENV{'ftp_proxy'};
1332 $Ua->proxy('http', $var)
1333 if $var = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
1335 if $var = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
1339 # Try the list of urls for each single object. We keep a record
1340 # where we did get a file from
1342 for $i (0..$#{$CPAN::Config->{urllist}}) {
1343 my $url = $CPAN::Config->{urllist}[$i];
1344 $url .= "/" unless substr($url,-1) eq "/";
1346 $self->debug("localizing[$url]") if $CPAN::DEBUG;
1347 if ($url =~ /^file:/) {
1349 if ($CPAN::META->hasLWP) {
1351 my $u = new URI::URL $url;
1353 } else { # works only on Unix, is poorly constructed, but
1354 # hopefully better than nothing.
1355 # RFC 1738 says fileurl BNF is
1356 # fileurl = "file://" [ host | "localhost" ] "/" fpath
1357 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for the code
1358 ($l = $url) =~ s,^file://[^/]+,,; # discard the host part
1359 $l =~ s/^file://; # assume they meant file://localhost
1361 return $l if -f $l && -r _;
1362 # Maybe mirror has compressed it?
1364 $self->debug("found compressed $l.gz");
1365 system("$CPAN::Config->{gzip} -dc $l.gz > $aslocal");
1366 return $aslocal if -f $aslocal;
1370 if ($CPAN::META->hasLWP) {
1371 print "Fetching $url with LWP\n";
1372 my $res = $Ua->mirror($url, $aslocal);
1373 if ($res->is_success) {
1377 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
1378 # that's the nice and easy way thanks to Graham
1379 my($host,$dir,$getfile) = ($1,$2,$3);
1380 if ($CPAN::META->hasFTP) {
1382 $self->debug("Going to fetch file [$getfile]
1385 as local [$aslocal]") if $CPAN::DEBUG;
1386 CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal) && return $aslocal;
1387 warn "Net::FTP failed for some reason\n";
1390 Please, install Net::FTP as soon as possible. Just type
1398 # Came back if Net::FTP couldn't establish connection (or failed otherwise)
1399 # Maybe they are behind a firewall, but they gave us
1400 # a socksified (or other) ftp program...
1403 # does ncftp handle http?
1404 for $funkyftp ($CPAN::Config->{'lynx'},$CPAN::Config->{'ncftp'}) {
1405 next unless defined $funkyftp;
1406 next unless -x $funkyftp;
1407 my($want_compressed);
1410 Trying with $funkyftp to get
1413 $want_compressed = $aslocal =~ s/\.gz//;
1414 my($source_switch) = "";
1415 $source_switch = "-source" if $funkyftp =~ /\blynx$/;
1416 my($system) = "$funkyftp $source_switch '$url' > $aslocal";
1418 if (($wstatus = system($system)) == 0) {
1419 if ($want_compressed) {
1420 $system = "$CPAN::Config->{'gzip'} -dt $aslocal";
1421 if (system($system)==0) {
1422 rename $aslocal, "$aslocal.gz";
1424 $system = "$CPAN::Config->{'gzip'} $aslocal";
1427 return "$aslocal.gz";
1429 $system = "$CPAN::Config->{'gzip'} -dt $aslocal";
1430 if (system($system)==0) {
1431 $system = "$CPAN::Config->{'gzip'} -d $aslocal";
1434 # should be fine, eh?
1439 my $estatus = $wstatus >> 8;
1441 System call "$system"
1442 returned status $estatus (wstat $wstatus)
1447 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
1448 my($host,$dir,$getfile) = ($1,$2,$3);
1450 if (-x $CPAN::Config->{'ftp'}) {
1452 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
1453 $ctime,$blksize,$blocks) = stat($aslocal);
1454 $timestamp = $mtime ||=0;
1456 my($netrc) = CPAN::FTP::netrc->new;
1457 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
1459 my $targetfile = File::Basename::basename($aslocal);
1465 map("cd $_", split "/", $dir), # RFC 1738
1467 "get $getfile $targetfile",
1470 if (! $netrc->netrc) {
1471 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
1472 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
1475 "hasdef[%d]cont($host)[%d]",
1477 $netrc->contains($host)
1480 if ($netrc->protected) {
1483 Trying with external ftp to get
1485 As this requires some features that are not thoroughly tested, we\'re
1486 not sure, that we get it right....
1490 my $fh = FileHandle->new;
1491 $fh->open("|$CPAN::Config->{'ftp'}$verbose $host")
1492 or die "Couldn't open ftp: $!";
1493 # pilot is blind now
1494 CPAN->debug("dialog [".(join "|",@dialog)."]")
1496 foreach (@dialog) { $fh->print("$_\n") }
1497 $fh->close; # Wait for process to complete
1499 my $estatus = $wstatus >> 8;
1501 Subprocess "|$CPAN::Config->{'ftp'}$verbose $host"
1502 returned status $estatus (wstat $wstatus)
1504 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1505 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
1507 if ($mtime > $timestamp) {
1508 print "GOT $aslocal\n";
1511 print "Hmm... Still failed!\n";
1514 warn "Your $netrcfile is not correctly protected.\n";
1517 warn "Your ~/.netrc neither contains $host
1518 nor does it have a default entry\n";
1521 # OK, they don't have a valid ~/.netrc. Use 'ftp -n' then and
1522 # login manually to host, using e-mail as password.
1523 print qq{Issuing "$CPAN::Config->{'ftp'}$verbose -n"\n};
1527 "user anonymous $Config::Config{'cf_email'}"
1529 CPAN->debug("dialog [".(join "|",@dialog)."]") if $CPAN::DEBUG;
1530 $fh = FileHandle->new;
1531 $fh->open("|$CPAN::Config->{'ftp'}$verbose -n") or
1532 die "Cannot fork: $!\n";
1533 foreach (@dialog) { $fh->print("$_\n") }
1536 my $estatus = $wstatus >> 8;
1538 Subprocess "|$CPAN::Config->{'ftp'}$verbose -n"
1539 returned status $estatus (wstat $wstatus)
1541 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1542 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
1544 if ($mtime > $timestamp) {
1545 print "GOT $aslocal\n";
1548 print "Bad luck... Still failed!\n";
1554 print "Can't access URL $url.\n\n";
1556 push @mess, "LWP" unless CPAN->hasLWP;
1557 push @mess, "Net::FTP" unless CPAN->hasFTP;
1559 for $ext (qw/lynx ncftp ftp/) {
1560 $CPAN::Config->{$ext} ||= "";
1561 push @mess, "an external $ext" unless -x $CPAN::Config->{$ext};
1563 $mess = qq{Either get }.
1565 qq{ or check, if the URL found in your configuration file, }.
1566 $CPAN::Config->{urllist}[$i].
1568 print Text::Wrap::wrap("","",$mess), "\n";
1570 print "Cannot fetch $file\n";
1574 package CPAN::FTP::netrc;
1578 my $file = MM->catfile($ENV{HOME},".netrc");
1580 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1581 $atime,$mtime,$ctime,$blksize,$blocks)
1586 my($fh,@machines,$hasdefault);
1588 $fh = FileHandle->new or die "Could not create a filehandle";
1590 if($fh->open($file)){
1591 $protected = ($mode & 077) == 0;
1593 NETRC: while (<$fh>) {
1594 my(@tokens) = split " ", $_;
1595 TOKEN: while (@tokens) {
1596 my($t) = shift @tokens;
1597 if ($t eq "default"){
1599 warn "saw a default entry before tokens[@tokens]";
1602 last TOKEN if $t eq "macdef";
1603 if ($t eq "machine") {
1604 push @machines, shift @tokens;
1609 $file = $hasdefault = $protected = "";
1613 'mach' => [@machines],
1615 'hasdefault' => $hasdefault,
1616 'protected' => $protected,
1620 sub hasdefault { shift->{'hasdefault'} }
1621 sub netrc { shift->{'netrc'} }
1622 sub protected { shift->{'protected'} }
1624 my($self,$mach) = @_;
1625 for ( @{$self->{'mach'}} ) {
1626 return 1 if $_ eq $mach;
1631 package CPAN::Complete;
1632 @CPAN::Complete::ISA = qw(CPAN::Debug);
1634 #-> sub CPAN::Complete::complete ;
1636 my($word,$line,$pos) = @_;
1640 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1642 if ($line =~ s/^(force\s*)//) {
1650 ! a b d h i m o q r u autobundle clean
1651 make test install force reload look
1654 } elsif ( $line !~ /^[\!abdhimorutl]/ ) {
1656 } elsif ($line =~ /^a\s/) {
1657 @return = completex('CPAN::Author',$word);
1658 } elsif ($line =~ /^b\s/) {
1659 @return = completex('CPAN::Bundle',$word);
1660 } elsif ($line =~ /^d\s/) {
1661 @return = completex('CPAN::Distribution',$word);
1662 } elsif ($line =~ /^([mru]|make|clean|test|install|readme|look)\s/ ) {
1663 @return = (completex('CPAN::Module',$word),completex('CPAN::Bundle',$word));
1664 } elsif ($line =~ /^i\s/) {
1665 @return = complete_any($word);
1666 } elsif ($line =~ /^reload\s/) {
1667 @return = complete_reload($word,$line,$pos);
1668 } elsif ($line =~ /^o\s/) {
1669 @return = complete_option($word,$line,$pos);
1676 #-> sub CPAN::Complete::completex ;
1678 my($class, $word) = @_;
1679 grep /^\Q$word\E/, map { $_->id } $CPAN::META->all($class);
1682 #-> sub CPAN::Complete::complete_any ;
1686 completex('CPAN::Author',$word),
1687 completex('CPAN::Bundle',$word),
1688 completex('CPAN::Distribution',$word),
1689 completex('CPAN::Module',$word),
1693 #-> sub CPAN::Complete::complete_reload ;
1694 sub complete_reload {
1695 my($word,$line,$pos) = @_;
1697 my(@words) = split " ", $line;
1698 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1699 my(@ok) = qw(cpan index);
1700 return @ok if @words==1;
1701 return grep /^\Q$word\E/, @ok if @words==2 && $word;
1704 #-> sub CPAN::Complete::complete_option ;
1705 sub complete_option {
1706 my($word,$line,$pos) = @_;
1708 my(@words) = split " ", $line;
1709 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1710 my(@ok) = qw(conf debug);
1711 return @ok if @words==1;
1712 return grep /^\Q$word\E/, @ok if @words==2 && $word;
1714 } elsif ($words[1] eq 'index') {
1716 } elsif ($words[1] eq 'conf') {
1717 return CPAN::Config::complete(@_);
1718 } elsif ($words[1] eq 'debug') {
1719 return sort grep /^\Q$word\E/, sort keys %CPAN::DEBUG, 'all';
1723 package CPAN::Index;
1724 use vars qw($last_time);
1725 @CPAN::Index::ISA = qw(CPAN::Debug);
1728 #-> sub CPAN::Index::force_reload ;
1731 $CPAN::Index::last_time = 0;
1735 #-> sub CPAN::Index::reload ;
1737 my($cl,$force) = @_;
1740 # XXX check if a newer one is available. (We currently read it from time to time)
1741 return if $last_time + $CPAN::Config->{index_expire}*86400 > $time;
1744 $cl->read_authindex($cl->reload_x(
1745 "authors/01mailrc.txt.gz",
1748 return if $CPAN::Signal; # this is sometimes lengthy
1749 $cl->read_modpacks($cl->reload_x(
1750 "modules/02packages.details.txt.gz",
1753 return if $CPAN::Signal; # this is sometimes lengthy
1754 $cl->read_modlist($cl->reload_x(
1755 "modules/03modlist.data.gz",
1760 #-> sub CPAN::Index::reload_x ;
1762 my($cl,$wanted,$localname,$force) = @_;
1764 my $abs_wanted = CPAN->catfile($CPAN::Config->{'keep_source_where'},$localname);
1765 if (-f $abs_wanted &&
1766 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
1768 my($s) = $CPAN::Config->{'index_expire'} != 1;
1769 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
1770 qq{day$s. I\'ll use that.\n});
1775 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
1778 #-> sub CPAN::Index::read_authindex ;
1779 sub read_authindex {
1780 my($cl,$index_target) = @_;
1781 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $index_target";
1782 warn "Going to read $index_target\n";
1783 my $fh = FileHandle->new("$pipe|");
1786 my($userid,$fullname,$email) = /alias\s+(\S+)\s+\"([^\"\<]+)\s+<([^\>]+)\>\"/;
1787 next unless $userid && $fullname && $email;
1789 # instantiate an author object
1790 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
1791 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
1792 return if $CPAN::Signal;
1795 $? and Carp::croak "FAILED $pipe: exit status [$?]";
1798 #-> sub CPAN::Index::read_modpacks ;
1800 my($cl,$index_target) = @_;
1801 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $index_target";
1802 warn "Going to read $index_target\n";
1803 my $fh = FileHandle->new("$pipe|");
1807 my($mod,$version,$dist) = split;
1808 $version =~ s/^\+//;
1810 # if it as a bundle, instatiate a bundle object
1812 if ($mod =~ /^Bundle::(.*)/) {
1816 if ($mod eq 'CPAN') {
1818 if ($version > $CPAN::VERSION){
1820 Hey, you know what? There\'s a new CPAN.pm version (v$version)
1821 available! I\'d suggest--provided you have time--you try
1824 without quitting the current session. It should be a seemless upgrade
1825 while we are running...
1830 last if $CPAN::Signal;
1835 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
1836 $id->set('CPAN_VERSION' => $version, 'CPAN_FILE' => $dist);
1837 # This "next" makes us faster but if the job is running long, we ignore
1838 # rereads which is bad. So we have to be a bit slower again.
1839 # } elsif ($CPAN::META->exists('CPAN::Module',$mod)) {
1842 # instantiate a module object
1843 $id = $CPAN::META->instance('CPAN::Module',$mod);
1844 $id->set('CPAN_VERSION' => $version, 'CPAN_FILE' => $dist);
1847 # determine the author
1848 my($userid) = $dist =~ /([^\/]+)/;
1849 $id->set('CPAN_USERID' => $userid) if $userid =~ /\w/;
1851 # instantiate a distribution object
1852 unless ($CPAN::META->exists('CPAN::Distribution',$dist)) {
1853 $CPAN::META->instance(
1854 'CPAN::Distribution' => $dist
1856 'CPAN_USERID' => $userid
1861 return if $CPAN::Signal;
1864 $? and Carp::croak "FAILED $pipe: exit status [$?]";
1867 #-> sub CPAN::Index::read_modlist ;
1869 my($cl,$index_target) = @_;
1870 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $index_target";
1871 warn "Going to read $index_target\n";
1872 my $fh = FileHandle->new("$pipe|");
1876 next if /use vars/; # will go away in 03...
1878 return if $CPAN::Signal;
1880 $eval .= q{CPAN::Modulelist->data;};
1882 my($comp) = Safe->new("CPAN::Safe1");
1883 my $ret = $comp->reval($eval);
1884 Carp::confess($@) if $@;
1885 return if $CPAN::Signal;
1887 my $obj = $CPAN::META->instance(CPAN::Module,$_);
1888 $obj->set(%{$ret->{$_}});
1889 return if $CPAN::Signal;
1893 package CPAN::InfoObj;
1894 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
1896 #-> sub CPAN::InfoObj::new ;
1897 sub new { my $this = bless {}, shift; %$this = @_; $this }
1899 #-> sub CPAN::InfoObj::set ;
1901 my($self,%att) = @_;
1902 my(%oldatt) = %$self;
1903 %$self = (%oldatt, %att);
1906 #-> sub CPAN::InfoObj::id ;
1907 sub id { shift->{'ID'} }
1909 #-> sub CPAN::InfoObj::as_glimpse ;
1913 my $class = ref($self);
1914 $class =~ s/^CPAN:://;
1915 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
1919 #-> sub CPAN::InfoObj::as_string ;
1923 my $class = ref($self);
1924 $class =~ s/^CPAN:://;
1925 push @m, $class, " id = $self->{ID}\n";
1926 for (sort keys %$self) {
1929 $_ eq "CPAN_USERID" and $extra = " (".$self->author.")";
1930 if (ref($self->{$_}) eq "ARRAY") { # Should we setup a language interface? XXX
1931 push @m, sprintf " %-12s %s%s\n", $_, "@{$self->{$_}}", $extra;
1933 push @m, sprintf " %-12s %s%s\n", $_, $self->{$_}, $extra;
1939 #-> sub CPAN::InfoObj::author ;
1942 $CPAN::META->instance(CPAN::Author,$self->{CPAN_USERID})->fullname;
1945 package CPAN::Author;
1946 @CPAN::Author::ISA = qw(CPAN::InfoObj);
1948 #-> sub CPAN::Author::as_glimpse ;
1952 my $class = ref($self);
1953 $class =~ s/^CPAN:://;
1954 push @m, sprintf "%-15s %s (%s)\n", $class, $self->{ID}, $self->fullname;
1958 # Dead code, I would have liked to have,,, but it was never reached,,,
1961 # return "Don't be silly, you can't make $self->{FULLNAME} ;-)\n";
1964 #-> sub CPAN::Author::fullname ;
1965 sub fullname { shift->{'FULLNAME'} }
1967 #-> sub CPAN::Author::email ;
1968 sub email { shift->{'EMAIL'} }
1970 package CPAN::Distribution;
1971 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
1973 #-> sub CPAN::Distribution::called_for ;
1976 $self->{'CALLED_FOR'} = $id if defined $id;
1977 return $self->{'CALLED_FOR'};
1980 #-> sub CPAN::Distribution::get ;
1985 exists $self->{'build_dir'} and push @e,
1986 "Unwrapped into directory $self->{'build_dir'}";
1987 print join "", map {" $_\n"} @e and return if @e;
1992 $CPAN::Config->{keep_source_where},
1995 split("/",$self->{ID})
1998 $self->debug("Doing localize") if $CPAN::DEBUG;
1999 $local_file = CPAN::FTP->localize("authors/id/$self->{ID}", $local_wanted);
2000 $self->{localfile} = $local_file;
2001 my $builddir = $CPAN::META->{cachemgr}->dir;
2002 $self->debug("doing chdir $builddir") if $CPAN::DEBUG;
2003 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
2006 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
2007 if ($CPAN::META->hasMD5) {
2010 if ($local_file =~ /(\.tar\.(gz|Z)|\.tgz|\.zip)$/i){
2011 $self->debug("Removing tmp") if $CPAN::DEBUG;
2012 File::Path::rmtree("tmp");
2013 mkdir "tmp", 0777 or Carp::croak "Couldn't mkdir tmp: $!";
2015 $self->debug("Changed directory to tmp") if $CPAN::DEBUG;
2016 if ($local_file =~ /z$/i){
2017 $self->{archived} = "tar";
2018 if (system("$CPAN::Config->{gzip} --decompress --stdout $local_file | $CPAN::Config->{tar} xvf -")==0) {
2019 $self->{unwrapped} = "YES";
2021 $self->{unwrapped} = "NO";
2023 } elsif ($local_file =~ /zip$/i) {
2024 $self->{archived} = "zip";
2025 if (system("$CPAN::Config->{unzip} $local_file")==0) {
2026 $self->{unwrapped} = "YES";
2028 $self->{unwrapped} = "NO";
2031 # Let's check if the package has its own directory.
2032 opendir DIR, "." or Carp::croak("Weird: couldn't opendir .: $!");
2033 my @readdir = grep $_ !~ /^\.\.?$/, readdir DIR; ### MAC??
2035 my ($distdir,$packagedir);
2036 if (@readdir == 1 && -d $readdir[0]) {
2037 $distdir = $readdir[0];
2038 $packagedir = $CPAN::META->catdir($builddir,$distdir);
2039 -d $packagedir and print "Removing previously used $packagedir\n";
2040 File::Path::rmtree($packagedir);
2041 rename($distdir,$packagedir) or Carp::confess("Couldn't rename $distdir to $packagedir: $!");
2043 my $pragmatic_dir = $self->{'CPAN_USERID'} . '000';
2044 $pragmatic_dir =~ s/\W_//g;
2045 $pragmatic_dir++ while -d "../$pragmatic_dir";
2046 $packagedir = $CPAN::META->catdir($builddir,$pragmatic_dir);
2047 File::Path::mkpath($packagedir);
2049 for $f (@readdir) { # is already without "." and ".."
2050 my $to = $CPAN::META->catdir($packagedir,$f);
2051 rename($f,$to) or Carp::confess("Couldn't rename $f to $to: $!");
2054 $self->{'build_dir'} = $packagedir;
2057 $self->debug("Changed directory to .. (self is $self [".$self->as_string."])")
2059 File::Path::rmtree("tmp");
2060 if ($CPAN::Config->{keep_source_where} =~ /^no/i ){
2061 print "Going to unlink $local_file\n";
2062 unlink $local_file or Carp::carp "Couldn't unlink $local_file";
2064 my($makefilepl) = $CPAN::META->catfile($packagedir,"Makefile.PL");
2065 unless (-f $makefilepl) {
2066 my($configure) = $CPAN::META->catfile($packagedir,"Configure");
2067 if (-f $configure) {
2068 # do we have anything to do?
2069 $self->{'configure'} = $configure;
2071 my $fh = FileHandle->new(">$makefilepl")
2072 or Carp::croak("Could not open >$makefilepl");
2073 my $cf = $self->called_for || "unknown";
2075 # This Makefile.PL has been autogenerated by the module CPAN.pm
2076 # Autogenerated on: }.scalar localtime().qq{
2077 use ExtUtils::MakeMaker;
2078 WriteMakefile(NAME => q[$cf]);
2080 print qq{Package comes without Makefile.PL.\n}.
2081 qq{ Writing one on our own (calling it $cf)\n};
2085 $self->{archived} = "NO";
2090 #-> sub CPAN::Distribution::new ;
2092 my($class,%att) = @_;
2094 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
2096 my $this = { %att };
2097 return bless $this, $class;
2100 #-> sub CPAN::Distribution::look ;
2103 if ( $CPAN::Config->{'shell'} ) {
2105 Trying to open a subshell in the build directory...
2109 Your configuration does not define a value for subshells.
2110 Please define it with "o conf shell <your shell>"
2114 my $dist = $self->id;
2115 my $dir = $self->dir or $self->get;
2117 my $pwd = Cwd::cwd();
2119 print qq{Working directory is $dir.\n};
2120 system($CPAN::Config->{'shell'})==0 or die "Subprocess shell error";
2124 #-> sub CPAN::Distribution::readme ;
2127 my($dist) = $self->id;
2128 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
2129 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
2133 $CPAN::Config->{keep_source_where},
2136 split("/","$sans.readme"),
2138 $self->debug("Doing localize") if $CPAN::DEBUG;
2139 $local_file = CPAN::FTP->localize("authors/id/$sans.readme", $local_wanted);
2140 my $fh_pager = FileHandle->new;
2141 $fh_pager->open("|$CPAN::Config->{'pager'}")
2142 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
2143 my $fh_readme = FileHandle->new;
2144 $fh_readme->open($local_file) or die "Could not open $local_file: $!";
2145 $fh_pager->print(<$fh_readme>);
2148 #-> sub CPAN::Distribution::verifyMD5 ;
2153 $self->{MD5_STATUS} ||= "";
2154 $self->{MD5_STATUS} eq "OK" and push @e, "MD5 Checksum was ok";
2155 print join "", map {" $_\n"} @e and return if @e;
2158 my(@local) = split("/",$self->{ID});
2159 my($basename) = pop @local;
2160 push @local, "CHECKSUMS";
2163 $CPAN::Config->{keep_source_where},
2172 $self->MD5_check_file($local_wanted,$basename)
2174 return $self->{MD5_STATUS} = "OK";
2176 $local_file = CPAN::FTP->localize(
2177 "authors/id/@local",
2184 $local[-1] .= ".gz";
2185 $local_file = CPAN::FTP->localize(
2186 "authors/id/@local",
2190 my $system = "$CPAN::Config->{gzip} --decompress $local_file";
2191 system($system)==0 or die "Could not uncompress $local_file";
2192 $local_file =~ s/\.gz$//;
2194 $self->MD5_check_file($local_file,$basename);
2197 #-> sub CPAN::Distribution::MD5_check_file ;
2198 sub MD5_check_file {
2199 my($self,$lfile,$basename) = @_;
2201 my $fh = new FileHandle;
2203 if (open $fh, $lfile){
2206 my($comp) = Safe->new();
2207 $cksum = $comp->reval($eval);
2208 Carp::confess($@) if $@;
2209 if ($cksum->{$basename}->{md5}) {
2210 $self->debug("Found checksum for $basename: $cksum->{$basename}->{md5}\n")
2212 my $file = $self->{localfile};
2213 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $self->{localfile}|";
2215 open($fh, $file) && $self->eq_MD5($fh,$cksum->{$basename}->{md5})
2217 open($fh, $pipe) && $self->eq_MD5($fh,$cksum->{$basename}->{'md5-ungz'})
2219 print "Checksum for $file ok\n";
2220 return $self->{MD5_STATUS} = "OK";
2224 qq{Checksum mismatch for distribution file. },
2225 qq{Please investigate.\n\n}
2227 print $self->as_string;
2228 print $CPAN::META->instance(
2230 $self->{CPAN_USERID}
2232 my $wrap = qq{I\'d recommend removing $self->{'localfile'}}.
2233 qq{, put another URL at the top of the list of URLs to }.
2234 qq{visit, and restart CPAN.pm. If all this doesn\'t help, }.
2235 qq{please contact the author or your CPAN site admin};
2236 print Text::Wrap::wrap("","",$wrap);
2241 close $fh if fileno($fh);
2243 $self->{MD5_STATUS} ||= "";
2244 if ($self->{MD5_STATUS} eq "NIL") {
2245 print "\nNo md5 checksum for $basename in local $lfile.";
2246 print "Removing $lfile\n";
2247 unlink $lfile or print "Could not unlink: $!";
2250 $self->{MD5_STATUS} = "NIL";
2254 Carp::carp "Could not open $lfile for reading";
2258 #-> sub CPAN::Distribution::eq_MD5 ;
2260 my($self,$fh,$expectMD5) = @_;
2263 my $hexdigest = $md5->hexdigest;
2264 $hexdigest eq $expectMD5;
2267 #-> sub CPAN::Distribution::force ;
2270 $self->{'force_update'}++;
2271 delete $self->{'MD5_STATUS'};
2272 delete $self->{'archived'};
2273 delete $self->{'build_dir'};
2274 delete $self->{'localfile'};
2275 delete $self->{'make'};
2276 delete $self->{'install'};
2277 delete $self->{'unwrapped'};
2278 delete $self->{'writemakefile'};
2281 #-> sub CPAN::Distribution::make ;
2284 $self->debug($self->id) if $CPAN::DEBUG;
2285 print "Running make\n";
2289 $self->{archived} eq "NO" and push @e,
2290 "Is neither a tar nor a zip archive.";
2292 $self->{unwrapped} eq "NO" and push @e,
2293 "had problems unarchiving. Please build manually";
2295 exists $self->{writemakefile} &&
2296 $self->{writemakefile} eq "NO" and push @e,
2297 "Had some problem writing Makefile";
2299 defined $self->{'make'} and push @e,
2300 "Has already been processed within this session";
2302 print join "", map {" $_\n"} @e and return if @e;
2304 print "\n CPAN.pm: Going to build ".$self->id."\n\n";
2305 my $builddir = $self->dir;
2306 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
2307 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
2310 if ($self->{'configure'}) {
2311 $system = $self->{'configure'};
2313 my($perl) = MM->file_name_is_absolute($^X) ? $^X : "";
2314 $perl ||= "$CPAN::Cwd/$^X" if -x "$CPAN::Cwd/$^X";
2316 my ($component,$perl_name);
2317 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
2318 DIST_COMPONENT: foreach $component (MM->path(), $Config::Config{'binexp'}) {
2319 next unless defined($component) && $component;
2320 my($abs) = MM->catfile($component,$perl_name);
2321 if (MM->maybe_command($abs)) {
2328 die "Couldn\'t find executable perl\n" unless $perl;
2329 $system = "$perl Makefile.PL $CPAN::Config->{makepl_arg}";
2331 $SIG{ALRM} = sub { die "inactivity_timeout reached\n" };
2334 if ($CPAN::Config->{inactivity_timeout}) {
2336 alarm $CPAN::Config->{inactivity_timeout};
2337 #$SIG{CHLD} = \&REAPER;
2338 if (defined($pid=fork)) {
2345 print "Cannot fork: $!";
2348 $ret = system($system);
2352 $ret = system($system);
2358 $self->{writemakefile} = "NO - $@";
2361 } elsif ($ret != 0) {
2362 $self->{writemakefile} = "NO";
2365 $self->{writemakefile} = "YES";
2366 return if $CPAN::Signal;
2367 $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
2368 if (system($system)==0) {
2369 print " $system -- OK\n";
2370 $self->{'make'} = "YES";
2372 $self->{writemakefile} = "YES";
2373 $self->{'make'} = "NO";
2374 print " $system -- NOT OK\n";
2378 #-> sub CPAN::Distribution::test ;
2382 return if $CPAN::Signal;
2383 print "Running make test\n";
2386 exists $self->{'make'} or push @e,
2387 "Make had some problems, maybe interrupted? Won't test";
2389 exists $self->{'make'} and
2390 $self->{'make'} eq 'NO' and
2391 push @e, "Oops, make had returned bad status";
2393 exists $self->{'build_dir'} or push @e, "Has no own directory";
2394 print join "", map {" $_\n"} @e and return if @e;
2396 chdir $self->{'build_dir'} or Carp::croak("Couldn't chdir to $self->{'build_dir'}");
2397 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
2398 my $system = join " ", $CPAN::Config->{'make'}, "test";
2399 if (system($system)==0) {
2400 print " $system -- OK\n";
2401 $self->{'make_test'} = "YES";
2403 $self->{'make_test'} = "NO";
2404 print " $system -- NOT OK\n";
2408 #-> sub CPAN::Distribution::clean ;
2411 print "Running make clean\n";
2414 exists $self->{'build_dir'} or push @e, "Has no own directory";
2415 print join "", map {" $_\n"} @e and return if @e;
2417 chdir $self->{'build_dir'} or Carp::croak("Couldn't chdir to $self->{'build_dir'}");
2418 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
2419 my $system = join " ", $CPAN::Config->{'make'}, "clean";
2420 if (system($system)==0) {
2421 print " $system -- OK\n";
2424 # Hmmm, what to do if make clean failed?
2428 #-> sub CPAN::Distribution::install ;
2432 return if $CPAN::Signal;
2433 print "Running make install\n";
2436 exists $self->{'build_dir'} or push @e, "Has no own directory";
2438 exists $self->{'make'} or push @e,
2439 "Make had some problems, maybe interrupted? Won't install";
2441 exists $self->{'make'} and
2442 $self->{'make'} eq 'NO' and
2443 push @e, "Oops, make had returned bad status";
2445 exists $self->{'install'} and push @e,
2446 $self->{'install'} eq "YES" ?
2447 "Already done" : "Already tried without success";
2449 print join "", map {" $_\n"} @e and return if @e;
2451 chdir $self->{'build_dir'} or Carp::croak("Couldn't chdir to $self->{'build_dir'}");
2452 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
2453 my $system = join " ", $CPAN::Config->{'make'}, "install", $CPAN::Config->{make_install_arg};
2454 my($pipe) = FileHandle->new("$system 2>&1 |");
2462 print " $system -- OK\n";
2463 $self->{'install'} = "YES";
2465 $self->{'install'} = "NO";
2466 print " $system -- NOT OK\n";
2467 if ($makeout =~ /permission/s && $> > 0) {
2468 print " You may have to su to root to install the package\n";
2473 #-> sub CPAN::Distribution::dir ;
2475 shift->{'build_dir'};
2478 package CPAN::Bundle;
2479 @CPAN::Bundle::ISA = qw(CPAN::Module);
2481 #-> sub CPAN::Bundle::as_string ;
2485 $self->{INST_VERSION} = $self->inst_version;
2486 return $self->SUPER::as_string;
2489 #-> sub CPAN::Bundle::contains ;
2492 my($parsefile) = $self->inst_file;
2493 unless ($parsefile) {
2494 # Try to get at it in the cpan directory
2495 $self->debug("no parsefile") if $CPAN::DEBUG;
2496 my $dist = $CPAN::META->instance('CPAN::Distribution',$self->{'CPAN_FILE'});
2497 $self->debug($dist->as_string) if $CPAN::DEBUG;
2499 $self->debug($dist->as_string) if $CPAN::DEBUG;
2500 my($todir) = $CPAN::META->catdir($CPAN::Config->{'cpan_home'},"Bundle");
2501 File::Path::mkpath($todir);
2503 ($me = $self->id) =~ s/.*://;
2504 $from = $CPAN::META->catfile($dist->{'build_dir'},"$me.pm");
2505 $to = $CPAN::META->catfile($todir,"$me.pm");
2506 File::Copy::copy($from, $to) or Carp::confess("Couldn't copy $from to $to: $!");
2510 my $fh = new FileHandle;
2512 open($fh,$parsefile) or die "Could not open '$parsefile': $!";
2515 $inpod = /^=(?!head1\s+CONTENTS)/ ? 0 : /^=head1\s+CONTENTS/ ? 1 : $inpod;
2520 push @result, (split " ", $_, 2)[0];
2523 delete $self->{STATUS};
2524 $self->{CONTAINS} = [@result];
2528 #-> sub CPAN::Bundle::inst_file ;
2532 ($me = $self->id) =~ s/.*://;
2533 $inst_file = $CPAN::META->catfile($CPAN::Config->{'cpan_home'},"Bundle", "$me.pm");
2534 return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
2535 $inst_file = $self->SUPER::inst_file;
2536 return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
2537 return $self->{'INST_FILE'}; # even if undefined?
2540 #-> sub CPAN::Bundle::rematein ;
2542 my($self,$meth) = @_;
2543 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
2545 for $s ($self->contains) {
2546 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
2547 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
2548 if ($type eq 'CPAN::Distribution') {
2550 The Bundle }.$self->id.qq{ contains
2551 explicitly a file $s.
2555 $CPAN::META->instance($type,$s)->$meth();
2559 #-> sub CPAN::Bundle::force ;
2560 sub force { shift->rematein('force',@_); }
2561 #-> sub CPAN::Bundle::get ;
2562 sub get { shift->rematein('get',@_); }
2563 #-> sub CPAN::Bundle::make ;
2564 sub make { shift->rematein('make',@_); }
2565 #-> sub CPAN::Bundle::test ;
2566 sub test { shift->rematein('test',@_); }
2567 #-> sub CPAN::Bundle::install ;
2568 sub install { shift->rematein('install',@_); }
2569 #-> sub CPAN::Bundle::clean ;
2570 sub clean { shift->rematein('clean',@_); }
2572 #-> sub CPAN::Bundle::readme ;
2575 my($file) = $self->cpan_file or print("No File found for bundle ", $self->id, "\n"), return;
2576 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
2577 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
2580 package CPAN::Module;
2581 @CPAN::Module::ISA = qw(CPAN::InfoObj);
2583 #-> sub CPAN::Module::as_glimpse ;
2587 my $class = ref($self);
2588 $class =~ s/^CPAN:://;
2589 push @m, sprintf "%-15s %-15s (%s)\n", $class, $self->{ID}, $self->cpan_file;
2593 #-> sub CPAN::Module::as_string ;
2597 CPAN->debug($self) if $CPAN::DEBUG;
2598 my $class = ref($self);
2599 $class =~ s/^CPAN:://;
2601 push @m, $class, " id = $self->{ID}\n";
2602 my $sprintf = " %-12s %s\n";
2603 push @m, sprintf $sprintf, 'DESCRIPTION', $self->{description} if $self->{description};
2604 my $sprintf2 = " %-12s %s (%s)\n";
2606 if ($userid = $self->{'CPAN_USERID'} || $self->{'userid'}){
2611 $CPAN::META->instance(CPAN::Author,$userid)->fullname
2614 push @m, sprintf $sprintf, 'CPAN_VERSION', $self->{CPAN_VERSION} if $self->{CPAN_VERSION};
2615 push @m, sprintf $sprintf, 'CPAN_FILE', $self->{CPAN_FILE} if $self->{CPAN_FILE};
2616 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
2617 my(%statd,%stats,%statl,%stati);
2618 @statd{qw,? i c a b R M S,} = qw,unknown idea pre-alpha alpha beta released mature standard,;
2619 @stats{qw,? m d u n,} = qw,unknown mailing-list developer comp.lang.perl.* none,;
2620 @statl{qw,? p c + o,} = qw,unknown perl C C++ other,;
2621 @stati{qw,? f r O,} = qw,unknown functions references+ties object-oriented,;
2622 $statd{' '} = 'unknown';
2623 $stats{' '} = 'unknown';
2624 $statl{' '} = 'unknown';
2625 $stati{' '} = 'unknown';
2633 $statd{$self->{statd}},
2634 $stats{$self->{stats}},
2635 $statl{$self->{statl}},
2636 $stati{$self->{stati}}
2637 ) if $self->{statd};
2638 my $local_file = $self->inst_file;
2639 if ($local_file && ! exists $self->{MANPAGE}) {
2640 my $fh = FileHandle->new($local_file) or Carp::croak("Couldn't open $local_file: $!");
2645 $inpod = /^=(?!head1\s+NAME)/ ? 0 : /^=head1\s+NAME/ ? 1 : $inpod;
2653 $self->{MANPAGE} = join " ", @result;
2655 push @m, sprintf $sprintf, 'MANPAGE', $self->{MANPAGE} if $self->{MANPAGE};
2656 push @m, sprintf $sprintf, 'INST_FILE', $local_file || "(not installed)";
2657 push @m, sprintf $sprintf, 'INST_VERSION', $self->inst_version if $local_file;
2661 #-> sub CPAN::Module::cpan_file ;
2664 CPAN->debug($self->id) if $CPAN::DEBUG;
2665 unless (defined $self->{'CPAN_FILE'}) {
2666 CPAN::Index->reload;
2668 if (defined $self->{'CPAN_FILE'}){
2669 return $self->{'CPAN_FILE'};
2670 } elsif (defined $self->{'userid'}) {
2671 return "Contact Author ".$self->{'userid'}."=".$CPAN::META->instance(CPAN::Author,$self->{'userid'})->fullname
2677 *name = \&cpan_file;
2679 #-> sub CPAN::Module::cpan_version ;
2680 sub cpan_version { shift->{'CPAN_VERSION'} }
2682 #-> sub CPAN::Module::force ;
2685 $self->{'force_update'}++;
2688 #-> sub CPAN::Module::rematein ;
2690 my($self,$meth) = @_;
2691 $self->debug($self->id) if $CPAN::DEBUG;
2692 my $cpan_file = $self->cpan_file;
2693 return if $cpan_file eq "N/A";
2694 return if $cpan_file =~ /^Contact Author/;
2695 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
2696 $pack->called_for($self->id);
2697 $pack->force if exists $self->{'force_update'};
2699 delete $self->{'force_update'};
2702 #-> sub CPAN::Module::readme ;
2703 sub readme { shift->rematein('readme') }
2704 #-> sub CPAN::Module::look ;
2705 sub look { shift->rematein('look') }
2706 #-> sub CPAN::Module::get ;
2707 sub get { shift->rematein('get',@_); }
2708 #-> sub CPAN::Module::make ;
2709 sub make { shift->rematein('make') }
2710 #-> sub CPAN::Module::test ;
2711 sub test { shift->rematein('test') }
2712 #-> sub CPAN::Module::install ;
2716 my($latest) = $self->cpan_version;
2718 my($inst_file) = $self->inst_file;
2720 if (defined $inst_file) {
2721 $have = $self->inst_version;
2723 if ($inst_file && $have >= $latest && not exists $self->{'force_update'}) {
2724 print $self->id, " is up to date.\n";
2728 $self->rematein('install') if $doit;
2730 #-> sub CPAN::Module::clean ;
2731 sub clean { shift->rematein('clean') }
2733 #-> sub CPAN::Module::inst_file ;
2737 @packpath = split /::/, $self->{ID};
2738 $packpath[-1] .= ".pm";
2739 foreach $dir (@INC) {
2740 my $pmfile = CPAN->catfile($dir,@packpath);
2747 #-> sub CPAN::Module::xs_file ;
2751 @packpath = split /::/, $self->{ID};
2752 push @packpath, $packpath[-1];
2753 $packpath[-1] .= "." . $Config::Config{'dlext'};
2754 foreach $dir (@INC) {
2755 my $xsfile = CPAN->catfile($dir,'auto',@packpath);
2762 #-> sub CPAN::Module::inst_version ;
2765 my $parsefile = $self->inst_file or return 0;
2766 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
2767 my $have = MM->parse_version($parsefile);
2778 CPAN - query, download and build perl modules from CPAN sites
2784 perl -MCPAN -e shell;
2790 autobundle, clean, install, make, recompile, test
2794 The CPAN module is designed to automate the make and install of perl
2795 modules and extensions. It includes some searching capabilities and
2796 knows how to use Net::FTP or LWP (or lynx or an external ftp client)
2797 to fetch the raw data from the net.
2799 Modules are fetched from one or more of the mirrored CPAN
2800 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
2803 The CPAN module also supports the concept of named and versioned
2804 'bundles' of modules. Bundles simplify the handling of sets of
2805 related modules. See BUNDLES below.
2807 The package contains a session manager and a cache manager. There is
2808 no status retained between sessions. The session manager keeps track
2809 of what has been fetched, built and installed in the current
2810 session. The cache manager keeps track of the disk space occupied by
2811 the make processes and deletes excess space according to a simple FIFO
2814 All methods provided are accessible in a programmer style and in an
2815 interactive shell style.
2817 =head2 Interactive Mode
2819 The interactive mode is entered by running
2821 perl -MCPAN -e shell
2823 which puts you into a readline interface. You will have most fun if
2824 you install Term::ReadKey and Term::ReadLine to enjoy both history and
2827 Once you are on the command line, type 'h' and the rest should be
2830 The most common uses of the interactive modes are
2834 =item Searching for authors, bundles, distribution files and modules
2836 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
2837 for each of the four categories and another, C<i> for any of the
2838 mentioned four. Each of the four entities is implemented as a class
2839 with slightly differing methods for displaying an object.
2841 Arguments you pass to these commands are either strings matching exact
2842 the identification string of an object or regular expressions that are
2843 then matched case-insensitively against various attributes of the
2844 objects. The parser recognizes a regualar expression only if you
2845 enclose it between two slashes.
2847 The principle is that the number of found objects influences how an
2848 item is displayed. If the search finds one item, we display the result
2849 of object-E<gt>as_string, but if we find more than one, we display
2850 each as object-E<gt>as_glimpse. E.g.
2854 EMAIL a.koenig@franz.ww.TU-Berlin.DE
2855 FULLNAME Andreas König
2860 EMAIL a.koenig@franz.ww.TU-Berlin.DE
2861 FULLNAME Andreas König
2865 Author ANDYD (Andy Dougherty)
2866 Author MERLYN (Randal L. Schwartz)
2868 =item make, test, install, clean modules or distributions
2870 These commands do indeed exist just as written above. Each of them
2871 takes any number of arguments and investigates for each what it might
2872 be. Is it a distribution file (recognized by embedded slashes), this
2873 file is being processed. Is it a module, CPAN determines the
2874 distribution file where this module is included and processes that.
2876 Any C<make>, C<test>, and C<readme> are run unconditionally. A
2878 install <distribution_file>
2880 also is run unconditionally. But for
2884 CPAN checks if an install is actually needed for it and prints
2885 I<Foo up to date> in case the module doesnE<39>t need to be updated.
2887 CPAN also keeps track of what it has done within the current session
2888 and doesnE<39>t try to build a package a second time regardless if it
2889 succeeded or not. The C<force > command takes as first argument the
2890 method to invoke (currently: make, test, or install) and executes the
2891 command from scratch.
2895 cpan> install OpenGL
2896 OpenGL is up to date.
2897 cpan> force install OpenGL
2900 OpenGL-0.4/COPYRIGHT
2903 =item readme, look module or distribution
2905 These two commands take only one argument, be it a module or a
2906 distribution file. C<readme> displays the README of the associated
2907 distribution file. C<Look> gets and untars (if not yet done) the
2908 distribution file, changes to the appropriate directory and opens a
2909 subshell process in that directory.
2915 The commands that are available in the shell interface are methods in
2916 the package CPAN::Shell. If you enter the shell command, all your
2917 input is split by the Text::ParseWords::shellwords() routine which
2918 acts like most shells do. The first word is being interpreted as the
2919 method to be called and the rest of the words are treated as arguments
2924 C<autobundle> writes a bundle file into the
2925 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
2926 a list of all modules that are both available from CPAN and currently
2927 installed within @INC. The name of the bundle file is based on the
2928 current date and a counter.
2932 recompile() is a very special command in that it takes no argument and
2933 runs the make/test/install cycle with brute force over all installed
2934 dynamically loadable extensions (aka XS modules) with 'force' in
2935 effect. Primary purpose of this command is to finish a network
2936 installation. Imagine, you have a common source tree for two different
2937 architectures. You decide to do a completely independent fresh
2938 installation. You start on one architecture with the help of a Bundle
2939 file produced earlier. CPAN installs the whole Bundle for you, but
2940 when you try to repeat the job on the second architecture, CPAN
2941 responds with a C<"Foo up to date"> message for all modules. So you
2942 will be glad to run recompile in the second architecture and
2945 Another popular use for C<recompile> is to act as a rescue in case your
2946 perl breaks binary compatibility. If one of the modules that CPAN uses
2947 is in turn depending on binary compatibility (so you cannot run CPAN
2948 commands), then you should try the CPAN::Nox module for recovery.
2950 =head2 ProgrammerE<39>s interface
2952 If you do not enter the shell, the available shell commands are both
2953 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
2954 functions in the calling package (C<install(...)>). The
2955 programmerE<39>s interface has beta status. Do not heavily rely on it,
2956 changes may still be necessary.
2958 =head2 Cache Manager
2960 Currently the cache manager only keeps track of the build directory
2961 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
2962 deletes complete directories below C<build_dir> as soon as the size of
2963 all directories there gets bigger than $CPAN::Config->{build_cache}
2964 (in MB). The contents of this cache may be used for later
2965 re-installations that you intend to do manually, but will never be
2966 trusted by CPAN itself. This is due to the fact that the user might
2967 use these directories for building modules on different architectures.
2969 There is another directory ($CPAN::Config->{keep_source_where}) where
2970 the original distribution files are kept. This directory is not
2971 covered by the cache manager and must be controlled by the user. If
2972 you choose to have the same directory as build_dir and as
2973 keep_source_where directory, then your sources will be deleted with
2974 the same fifo mechanism.
2978 A bundle is just a perl module in the namespace Bundle:: that does not
2979 define any functions or methods. It usually only contains documentation.
2981 It starts like a perl module with a package declaration and a $VERSION
2982 variable. After that the pod section looks like any other pod with the
2983 only difference, that I<one special pod section> exists starting with
2988 In this pod section each line obeys the format
2990 Module_Name [Version_String] [- optional text]
2992 The only required part is the first field, the name of a module
2993 (eg. Foo::Bar, ie. I<not> the name of the distribution file). The rest
2994 of the line is optional. The comment part is delimited by a dash just
2995 as in the man page header.
2997 The distribution of a bundle should follow the same convention as
2998 other distributions.
3000 Bundles are treated specially in the CPAN package. If you say 'install
3001 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
3002 the modules in the CONTENTS section of the pod. You can install your
3003 own Bundles locally by placing a conformant Bundle file somewhere into
3004 your @INC path. The autobundle() command which is available in the
3005 shell interface does that for you by including all currently installed
3006 modules in a snapshot bundle file.
3008 There is a meaningless Bundle::Demo available on CPAN. Try to install
3009 it, it usually does no harm, just demonstrates what the Bundle
3010 interface looks like.
3012 =head2 Prerequisites
3014 If you have a local mirror of CPAN and can access all files with
3015 "file:" URLs, then you only need a perl better than perl5.003 to run
3016 this module. Otherwise Net::FTP is strongly recommended. LWP may be
3017 required for non-UNIX systems or if your nearest CPAN site is
3018 associated with an URL that is not C<ftp:>.
3020 If you have neither Net::FTP nor LWP, there is a fallback mechanism
3021 implemented for an external ftp command or for an external lynx
3024 This module presumes that all packages on CPAN
3030 declare their $VERSION variable in an easy to parse manner. This
3031 prerequisite can hardly be relaxed because it consumes by far too much
3032 memory to load all packages into the running program just to determine
3033 the $VERSION variable . Currently all programs that are dealing with
3034 version use something like this
3036 perl -MExtUtils::MakeMaker -le \
3037 'print MM->parse_version($ARGV[0])' filename
3039 If you are author of a package and wonder if your $VERSION can be
3040 parsed, please try the above method.
3044 come as compressed or gzipped tarfiles or as zip files and contain a
3045 Makefile.PL (well we try to handle a bit more, but without much
3052 The debugging of this module is pretty difficult, because we have
3053 interferences of the software producing the indices on CPAN, of the
3054 mirroring process on CPAN, of packaging, of configuration, of
3055 synchronicity, and of bugs within CPAN.pm.
3057 In interactive mode you can try "o debug" which will list options for
3058 debugging the various parts of the package. The output may not be very
3059 useful for you as it's just a byproduct of my own testing, but if you
3060 have an idea which part of the package may have a bug, it's sometimes
3061 worth to give it a try and send me more specific output. You should
3062 know that "o debug" has built-in completion support.
3064 =head2 Floppy, Zip, and all that Jazz
3066 CPAN.pm works nicely without network too. If you maintain machines
3067 that are not networked at all, you should consider working with file:
3068 URLs. Of course, you have to collect your modules somewhere first. So
3069 you might use CPAN.pm to put together all you need on a networked
3070 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
3071 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
3072 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
3075 =head1 CONFIGURATION
3077 When the CPAN module is installed a site wide configuration file is
3078 created as CPAN/Config.pm. The default values defined there can be
3079 overridden in another configuration file: CPAN/MyConfig.pm. You can
3080 store this file in $HOME/.cpan/CPAN/MyConfig.pm if you want, because
3081 $HOME/.cpan is added to the search path of the CPAN module before the
3082 use() or require() statements.
3084 Currently the following keys in the hash reference $CPAN::Config are
3087 build_cache size of cache for directories to build modules
3088 build_dir locally accessible directory to build modules
3089 index_expire after how many days refetch index files
3090 cpan_home local directory reserved for this package
3091 gzip location of external program gzip
3092 inactivity_timeout breaks interactive Makefile.PLs after that
3093 many seconds inactivity. Set to 0 to never break.
3094 inhibit_startup_message
3095 if true, does not print the startup message
3096 keep_source keep the source in a local directory?
3097 keep_source_where where keep the source (if we do)
3098 make location of external program make
3099 make_arg arguments that should always be passed to 'make'
3100 make_install_arg same as make_arg for 'make install'
3101 makepl_arg arguments passed to 'perl Makefile.PL'
3102 pager location of external program more (or any pager)
3103 tar location of external program tar
3104 unzip location of external program unzip
3105 urllist arrayref to nearby CPAN sites (or equivalent locations)
3107 You can set and query each of these options interactively in the cpan
3108 shell with the command set defined within the C<o conf> command:
3112 =item o conf E<lt>scalar optionE<gt>
3114 prints the current value of the I<scalar option>
3116 =item o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>
3118 Sets the value of the I<scalar option> to I<value>
3120 =item o conf E<lt>list optionE<gt>
3122 prints the current value of the I<list option> in MakeMaker's
3125 =item o conf E<lt>list optionE<gt> [shift|pop]
3127 shifts or pops the array in the I<list option> variable
3129 =item o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>
3131 works like the corresponding perl commands.
3137 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
3138 install foreign, unmasked, unsigned code on your machine. We compare
3139 to a checksum that comes from the net just as the distribution file
3140 itself. If somebody has managed to tamper with the distribution file,
3141 they may have as well tampered with the CHECKSUMS file. Future
3142 development will go towards strong authentification.
3146 Most functions in package CPAN are exported per default. The reason
3147 for this is that the primary use is intended for the cpan shell or for
3152 we should give coverage for _all_ of the CPAN and not just the
3153 __PAUSE__ part, right? In this discussion CPAN and PAUSE have become
3154 equal -- but they are not. PAUSE is authors/ and modules/. CPAN is
3155 PAUSE plus the clpa/, doc/, misc/, ports/, src/, scripts/.
3157 Future development should be directed towards a better intergration of
3162 Andreas König E<lt>a.koenig@mind.deE<gt>
3166 perl(1), CPAN::Nox(3)