2 use vars qw{$META $Signal $Cwd $End $Suppress_readline};
6 # $Id: CPAN.pm,v 1.139 1997/03/31 22:43:23 k Exp $
8 # my $version = substr q$Revision: 1.139 $, 10; # only used during development
15 use ExtUtils::MakeMaker ();
16 use File::Basename ();
22 use Text::ParseWords ();
26 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
27 $Cwd = Cwd->$getcwd();
29 END { $End++; &cleanup; }
51 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $term);
54 @CPAN::ISA = qw(CPAN::Debug Exporter MM); # the MM class from
58 $META ||= new CPAN; # In case we reeval ourselves we
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 $self->debug("Signal handler set.") if $CPAN::DEBUG;
188 #-> sub CPAN::DESTROY ;
190 &cleanup; # need an eval?
193 #-> sub CPAN::exists ;
195 my($mgr,$class,$id) = @_;
197 ### Carp::croak "exists called without class argument" unless $class;
199 exists $META->{$class}{$id};
202 #-> sub CPAN::hasFTP ;
206 return $self->{'hasFTP'} = $arg;
207 } elsif (not defined $self->{'hasFTP'}) {
208 eval {require Net::FTP;};
209 $self->{'hasFTP'} = $@ ? 0 : 1;
211 return $self->{'hasFTP'};
214 #-> sub CPAN::hasLWP ;
218 return $self->{'hasLWP'} = $arg;
219 } elsif (not defined $self->{'hasLWP'}) {
222 $self->{'hasLWP'} = $LWP::VERSION >= 4.98;
224 return $self->{'hasLWP'};
227 #-> sub CPAN::hasMD5 ;
231 $self->{'hasMD5'} = $arg;
232 } elsif (not defined $self->{'hasMD5'}) {
235 print "MD5 security checks disabled because MD5 not installed.
236 Please consider installing the MD5 module\n";
237 $self->{'hasMD5'} = 0;
242 return $self->{'hasMD5'};
245 #-> sub CPAN::hasWAIT ;
249 $self->{'hasWAIT'} = $arg;
250 } elsif (not defined $self->{'hasWAIT'}) {
251 eval {require CPAN::WAIT;};
253 $self->{'hasWAIT'} = 0;
255 $self->{'hasWAIT'} = 1;
258 return $self->{'hasWAIT'};
261 #-> sub CPAN::instance ;
263 my($mgr,$class,$id) = @_;
264 ### CPAN::Index->reload; ### not faster: unless time - $CPAN::Index::last_time > 60;
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';
309 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
310 my $cwd = Cwd->$getcwd();
311 my $rl_avail = $Suppress_readline ? "suppressed" :
312 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
313 "available (get Term::ReadKey and Term::ReadLine::Perl ".
314 "or get Term::ReadLine::Gnu)";
317 cpan shell -- CPAN exploration and modules installation (v$CPAN::VERSION)
318 Readline support $rl_avail
320 } unless $CPAN::Config->{'inhibit_startup_message'} ;
322 if ($Suppress_readline) {
324 last unless defined ($_ = <> );
327 # if (defined($CPAN::ANDK) && $CPAN::DEBUG) { # !$CPAN::ANDK++;$CPAN::DEBUG=1024
330 # for $item (qw/ReadLine IN OUT MinLine findConsole Features/) {
331 # $report .= sprintf "%-15s", $item;
332 # $report .= $term->$item() || "";
336 # CPAN->debug($report);
338 last unless defined ($_ = $term->readline($prompt));
342 $_ = 'h' if $_ eq '?';
347 use vars qw($import_done);
348 CPAN->import(':DEFAULT') unless $import_done++;
349 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
352 } elsif (/^q(?:uit)?$/i) {
356 if ($] < 5.00322) { # parsewords had a bug until recently
359 eval { @line = Text::ParseWords::shellwords($_) };
360 warn($@), next if $@;
362 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
363 my $command = shift @line;
364 eval { CPAN::Shell->$command(@line) };
368 &cleanup, die if $Signal;
374 package CPAN::CacheMgr;
376 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj);
379 #-> sub CPAN::CacheMgr::as_string ;
381 eval { require Data::Dumper };
383 return shift->SUPER::as_string;
385 return Data::Dumper::Dumper(shift);
389 #-> sub CPAN::CacheMgr::cachesize ;
395 # my($self,@dirs) = @_;
396 # return unless -d $self->{ID};
398 # @dirs = $self->dirs unless @dirs;
400 # $self->disk_usage($dir);
404 #-> sub CPAN::CacheMgr::clean_cache ;
405 #=# sub clean_cache {
406 #=# my $self = shift;
408 #=# while ($self->{DU} > $self->{'MAX'} and $dir = shift @{$self->{FIFO}}) {
409 #=# $self->force_clean_cache($dir);
411 #=# $self->debug("leaving clean_cache with $self->{DU}") if $CPAN::DEBUG;
414 #-> sub CPAN::CacheMgr::dir ;
419 #-> sub CPAN::CacheMgr::entries ;
422 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
423 $dir ||= $self->{ID};
425 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
426 my($cwd) = Cwd->$getcwd();
427 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
428 my $dh = DirHandle->new(".") or Carp::croak("Couldn't opendir $dir: $!");
431 next if $_ eq "." || $_ eq "..";
433 push @entries, $CPAN::META->catfile($dir,$_);
435 push @entries, $CPAN::META->catdir($dir,$_);
437 print STDERR "Warning: weird direntry in $dir: $_\n";
440 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
441 sort { -M $b <=> -M $a} @entries;
444 #-> sub CPAN::CacheMgr::disk_usage ;
447 # if (! defined $dir or $dir eq "") {
448 # $self->debug("Cannot determine disk usage for some reason") if $CPAN::DEBUG;
451 return if $self->{SIZE}{$dir};
460 $self->{SIZE}{$dir} = $Du/1024/1024;
461 push @{$self->{FIFO}}, $dir;
462 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
463 $self->{DU} += $Du/1024/1024;
464 if ($self->{DU} > $self->{'MAX'} ) {
465 my($toremove) = shift @{$self->{FIFO}};
466 printf "...Hold on a sec... cleaning from cache (%.1f>%.1f MB): $toremove\n",
467 $self->{DU}, $self->{'MAX'};
468 $self->force_clean_cache($toremove);
473 #-> sub CPAN::CacheMgr::force_clean_cache ;
474 sub force_clean_cache {
476 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
478 File::Path::rmtree($dir);
479 $self->{DU} -= $self->{SIZE}{$dir};
480 delete $self->{SIZE}{$dir};
483 #-> sub CPAN::CacheMgr::new ;
490 ID => $CPAN::Config->{'build_dir'},
491 MAX => $CPAN::Config->{'build_cache'},
494 File::Path::mkpath($self->{ID});
495 my $dh = DirHandle->new($self->{ID});
497 $self->debug("dir [$self->{ID}]") if $CPAN::DEBUG;
499 for $e ($self->entries) {
500 next if $e eq ".." || $e eq ".";
501 $self->disk_usage($e);
504 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
506 CPAN->debug($debug) if $CPAN::DEBUG;
512 #-> sub CPAN::Debug::debug ;
515 my($caller,$func,$line,@rest) = caller(1); # caller(0) eg
516 # Complete, caller(1)
518 ($caller) = caller(0);
520 # print "caller[$caller]func[$func]line[$line]rest[@rest]\n";
521 # print "CPAN::DEBUG{caller}[$CPAN::DEBUG{$caller}]CPAN::DEBUG[$CPAN::DEBUG]\n";
522 if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
524 eval { require Data::Dumper };
526 print $arg->as_string;
528 print Data::Dumper::Dumper($arg);
531 print "Debug($caller:$func,$line,@rest): $arg\n"
536 package CPAN::Config;
537 import ExtUtils::MakeMaker 'neatvalue';
541 'commit' => "Commit changes to disk",
542 'defaults' => "Reload defaults from disk",
543 'init' => "Interactive setting of all options",
546 #-> sub CPAN::Config::edit ;
548 my($class,@args) = @_;
550 CPAN->debug("class[$class]args[".join(" | ",@args)."]");
551 my($o,$str,$func,$args,$key_exists);
557 if (ref($CPAN::Config->{$o}) eq ARRAY) {
560 # Let's avoid eval, it's easier to comprehend without.
561 if ($func eq "push") {
562 push @{$CPAN::Config->{$o}}, @args;
563 } elsif ($func eq "pop") {
564 pop @{$CPAN::Config->{$o}};
565 } elsif ($func eq "shift") {
566 shift @{$CPAN::Config->{$o}};
567 } elsif ($func eq "unshift") {
568 unshift @{$CPAN::Config->{$o}}, @args;
569 } elsif ($func eq "splice") {
570 splice @{$CPAN::Config->{$o}}, @args;
572 $CPAN::Config->{$o} = [@args];
576 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$o}),
581 $CPAN::Config->{$o} = $args[0] if defined $args[0];
583 print defined $CPAN::Config->{$o} ? $CPAN::Config->{$o} : "UNDEFINED";
588 #-> sub CPAN::Config::commit ;
590 my($self,$configpm) = @_;
591 unless (defined $configpm){
592 $configpm ||= $INC{"CPAN/MyConfig.pm"};
593 $configpm ||= $INC{"CPAN/Config.pm"};
594 $configpm || Carp::confess(qq{
595 CPAN::Config::commit called without an argument.
596 Please specify a filename where to save the configuration or try
597 "o conf init" to have an interactive course through configing.
602 $mode = (stat $configpm)[2];
603 if ($mode && ! -w _) {
604 Carp::confess("$configpm is not writable");
608 my $msg = <<EOF unless $configpm =~ /MyConfig/;
610 # This is CPAN.pm's systemwide configuration file. This file provides
611 # defaults for users, and the values can be changed in a per-user configuration
612 # file. The user-config file is being looked for as ~/.cpan/CPAN/MyConfig.pm.
616 my($fh) = FileHandle->new;
617 open $fh, ">$configpm" or warn "Couldn't open >$configpm: $!";
618 print $fh qq[$msg\$CPAN::Config = \{\n];
619 foreach (sort keys %$CPAN::Config) {
622 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}),
627 print $fh "};\n1;\n__END__\n";
630 #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
631 #chmod $mode, $configpm;
632 ###why was that so? $self->defaults;
633 print "commit: wrote $configpm\n";
637 *default = \&defaults;
638 #-> sub CPAN::Config::defaults ;
648 undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
658 #-> sub CPAN::Config::load ;
662 eval {require CPAN::Config;}; # We eval, because of some MakeMaker problems
663 unshift @INC, $CPAN::META->catdir($ENV{HOME},".cpan") unless $dot_cpan++;
664 eval {require CPAN::MyConfig;}; # where you can override system wide settings
665 return unless @miss = $self->not_loaded;
666 require CPAN::FirstTime;
667 my($configpm,$fh,$redo);
669 if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
670 $configpm = $INC{"CPAN/Config.pm"};
672 } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
673 $configpm = $INC{"CPAN/MyConfig.pm"};
676 my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
677 my($configpmdir) = MM->catdir($path_to_cpan,"CPAN");
678 my($configpmtest) = MM->catfile($configpmdir,"Config.pm");
679 if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
680 if (-w $configpmtest) {
681 $configpm = $configpmtest;
682 } elsif (-w $configpmdir) {
683 #_#_# following code dumped core on me with 5.003_11, a.k.
684 unlink "$configpmtest.bak" if -f "$configpmtest.bak";
685 rename $configpmtest, "$configpmtest.bak" if -f $configpmtest;
686 my $fh = FileHandle->new;
687 if ($fh->open(">$configpmtest")) {
689 $configpm = $configpmtest;
691 # Should never happen
692 Carp::confess("Cannot open >$configpmtest");
697 $configpmdir = MM->catdir($ENV{HOME},".cpan","CPAN");
698 File::Path::mkpath($configpmdir);
699 $configpmtest = MM->catfile($configpmdir,"MyConfig.pm");
700 if (-w $configpmtest) {
701 $configpm = $configpmtest;
702 } elsif (-w $configpmdir) {
703 #_#_# following code dumped core on me with 5.003_11, a.k.
704 my $fh = FileHandle->new;
705 if ($fh->open(">$configpmtest")) {
707 $configpm = $configpmtest;
709 # Should never happen
710 Carp::confess("Cannot open >$configpmtest");
713 Carp::confess(qq{WARNING: CPAN.pm is unable to }.
714 qq{create a configuration file.});
720 We have to reconfigure CPAN.pm due to following uninitialized parameters:
725 $configpm initialized.
728 CPAN::FirstTime::init($configpm);
731 #-> sub CPAN::Config::not_loaded ;
735 cpan_home keep_source_where build_dir build_cache index_expire
736 gzip tar unzip make pager makepl_arg make_arg make_install_arg
737 urllist inhibit_startup_message ftp_proxy http_proxy no_proxy
739 push @miss, $_ unless defined $CPAN::Config->{$_};
744 #-> sub CPAN::Config::unload ;
746 delete $INC{'CPAN/MyConfig.pm'};
747 delete $INC{'CPAN/Config.pm'};
751 #-> sub CPAN::Config::help ;
755 defaults reload default config values from disk
756 commit commit session changes to disk
757 init go through a dialog to set all parameters
759 You may edit key values in the follow fashion:
761 o conf build_cache 15
763 o conf build_dir "/foo/bar"
767 o conf urllist unshift ftp://ftp.foo.bar/
770 undef; #don't reprint CPAN::Config
773 #-> sub CPAN::Config::complete ;
775 my($word,$line,$pos) = @_;
777 my(@o_conf) = (keys %CPAN::Config::can, keys %$CPAN::Config);
778 return grep /^\Q$word\E/, @o_conf;
782 use vars qw($AUTOLOAD $redef @ISA);
783 @CPAN::Shell::ISA = qw(CPAN::Debug);
784 if ($CPAN::META->hasWAIT) {
785 unshift @ISA, "CPAN::WAIT";
787 # private function ro re-eval this module (handy during development)
788 #-> sub CPAN::Shell::AUTOLOAD ;
790 my($autoload) = $AUTOLOAD;
791 $autoload =~ s/.*:://;
792 if ($autoload =~ /^w/) {
793 if ($CPAN::META->hasWAIT) {
798 Commands starting with "w" require CPAN::WAIT to be installed.
799 Please consider installing CPAN::WAIT to use the fulltext index.
800 Type "install CPAN::WAIT" and restart CPAN.pm.
804 warn "CPAN::Shell doesn't know how to autoload $autoload :-(
811 #-> sub CPAN::Shell::h ;
813 my($class,$about) = @_;
814 if (defined $about) {
815 print "Detailed help not yet implemented\n";
818 command arguments description
821 d /regex/ info distributions
823 i none anything of above
825 r as reinstall recommendations
826 u above uninstalled distributions
827 See manpage for autobundle, recompile, force, look, etc.
830 test modules, make test (implies make)
831 install dists, bundles, make install (implies test)
832 clean "r" or "u" make clean
833 readme display the README file
835 reload index|cpan load most recent indices/CPAN.pm
836 h or ? display this menu
837 o various set and query options
838 ! perl-code eval a perl command
839 q quit the shell subroutine
844 #-> sub CPAN::Shell::a ;
845 sub a { print shift->format_result('Author',@_);}
846 #-> sub CPAN::Shell::b ;
848 my($self,@which) = @_;
849 CPAN->debug("which[@which]") if $CPAN::DEBUG;
850 my($incdir,$bdir,$dh);
851 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
852 $bdir = $CPAN::META->catdir($incdir,"Bundle");
853 if ($dh = DirHandle->new($bdir)) { # may fail
855 for $entry ($dh->read) {
856 next if -d $CPAN::META->catdir($bdir,$entry);
857 next unless $entry =~ s/\.pm$//;
858 $CPAN::META->instance('CPAN::Bundle',"Bundle::$entry");
862 print $self->format_result('Bundle',@which);
864 #-> sub CPAN::Shell::d ;
865 sub d { print shift->format_result('Distribution',@_);}
866 #-> sub CPAN::Shell::m ;
867 sub m { print shift->format_result('Module',@_);}
869 #-> sub CPAN::Shell::i ;
874 @type = qw/Author Bundle Distribution Module/;
875 @args = '/./' unless @args;
878 push @result, $self->expand($type,@args);
880 my $result = @result == 1 ?
881 $result[0]->as_string :
882 join "", map {$_->as_glimpse} @result;
883 $result ||= "No objects found of any type for argument @args\n";
887 #-> sub CPAN::Shell::o ;
889 my($self,$o_type,@o_what) = @_;
891 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
892 if ($o_type eq 'conf') {
893 shift @o_what if @o_what && $o_what[0] eq 'help';
896 print "CPAN::Config options:\n";
897 for $k (sort keys %CPAN::Config::can) {
898 $v = $CPAN::Config::can{$k};
899 printf " %-18s %s\n", $k, $v;
902 for $k (sort keys %$CPAN::Config) {
903 $v = $CPAN::Config->{$k};
905 printf " %-18s\n", $k;
906 print map {"\t$_\n"} @{$v};
908 printf " %-18s %s\n", $k, $v;
912 } elsif (!CPAN::Config->edit(@o_what)) {
913 print qq[Type 'o conf' to view configuration edit options\n\n];
915 } elsif ($o_type eq 'debug') {
917 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
920 my($what) = shift @o_what;
921 if ( exists $CPAN::DEBUG{$what} ) {
922 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
923 } elsif ($what =~ /^\d/) {
924 $CPAN::DEBUG = $what;
925 } elsif (lc $what eq 'all') {
927 for (values %CPAN::DEBUG) {
933 for (keys %CPAN::DEBUG) {
934 next unless lc($_) eq lc($what);
935 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
938 print "unknown argument [$what]\n" unless $known;
942 print "Valid options for debug are ".
943 join(", ",sort(keys %CPAN::DEBUG), 'all').
944 qq{ or a number. Completion works on the options. }.
945 qq{Case is ignored.\n\n};
948 print "Options set for debugging:\n";
950 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
951 $v = $CPAN::DEBUG{$k};
952 printf " %-14s(%s)\n", $k, $v if $v & $CPAN::DEBUG;
955 print "Debugging turned off completely.\n";
960 conf set or get configuration variables
961 debug set or get debugging options
966 #-> sub CPAN::Shell::reload ;
968 my($self,$command,@arg) = @_;
970 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
971 if ($command =~ /cpan/i) {
972 CPAN->debug("reloading the whole CPAN.pm") if $CPAN::DEBUG;
973 my $fh = FileHandle->new($INC{'CPAN.pm'});
977 local($SIG{__WARN__})
979 if ( $_[0] =~ /Subroutine \w+ redefined/ ) {
989 print "\n$redef subroutines redefined\n";
990 } elsif ($command =~ /index/) {
991 CPAN::Index->force_reload;
993 print qq{cpan re-evals the CPAN.pm file\n};
994 print qq{index re-reads the index files\n};
998 #-> sub CPAN::Shell::_binary_extensions ;
999 sub _binary_extensions {
1000 my($self) = shift @_;
1001 my(@result,$module,%seen,%need,$headerdone);
1002 for $module ($self->expand('Module','/./')) {
1003 my $file = $module->cpan_file;
1004 next if $file eq "N/A";
1005 next if $file =~ /^Contact Author/;
1006 next if $file =~ /perl5[._-]\d{3}(?:[\d_]+)?\.tar[._-]gz$/;
1007 next unless $module->xs_file;
1010 push @result, $module;
1012 # print join " | ", @result;
1017 #-> sub CPAN::Shell::recompile ;
1019 my($self) = shift @_;
1020 my($module,@module,$cpan_file,%dist);
1021 @module = $self->_binary_extensions();
1022 for $module (@module){ # we force now and compile later, so we don't do it twice
1023 $cpan_file = $module->cpan_file;
1024 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1026 $dist{$cpan_file}++;
1028 for $cpan_file (sort keys %dist) {
1029 print " CPAN: Recompiling $cpan_file\n\n";
1030 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1032 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1033 # stop a package from recompiling,
1034 # e.g. IO-1.12 when we have perl5.003_10
1038 #-> sub CPAN::Shell::_u_r_common ;
1040 my($self) = shift @_;
1041 my($what) = shift @_;
1042 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1043 Carp::croak "Usage: \$obj->_u_r_common($what)" unless defined $what;
1044 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless $what =~ /^[aru]$/;
1046 @args = '/./' unless @args;
1047 my(@result,$module,%seen,%need,$headerdone,$version_zeroes);
1048 $version_zeroes = 0;
1049 my $sprintf = "%-25s %9s %9s %s\n";
1050 for $module ($self->expand('Module',@args)) {
1051 my $file = $module->cpan_file;
1052 next unless defined $file; # ??
1053 my($latest) = $module->cpan_version || 0;
1054 my($inst_file) = $module->inst_file;
1058 $have = $module->inst_version;
1059 } elsif ($what eq "r") {
1060 $have = $module->inst_version;
1062 $version_zeroes++ unless $have;
1063 next if $have >= $latest;
1064 } elsif ($what eq "u") {
1070 } elsif ($what eq "r") {
1072 } elsif ($what eq "u") {
1076 return if $CPAN::Signal; # this is sometimes lengthy
1079 push @result, sprintf "%s %s\n", $module->id, $have;
1080 } elsif ($what eq "r") {
1081 push @result, $module->id;
1082 next if $seen{$file}++;
1083 } elsif ($what eq "u") {
1084 push @result, $module->id;
1085 next if $seen{$file}++;
1086 next if $file =~ /^Contact/;
1088 unless ($headerdone++){
1092 "Package namespace",
1098 $latest = substr($latest,0,8) if length($latest) > 8;
1099 $have = substr($have,0,8) if length($have) > 8;
1100 printf $sprintf, $module->id, $have, $latest, $file;
1101 $need{$module->id}++;
1105 print "No modules found for @args\n";
1106 } elsif ($what eq "r") {
1107 print "All modules are up to date for @args\n";
1110 if ($what eq "r" && $version_zeroes) {
1111 my $s = $version_zeroes > 1 ? "s have" : " has";
1112 print qq{$version_zeroes installed module$s no version number to compare\n};
1117 #-> sub CPAN::Shell::r ;
1119 shift->_u_r_common("r",@_);
1122 #-> sub CPAN::Shell::u ;
1124 shift->_u_r_common("u",@_);
1127 #-> sub CPAN::Shell::autobundle ;
1130 my(@bundle) = $self->_u_r_common("a",@_);
1131 my($todir) = $CPAN::META->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1132 File::Path::mkpath($todir);
1133 unless (-d $todir) {
1134 print "Couldn't mkdir $todir for some reason\n";
1137 my($y,$m,$d) = (localtime)[5,4,3];
1141 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1142 my($to) = $CPAN::META->catfile($todir,"$me.pm");
1144 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1145 $to = $CPAN::META->catfile($todir,"$me.pm");
1147 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1149 "package Bundle::$me;\n\n",
1150 "\$VERSION = '0.01';\n\n",
1154 "Bundle::$me - Snapshot of installation on ",
1155 $Config::Config{'myhostname'},
1158 "\n\n=head1 SYNOPSIS\n\n",
1159 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1160 "=head1 CONTENTS\n\n",
1161 join("\n", @bundle),
1162 "\n\n=head1 CONFIGURATION\n\n",
1164 "\n\n=head1 AUTHOR\n\n",
1165 "This Bundle has been generated automatically ",
1166 "by the autobundle routine in CPAN.pm.\n",
1169 print "\nWrote bundle file
1173 #-> sub CPAN::Shell::expand ;
1176 my($type,@args) = @_;
1180 if ($arg =~ m|^/(.*)/$|) {
1183 my $class = "CPAN::$type";
1185 if (defined $regex) {
1186 for $obj ( sort {$a->id cmp $b->id} $CPAN::META->all($class)) {
1189 $obj->id =~ /$regex/i
1193 $] < 5.00303 ### provide sort of compatibility with 5.003
1198 $obj->name =~ /$regex/i
1203 if ( $type eq 'Bundle' ) {
1204 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
1206 if ($CPAN::META->exists($class,$xarg)) {
1207 $obj = $CPAN::META->instance($class,$xarg);
1208 } elsif ($CPAN::META->exists($class,$arg)) {
1209 $obj = $CPAN::META->instance($class,$arg);
1216 return wantarray ? @m : $m[0];
1219 #-> sub CPAN::Shell::format_result ;
1222 my($type,@args) = @_;
1223 @args = '/./' unless @args;
1224 my(@result) = $self->expand($type,@args);
1225 my $result = @result == 1 ?
1226 $result[0]->as_string :
1227 join "", map {$_->as_glimpse} @result;
1228 $result ||= "No objects of type $type found for argument @args\n";
1232 #-> sub CPAN::Shell::rematein ;
1235 my($meth,@some) = @_;
1237 if ($meth eq 'force') {
1239 $meth = shift @some;
1241 CPAN->debug("pragma[$pragma]meth[$meth] some[@some]") if $CPAN::DEBUG;
1243 foreach $s (@some) {
1247 } elsif ($s =~ m|/|) { # looks like a file
1248 $obj = $CPAN::META->instance('CPAN::Distribution',$s);
1249 } elsif ($s =~ m|^Bundle::|) {
1250 $obj = $CPAN::META->instance('CPAN::Bundle',$s);
1252 $obj = $CPAN::META->instance('CPAN::Module',$s)
1253 if $CPAN::META->exists('CPAN::Module',$s);
1257 qq{pragma[$pragma] meth[$meth] obj[$obj] as_string\[}.
1265 ($] < 5.00303 || $obj->can($pragma)); ### compatibility with 5.003
1267 } elsif ($CPAN::META->exists('CPAN::Author',$s)) {
1268 $obj = $CPAN::META->instance('CPAN::Author',$s);
1269 print "Don't be silly, you can't $meth ", $obj->fullname, " ;-)\n";
1271 print qq{Warning: Cannot $meth $s, don\'t know what it is.
1276 to find objects with similar identifiers.
1282 #-> sub CPAN::Shell::force ;
1283 sub force { shift->rematein('force',@_); }
1284 #-> sub CPAN::Shell::get ;
1285 sub get { shift->rematein('get',@_); }
1286 #-> sub CPAN::Shell::readme ;
1287 sub readme { shift->rematein('readme',@_); }
1288 #-> sub CPAN::Shell::make ;
1289 sub make { shift->rematein('make',@_); }
1290 #-> sub CPAN::Shell::test ;
1291 sub test { shift->rematein('test',@_); }
1292 #-> sub CPAN::Shell::install ;
1293 sub install { shift->rematein('install',@_); }
1294 #-> sub CPAN::Shell::clean ;
1295 sub clean { shift->rematein('clean',@_); }
1296 #-> sub CPAN::Shell::look ;
1297 sub look { shift->rematein('look',@_); }
1301 @CPAN::FTP::ISA = qw(CPAN::Debug);
1303 #-> sub CPAN::FTP::ftp_get ;
1305 my($class,$host,$dir,$file,$target) = @_;
1307 qq[Going to fetch file [$file] from dir [$dir]
1308 on host [$host] as local [$target]\n]
1310 my $ftp = Net::FTP->new($host);
1311 return 0 unless defined $ftp;
1312 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
1313 $class->debug(qq[Going to ->login("anonymous","$Config::Config{'cf_email'}")\n]);
1314 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
1315 warn "Couldn't login on $host";
1318 # print qq[Going to ->cwd("$dir")\n];
1319 unless ( $ftp->cwd($dir) ){
1320 warn "Couldn't cwd $dir";
1324 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
1325 unless ( $ftp->get($file,$target) ){
1326 warn "Couldn't fetch $file from $host\n";
1329 $ftp->quit; # it's ok if this fails
1333 #-> sub CPAN::FTP::localize ;
1335 my($self,$file,$aslocal,$force) = @_;
1337 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
1338 unless defined $aslocal;
1339 $self->debug("file [$file] aslocal [$aslocal]") if $CPAN::DEBUG;
1341 return $aslocal if -f $aslocal && -r _ && ! $force;
1342 rename $aslocal, "$aslocal.bak" if -f $aslocal;
1344 my($aslocal_dir) = File::Basename::dirname($aslocal);
1345 File::Path::mkpath($aslocal_dir);
1346 print STDERR qq{Warning: You are not allowed to write into }.
1347 qq{directory "$aslocal_dir".
1348 I\'ll continue, but if you face any problems, they may be due
1349 to insufficient permissions.\n} unless -w $aslocal_dir;
1351 # Inheritance is not easier to manage than a few if/else branches
1352 if ($CPAN::META->hasLWP) {
1353 require LWP::UserAgent;
1355 $Ua = new LWP::UserAgent;
1357 $Ua->proxy('ftp', $var)
1358 if $var = $CPAN::Config->{'ftp_proxy'} || $ENV{'ftp_proxy'};
1359 $Ua->proxy('http', $var)
1360 if $var = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
1362 if $var = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
1366 # Try the list of urls for each single object. We keep a record
1367 # where we did get a file from
1369 for $i (0..$#{$CPAN::Config->{urllist}}) {
1370 my $url = $CPAN::Config->{urllist}[$i];
1371 $url .= "/" unless substr($url,-1) eq "/";
1373 $self->debug("localizing[$url]") if $CPAN::DEBUG;
1374 if ($url =~ /^file:/) {
1376 if ($CPAN::META->hasLWP) {
1378 my $u = new URI::URL $url;
1380 } else { # works only on Unix, is poorly constructed, but
1381 # hopefully better than nothing.
1382 # RFC 1738 says fileurl BNF is
1383 # fileurl = "file://" [ host | "localhost" ] "/" fpath
1384 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for the code
1385 ($l = $url) =~ s,^file://[^/]+,,; # discard the host part
1386 $l =~ s/^file://; # assume they meant file://localhost
1388 return $l if -f $l && -r _;
1389 # Maybe mirror has compressed it?
1391 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
1392 system("$CPAN::Config->{gzip} -dc $l.gz > $aslocal");
1393 return $aslocal if -f $aslocal;
1397 if ($CPAN::META->hasLWP) {
1398 print "Fetching $url with LWP\n";
1399 my $res = $Ua->mirror($url, $aslocal);
1400 if ($res->is_success) {
1404 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
1405 # that's the nice and easy way thanks to Graham
1406 my($host,$dir,$getfile) = ($1,$2,$3);
1407 if ($CPAN::META->hasFTP) {
1409 $self->debug("Going to fetch file [$getfile]
1412 as local [$aslocal]") if $CPAN::DEBUG;
1413 CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal) && return $aslocal;
1414 warn "Net::FTP failed for some reason\n";
1417 Please, install Net::FTP as soon as possible. Just type
1425 # Came back if Net::FTP couldn't establish connection (or failed otherwise)
1426 # Maybe they are behind a firewall, but they gave us
1427 # a socksified (or other) ftp program...
1430 # does ncftp handle http?
1431 for $funkyftp ($CPAN::Config->{'lynx'},$CPAN::Config->{'ncftp'}) {
1432 next unless defined $funkyftp;
1433 next unless -x $funkyftp;
1434 my($want_compressed);
1437 Trying with $funkyftp to get
1440 $want_compressed = $aslocal =~ s/\.gz//;
1441 my($source_switch) = "";
1442 $source_switch = "-source" if $funkyftp =~ /\blynx$/;
1443 my($system) = "$funkyftp $source_switch '$url' > $aslocal";
1445 if (($wstatus = system($system)) == 0) {
1446 if ($want_compressed) {
1447 $system = "$CPAN::Config->{'gzip'} -dt $aslocal";
1448 if (system($system) == 0) {
1449 rename $aslocal, "$aslocal.gz";
1451 $system = "$CPAN::Config->{'gzip'} $aslocal";
1454 return "$aslocal.gz";
1456 $system = "$CPAN::Config->{'gzip'} -dt $aslocal";
1457 if (system($system) == 0) {
1458 $system = "$CPAN::Config->{'gzip'} -d $aslocal";
1461 # should be fine, eh?
1466 my $estatus = $wstatus >> 8;
1468 System call "$system"
1469 returned status $estatus (wstat $wstatus)
1474 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
1475 my($host,$dir,$getfile) = ($1,$2,$3);
1477 if (-x $CPAN::Config->{'ftp'}) {
1479 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
1480 $ctime,$blksize,$blocks) = stat($aslocal);
1481 $timestamp = $mtime ||= 0;
1483 my($netrc) = CPAN::FTP::netrc->new;
1484 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
1486 my $targetfile = File::Basename::basename($aslocal);
1492 map("cd $_", split "/", $dir), # RFC 1738
1494 "get $getfile $targetfile",
1497 if (! $netrc->netrc) {
1498 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
1499 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
1502 "hasdef[%d]cont($host)[%d]",
1504 $netrc->contains($host)
1507 if ($netrc->protected) {
1510 Trying with external ftp to get
1512 As this requires some features that are not thoroughly tested, we\'re
1513 not sure, that we get it right....
1517 my $fh = FileHandle->new;
1518 $fh->open("|$CPAN::Config->{'ftp'}$verbose $host")
1519 or die "Couldn't open ftp: $!";
1520 # pilot is blind now
1521 CPAN->debug("dialog [".(join "|",@dialog)."]")
1523 foreach (@dialog) { $fh->print("$_\n") }
1524 $fh->close; # Wait for process to complete
1526 my $estatus = $wstatus >> 8;
1528 Subprocess "|$CPAN::Config->{'ftp'}$verbose $host"
1529 returned status $estatus (wstat $wstatus)
1531 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1532 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
1534 if ($mtime > $timestamp) {
1535 print "GOT $aslocal\n";
1538 print "Hmm... Still failed!\n";
1541 warn "Your $netrcfile is not correctly protected.\n";
1544 warn "Your ~/.netrc neither contains $host
1545 nor does it have a default entry\n";
1548 # OK, they don't have a valid ~/.netrc. Use 'ftp -n' then and
1549 # login manually to host, using e-mail as password.
1550 print qq{Issuing "$CPAN::Config->{'ftp'}$verbose -n"\n};
1554 "user anonymous $Config::Config{'cf_email'}"
1556 CPAN->debug("dialog [".(join "|",@dialog)."]") if $CPAN::DEBUG;
1557 $fh = FileHandle->new;
1558 $fh->open("|$CPAN::Config->{'ftp'}$verbose -n") or
1559 die "Cannot fork: $!\n";
1560 foreach (@dialog) { $fh->print("$_\n") }
1563 my $estatus = $wstatus >> 8;
1565 Subprocess "|$CPAN::Config->{'ftp'}$verbose -n"
1566 returned status $estatus (wstat $wstatus)
1568 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1569 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
1571 if ($mtime > $timestamp) {
1572 print "GOT $aslocal\n";
1575 print "Bad luck... Still failed!\n";
1581 print "Can't access URL $url.\n\n";
1583 push @mess, "LWP" unless CPAN->hasLWP;
1584 push @mess, "Net::FTP" unless CPAN->hasFTP;
1586 for $ext (qw/lynx ncftp ftp/) {
1587 $CPAN::Config->{$ext} ||= "";
1588 push @mess, "an external $ext" unless -x $CPAN::Config->{$ext};
1590 $mess = qq{Either get }.
1592 qq{ or check, if the URL found in your configuration file, }.
1593 $CPAN::Config->{urllist}[$i].
1595 print Text::Wrap::wrap("","",$mess), "\n";
1597 print "Cannot fetch $file\n";
1598 if (-f "$aslocal.bak") {
1599 rename "$aslocal.bak", $aslocal;
1600 print "Trying to get away with old file:\n";
1601 print $self->ls($aslocal);
1607 # find2perl needs modularization, too, all the following is stolen
1610 my($self,$name) = @_;
1611 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
1612 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
1614 my($perms,%user,%group);
1617 if (defined $blocks) {
1618 $blocks = int(($blocks + 1) / 2);
1621 $blocks = int(($sizemm + 1023) / 1024);
1624 if (-f _) { $perms = '-'; }
1625 elsif (-d _) { $perms = 'd'; }
1626 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
1627 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
1628 elsif (-p _) { $perms = 'p'; }
1629 elsif (-S _) { $perms = 's'; }
1630 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
1632 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
1633 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
1634 my $tmpmode = $mode;
1635 my $tmp = $rwx[$tmpmode & 7];
1637 $tmp = $rwx[$tmpmode & 7] . $tmp;
1639 $tmp = $rwx[$tmpmode & 7] . $tmp;
1640 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
1641 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
1642 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
1645 my $user = $user{$uid} || $uid; # too lazy to implement lookup
1646 my $group = $group{$gid} || $gid;
1648 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
1650 my($moname) = $moname[$mon];
1651 if (-M _ > 365.25 / 2) {
1652 $timeyear = $year + 1900;
1655 $timeyear = sprintf("%02d:%02d", $hour, $min);
1658 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
1672 package CPAN::FTP::netrc;
1676 my $file = MM->catfile($ENV{HOME},".netrc");
1678 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1679 $atime,$mtime,$ctime,$blksize,$blocks)
1684 my($fh,@machines,$hasdefault);
1686 $fh = FileHandle->new or die "Could not create a filehandle";
1688 if($fh->open($file)){
1689 $protected = ($mode & 077) == 0;
1691 NETRC: while (<$fh>) {
1692 my(@tokens) = split " ", $_;
1693 TOKEN: while (@tokens) {
1694 my($t) = shift @tokens;
1695 if ($t eq "default"){
1697 # warn "saw a default entry before tokens[@tokens]";
1700 last TOKEN if $t eq "macdef";
1701 if ($t eq "machine") {
1702 push @machines, shift @tokens;
1707 $file = $hasdefault = $protected = "";
1711 'mach' => [@machines],
1713 'hasdefault' => $hasdefault,
1714 'protected' => $protected,
1718 sub hasdefault { shift->{'hasdefault'} }
1719 sub netrc { shift->{'netrc'} }
1720 sub protected { shift->{'protected'} }
1722 my($self,$mach) = @_;
1723 for ( @{$self->{'mach'}} ) {
1724 return 1 if $_ eq $mach;
1729 package CPAN::Complete;
1730 @CPAN::Complete::ISA = qw(CPAN::Debug);
1732 #-> sub CPAN::Complete::complete ;
1734 my($word,$line,$pos) = @_;
1738 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1740 if ($line =~ s/^(force\s*)//) {
1748 ! a b d h i m o q r u autobundle clean
1749 make test install force reload look
1752 } elsif ( $line !~ /^[\!abdhimorutl]/ ) {
1754 } elsif ($line =~ /^a\s/) {
1755 @return = completex('CPAN::Author',$word);
1756 } elsif ($line =~ /^b\s/) {
1757 @return = completex('CPAN::Bundle',$word);
1758 } elsif ($line =~ /^d\s/) {
1759 @return = completex('CPAN::Distribution',$word);
1760 } elsif ($line =~ /^([mru]|make|clean|test|install|readme|look)\s/ ) {
1761 @return = (completex('CPAN::Module',$word),completex('CPAN::Bundle',$word));
1762 } elsif ($line =~ /^i\s/) {
1763 @return = complete_any($word);
1764 } elsif ($line =~ /^reload\s/) {
1765 @return = complete_reload($word,$line,$pos);
1766 } elsif ($line =~ /^o\s/) {
1767 @return = complete_option($word,$line,$pos);
1774 #-> sub CPAN::Complete::completex ;
1776 my($class, $word) = @_;
1777 grep /^\Q$word\E/, map { $_->id } $CPAN::META->all($class);
1780 #-> sub CPAN::Complete::complete_any ;
1784 completex('CPAN::Author',$word),
1785 completex('CPAN::Bundle',$word),
1786 completex('CPAN::Distribution',$word),
1787 completex('CPAN::Module',$word),
1791 #-> sub CPAN::Complete::complete_reload ;
1792 sub complete_reload {
1793 my($word,$line,$pos) = @_;
1795 my(@words) = split " ", $line;
1796 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1797 my(@ok) = qw(cpan index);
1798 return @ok if @words == 1;
1799 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
1802 #-> sub CPAN::Complete::complete_option ;
1803 sub complete_option {
1804 my($word,$line,$pos) = @_;
1806 my(@words) = split " ", $line;
1807 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1808 my(@ok) = qw(conf debug);
1809 return @ok if @words == 1;
1810 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
1812 } elsif ($words[1] eq 'index') {
1814 } elsif ($words[1] eq 'conf') {
1815 return CPAN::Config::complete(@_);
1816 } elsif ($words[1] eq 'debug') {
1817 return sort grep /^\Q$word\E/, sort keys %CPAN::DEBUG, 'all';
1821 package CPAN::Index;
1822 use vars qw($last_time $date_of_03);
1823 @CPAN::Index::ISA = qw(CPAN::Debug);
1827 #-> sub CPAN::Index::force_reload ;
1830 $CPAN::Index::last_time = 0;
1834 #-> sub CPAN::Index::reload ;
1836 my($cl,$force) = @_;
1839 # XXX check if a newer one is available. (We currently read it from time to time)
1840 for ($CPAN::Config->{index_expire}) {
1841 $_ = 0.001 unless $_ > 0.001;
1843 return if $last_time + $CPAN::Config->{index_expire}*86400 > $time;
1847 $cl->read_authindex($cl->reload_x(
1848 "authors/01mailrc.txt.gz",
1852 $debug = "timing reading 01[".($t2 - $time)."]";
1854 return if $CPAN::Signal; # this is sometimes lengthy
1855 $cl->read_modpacks($cl->reload_x(
1856 "modules/02packages.details.txt.gz",
1860 $debug .= "02[".($t2 - $time)."]";
1862 return if $CPAN::Signal; # this is sometimes lengthy
1863 $cl->read_modlist($cl->reload_x(
1864 "modules/03modlist.data.gz",
1868 $debug .= "03[".($t2 - $time)."]";
1870 CPAN->debug($debug) if $CPAN::DEBUG;
1873 #-> sub CPAN::Index::reload_x ;
1875 my($cl,$wanted,$localname,$force) = @_;
1877 CPAN::Config->load; # we should guarantee loading wherever we rely on Config XXX
1878 my $abs_wanted = CPAN->catfile($CPAN::Config->{'keep_source_where'},$localname);
1881 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
1884 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
1885 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
1886 qq{day$s. I\'ll use that.});
1891 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
1894 #-> sub CPAN::Index::read_authindex ;
1895 sub read_authindex {
1896 my($cl,$index_target) = @_;
1897 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $index_target";
1898 print "Going to read $index_target\n";
1899 my $fh = FileHandle->new("$pipe|");
1902 my($userid,$fullname,$email) = /alias\s+(\S+)\s+\"([^\"\<]+)\s+<([^\>]+)\>\"/;
1903 next unless $userid && $fullname && $email;
1905 # instantiate an author object
1906 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
1907 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
1908 return if $CPAN::Signal;
1911 $? and Carp::croak "FAILED $pipe: exit status [$?]";
1914 #-> sub CPAN::Index::read_modpacks ;
1916 my($cl,$index_target) = @_;
1917 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $index_target";
1918 print "Going to read $index_target\n";
1919 my $fh = FileHandle->new("$pipe|");
1925 my($mod,$version,$dist) = split;
1926 ### $version =~ s/^\+//;
1928 # if it as a bundle, instatiate a bundle object
1929 my($bundle,$id,$userid);
1931 if ($mod eq 'CPAN') {
1933 if ($version > $CPAN::VERSION){
1935 There\'s a new CPAN.pm version (v$version) available!
1936 You might want to try
1939 without quitting the current session. It should be a seemless upgrade
1940 while we are running...
1945 last if $CPAN::Signal;
1946 } elsif ($mod =~ /^Bundle::(.*)/) {
1951 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
1952 ### $id->set('CPAN_VERSION' => $version, 'CPAN_FILE' => $dist);
1953 # This "next" makes us faster but if the job is running long, we ignore
1954 # rereads which is bad. So we have to be a bit slower again.
1955 # } elsif ($CPAN::META->exists('CPAN::Module',$mod)) {
1958 # instantiate a module object
1959 $id = $CPAN::META->instance('CPAN::Module',$mod);
1960 ### $id->set('CPAN_VERSION' => $version, 'CPAN_FILE' => $dist)
1961 ### if $id->cpan_version ne $version || $id->cpan_file ne $dist; # good speed in here
1964 if ($id->cpan_file ne $dist){
1965 # determine the author
1966 ($userid) = $dist =~ /([^\/]+)/;
1968 'CPAN_USERID' => $userid,
1969 'CPAN_VERSION' => $version,
1970 'CPAN_FILE' => $dist
1974 # instantiate a distribution object
1975 unless ($CPAN::META->exists('CPAN::Distribution',$dist)) {
1976 $CPAN::META->instance(
1977 'CPAN::Distribution' => $dist
1979 'CPAN_USERID' => $userid
1983 return if $CPAN::Signal;
1986 $? and Carp::croak "FAILED $pipe: exit status [$?]";
1989 #-> sub CPAN::Index::read_modlist ;
1991 my($cl,$index_target) = @_;
1992 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $index_target";
1993 print "Going to read $index_target\n";
1994 my $fh = FileHandle->new("$pipe|");
1997 if (/^Date:\s+(.*)/){
1998 return if $date_of_03 eq $1;
2006 $eval .= q{CPAN::Modulelist->data;};
2008 my($comp) = Safe->new("CPAN::Safe1");
2009 my $ret = $comp->reval($eval);
2010 Carp::confess($@) if $@;
2011 return if $CPAN::Signal;
2013 my $obj = $CPAN::META->instance(CPAN::Module,$_);
2014 $obj->set(%{$ret->{$_}});
2015 return if $CPAN::Signal;
2019 package CPAN::InfoObj;
2020 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
2022 #-> sub CPAN::InfoObj::new ;
2023 sub new { my $this = bless {}, shift; %$this = @_; $this }
2025 #-> sub CPAN::InfoObj::set ;
2027 my($self,%att) = @_;
2028 my(%oldatt) = %$self;
2029 %$self = (%oldatt, %att);
2032 #-> sub CPAN::InfoObj::id ;
2033 sub id { shift->{'ID'} }
2035 #-> sub CPAN::InfoObj::as_glimpse ;
2039 my $class = ref($self);
2040 $class =~ s/^CPAN:://;
2041 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
2045 #-> sub CPAN::InfoObj::as_string ;
2049 my $class = ref($self);
2050 $class =~ s/^CPAN:://;
2051 push @m, $class, " id = $self->{ID}\n";
2052 for (sort keys %$self) {
2055 $_ eq "CPAN_USERID" and $extra = " (".$self->author.")";
2056 if (ref($self->{$_}) eq "ARRAY") { # Should we setup a language interface? XXX
2057 push @m, sprintf " %-12s %s%s\n", $_, "@{$self->{$_}}", $extra;
2059 push @m, sprintf " %-12s %s%s\n", $_, $self->{$_}, $extra;
2065 #-> sub CPAN::InfoObj::author ;
2068 $CPAN::META->instance(CPAN::Author,$self->{CPAN_USERID})->fullname;
2071 package CPAN::Author;
2072 @CPAN::Author::ISA = qw(CPAN::InfoObj);
2074 #-> sub CPAN::Author::as_glimpse ;
2078 my $class = ref($self);
2079 $class =~ s/^CPAN:://;
2080 push @m, sprintf "%-15s %s (%s)\n", $class, $self->{ID}, $self->fullname;
2084 # Dead code, I would have liked to have,,, but it was never reached,,,
2087 # return "Don't be silly, you can't make $self->{FULLNAME} ;-)\n";
2090 #-> sub CPAN::Author::fullname ;
2091 sub fullname { shift->{'FULLNAME'} }
2093 #-> sub CPAN::Author::email ;
2094 sub email { shift->{'EMAIL'} }
2096 package CPAN::Distribution;
2097 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
2099 #-> sub CPAN::Distribution::called_for ;
2102 $self->{'CALLED_FOR'} = $id if defined $id;
2103 return $self->{'CALLED_FOR'};
2106 #-> sub CPAN::Distribution::get ;
2111 exists $self->{'build_dir'} and push @e,
2112 "Unwrapped into directory $self->{'build_dir'}";
2113 print join "", map {" $_\n"} @e and return if @e;
2118 $CPAN::Config->{keep_source_where},
2121 split("/",$self->{ID})
2124 $self->debug("Doing localize") if $CPAN::DEBUG;
2125 $local_file = CPAN::FTP->localize("authors/id/$self->{ID}", $local_wanted);
2126 $self->{localfile} = $local_file;
2127 my $builddir = $CPAN::META->{cachemgr}->dir;
2128 $self->debug("doing chdir $builddir") if $CPAN::DEBUG;
2129 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
2132 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
2133 if ($CPAN::META->hasMD5) {
2136 if ($local_file =~ /(\.tar\.(gz|Z)|\.tgz|\.zip)$/i){
2137 $self->debug("Removing tmp") if $CPAN::DEBUG;
2138 File::Path::rmtree("tmp");
2139 mkdir "tmp", 0777 or Carp::croak "Couldn't mkdir tmp: $!";
2141 $self->debug("Changed directory to tmp") if $CPAN::DEBUG;
2142 if ($local_file =~ /z$/i){
2143 $self->{archived} = "tar";
2144 if (system("$CPAN::Config->{gzip} --decompress --stdout $local_file | $CPAN::Config->{tar} xvf -")== 0) {
2145 $self->{unwrapped} = "YES";
2147 $self->{unwrapped} = "NO";
2149 } elsif ($local_file =~ /zip$/i) {
2150 $self->{archived} = "zip";
2151 if (system("$CPAN::Config->{unzip} $local_file") == 0) {
2152 $self->{unwrapped} = "YES";
2154 $self->{unwrapped} = "NO";
2157 # Let's check if the package has its own directory.
2158 opendir DIR, "." or Carp::croak("Weird: couldn't opendir .: $!");
2159 my @readdir = grep $_ !~ /^\.\.?$/, readdir DIR; ### MAC??
2161 my ($distdir,$packagedir);
2162 if (@readdir == 1 && -d $readdir[0]) {
2163 $distdir = $readdir[0];
2164 $packagedir = $CPAN::META->catdir($builddir,$distdir);
2165 -d $packagedir and print "Removing previously used $packagedir\n";
2166 File::Path::rmtree($packagedir);
2167 rename($distdir,$packagedir) or Carp::confess("Couldn't rename $distdir to $packagedir: $!");
2169 my $pragmatic_dir = $self->{'CPAN_USERID'} . '000';
2170 $pragmatic_dir =~ s/\W_//g;
2171 $pragmatic_dir++ while -d "../$pragmatic_dir";
2172 $packagedir = $CPAN::META->catdir($builddir,$pragmatic_dir);
2173 File::Path::mkpath($packagedir);
2175 for $f (@readdir) { # is already without "." and ".."
2176 my $to = $CPAN::META->catdir($packagedir,$f);
2177 rename($f,$to) or Carp::confess("Couldn't rename $f to $to: $!");
2180 $self->{'build_dir'} = $packagedir;
2183 $self->debug("Changed directory to .. (self is $self [".$self->as_string."])")
2185 File::Path::rmtree("tmp");
2186 if ($CPAN::Config->{keep_source_where} =~ /^no/i ){
2187 print "Going to unlink $local_file\n";
2188 unlink $local_file or Carp::carp "Couldn't unlink $local_file";
2190 my($makefilepl) = $CPAN::META->catfile($packagedir,"Makefile.PL");
2191 unless (-f $makefilepl) {
2192 my($configure) = $CPAN::META->catfile($packagedir,"Configure");
2193 if (-f $configure) {
2194 # do we have anything to do?
2195 $self->{'configure'} = $configure;
2197 my $fh = FileHandle->new(">$makefilepl")
2198 or Carp::croak("Could not open >$makefilepl");
2199 my $cf = $self->called_for || "unknown";
2201 # This Makefile.PL has been autogenerated by the module CPAN.pm
2202 # Autogenerated on: }.scalar localtime().qq{
2203 use ExtUtils::MakeMaker;
2204 WriteMakefile(NAME => q[$cf]);
2206 print qq{Package comes without Makefile.PL.\n}.
2207 qq{ Writing one on our own (calling it $cf)\n};
2211 $self->{archived} = "NO";
2216 #-> sub CPAN::Distribution::new ;
2218 my($class,%att) = @_;
2220 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
2222 my $this = { %att };
2223 return bless $this, $class;
2226 #-> sub CPAN::Distribution::look ;
2229 if ( $CPAN::Config->{'shell'} ) {
2231 Trying to open a subshell in the build directory...
2235 Your configuration does not define a value for subshells.
2236 Please define it with "o conf shell <your shell>"
2240 my $dist = $self->id;
2241 my $dir = $self->dir or $self->get;
2244 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
2245 my $pwd = Cwd->$getcwd();
2247 print qq{Working directory is $dir.\n};
2248 system($CPAN::Config->{'shell'}) == 0 or die "Subprocess shell error";
2252 #-> sub CPAN::Distribution::readme ;
2255 my($dist) = $self->id;
2256 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
2257 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
2261 $CPAN::Config->{keep_source_where},
2264 split("/","$sans.readme"),
2266 $self->debug("Doing localize") if $CPAN::DEBUG;
2267 $local_file = CPAN::FTP->localize("authors/id/$sans.readme", $local_wanted);
2268 my $fh_pager = FileHandle->new;
2269 $fh_pager->open("|$CPAN::Config->{'pager'}")
2270 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
2271 my $fh_readme = FileHandle->new;
2272 $fh_readme->open($local_file) or die "Could not open $local_file: $!";
2273 $fh_pager->print(<$fh_readme>);
2276 #-> sub CPAN::Distribution::verifyMD5 ;
2281 $self->{MD5_STATUS} ||= "";
2282 $self->{MD5_STATUS} eq "OK" and push @e, "MD5 Checksum was ok";
2283 print join "", map {" $_\n"} @e and return if @e;
2286 my(@local) = split("/",$self->{ID});
2287 my($basename) = pop @local;
2288 push @local, "CHECKSUMS";
2291 $CPAN::Config->{keep_source_where},
2300 $self->MD5_check_file($local_wanted,$basename)
2302 return $self->{MD5_STATUS} = "OK";
2304 $local_file = CPAN::FTP->localize(
2305 "authors/id/@local",
2312 $local[-1] .= ".gz";
2313 $local_file = CPAN::FTP->localize(
2314 "authors/id/@local",
2318 my $system = "$CPAN::Config->{gzip} --decompress $local_file";
2319 system($system) == 0 or die "Could not uncompress $local_file";
2320 $local_file =~ s/\.gz$//;
2322 $self->MD5_check_file($local_file,$basename);
2325 #-> sub CPAN::Distribution::MD5_check_file ;
2326 sub MD5_check_file {
2327 my($self,$lfile,$basename) = @_;
2329 my $fh = new FileHandle;
2331 if (open $fh, $lfile){
2334 my($comp) = Safe->new();
2335 $cksum = $comp->reval($eval);
2336 Carp::confess($@) if $@;
2337 if ($cksum->{$basename}->{md5}) {
2338 $self->debug("Found checksum for $basename: $cksum->{$basename}->{md5}\n")
2340 my $file = $self->{localfile};
2341 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $self->{localfile}|";
2343 open($fh, $file) && $self->eq_MD5($fh,$cksum->{$basename}->{md5})
2345 open($fh, $pipe) && $self->eq_MD5($fh,$cksum->{$basename}->{'md5-ungz'})
2347 print "Checksum for $file ok\n";
2348 return $self->{MD5_STATUS} = "OK";
2352 qq{Checksum mismatch for distribution file. },
2353 qq{Please investigate.\n\n}
2355 print $self->as_string;
2356 print $CPAN::META->instance(
2358 $self->{CPAN_USERID}
2360 my $wrap = qq{I\'d recommend removing $self->{'localfile'}}.
2361 qq{, put another URL at the top of the list of URLs to }.
2362 qq{visit, and restart CPAN.pm. If all this doesn\'t help, }.
2363 qq{please contact the author or your CPAN site admin};
2364 print Text::Wrap::wrap("","",$wrap);
2369 close $fh if fileno($fh);
2371 $self->{MD5_STATUS} ||= "";
2372 if ($self->{MD5_STATUS} eq "NIL") {
2373 print "\nNo md5 checksum for $basename in local $lfile.";
2374 print "Removing $lfile\n";
2375 unlink $lfile or print "Could not unlink: $!";
2378 $self->{MD5_STATUS} = "NIL";
2382 Carp::carp "Could not open $lfile for reading";
2386 #-> sub CPAN::Distribution::eq_MD5 ;
2388 my($self,$fh,$expectMD5) = @_;
2391 my $hexdigest = $md5->hexdigest;
2392 $hexdigest eq $expectMD5;
2395 #-> sub CPAN::Distribution::force ;
2398 $self->{'force_update'}++;
2399 delete $self->{'MD5_STATUS'};
2400 delete $self->{'archived'};
2401 delete $self->{'build_dir'};
2402 delete $self->{'localfile'};
2403 delete $self->{'make'};
2404 delete $self->{'install'};
2405 delete $self->{'unwrapped'};
2406 delete $self->{'writemakefile'};
2409 #-> sub CPAN::Distribution::perl ;
2412 my($perl) = MM->file_name_is_absolute($^X) ? $^X : "";
2413 my $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
2414 my $pwd = Cwd->$getcwd();
2415 my $candidate = $CPAN::META->catfile($pwd,$^X);
2416 $perl ||= $candidate if MM->maybe_command($candidate);
2418 my ($component,$perl_name);
2419 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
2420 PATH_COMPONENT: foreach $component (MM->path(), $Config::Config{'binexp'}) {
2421 next unless defined($component) && $component;
2422 my($abs) = MM->catfile($component,$perl_name);
2423 if (MM->maybe_command($abs)) {
2433 #-> sub CPAN::Distribution::make ;
2436 $self->debug($self->id) if $CPAN::DEBUG;
2437 print "Running make\n";
2441 $self->{archived} eq "NO" and push @e,
2442 "Is neither a tar nor a zip archive.";
2444 $self->{unwrapped} eq "NO" and push @e,
2445 "had problems unarchiving. Please build manually";
2447 exists $self->{writemakefile} &&
2448 $self->{writemakefile} eq "NO" and push @e,
2449 "Had some problem writing Makefile";
2451 defined $self->{'make'} and push @e,
2452 "Has already been processed within this session";
2454 print join "", map {" $_\n"} @e and return if @e;
2456 print "\n CPAN.pm: Going to build ".$self->id."\n\n";
2457 my $builddir = $self->dir;
2458 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
2459 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
2462 if ($self->{'configure'}) {
2463 $system = $self->{'configure'};
2465 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
2467 # This needs a handler that can be turned on or off:
2468 # $switch = "-MExtUtils::MakeMaker ".
2469 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
2471 $system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}";
2474 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
2477 if ($CPAN::Config->{inactivity_timeout}) {
2479 alarm $CPAN::Config->{inactivity_timeout};
2480 local $SIG{CHLD} = sub { wait };
2481 if (defined($pid = fork)) {
2488 print "Cannot fork: $!";
2497 $self->{writemakefile} = "NO - $@";
2502 $ret = system($system);
2504 $self->{writemakefile} = "NO";
2509 $self->{writemakefile} = "YES";
2510 return if $CPAN::Signal;
2511 $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
2512 if (system($system) == 0) {
2513 print " $system -- OK\n";
2514 $self->{'make'} = "YES";
2516 $self->{writemakefile} = "YES";
2517 $self->{'make'} = "NO";
2518 print " $system -- NOT OK\n";
2522 #-> sub CPAN::Distribution::test ;
2526 return if $CPAN::Signal;
2527 print "Running make test\n";
2530 exists $self->{'make'} or push @e,
2531 "Make had some problems, maybe interrupted? Won't test";
2533 exists $self->{'make'} and
2534 $self->{'make'} eq 'NO' and
2535 push @e, "Oops, make had returned bad status";
2537 exists $self->{'build_dir'} or push @e, "Has no own directory";
2538 print join "", map {" $_\n"} @e and return if @e;
2540 chdir $self->{'build_dir'} or Carp::croak("Couldn't chdir to $self->{'build_dir'}");
2541 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
2542 my $system = join " ", $CPAN::Config->{'make'}, "test";
2543 if (system($system) == 0) {
2544 print " $system -- OK\n";
2545 $self->{'make_test'} = "YES";
2547 $self->{'make_test'} = "NO";
2548 print " $system -- NOT OK\n";
2552 #-> sub CPAN::Distribution::clean ;
2555 print "Running make clean\n";
2558 exists $self->{'build_dir'} or push @e, "Has no own directory";
2559 print join "", map {" $_\n"} @e and return if @e;
2561 chdir $self->{'build_dir'} or Carp::croak("Couldn't chdir to $self->{'build_dir'}");
2562 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
2563 my $system = join " ", $CPAN::Config->{'make'}, "clean";
2564 if (system($system) == 0) {
2565 print " $system -- OK\n";
2568 # Hmmm, what to do if make clean failed?
2572 #-> sub CPAN::Distribution::install ;
2576 return if $CPAN::Signal;
2577 print "Running make install\n";
2580 exists $self->{'build_dir'} or push @e, "Has no own directory";
2582 exists $self->{'make'} or push @e,
2583 "Make had some problems, maybe interrupted? Won't install";
2585 exists $self->{'make'} and
2586 $self->{'make'} eq 'NO' and
2587 push @e, "Oops, make had returned bad status";
2589 push @e, "make test had returned bad status, won't install without force"
2590 if exists $self->{'make_test'} and
2591 $self->{'make_test'} eq 'NO' and
2592 ! $self->{'force_update'};
2594 exists $self->{'install'} and push @e,
2595 $self->{'install'} eq "YES" ?
2596 "Already done" : "Already tried without success";
2598 print join "", map {" $_\n"} @e and return if @e;
2600 chdir $self->{'build_dir'} or Carp::croak("Couldn't chdir to $self->{'build_dir'}");
2601 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
2602 my $system = join " ", $CPAN::Config->{'make'}, "install", $CPAN::Config->{make_install_arg};
2603 my($pipe) = FileHandle->new("$system 2>&1 |");
2611 print " $system -- OK\n";
2612 $self->{'install'} = "YES";
2614 $self->{'install'} = "NO";
2615 print " $system -- NOT OK\n";
2616 if ($makeout =~ /permission/s && $> > 0) {
2617 print " You may have to su to root to install the package\n";
2622 #-> sub CPAN::Distribution::dir ;
2624 shift->{'build_dir'};
2627 package CPAN::Bundle;
2628 @CPAN::Bundle::ISA = qw(CPAN::Module);
2630 #-> sub CPAN::Bundle::as_string ;
2634 $self->{INST_VERSION} = $self->inst_version;
2635 return $self->SUPER::as_string;
2638 #-> sub CPAN::Bundle::contains ;
2641 my($parsefile) = $self->inst_file;
2642 unless ($parsefile) {
2643 # Try to get at it in the cpan directory
2644 $self->debug("no parsefile") if $CPAN::DEBUG;
2645 my $dist = $CPAN::META->instance('CPAN::Distribution',$self->{'CPAN_FILE'});
2647 $self->debug($dist->as_string) if $CPAN::DEBUG;
2648 my($todir) = $CPAN::META->catdir($CPAN::Config->{'cpan_home'},"Bundle");
2649 File::Path::mkpath($todir);
2651 ($me = $self->id) =~ s/.*://;
2652 $from = $self->find_bundle_file($dist->{'build_dir'},"$me.pm");
2653 $to = $CPAN::META->catfile($todir,"$me.pm");
2654 File::Copy::copy($from, $to) or Carp::confess("Couldn't copy $from to $to: $!");
2658 my $fh = new FileHandle;
2660 open($fh,$parsefile) or die "Could not open '$parsefile': $!";
2662 $self->debug("parsefile[$parsefile]") if $CPAN::DEBUG;
2664 $inpod = /^=(?!head1\s+CONTENTS)/ ? 0 : /^=head1\s+CONTENTS/ ? 1 : $inpod;
2669 push @result, (split " ", $_, 2)[0];
2672 delete $self->{STATUS};
2673 $self->{CONTAINS} = join ", ", @result;
2674 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
2678 #-> sub CPAN::Bundle::find_bundle_file
2679 sub find_bundle_file {
2680 my($self,$where,$what) = @_;
2681 my $bu = $CPAN::META->catfile($where,$what);
2682 return $bu if -f $bu;
2683 my $manifest = $CPAN::META->catfile($where,"MANIFEST");
2684 unless (-f $manifest) {
2685 require ExtUtils::Manifest;
2686 my $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
2687 my $cwd = Cwd->$getcwd();
2689 ExtUtils::Manifest::mkmanifest();
2692 my $fh = FileHandle->new($manifest) or Carp::croak("Couldn't open $manifest: $!");
2696 my($file) = /(\S+)/;
2697 if ($file =~ m|Bundle/$what$|) {
2699 return $CPAN::META->catfile($where,$bu);
2702 Carp::croak("Could't find a Bundle file in $where");
2705 #-> sub CPAN::Bundle::inst_file ;
2709 ($me = $self->id) =~ s/.*://;
2710 $inst_file = $CPAN::META->catfile($CPAN::Config->{'cpan_home'},"Bundle", "$me.pm");
2711 return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
2713 $self->SUPER::inst_file;
2714 # return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
2715 # return $self->{'INST_FILE'}; # even if undefined?
2718 #-> sub CPAN::Bundle::rematein ;
2720 my($self,$meth) = @_;
2721 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
2723 for $s ($self->contains) {
2724 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
2725 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
2726 if ($type eq 'CPAN::Distribution') {
2728 The Bundle }.$self->id.qq{ contains
2729 explicitly a file $s.
2733 $CPAN::META->instance($type,$s)->$meth();
2737 #sub CPAN::Bundle::xs_file
2739 # If a bundle contains another that contains an xs_file we have
2740 # here, we just don't bother I suppose
2744 #-> sub CPAN::Bundle::force ;
2745 sub force { shift->rematein('force',@_); }
2746 #-> sub CPAN::Bundle::get ;
2747 sub get { shift->rematein('get',@_); }
2748 #-> sub CPAN::Bundle::make ;
2749 sub make { shift->rematein('make',@_); }
2750 #-> sub CPAN::Bundle::test ;
2751 sub test { shift->rematein('test',@_); }
2752 #-> sub CPAN::Bundle::install ;
2753 sub install { shift->rematein('install',@_); }
2754 #-> sub CPAN::Bundle::clean ;
2755 sub clean { shift->rematein('clean',@_); }
2757 #-> sub CPAN::Bundle::readme ;
2760 my($file) = $self->cpan_file or print("No File found for bundle ", $self->id, "\n"), return;
2761 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
2762 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
2765 package CPAN::Module;
2766 @CPAN::Module::ISA = qw(CPAN::InfoObj);
2768 #-> sub CPAN::Module::as_glimpse ;
2772 my $class = ref($self);
2773 $class =~ s/^CPAN:://;
2774 push @m, sprintf "%-15s %-15s (%s)\n", $class, $self->{ID}, $self->cpan_file;
2778 #-> sub CPAN::Module::as_string ;
2782 CPAN->debug($self) if $CPAN::DEBUG;
2783 my $class = ref($self);
2784 $class =~ s/^CPAN:://;
2786 push @m, $class, " id = $self->{ID}\n";
2787 my $sprintf = " %-12s %s\n";
2788 push @m, sprintf $sprintf, 'DESCRIPTION', $self->{description} if $self->{description};
2789 my $sprintf2 = " %-12s %s (%s)\n";
2791 if ($userid = $self->{'CPAN_USERID'} || $self->{'userid'}){
2796 CPAN::Shell->expand('Author',$userid)->fullname
2799 push @m, sprintf $sprintf, 'CPAN_VERSION', $self->{CPAN_VERSION} if $self->{CPAN_VERSION};
2800 push @m, sprintf $sprintf, 'CPAN_FILE', $self->{CPAN_FILE} if $self->{CPAN_FILE};
2801 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
2802 my(%statd,%stats,%statl,%stati);
2803 @statd{qw,? i c a b R M S,} = qw,unknown idea pre-alpha alpha beta released mature standard,;
2804 @stats{qw,? m d u n,} = qw,unknown mailing-list developer comp.lang.perl.* none,;
2805 @statl{qw,? p c + o,} = qw,unknown perl C C++ other,;
2806 @stati{qw,? f r O,} = qw,unknown functions references+ties object-oriented,;
2807 $statd{' '} = 'unknown';
2808 $stats{' '} = 'unknown';
2809 $statl{' '} = 'unknown';
2810 $stati{' '} = 'unknown';
2818 $statd{$self->{statd}},
2819 $stats{$self->{stats}},
2820 $statl{$self->{statl}},
2821 $stati{$self->{stati}}
2822 ) if $self->{statd};
2823 my $local_file = $self->inst_file;
2824 if ($local_file && ! exists $self->{MANPAGE}) {
2825 my $fh = FileHandle->new($local_file) or Carp::croak("Couldn't open $local_file: $!");
2830 $inpod = /^=(?!head1\s+NAME)/ ? 0 : /^=head1\s+NAME/ ? 1 : $inpod;
2838 $self->{MANPAGE} = join " ", @result;
2841 for $item (qw/MANPAGE CONTAINS/) {
2842 push @m, sprintf $sprintf, $item, $self->{$item} if exists $self->{$item};
2844 push @m, sprintf $sprintf, 'INST_FILE', $local_file || "(not installed)";
2845 push @m, sprintf $sprintf, 'INST_VERSION', $self->inst_version if $local_file;
2849 #-> sub CPAN::Module::cpan_file ;
2852 CPAN->debug($self->id) if $CPAN::DEBUG;
2853 unless (defined $self->{'CPAN_FILE'}) {
2854 CPAN::Index->reload;
2856 if (defined $self->{'CPAN_FILE'}){
2857 return $self->{'CPAN_FILE'};
2858 } elsif (defined $self->{'userid'}) {
2859 return "Contact Author ".$self->{'userid'}."=".$CPAN::META->instance(CPAN::Author,$self->{'userid'})->fullname
2865 *name = \&cpan_file;
2867 #-> sub CPAN::Module::cpan_version ;
2868 sub cpan_version { shift->{'CPAN_VERSION'} }
2870 #-> sub CPAN::Module::force ;
2873 $self->{'force_update'}++;
2876 #-> sub CPAN::Module::rematein ;
2878 my($self,$meth) = @_;
2879 $self->debug($self->id) if $CPAN::DEBUG;
2880 my $cpan_file = $self->cpan_file;
2881 return if $cpan_file eq "N/A";
2882 return if $cpan_file =~ /^Contact Author/;
2883 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
2884 $pack->called_for($self->id);
2885 $pack->force if exists $self->{'force_update'};
2887 delete $self->{'force_update'};
2890 #-> sub CPAN::Module::readme ;
2891 sub readme { shift->rematein('readme') }
2892 #-> sub CPAN::Module::look ;
2893 sub look { shift->rematein('look') }
2894 #-> sub CPAN::Module::get ;
2895 sub get { shift->rematein('get',@_); }
2896 #-> sub CPAN::Module::make ;
2897 sub make { shift->rematein('make') }
2898 #-> sub CPAN::Module::test ;
2899 sub test { shift->rematein('test') }
2900 #-> sub CPAN::Module::install ;
2904 my($latest) = $self->cpan_version;
2906 my($inst_file) = $self->inst_file;
2908 if (defined $inst_file) {
2909 $have = $self->inst_version;
2911 if (1){ # A block for scoping $^W, the if is just for the visual
2914 if ($inst_file && $have >= $latest && not exists $self->{'force_update'}) {
2915 print $self->id, " is up to date.\n";
2920 $self->rematein('install') if $doit;
2922 #-> sub CPAN::Module::clean ;
2923 sub clean { shift->rematein('clean') }
2925 #-> sub CPAN::Module::inst_file ;
2929 @packpath = split /::/, $self->{ID};
2930 $packpath[-1] .= ".pm";
2931 foreach $dir (@INC) {
2932 my $pmfile = CPAN->catfile($dir,@packpath);
2940 #-> sub CPAN::Module::xs_file ;
2944 @packpath = split /::/, $self->{ID};
2945 push @packpath, $packpath[-1];
2946 $packpath[-1] .= "." . $Config::Config{'dlext'};
2947 foreach $dir (@INC) {
2948 my $xsfile = CPAN->catfile($dir,'auto',@packpath);
2956 #-> sub CPAN::Module::inst_version ;
2959 my $parsefile = $self->inst_file or return 0;
2960 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
2961 my $have = MM->parse_version($parsefile);
2968 # Do this after you have set up the whole inheritance
2969 CPAN::Config->load unless defined $CPAN::No_Config_is_ok;
2976 CPAN - query, download and build perl modules from CPAN sites
2982 perl -MCPAN -e shell;
2988 autobundle, clean, install, make, recompile, test
2992 The CPAN module is designed to automate the make and install of perl
2993 modules and extensions. It includes some searching capabilities and
2994 knows how to use Net::FTP or LWP (or lynx or an external ftp client)
2995 to fetch the raw data from the net.
2997 Modules are fetched from one or more of the mirrored CPAN
2998 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
3001 The CPAN module also supports the concept of named and versioned
3002 'bundles' of modules. Bundles simplify the handling of sets of
3003 related modules. See BUNDLES below.
3005 The package contains a session manager and a cache manager. There is
3006 no status retained between sessions. The session manager keeps track
3007 of what has been fetched, built and installed in the current
3008 session. The cache manager keeps track of the disk space occupied by
3009 the make processes and deletes excess space according to a simple FIFO
3012 All methods provided are accessible in a programmer style and in an
3013 interactive shell style.
3015 =head2 Interactive Mode
3017 The interactive mode is entered by running
3019 perl -MCPAN -e shell
3021 which puts you into a readline interface. You will have most fun if
3022 you install Term::ReadKey and Term::ReadLine to enjoy both history and
3025 Once you are on the command line, type 'h' and the rest should be
3028 The most common uses of the interactive modes are
3032 =item Searching for authors, bundles, distribution files and modules
3034 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
3035 for each of the four categories and another, C<i> for any of the
3036 mentioned four. Each of the four entities is implemented as a class
3037 with slightly differing methods for displaying an object.
3039 Arguments you pass to these commands are either strings matching exact
3040 the identification string of an object or regular expressions that are
3041 then matched case-insensitively against various attributes of the
3042 objects. The parser recognizes a regualar expression only if you
3043 enclose it between two slashes.
3045 The principle is that the number of found objects influences how an
3046 item is displayed. If the search finds one item, we display the result
3047 of object-E<gt>as_string, but if we find more than one, we display
3048 each as object-E<gt>as_glimpse. E.g.
3052 EMAIL a.koenig@franz.ww.TU-Berlin.DE
3053 FULLNAME Andreas König
3058 EMAIL a.koenig@franz.ww.TU-Berlin.DE
3059 FULLNAME Andreas König
3063 Author ANDYD (Andy Dougherty)
3064 Author MERLYN (Randal L. Schwartz)
3066 =item make, test, install, clean modules or distributions
3068 These commands do indeed exist just as written above. Each of them
3069 takes any number of arguments and investigates for each what it might
3070 be. Is it a distribution file (recognized by embedded slashes), this
3071 file is being processed. Is it a module, CPAN determines the
3072 distribution file where this module is included and processes that.
3074 Any C<make>, C<test>, and C<readme> are run unconditionally. A
3076 install <distribution_file>
3078 also is run unconditionally. But for
3082 CPAN checks if an install is actually needed for it and prints
3083 I<Foo up to date> in case the module doesnE<39>t need to be updated.
3085 CPAN also keeps track of what it has done within the current session
3086 and doesnE<39>t try to build a package a second time regardless if it
3087 succeeded or not. The C<force > command takes as first argument the
3088 method to invoke (currently: make, test, or install) and executes the
3089 command from scratch.
3093 cpan> install OpenGL
3094 OpenGL is up to date.
3095 cpan> force install OpenGL
3098 OpenGL-0.4/COPYRIGHT
3101 =item readme, look module or distribution
3103 These two commands take only one argument, be it a module or a
3104 distribution file. C<readme> displays the README of the associated
3105 distribution file. C<Look> gets and untars (if not yet done) the
3106 distribution file, changes to the appropriate directory and opens a
3107 subshell process in that directory.
3113 The commands that are available in the shell interface are methods in
3114 the package CPAN::Shell. If you enter the shell command, all your
3115 input is split by the Text::ParseWords::shellwords() routine which
3116 acts like most shells do. The first word is being interpreted as the
3117 method to be called and the rest of the words are treated as arguments
3122 C<autobundle> writes a bundle file into the
3123 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
3124 a list of all modules that are both available from CPAN and currently
3125 installed within @INC. The name of the bundle file is based on the
3126 current date and a counter.
3130 recompile() is a very special command in that it takes no argument and
3131 runs the make/test/install cycle with brute force over all installed
3132 dynamically loadable extensions (aka XS modules) with 'force' in
3133 effect. Primary purpose of this command is to finish a network
3134 installation. Imagine, you have a common source tree for two different
3135 architectures. You decide to do a completely independent fresh
3136 installation. You start on one architecture with the help of a Bundle
3137 file produced earlier. CPAN installs the whole Bundle for you, but
3138 when you try to repeat the job on the second architecture, CPAN
3139 responds with a C<"Foo up to date"> message for all modules. So you
3140 will be glad to run recompile in the second architecture and
3143 Another popular use for C<recompile> is to act as a rescue in case your
3144 perl breaks binary compatibility. If one of the modules that CPAN uses
3145 is in turn depending on binary compatibility (so you cannot run CPAN
3146 commands), then you should try the CPAN::Nox module for recovery.
3148 =head2 The 4 Classes: Authors, Bundles, Modules, Distributions
3150 Although it may be considered internal, the class hierarchie does
3151 matter for both users and programmer. CPAN.pm deals with above
3152 mentioned four classes, and all those classes share a set of
3153 methods. It is a classical single polymorphism that is in effect. A
3154 metaclass object registers all objects of all kinds and indexes them
3155 with a string. The strings referencing objects have a separated
3156 namespace (well, not completely separated):
3160 words containing a "/" (slash) Distribution
3161 words starting with Bundle:: Bundle
3162 everything else Module or Author
3164 Modules know their associated Distribution objects. They always refer
3165 to the most recent official release. Developers may mark their
3166 releases as unstable development versions (by inserting an underbar
3167 into the visible version number), so not always is the default
3168 distribution for a given module the really hottest and newest. If a
3169 module Foo circulates on CPAN in both version 1.23 and 1.23_90,
3170 CPAN.pm offers a convenient way to install version 1.23 by saying
3174 This would install the complete distribution file (say
3175 BAR/Foo-1.23.tar.gz) with all accompanying material in there. But if
3176 you would like to install version 1.23_90, you need to know where the
3177 distribution file resides on CPAN relative to the authors/id/
3178 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz,
3179 so he would have say
3181 install BAR/Foo-1.23_90.tar.gz
3183 The first example will be driven by an object of the class
3184 CPAN::Module, the second by an object of class Distribution.
3186 =head2 ProgrammerE<39>s interface
3188 If you do not enter the shell, the available shell commands are both
3189 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
3190 functions in the calling package (C<install(...)>).
3192 There's currently only one class that has a stable interface,
3193 CPAN::Shell. All commands that are available in the CPAN shell are
3194 methods of the class CPAN::Shell. The commands that produce listings
3195 of modules (C<r>, C<autobundle>, C<u>) return a list of the IDs of all
3196 modules within the list.
3200 =item expand($type,@things)
3202 The IDs of all objects available within a program are strings that can
3203 be expanded to the corresponding real objects with the
3204 C<CPAN::Shell-E<gt>expand()> method. Expand returns a list of
3205 CPAN::Module objects according to the C<@things> arguments given. In
3206 scalar context it only returns the first element of the list.
3208 =item Programming Examples
3210 This enables the programmer to do operations like these:
3212 # install everything that is outdated on my disk:
3213 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
3215 # install my favorite programs if necessary:
3216 for $mod (qw(Net::FTP MD5 Data::Dumper)){
3217 my $obj = CPAN::Shell->expand('Module',$mod);
3223 =head2 Cache Manager
3225 Currently the cache manager only keeps track of the build directory
3226 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
3227 deletes complete directories below C<build_dir> as soon as the size of
3228 all directories there gets bigger than $CPAN::Config->{build_cache}
3229 (in MB). The contents of this cache may be used for later
3230 re-installations that you intend to do manually, but will never be
3231 trusted by CPAN itself. This is due to the fact that the user might
3232 use these directories for building modules on different architectures.
3234 There is another directory ($CPAN::Config->{keep_source_where}) where
3235 the original distribution files are kept. This directory is not
3236 covered by the cache manager and must be controlled by the user. If
3237 you choose to have the same directory as build_dir and as
3238 keep_source_where directory, then your sources will be deleted with
3239 the same fifo mechanism.
3243 A bundle is just a perl module in the namespace Bundle:: that does not
3244 define any functions or methods. It usually only contains documentation.
3246 It starts like a perl module with a package declaration and a $VERSION
3247 variable. After that the pod section looks like any other pod with the
3248 only difference, that I<one special pod section> exists starting with
3253 In this pod section each line obeys the format
3255 Module_Name [Version_String] [- optional text]
3257 The only required part is the first field, the name of a module
3258 (eg. Foo::Bar, ie. I<not> the name of the distribution file). The rest
3259 of the line is optional. The comment part is delimited by a dash just
3260 as in the man page header.
3262 The distribution of a bundle should follow the same convention as
3263 other distributions.
3265 Bundles are treated specially in the CPAN package. If you say 'install
3266 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
3267 the modules in the CONTENTS section of the pod. You can install your
3268 own Bundles locally by placing a conformant Bundle file somewhere into
3269 your @INC path. The autobundle() command which is available in the
3270 shell interface does that for you by including all currently installed
3271 modules in a snapshot bundle file.
3273 There is a meaningless Bundle::Demo available on CPAN. Try to install
3274 it, it usually does no harm, just demonstrates what the Bundle
3275 interface looks like.
3277 =head2 Prerequisites
3279 If you have a local mirror of CPAN and can access all files with
3280 "file:" URLs, then you only need a perl better than perl5.003 to run
3281 this module. Otherwise Net::FTP is strongly recommended. LWP may be
3282 required for non-UNIX systems or if your nearest CPAN site is
3283 associated with an URL that is not C<ftp:>.
3285 If you have neither Net::FTP nor LWP, there is a fallback mechanism
3286 implemented for an external ftp command or for an external lynx
3289 This module presumes that all packages on CPAN
3295 declare their $VERSION variable in an easy to parse manner. This
3296 prerequisite can hardly be relaxed because it consumes by far too much
3297 memory to load all packages into the running program just to determine
3298 the $VERSION variable . Currently all programs that are dealing with
3299 version use something like this
3301 perl -MExtUtils::MakeMaker -le \
3302 'print MM->parse_version($ARGV[0])' filename
3304 If you are author of a package and wonder if your $VERSION can be
3305 parsed, please try the above method.
3309 come as compressed or gzipped tarfiles or as zip files and contain a
3310 Makefile.PL (well we try to handle a bit more, but without much
3317 The debugging of this module is pretty difficult, because we have
3318 interferences of the software producing the indices on CPAN, of the
3319 mirroring process on CPAN, of packaging, of configuration, of
3320 synchronicity, and of bugs within CPAN.pm.
3322 In interactive mode you can try "o debug" which will list options for
3323 debugging the various parts of the package. The output may not be very
3324 useful for you as it's just a byproduct of my own testing, but if you
3325 have an idea which part of the package may have a bug, it's sometimes
3326 worth to give it a try and send me more specific output. You should
3327 know that "o debug" has built-in completion support.
3329 =head2 Floppy, Zip, and all that Jazz
3331 CPAN.pm works nicely without network too. If you maintain machines
3332 that are not networked at all, you should consider working with file:
3333 URLs. Of course, you have to collect your modules somewhere first. So
3334 you might use CPAN.pm to put together all you need on a networked
3335 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
3336 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
3337 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
3340 =head1 CONFIGURATION
3342 When the CPAN module is installed a site wide configuration file is
3343 created as CPAN/Config.pm. The default values defined there can be
3344 overridden in another configuration file: CPAN/MyConfig.pm. You can
3345 store this file in $HOME/.cpan/CPAN/MyConfig.pm if you want, because
3346 $HOME/.cpan is added to the search path of the CPAN module before the
3347 use() or require() statements.
3349 Currently the following keys in the hash reference $CPAN::Config are
3352 build_cache size of cache for directories to build modules
3353 build_dir locally accessible directory to build modules
3354 index_expire after how many days refetch index files
3355 cpan_home local directory reserved for this package
3356 gzip location of external program gzip
3357 inactivity_timeout breaks interactive Makefile.PLs after that
3358 many seconds inactivity. Set to 0 to never break.
3359 inhibit_startup_message
3360 if true, does not print the startup message
3361 keep_source keep the source in a local directory?
3362 keep_source_where where keep the source (if we do)
3363 make location of external program make
3364 make_arg arguments that should always be passed to 'make'
3365 make_install_arg same as make_arg for 'make install'
3366 makepl_arg arguments passed to 'perl Makefile.PL'
3367 pager location of external program more (or any pager)
3368 tar location of external program tar
3369 unzip location of external program unzip
3370 urllist arrayref to nearby CPAN sites (or equivalent locations)
3372 You can set and query each of these options interactively in the cpan
3373 shell with the command set defined within the C<o conf> command:
3377 =item o conf E<lt>scalar optionE<gt>
3379 prints the current value of the I<scalar option>
3381 =item o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>
3383 Sets the value of the I<scalar option> to I<value>
3385 =item o conf E<lt>list optionE<gt>
3387 prints the current value of the I<list option> in MakeMaker's
3390 =item o conf E<lt>list optionE<gt> [shift|pop]
3392 shifts or pops the array in the I<list option> variable
3394 =item o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>
3396 works like the corresponding perl commands.
3402 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
3403 install foreign, unmasked, unsigned code on your machine. We compare
3404 to a checksum that comes from the net just as the distribution file
3405 itself. If somebody has managed to tamper with the distribution file,
3406 they may have as well tampered with the CHECKSUMS file. Future
3407 development will go towards strong authentification.
3411 Most functions in package CPAN are exported per default. The reason
3412 for this is that the primary use is intended for the cpan shell or for
3417 we should give coverage for _all_ of the CPAN and not just the
3418 __PAUSE__ part, right? In this discussion CPAN and PAUSE have become
3419 equal -- but they are not. PAUSE is authors/ and modules/. CPAN is
3420 PAUSE plus the clpa/, doc/, misc/, ports/, src/, scripts/.
3422 Future development should be directed towards a better intergration of
3427 Andreas König E<lt>a.koenig@mind.deE<gt>
3431 perl(1), CPAN::Nox(3)