1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
2 # vim: ts=4 sts=4 sw=4:
5 $CPAN::VERSION = '1.93_03'; # make the _03 a dev release and release it as 1.9304 after merge into blead
6 $CPAN::VERSION =~ s/_//;
8 # we need to run chdir all over and we would get at wrong libraries
12 if (File::Spec->can("rel2abs")) {
14 $inc = File::Spec->rel2abs($inc) unless ref $inc;
18 use CPAN::HandleConfig;
23 use CPAN::DeferedCode;
29 use ExtUtils::MakeMaker qw(prompt); # for some unknown reason,
30 # 5.005_04 does not work without
32 use File::Basename ();
39 use Sys::Hostname qw(hostname);
40 use Text::ParseWords ();
43 # protect against "called too early"
49 require Mac::BuildTools if $^O eq 'MacOS';
50 if ($ENV{PERL5_CPAN_IS_RUNNING} && $$ != $ENV{PERL5_CPAN_IS_RUNNING}) {
51 $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION} ||= $ENV{PERL5_CPAN_IS_RUNNING};
52 my $rec = $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION} .= ",$$";
53 my @rec = split /,/, $rec;
54 # warn "# Note: Recursive call of CPAN.pm detected\n";
55 my $w = sprintf "# Note: CPAN.pm is running in process %d now", pop @rec;
61 my $sleep = @rec > 7 ? 300 : ($sleep{scalar @rec}||0);
62 my $verbose = @rec >= 4;
64 $w .= sprintf " which has been called by process %d", pop @rec;
67 $w .= ".\n\n# Sleeping $sleep seconds to protect other processes\n";
74 printf "\r#%5d", --$sleep;
79 $ENV{PERL5_CPAN_IS_RUNNING}=$$;
80 $ENV{PERL5_CPANPLUS_IS_RUNNING}=$$; # https://rt.cpan.org/Ticket/Display.html?id=23735
82 END { $CPAN::End++; &cleanup; }
85 $CPAN::Frontend ||= "CPAN::Shell";
86 unless (@CPAN::Defaultsites) {
87 @CPAN::Defaultsites = map {
88 CPAN::URL->new(TEXT => $_, FROM => "DEF")
90 "http://www.perl.org/CPAN/",
91 "ftp://ftp.perl.org/pub/CPAN/";
93 # $CPAN::iCwd (i for initial)
94 $CPAN::iCwd ||= CPAN::anycwd();
95 $CPAN::Perl ||= CPAN::find_perl();
96 $CPAN::Defaultdocs ||= "http://search.cpan.org/perldoc?";
97 $CPAN::Defaultrecent ||= "http://search.cpan.org/uploads.rdf";
98 $CPAN::Defaultrecent ||= "http://cpan.uwinnipeg.ca/htdocs/cpan.xml";
100 # our globals are getting a mess
126 @CPAN::ISA = qw(CPAN::Debug Exporter);
128 # note that these functions live in CPAN::Shell and get executed via
129 # AUTOLOAD when called directly
156 sub soft_chdir_with_alternatives ($);
159 $autoload_recursion ||= 0;
161 #-> sub CPAN::AUTOLOAD ;
163 $autoload_recursion++;
167 warn "Refusing to autoload '$l' while signal pending";
168 $autoload_recursion--;
171 if ($autoload_recursion > 1) {
172 my $fullcommand = join " ", map { "'$_'" } $l, @_;
173 warn "Refusing to autoload $fullcommand in recursion\n";
174 $autoload_recursion--;
178 @export{@EXPORT} = '';
179 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
180 if (exists $export{$l}) {
183 die(qq{Unknown CPAN command "$AUTOLOAD". }.
184 qq{Type ? for help.\n});
186 $autoload_recursion--;
191 my $x = *SAVEOUT; # avoid warning
192 open($x,">&STDOUT") or die "dup failed";
198 while(defined($_=shift)) {
200 my ($m) = s/^>// ? ">" : "";
202 $_=shift unless length;
203 die "no dest" unless defined;
204 open(STDOUT,">$m$_") or die "open:$_:$!\n";
206 } elsif ( s/^\s*\|\s*// ) {
208 while(defined($_[0])){
209 $pipe .= ' ' . shift;
211 open(STDOUT,$pipe) or die "open:$pipe:$!\n";
220 return unless $redir;
222 ## redirect: unredirect and propagate errors. explicit close to wait for pipe.
224 open(STDOUT,">&SAVEOUT");
230 #-> sub CPAN::shell ;
233 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
234 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
236 my $oprompt = shift || CPAN::Prompt->new;
237 my $prompt = $oprompt;
238 my $commandline = shift || "";
239 $CPAN::CurrentCommandId ||= 1;
242 unless ($Suppress_readline) {
243 require Term::ReadLine;
246 $term->ReadLine eq "Term::ReadLine::Stub"
248 $term = Term::ReadLine->new('CPAN Monitor');
250 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
251 my $attribs = $term->Attribs;
252 $attribs->{attempted_completion_function} = sub {
253 &CPAN::Complete::gnu_cpl;
256 $readline::rl_completion_function =
257 $readline::rl_completion_function = 'CPAN::Complete::cpl';
259 if (my $histfile = $CPAN::Config->{'histfile'}) {{
260 unless ($term->can("AddHistory")) {
261 $CPAN::Frontend->mywarn("Terminal does not support AddHistory.\n");
264 $META->readhist($term,$histfile);
266 for ($CPAN::Config->{term_ornaments}) { # alias
267 local $Term::ReadLine::termcap_nowarn = 1;
268 $term->ornaments($_) if defined;
270 # $term->OUT is autoflushed anyway
271 my $odef = select STDERR;
279 my @cwd = grep { defined $_ and length $_ }
281 File::Spec->can("tmpdir") ? File::Spec->tmpdir() : (),
282 File::Spec->rootdir();
283 my $try_detect_readline;
284 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
285 unless ($CPAN::Config->{inhibit_startup_message}) {
286 my $rl_avail = $Suppress_readline ? "suppressed" :
287 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
288 "available (maybe install Bundle::CPAN or Bundle::CPANxxl?)";
289 $CPAN::Frontend->myprint(
291 cpan shell -- CPAN exploration and modules installation (v%s)
299 my($continuation) = "";
300 my $last_term_ornaments;
301 SHELLCOMMAND: while () {
302 if ($Suppress_readline) {
303 if ($Echo_readline) {
307 last SHELLCOMMAND unless defined ($_ = <> );
308 if ($Echo_readline) {
309 # backdoor: I could not find a way to record sessions
314 last SHELLCOMMAND unless
315 defined ($_ = $term->readline($prompt, $commandline));
317 $_ = "$continuation$_" if $continuation;
319 next SHELLCOMMAND if /^$/;
321 if (/^(?:q(?:uit)?|bye|exit)$/i) {
332 use vars qw($import_done);
333 CPAN->import(':DEFAULT') unless $import_done++;
334 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
341 eval { @line = Text::ParseWords::shellwords($_) };
342 warn($@), next SHELLCOMMAND if $@;
343 warn("Text::Parsewords could not parse the line [$_]"),
344 next SHELLCOMMAND unless @line;
345 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
346 my $command = shift @line;
348 local (*STDOUT)=*STDOUT;
349 @line = _redirect(@line);
350 CPAN::Shell->$command(@line)
358 my $dv = Dumpvalue->new(tick => '"');
359 Carp::cluck(sprintf "Catching error: %s", $dv->stringify($err));
369 # pragmas for classic commands
378 # only commands that tell us something about failed distros
379 CPAN::Shell->failed($CPAN::CurrentCommandId,1);
381 soft_chdir_with_alternatives(\@cwd);
382 $CPAN::Frontend->myprint("\n");
384 $CPAN::CurrentCommandId++;
388 $commandline = ""; # I do want to be able to pass a default to
389 # shell, but on the second command I see no
392 CPAN::Queue->nullify_queue;
393 if ($try_detect_readline) {
394 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
396 $CPAN::META->has_inst("Term::ReadLine::Perl")
398 delete $INC{"Term/ReadLine.pm"};
400 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
401 require Term::ReadLine;
402 $CPAN::Frontend->myprint("\n$redef subroutines in ".
403 "Term::ReadLine redefined\n");
407 if ($term and $term->can("ornaments")) {
408 for ($CPAN::Config->{term_ornaments}) { # alias
410 if (not defined $last_term_ornaments
411 or $_ != $last_term_ornaments
413 local $Term::ReadLine::termcap_nowarn = 1;
414 $term->ornaments($_);
415 $last_term_ornaments = $_;
418 undef $last_term_ornaments;
422 for my $class (qw(Module Distribution)) {
423 # again unsafe meta access?
424 for my $dm (keys %{$CPAN::META->{readwrite}{"CPAN::$class"}}) {
425 next unless $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor};
426 CPAN->debug("BUG: $class '$dm' was in command state, resetting");
427 delete $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor};
431 $GOTOSHELL = 0; # not too often
432 $META->savehist if $CPAN::term && $CPAN::term->can("GetHistory");
437 soft_chdir_with_alternatives(\@cwd);
440 #-> CPAN::soft_chdir_with_alternatives ;
441 sub soft_chdir_with_alternatives ($) {
444 my $root = File::Spec->rootdir();
445 $CPAN::Frontend->mywarn(qq{Warning: no good directory to chdir to!
446 Trying '$root' as temporary haven.
451 if (chdir $cwd->[0]) {
455 $CPAN::Frontend->mywarn(qq{Could not chdir to "$cwd->[0]": $!
456 Trying to chdir to "$cwd->[1]" instead.
460 $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd->[0]": $!});
468 if ( $Config::Config{d_flock} || $Config::Config{d_fcntl_can_lock} ) {
469 return flock $fh, $mode;
470 } elsif (!$Have_warned->{"d_flock"}++) {
471 $CPAN::Frontend->mywarn("Your OS does not seem to support locking; continuing and ignoring all locking issues\n");
472 $CPAN::Frontend->mysleep(5);
479 sub _yaml_module () {
480 my $yaml_module = $CPAN::Config->{yaml_module} || "YAML";
482 $yaml_module ne "YAML"
484 !$CPAN::META->has_inst($yaml_module)
486 # $CPAN::Frontend->mywarn("'$yaml_module' not installed, falling back to 'YAML'\n");
487 $yaml_module = "YAML";
489 if ($yaml_module eq "YAML"
491 $CPAN::META->has_inst($yaml_module)
493 $YAML::VERSION < 0.60
495 !$Have_warned->{"YAML"}++
497 $CPAN::Frontend->mywarn("Warning: YAML version '$YAML::VERSION' is too low, please upgrade!\n".
498 "I'll continue but problems are *very* likely to happen.\n"
500 $CPAN::Frontend->mysleep(5);
505 # CPAN::_yaml_loadfile
507 my($self,$local_file) = @_;
508 return +[] unless -s $local_file;
509 my $yaml_module = _yaml_module;
510 if ($CPAN::META->has_inst($yaml_module)) {
511 # temporarly enable yaml code deserialisation
513 # 5.6.2 could not do the local() with the reference
514 # so we do it manually instead
515 my $old_loadcode = ${"$yaml_module\::LoadCode"};
516 ${ "$yaml_module\::LoadCode" } = $CPAN::Config->{yaml_load_code} || 0;
519 if ($code = UNIVERSAL::can($yaml_module, "LoadFile")) {
520 eval { @yaml = $code->($local_file); };
522 # this shall not be done by the frontend
523 die CPAN::Exception::yaml_process_error->new($yaml_module,$local_file,"parse",$@);
525 } elsif ($code = UNIVERSAL::can($yaml_module, "Load")) {
527 open FH, $local_file or die "Could not open '$local_file': $!";
530 eval { @yaml = $code->($ystream); };
532 # this shall not be done by the frontend
533 die CPAN::Exception::yaml_process_error->new($yaml_module,$local_file,"parse",$@);
536 ${"$yaml_module\::LoadCode"} = $old_loadcode;
539 # this shall not be done by the frontend
540 die CPAN::Exception::yaml_not_installed->new($yaml_module, $local_file, "parse");
545 # CPAN::_yaml_dumpfile
547 my($self,$local_file,@what) = @_;
548 my $yaml_module = _yaml_module;
549 if ($CPAN::META->has_inst($yaml_module)) {
551 if (UNIVERSAL::isa($local_file, "FileHandle")) {
552 $code = UNIVERSAL::can($yaml_module, "Dump");
553 eval { print $local_file $code->(@what) };
554 } elsif ($code = UNIVERSAL::can($yaml_module, "DumpFile")) {
555 eval { $code->($local_file,@what); };
556 } elsif ($code = UNIVERSAL::can($yaml_module, "Dump")) {
558 open FH, ">$local_file" or die "Could not open '$local_file': $!";
559 print FH $code->(@what);
562 die CPAN::Exception::yaml_process_error->new($yaml_module,$local_file,"dump",$@);
565 if (UNIVERSAL::isa($local_file, "FileHandle")) {
566 # I think this case does not justify a warning at all
568 die CPAN::Exception::yaml_not_installed->new($yaml_module, $local_file, "dump");
573 sub _init_sqlite () {
574 unless ($CPAN::META->has_inst("CPAN::SQLite")) {
575 $CPAN::Frontend->mywarn(qq{CPAN::SQLite not installed, trying to work without\n})
576 unless $Have_warned->{"CPAN::SQLite"}++;
579 require CPAN::SQLite::META; # not needed since CVS version of 2006-12-17
580 $CPAN::SQLite ||= CPAN::SQLite::META->new($CPAN::META);
584 my $negative_cache = {};
585 sub _sqlite_running {
586 if ($negative_cache->{time} && time < $negative_cache->{time} + 60) {
587 # need to cache the result, otherwise too slow
588 return $negative_cache->{fact};
590 $negative_cache = {}; # reset
592 my $ret = $CPAN::Config->{use_sqlite} && ($CPAN::SQLite || _init_sqlite());
593 return $ret if $ret; # fast anyway
594 $negative_cache->{time} = time;
595 return $negative_cache->{fact} = $ret;
599 package CPAN::CacheMgr;
601 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
607 use Fcntl qw(:flock);
608 use vars qw($connect_to_internet_ok $Ua $Thesite $ThesiteURL $Themethod);
609 @CPAN::FTP::ISA = qw(CPAN::Debug);
611 package CPAN::LWP::UserAgent;
613 use vars qw(@ISA $USER $PASSWD $SETUPDONE);
614 # we delay requiring LWP::UserAgent and setting up inheritance until we need it
616 package CPAN::Complete;
618 @CPAN::Complete::ISA = qw(CPAN::Debug);
619 # Q: where is the "How do I add a new command" HOWTO?
620 # A: svn diff -r 1048:1049 where andk added the report command
621 @CPAN::Complete::COMMANDS = sort qw(
622 ? ! a b d h i m o q r u
657 use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03 $HAVE_REANIMATED);
658 @CPAN::Index::ISA = qw(CPAN::Debug);
661 # use constant PROTOCOL => "2.0"; # outcommented to avoid warning on upgrade from 1.57
664 package CPAN::InfoObj;
666 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
668 package CPAN::Author;
670 @CPAN::Author::ISA = qw(CPAN::InfoObj);
672 package CPAN::Distribution;
674 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
676 package CPAN::Bundle;
678 @CPAN::Bundle::ISA = qw(CPAN::Module);
680 package CPAN::Module;
682 @CPAN::Module::ISA = qw(CPAN::InfoObj);
684 package CPAN::Exception::RecursiveDependency;
686 use overload '""' => "as_string";
688 # a module sees its distribution (no version)
689 # a distribution sees its prereqs (which are module names) (usually with versions)
690 # a bundle sees its module names and/or its distributions (no version)
695 my (@deps,%seen,$loop_starts_with);
696 DCHAIN: for my $dep (@$deps) {
697 push @deps, {name => $dep, display_as => $dep};
699 $loop_starts_with = $dep;
704 for my $i (0..$#deps) {
705 my $x = $deps[$i]{name};
706 $in_loop ||= $x eq $loop_starts_with;
707 my $xo = CPAN::Shell->expandany($x) or next;
708 if ($xo->isa("CPAN::Module")) {
709 my $have = $xo->inst_version || "N/A";
710 my($want,$d,$want_type);
711 if ($i>0 and $d = $deps[$i-1]{name}) {
712 my $do = CPAN::Shell->expandany($d);
713 $want = $do->{prereq_pm}{requires}{$x};
715 $want_type = "requires: ";
717 $want = $do->{prereq_pm}{build_requires}{$x};
719 $want_type = "build_requires: ";
721 $want_type = "unknown status";
726 $want = $xo->cpan_version;
727 $want_type = "want: ";
729 $deps[$i]{have} = $have;
730 $deps[$i]{want_type} = $want_type;
731 $deps[$i]{want} = $want;
732 $deps[$i]{display_as} = "$x (have: $have; $want_type$want)";
733 } elsif ($xo->isa("CPAN::Distribution")) {
734 $deps[$i]{display_as} = $xo->pretty_id;
736 $xo->{make} = CPAN::Distrostatus->new("NO cannot resolve circular dependency");
738 $xo->{make} = CPAN::Distrostatus->new("NO one dependency ($loop_starts_with) is a circular dependency");
740 $xo->store_persistent_state; # otherwise I will not reach
741 # all involved parties for
745 bless { deps => \@deps }, $class;
750 my $ret = "\nRecursive dependency detected:\n ";
751 $ret .= join("\n => ", map {$_->{display_as}} @{$self->{deps}});
752 $ret .= ".\nCannot resolve.\n";
756 package CPAN::Exception::yaml_not_installed;
758 use overload '""' => "as_string";
761 my($class,$module,$file,$during) = @_;
762 bless { module => $module, file => $file, during => $during }, $class;
767 "'$self->{module}' not installed, cannot $self->{during} '$self->{file}'\n";
770 package CPAN::Exception::yaml_process_error;
772 use overload '""' => "as_string";
775 my($class,$module,$file,$during,$error) = @_;
776 # my $at = Carp::longmess(""); # XXX find something more beautiful
777 bless { module => $module,
787 if ($self->{during}) {
789 if ($self->{module}) {
790 if ($self->{error}) {
791 return "Alert: While trying to '$self->{during}' YAML file\n".
792 " '$self->{file}'\n".
793 "with '$self->{module}' the following error was encountered:\n".
796 return "Alert: While trying to '$self->{during}' YAML file\n".
797 " '$self->{file}'\n".
798 "with '$self->{module}' some unknown error was encountered\n";
801 return "Alert: While trying to '$self->{during}' YAML file\n".
802 " '$self->{file}'\n".
803 "some unknown error was encountered\n";
806 return "Alert: While trying to '$self->{during}' some YAML file\n".
807 "some unknown error was encountered\n";
810 return "Alert: unknown error encountered\n";
814 package CPAN::Prompt; use overload '""' => "as_string";
815 use vars qw($prompt);
817 $CPAN::CurrentCommandId ||= 0;
823 unless ($CPAN::META->{LOCK}) {
824 $word = "nolock_cpan";
826 if ($CPAN::Config->{commandnumber_in_prompt}) {
827 sprintf "$word\[%d]> ", $CPAN::CurrentCommandId;
833 package CPAN::URL; use overload '""' => "as_string", fallback => 1;
834 # accessors: TEXT(the url string), FROM(DEF=>defaultlist,USER=>urllist),
835 # planned are things like age or quality
837 my($class,%args) = @_;
849 $self->{TEXT} = $set;
854 package CPAN::Distrostatus;
855 use overload '""' => "as_string",
857 use vars qw($something_has_failed_at);
859 my($class,$arg) = @_;
860 my $failed = substr($arg,0,2) eq "NO";
862 $something_has_failed_at = $CPAN::CurrentCommandId;
867 COMMANDID => $CPAN::CurrentCommandId,
871 sub something_has_just_failed () {
872 defined $something_has_failed_at &&
873 $something_has_failed_at == $CPAN::CurrentCommandId;
875 sub commandid { shift->{COMMANDID} }
876 sub failed { shift->{FAILED} }
880 $self->{TEXT} = $set;
904 "CPAN/Distroprefs.pm",
906 "CPAN/HandleConfig.pm",
909 "CPAN/Reporter/Config.pm",
910 "CPAN/Reporter/History.pm",
911 "CPAN/Reporter/PrereqCheck.pm",
917 # record the initial timestamp for reload.
918 $reload = { map {$INC{$_} ? ($_,(stat $INC{$_})[9]) : ()} @relo };
919 @CPAN::Shell::ISA = qw(CPAN::Debug);
921 $COLOR_REGISTERED ||= 0;
924 '!' => "eval the rest of the line as perl",
926 autobundle => "write inventory into a bundle file",
927 b => "info about bundle",
929 clean => "clean up a distribution's build directory",
931 d => "info about a distribution",
934 failed => "list all failed actions within current session",
935 fforce => "redo a command from scratch",
936 force => "redo a command",
937 get => "download a distribution",
939 help => "overview over commands; 'help ...' explains specific commands",
940 hosts => "statistics about recently used hosts",
941 i => "info about authors/bundles/distributions/modules",
942 install => "install a distribution",
943 install_tested => "install all distributions tested OK",
944 is_tested => "list all distributions tested OK",
945 look => "open a subshell in a distribution's directory",
946 ls => "list distributions according to a glob",
947 m => "info about a module",
948 make => "make/build a distribution",
949 mkmyconfig => "write current config into a CPAN/MyConfig.pm file",
950 notest => "run a (usually install) command but leave out the test phase",
951 o => "'o conf ...' for config stuff; 'o debug ...' for debugging",
952 perldoc => "try to get a manpage for a module",
954 quit => "leave the cpan shell",
955 r => "review over upgradeable modules",
956 readme => "display the README of a distro with a pager",
957 recent => "show recent uploads to the CPAN",
959 reload => "'reload cpan' or 'reload index'",
960 report => "test a distribution and send a test report to cpantesters",
961 reports => "info about reported tests from cpantesters",
964 test => "test a distribution",
965 u => "display uninstalled modules",
966 upgrade => "combine 'r' command with immediate installation",
969 $autoload_recursion ||= 0;
971 #-> sub CPAN::Shell::AUTOLOAD ;
973 $autoload_recursion++;
975 my $class = shift(@_);
976 # warn "autoload[$l] class[$class]";
979 warn "Refusing to autoload '$l' while signal pending";
980 $autoload_recursion--;
983 if ($autoload_recursion > 1) {
984 my $fullcommand = join " ", map { "'$_'" } $l, @_;
985 warn "Refusing to autoload $fullcommand in recursion\n";
986 $autoload_recursion--;
990 # XXX needs to be reconsidered
991 if ($CPAN::META->has_inst('CPAN::WAIT')) {
994 $CPAN::Frontend->mywarn(qq{
995 Commands starting with "w" require CPAN::WAIT to be installed.
996 Please consider installing CPAN::WAIT to use the fulltext index.
997 For this you just need to type
1002 $CPAN::Frontend->mywarn(qq{Unknown shell command '$l'. }.
1006 $autoload_recursion--;
1013 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
1015 # from here on only subs.
1016 ################################################################################
1018 sub _perl_fingerprint {
1019 my($self,$other_fingerprint) = @_;
1020 my $dll = eval {OS2::DLLname()};
1023 $mtime_dll = (-f $dll ? (stat(_))[9] : '-1');
1025 my $mtime_perl = (-f CPAN::find_perl ? (stat(_))[9] : '-1');
1026 my $this_fingerprint = {
1027 '$^X' => CPAN::find_perl,
1028 sitearchexp => $Config::Config{sitearchexp},
1029 'mtime_$^X' => $mtime_perl,
1030 'mtime_dll' => $mtime_dll,
1032 if ($other_fingerprint) {
1033 if (exists $other_fingerprint->{'stat($^X)'}) { # repair fp from rev. 1.88_57
1034 $other_fingerprint->{'mtime_$^X'} = $other_fingerprint->{'stat($^X)'}[9];
1036 # mandatory keys since 1.88_57
1037 for my $key (qw($^X sitearchexp mtime_dll mtime_$^X)) {
1038 return unless $other_fingerprint->{$key} eq $this_fingerprint->{$key};
1042 return $this_fingerprint;
1046 sub suggest_myconfig () {
1047 SUGGEST_MYCONFIG: if(!$INC{'CPAN/MyConfig.pm'}) {
1048 $CPAN::Frontend->myprint("You don't seem to have a user ".
1049 "configuration (MyConfig.pm) yet.\n");
1050 my $new = CPAN::Shell::colorable_makemaker_prompt("Do you want to create a ".
1051 "user configuration now? (Y/n)",
1053 if($new =~ m{^y}i) {
1054 CPAN::Shell->mkmyconfig();
1057 $CPAN::Frontend->mydie("OK, giving up.");
1062 #-> sub CPAN::all_objects ;
1064 my($mgr,$class) = @_;
1065 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
1066 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
1067 CPAN::Index->reload;
1068 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
1071 # Called by shell, not in batch mode. In batch mode I see no risk in
1072 # having many processes updating something as installations are
1073 # continually checked at runtime. In shell mode I suspect it is
1074 # unintentional to open more than one shell at a time
1076 #-> sub CPAN::checklock ;
1079 my $lockfile = File::Spec->catfile($CPAN::Config->{cpan_home},".lock");
1080 if (-f $lockfile && -M _ > 0) {
1081 my $fh = FileHandle->new($lockfile) or
1082 $CPAN::Frontend->mydie("Could not open lockfile '$lockfile': $!");
1083 my $otherpid = <$fh>;
1084 my $otherhost = <$fh>;
1086 if (defined $otherpid && $otherpid) {
1089 if (defined $otherhost && $otherhost) {
1092 my $thishost = hostname();
1093 if (defined $otherhost && defined $thishost &&
1094 $otherhost ne '' && $thishost ne '' &&
1095 $otherhost ne $thishost) {
1096 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile '$lockfile'\n".
1097 "reports other host $otherhost and other ".
1098 "process $otherpid.\n".
1099 "Cannot proceed.\n"));
1100 } elsif ($RUN_DEGRADED) {
1101 $CPAN::Frontend->mywarn("Running in degraded mode (experimental)\n");
1102 } elsif (defined $otherpid && $otherpid) {
1103 return if $$ == $otherpid; # should never happen
1104 $CPAN::Frontend->mywarn(
1106 There seems to be running another CPAN process (pid $otherpid). Contacting...
1108 if (kill 0, $otherpid or $!{EPERM}) {
1109 $CPAN::Frontend->mywarn(qq{Other job is running.\n});
1111 CPAN::Shell::colorable_makemaker_prompt
1112 (qq{Shall I try to run in degraded }.
1113 qq{mode? (Y/n)},"y");
1114 if ($ans =~ /^y/i) {
1115 $CPAN::Frontend->mywarn("Running in degraded mode (experimental).
1116 Please report if something unexpected happens\n");
1118 for ($CPAN::Config) {
1120 # $_->{build_dir_reuse} = 0; # 2006-11-17 akoenig Why was that?
1121 $_->{commandnumber_in_prompt} = 0; # visibility
1122 $_->{histfile} = ""; # who should win otherwise?
1123 $_->{cache_metadata} = 0; # better would be a lock?
1124 $_->{use_sqlite} = 0; # better would be a write lock!
1125 $_->{auto_commit} = 0; # we are violent, do not persist
1126 $_->{test_report} = 0; # Oliver Paukstadt had sent wrong reports in degraded mode
1129 $CPAN::Frontend->mydie("
1130 You may want to kill the other job and delete the lockfile. On UNIX try:
1135 } elsif (-w $lockfile) {
1137 CPAN::Shell::colorable_makemaker_prompt
1138 (qq{Other job not responding. Shall I overwrite }.
1139 qq{the lockfile '$lockfile'? (Y/n)},"y");
1140 $CPAN::Frontend->myexit("Ok, bye\n")
1141 unless $ans =~ /^y/i;
1144 qq{Lockfile '$lockfile' not writeable by you. }.
1145 qq{Cannot proceed.\n}.
1146 qq{ On UNIX try:\n}.
1147 qq{ rm '$lockfile'\n}.
1148 qq{ and then rerun us.\n}
1152 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Found invalid lockfile ".
1153 "'$lockfile', please remove. Cannot proceed.\n"));
1156 my $dotcpan = $CPAN::Config->{cpan_home};
1157 eval { File::Path::mkpath($dotcpan);};
1159 # A special case at least for Jarkko.
1160 my $firsterror = $@;
1164 $symlinkcpan = readlink $dotcpan;
1165 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
1166 eval { File::Path::mkpath($symlinkcpan); };
1170 $CPAN::Frontend->mywarn(qq{
1171 Working directory $symlinkcpan created.
1175 unless (-d $dotcpan) {
1177 Your configuration suggests "$dotcpan" as your
1178 CPAN.pm working directory. I could not create this directory due
1179 to this error: $firsterror\n};
1181 As "$dotcpan" is a symlink to "$symlinkcpan",
1182 I tried to create that, but I failed with this error: $seconderror
1185 Please make sure the directory exists and is writable.
1187 $CPAN::Frontend->mywarn($mess);
1188 return suggest_myconfig;
1190 } # $@ after eval mkpath $dotcpan
1191 if (0) { # to test what happens when a race condition occurs
1192 for (reverse 1..10) {
1198 if (!$RUN_DEGRADED && !$self->{LOCKFH}) {
1200 unless ($fh = FileHandle->new("+>>$lockfile")) {
1201 if ($! =~ /Permission/) {
1202 $CPAN::Frontend->mywarn(qq{
1204 Your configuration suggests that CPAN.pm should use a working
1206 $CPAN::Config->{cpan_home}
1207 Unfortunately we could not create the lock file
1209 due to permission problems.
1211 Please make sure that the configuration variable
1212 \$CPAN::Config->{cpan_home}
1213 points to a directory where you can write a .lock file. You can set
1214 this variable in either a CPAN/MyConfig.pm or a CPAN/Config.pm in your
1217 return suggest_myconfig;
1221 while (!CPAN::_flock($fh, LOCK_EX|LOCK_NB)) {
1223 $CPAN::Frontend->mydie("Giving up\n");
1225 $CPAN::Frontend->mysleep($sleep++);
1226 $CPAN::Frontend->mywarn("Could not lock lockfile with flock: $!; retrying\n");
1232 $fh->print($$, "\n");
1233 $fh->print(hostname(), "\n");
1234 $self->{LOCK} = $lockfile;
1235 $self->{LOCKFH} = $fh;
1240 $CPAN::Frontend->mydie("Got SIG$sig, leaving");
1245 &cleanup if $Signal;
1246 die "Got yet another signal" if $Signal > 1;
1247 $CPAN::Frontend->mydie("Got another SIG$sig") if $Signal;
1248 $CPAN::Frontend->mywarn("Caught SIG$sig, trying to continue\n");
1252 # From: Larry Wall <larry@wall.org>
1253 # Subject: Re: deprecating SIGDIE
1254 # To: perl5-porters@perl.org
1255 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
1257 # The original intent of __DIE__ was only to allow you to substitute one
1258 # kind of death for another on an application-wide basis without respect
1259 # to whether you were in an eval or not. As a global backstop, it should
1260 # not be used any more lightly (or any more heavily :-) than class
1261 # UNIVERSAL. Any attempt to build a general exception model on it should
1262 # be politely squashed. Any bug that causes every eval {} to have to be
1263 # modified should be not so politely squashed.
1265 # Those are my current opinions. It is also my optinion that polite
1266 # arguments degenerate to personal arguments far too frequently, and that
1267 # when they do, it's because both people wanted it to, or at least didn't
1268 # sufficiently want it not to.
1272 # global backstop to cleanup if we should really die
1273 $SIG{__DIE__} = \&cleanup;
1274 $self->debug("Signal handler set.") if $CPAN::DEBUG;
1277 #-> sub CPAN::DESTROY ;
1279 &cleanup; # need an eval?
1282 #-> sub CPAN::anycwd ;
1285 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
1290 sub cwd {Cwd::cwd();}
1292 #-> sub CPAN::getcwd ;
1293 sub getcwd {Cwd::getcwd();}
1295 #-> sub CPAN::fastcwd ;
1296 sub fastcwd {Cwd::fastcwd();}
1298 #-> sub CPAN::backtickcwd ;
1299 sub backtickcwd {my $cwd = `cwd`; chomp $cwd; $cwd}
1301 #-> sub CPAN::find_perl ;
1303 my($perl) = File::Spec->file_name_is_absolute($^X) ? $^X : "";
1305 my $candidate = File::Spec->catfile($CPAN::iCwd,$^X);
1306 $^X = $perl = $candidate if MM->maybe_command($candidate);
1309 my ($component,$perl_name);
1310 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
1311 PATH_COMPONENT: foreach $component (File::Spec->path(),
1312 $Config::Config{'binexp'}) {
1313 next unless defined($component) && $component;
1314 my($abs) = File::Spec->catfile($component,$perl_name);
1315 if (MM->maybe_command($abs)) {
1326 #-> sub CPAN::exists ;
1328 my($mgr,$class,$id) = @_;
1329 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
1330 CPAN::Index->reload;
1331 ### Carp::croak "exists called without class argument" unless $class;
1333 $id =~ s/:+/::/g if $class eq "CPAN::Module";
1335 if (CPAN::_sqlite_running) {
1336 $exists = (exists $META->{readonly}{$class}{$id} or
1337 $CPAN::SQLite->set($class, $id));
1339 $exists = exists $META->{readonly}{$class}{$id};
1341 $exists ||= exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
1344 #-> sub CPAN::delete ;
1346 my($mgr,$class,$id) = @_;
1347 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
1348 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
1351 #-> sub CPAN::has_usable
1352 # has_inst is sometimes too optimistic, we should replace it with this
1353 # has_usable whenever a case is given
1355 my($self,$mod,$message) = @_;
1356 return 1 if $HAS_USABLE->{$mod};
1357 my $has_inst = $self->has_inst($mod,$message);
1358 return unless $has_inst;
1361 LWP => [ # we frequently had "Can't locate object
1362 # method "new" via package "LWP::UserAgent" at
1363 # (eval 69) line 2006
1365 sub {require LWP::UserAgent},
1366 sub {require HTTP::Request},
1367 sub {require URI::URL},
1370 sub {require Net::FTP},
1371 sub {require Net::Config},
1373 'File::HomeDir' => [
1374 sub {require File::HomeDir;
1375 unless (CPAN::Version->vge(File::HomeDir::->VERSION, 0.52)) {
1376 for ("Will not use File::HomeDir, need 0.52\n") {
1377 $CPAN::Frontend->mywarn($_);
1384 sub {require Archive::Tar;
1385 unless (CPAN::Version->vge(Archive::Tar::->VERSION, 1.00)) {
1386 for ("Will not use Archive::Tar, need 1.00\n") {
1387 $CPAN::Frontend->mywarn($_);
1394 # XXX we should probably delete from
1395 # %INC too so we can load after we
1396 # installed a new enough version --
1398 sub {require File::Temp;
1399 unless (CPAN::Version->vge(File::Temp::->VERSION,0.16)) {
1400 for ("Will not use File::Temp, need 0.16\n") {
1401 $CPAN::Frontend->mywarn($_);
1408 if ($usable->{$mod}) {
1409 for my $c (0..$#{$usable->{$mod}}) {
1410 my $code = $usable->{$mod}[$c];
1411 my $ret = eval { &$code() };
1412 $ret = "" unless defined $ret;
1414 # warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
1419 return $HAS_USABLE->{$mod} = 1;
1422 #-> sub CPAN::has_inst
1424 my($self,$mod,$message) = @_;
1425 Carp::croak("CPAN->has_inst() called without an argument")
1426 unless defined $mod;
1427 my %dont = map { $_ => 1 } keys %{$CPAN::META->{dontload_hash}||{}},
1428 keys %{$CPAN::Config->{dontload_hash}||{}},
1429 @{$CPAN::Config->{dontload_list}||[]};
1430 if (defined $message && $message eq "no" # afair only used by Nox
1434 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
1442 # checking %INC is wrong, because $INC{LWP} may be true
1443 # although $INC{"URI/URL.pm"} may have failed. But as
1444 # I really want to say "bla loaded OK", I have to somehow
1446 ### warn "$file in %INC"; #debug
1448 } elsif (eval { require $file }) {
1449 # eval is good: if we haven't yet read the database it's
1450 # perfect and if we have installed the module in the meantime,
1451 # it tries again. The second require is only a NOOP returning
1452 # 1 if we had success, otherwise it's retrying
1454 my $mtime = (stat $INC{$file})[9];
1455 # privileged files loaded by has_inst; Note: we use $mtime
1456 # as a proxy for a checksum.
1457 $CPAN::Shell::reload->{$file} = $mtime;
1458 my $v = eval "\$$mod\::VERSION";
1459 $v = $v ? " (v$v)" : "";
1460 CPAN::Shell->optprint("load_module","CPAN: $mod loaded ok$v\n");
1461 if ($mod eq "CPAN::WAIT") {
1462 push @CPAN::Shell::ISA, 'CPAN::WAIT';
1465 } elsif ($mod eq "Net::FTP") {
1466 $CPAN::Frontend->mywarn(qq{
1467 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
1469 install Bundle::libnet
1471 }) unless $Have_warned->{"Net::FTP"}++;
1472 $CPAN::Frontend->mysleep(3);
1473 } elsif ($mod eq "Digest::SHA") {
1474 if ($Have_warned->{"Digest::SHA"}++) {
1475 $CPAN::Frontend->mywarn(qq{CPAN: checksum security checks disabled }.
1476 qq{because Digest::SHA not installed.\n});
1478 $CPAN::Frontend->mywarn(qq{
1479 CPAN: checksum security checks disabled because Digest::SHA not installed.
1480 Please consider installing the Digest::SHA module.
1483 $CPAN::Frontend->mysleep(2);
1485 } elsif ($mod eq "Module::Signature") {
1486 # NOT prefs_lookup, we are not a distro
1487 my $check_sigs = $CPAN::Config->{check_sigs};
1488 if (not $check_sigs) {
1489 # they do not want us:-(
1490 } elsif (not $Have_warned->{"Module::Signature"}++) {
1491 # No point in complaining unless the user can
1492 # reasonably install and use it.
1493 if (eval { require Crypt::OpenPGP; 1 } ||
1495 defined $CPAN::Config->{'gpg'}
1497 $CPAN::Config->{'gpg'} =~ /\S/
1500 $CPAN::Frontend->mywarn(qq{
1501 CPAN: Module::Signature security checks disabled because Module::Signature
1502 not installed. Please consider installing the Module::Signature module.
1503 You may also need to be able to connect over the Internet to the public
1504 keyservers like pgp.mit.edu (port 11371).
1507 $CPAN::Frontend->mysleep(2);
1511 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
1516 #-> sub CPAN::instance ;
1518 my($mgr,$class,$id) = @_;
1519 CPAN::Index->reload;
1521 # unsafe meta access, ok?
1522 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
1523 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
1531 #-> sub CPAN::cleanup ;
1533 # warn "cleanup called with arg[@_] End[$CPAN::End] Signal[$Signal]";
1534 local $SIG{__DIE__} = '';
1539 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
1540 $ineval = 1, last if
1541 $subroutine eq '(eval)';
1543 return if $ineval && !$CPAN::End;
1544 return unless defined $META->{LOCK};
1545 return unless -f $META->{LOCK};
1547 close $META->{LOCKFH};
1548 unlink $META->{LOCK};
1550 # Carp::cluck("DEBUGGING");
1551 if ( $CPAN::CONFIG_DIRTY ) {
1552 $CPAN::Frontend->mywarn("Warning: Configuration not saved.\n");
1554 $CPAN::Frontend->myprint("Lockfile removed.\n");
1557 #-> sub CPAN::readhist
1559 my($self,$term,$histfile) = @_;
1560 my $histsize = $CPAN::Config->{'histsize'} || 100;
1561 $term->Attribs->{'MaxHistorySize'} = $histsize if (defined($term->Attribs->{'MaxHistorySize'}));
1562 my($fh) = FileHandle->new;
1563 open $fh, "<$histfile" or return;
1567 $term->AddHistory($_);
1572 #-> sub CPAN::savehist
1575 my($histfile,$histsize);
1576 unless ($histfile = $CPAN::Config->{'histfile'}) {
1577 $CPAN::Frontend->mywarn("No history written (no histfile specified).\n");
1580 $histsize = $CPAN::Config->{'histsize'} || 100;
1582 unless ($CPAN::term->can("GetHistory")) {
1583 $CPAN::Frontend->mywarn("Terminal does not support GetHistory.\n");
1589 my @h = $CPAN::term->GetHistory;
1590 splice @h, 0, @h-$histsize if @h>$histsize;
1591 my($fh) = FileHandle->new;
1592 open $fh, ">$histfile" or $CPAN::Frontend->mydie("Couldn't open >$histfile: $!");
1593 local $\ = local $, = "\n";
1598 #-> sub CPAN::is_tested
1600 my($self,$what,$when) = @_;
1602 Carp::cluck("DEBUG: empty what");
1605 $self->{is_tested}{$what} = $when;
1608 #-> sub CPAN::reset_tested
1609 # forget all distributions tested -- resets what gets included in PERL5LIB
1612 $self->{is_tested} = {};
1615 #-> sub CPAN::is_installed
1616 # unsets the is_tested flag: as soon as the thing is installed, it is
1617 # not needed in set_perl5lib anymore
1619 my($self,$what) = @_;
1620 delete $self->{is_tested}{$what};
1623 sub _list_sorted_descending_is_tested {
1626 { ($self->{is_tested}{$b}||0) <=> ($self->{is_tested}{$a}||0) }
1627 keys %{$self->{is_tested}}
1630 #-> sub CPAN::set_perl5lib
1631 # Notes on max environment variable length:
1632 # - Win32 : XP or later, 8191; Win2000 or NT4, 2047
1636 my($self,$for) = @_;
1638 (undef,undef,undef,$for) = caller(1);
1641 $self->{is_tested} ||= {};
1642 return unless %{$self->{is_tested}};
1643 my $env = $ENV{PERL5LIB};
1644 $env = $ENV{PERLLIB} unless defined $env;
1646 push @env, split /\Q$Config::Config{path_sep}\E/, $env if defined $env and length $env;
1647 #my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}};
1648 #$CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
1650 my @dirs = map {("$_/blib/arch", "$_/blib/lib")} $self->_list_sorted_descending_is_tested;
1654 $CPAN::Frontend->optprint('perl5lib', "Prepending @dirs to PERL5LIB for '$for'\n");
1655 $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1656 } elsif (@dirs < 24 ) {
1657 my @d = map {my $cp = $_;
1658 $cp =~ s/^\Q$CPAN::Config->{build_dir}\E/%BUILDDIR%/;
1661 $CPAN::Frontend->optprint('perl5lib', "Prepending @d to PERL5LIB; ".
1662 "%BUILDDIR%=$CPAN::Config->{build_dir} ".
1665 $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1667 my $cnt = keys %{$self->{is_tested}};
1668 $CPAN::Frontend->optprint('perl5lib', "Prepending blib/arch and blib/lib of ".
1669 "$cnt build dirs to PERL5LIB; ".
1672 $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1676 package CPAN::CacheMgr;
1679 #-> sub CPAN::CacheMgr::as_string ;
1681 eval { require Data::Dumper };
1683 return shift->SUPER::as_string;
1685 return Data::Dumper::Dumper(shift);
1689 #-> sub CPAN::CacheMgr::cachesize ;
1694 #-> sub CPAN::CacheMgr::tidyup ;
1697 return unless $CPAN::META->{LOCK};
1698 return unless -d $self->{ID};
1699 my @toremove = grep { $self->{SIZE}{$_}==0 } @{$self->{FIFO}};
1700 for my $current (0..$#toremove) {
1701 my $toremove = $toremove[$current];
1702 $CPAN::Frontend->myprint(sprintf(
1703 "DEL(%d/%d): %s \n",
1709 return if $CPAN::Signal;
1710 $self->_clean_cache($toremove);
1711 return if $CPAN::Signal;
1715 #-> sub CPAN::CacheMgr::dir ;
1720 #-> sub CPAN::CacheMgr::entries ;
1722 my($self,$dir) = @_;
1723 return unless defined $dir;
1724 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
1725 $dir ||= $self->{ID};
1726 my($cwd) = CPAN::anycwd();
1727 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
1728 my $dh = DirHandle->new(File::Spec->curdir)
1729 or Carp::croak("Couldn't opendir $dir: $!");
1732 next if $_ eq "." || $_ eq "..";
1734 push @entries, File::Spec->catfile($dir,$_);
1736 push @entries, File::Spec->catdir($dir,$_);
1738 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
1741 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
1742 sort { -M $a <=> -M $b} @entries;
1745 #-> sub CPAN::CacheMgr::disk_usage ;
1747 my($self,$dir,$fast) = @_;
1748 return if exists $self->{SIZE}{$dir};
1749 return if $CPAN::Signal;
1754 unless (chmod 0755, $dir) {
1755 $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
1756 "permission to change the permission; cannot ".
1757 "estimate disk usage of '$dir'\n");
1758 $CPAN::Frontend->mysleep(5);
1763 # nothing to say, no matter what the permissions
1766 $CPAN::Frontend->mywarn("File or directory '$dir' has gone, ignoring\n");
1770 $Du = 0; # placeholder
1774 $File::Find::prune++ if $CPAN::Signal;
1776 if ($^O eq 'MacOS') {
1778 my $cat = Mac::Files::FSpGetCatInfo($_);
1779 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
1783 unless (chmod 0755, $_) {
1784 $CPAN::Frontend->mywarn("I have neither the -x permission nor ".
1785 "the permission to change the permission; ".
1786 "can only partially estimate disk usage ".
1788 $CPAN::Frontend->mysleep(5);
1800 return if $CPAN::Signal;
1801 $self->{SIZE}{$dir} = $Du/1024/1024;
1802 unshift @{$self->{FIFO}}, $dir;
1803 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
1804 $self->{DU} += $Du/1024/1024;
1808 #-> sub CPAN::CacheMgr::_clean_cache ;
1810 my($self,$dir) = @_;
1811 return unless -e $dir;
1812 unless (File::Spec->canonpath(File::Basename::dirname($dir))
1813 eq File::Spec->canonpath($CPAN::Config->{build_dir})) {
1814 $CPAN::Frontend->mywarn("Directory '$dir' not below $CPAN::Config->{build_dir}, ".
1815 "will not remove\n");
1816 $CPAN::Frontend->mysleep(5);
1819 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
1821 File::Path::rmtree($dir);
1823 if ($dir !~ /\.yml$/ && -f "$dir.yml") {
1824 my $yaml_module = CPAN::_yaml_module;
1825 if ($CPAN::META->has_inst($yaml_module)) {
1826 my($peek_yaml) = eval { CPAN->_yaml_loadfile("$dir.yml"); };
1828 $CPAN::Frontend->mywarn("(parse error on '$dir.yml' removing anyway)");
1829 unlink "$dir.yml" or
1830 $CPAN::Frontend->mywarn("(Could not unlink '$dir.yml': $!)");
1832 } elsif (my $id = $peek_yaml->[0]{distribution}{ID}) {
1833 $CPAN::META->delete("CPAN::Distribution", $id);
1835 # XXX we should restore the state NOW, otherise this
1836 # distro does not exist until we read an index. BUG ALERT(?)
1838 # $CPAN::Frontend->mywarn (" +++\n");
1842 unlink "$dir.yml"; # may fail
1843 unless ($id_deleted) {
1844 CPAN->debug("no distro found associated with '$dir'");
1847 $self->{DU} -= $self->{SIZE}{$dir};
1848 delete $self->{SIZE}{$dir};
1851 #-> sub CPAN::CacheMgr::new ;
1858 ID => $CPAN::Config->{build_dir},
1859 MAX => $CPAN::Config->{'build_cache'},
1860 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
1863 File::Path::mkpath($self->{ID});
1864 my $dh = DirHandle->new($self->{ID});
1865 bless $self, $class;
1868 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
1870 CPAN->debug($debug) if $CPAN::DEBUG;
1874 #-> sub CPAN::CacheMgr::scan_cache ;
1877 return if $self->{SCAN} eq 'never';
1878 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
1879 unless $self->{SCAN} eq 'atstart';
1880 return unless $CPAN::META->{LOCK};
1881 $CPAN::Frontend->myprint(
1882 sprintf("Scanning cache %s for sizes\n",
1885 my @entries = $self->entries($self->{ID});
1890 if ($self->{DU} > $self->{MAX}) {
1892 $self->disk_usage($e,1);
1894 $self->disk_usage($e);
1897 while (($painted/76) < ($i/@entries)) {
1898 $CPAN::Frontend->myprint($symbol);
1901 return if $CPAN::Signal;
1903 $CPAN::Frontend->myprint("DONE\n");
1907 package CPAN::Shell;
1910 #-> sub CPAN::Shell::h ;
1912 my($class,$about) = @_;
1913 if (defined $about) {
1915 if (exists $Help->{$about}) {
1916 if (ref $Help->{$about}) { # aliases
1917 $about = ${$Help->{$about}};
1919 $help = $Help->{$about};
1921 $help = "No help available";
1923 $CPAN::Frontend->myprint("$about\: $help\n");
1925 my $filler = " " x (80 - 28 - length($CPAN::VERSION));
1926 $CPAN::Frontend->myprint(qq{
1927 Display Information $filler (ver $CPAN::VERSION)
1928 command argument description
1929 a,b,d,m WORD or /REGEXP/ about authors, bundles, distributions, modules
1930 i WORD or /REGEXP/ about any of the above
1931 ls AUTHOR or GLOB about files in the author's directory
1932 (with WORD being a module, bundle or author name or a distribution
1933 name of the form AUTHOR/DISTRIBUTION)
1935 Download, Test, Make, Install...
1936 get download clean make clean
1937 make make (implies get) look open subshell in dist directory
1938 test make test (implies make) readme display these README files
1939 install make install (implies test) perldoc display POD documentation
1942 r WORDs or /REGEXP/ or NONE report updates for some/matching/all modules
1943 upgrade WORDs or /REGEXP/ or NONE upgrade some/matching/all modules
1946 force CMD try hard to do command fforce CMD try harder
1947 notest CMD skip testing
1950 h,? display this menu ! perl-code eval a perl command
1951 o conf [opt] set and query options q quit the cpan shell
1952 reload cpan load CPAN.pm again reload index load newer indices
1953 autobundle Snapshot recent latest CPAN uploads});
1959 #-> sub CPAN::Shell::a ;
1961 my($self,@arg) = @_;
1962 # authors are always UPPERCASE
1964 $_ = uc $_ unless /=/;
1966 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1969 #-> sub CPAN::Shell::globls ;
1971 my($self,$s,$pragmas) = @_;
1972 # ls is really very different, but we had it once as an ordinary
1973 # command in the Shell (upto rev. 321) and we could not handle
1975 my(@accept,@preexpand);
1976 if ($s =~ /[\*\?\/]/) {
1977 if ($CPAN::META->has_inst("Text::Glob")) {
1978 if (my($au,$pathglob) = $s =~ m|(.*?)/(.*)|) {
1979 my $rau = Text::Glob::glob_to_regex(uc $au);
1980 CPAN::Shell->debug("au[$au]pathglob[$pathglob]rau[$rau]")
1982 push @preexpand, map { $_->id . "/" . $pathglob }
1983 CPAN::Shell->expand_by_method('CPAN::Author',['id'],"/$rau/");
1985 my $rau = Text::Glob::glob_to_regex(uc $s);
1986 push @preexpand, map { $_->id }
1987 CPAN::Shell->expand_by_method('CPAN::Author',
1992 $CPAN::Frontend->mydie("Text::Glob not installed, cannot proceed");
1995 push @preexpand, uc $s;
1998 unless (/^[A-Z0-9\-]+(\/|$)/i) {
1999 $CPAN::Frontend->mywarn("ls command rejects argument $_: not an author\n");
2004 my $silent = @accept>1;
2005 my $last_alpha = "";
2007 for my $a (@accept) {
2008 my($author,$pathglob);
2009 if ($a =~ m|(.*?)/(.*)|) {
2012 $author = CPAN::Shell->expand_by_method('CPAN::Author',
2015 or $CPAN::Frontend->mydie("No author found for $a2\n");
2017 $author = CPAN::Shell->expand_by_method('CPAN::Author',
2020 or $CPAN::Frontend->mydie("No author found for $a\n");
2023 my $alpha = substr $author->id, 0, 1;
2025 if ($alpha eq $last_alpha) {
2029 $last_alpha = $alpha;
2031 $CPAN::Frontend->myprint($ad);
2033 for my $pragma (@$pragmas) {
2034 if ($author->can($pragma)) {
2038 push @results, $author->ls($pathglob,$silent); # silent if
2041 for my $pragma (@$pragmas) {
2042 my $unpragma = "un$pragma";
2043 if ($author->can($unpragma)) {
2044 $author->$unpragma();
2051 #-> sub CPAN::Shell::local_bundles ;
2053 my($self,@which) = @_;
2054 my($incdir,$bdir,$dh);
2055 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
2056 my @bbase = "Bundle";
2057 while (my $bbase = shift @bbase) {
2058 $bdir = File::Spec->catdir($incdir,split /::/, $bbase);
2059 CPAN->debug("bdir[$bdir]\@bbase[@bbase]") if $CPAN::DEBUG;
2060 if ($dh = DirHandle->new($bdir)) { # may fail
2062 for $entry ($dh->read) {
2063 next if $entry =~ /^\./;
2064 next unless $entry =~ /^\w+(\.pm)?(?!\n)\Z/;
2065 if (-d File::Spec->catdir($bdir,$entry)) {
2066 push @bbase, "$bbase\::$entry";
2068 next unless $entry =~ s/\.pm(?!\n)\Z//;
2069 $CPAN::META->instance('CPAN::Bundle',"$bbase\::$entry");
2077 #-> sub CPAN::Shell::b ;
2079 my($self,@which) = @_;
2080 CPAN->debug("which[@which]") if $CPAN::DEBUG;
2081 $self->local_bundles;
2082 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
2085 #-> sub CPAN::Shell::d ;
2086 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
2088 #-> sub CPAN::Shell::m ;
2089 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
2091 $CPAN::Frontend->myprint($self->format_result('Module',@_));
2094 #-> sub CPAN::Shell::i ;
2098 @args = '/./' unless @args;
2100 for my $type (qw/Bundle Distribution Module/) {
2101 push @result, $self->expand($type,@args);
2103 # Authors are always uppercase.
2104 push @result, $self->expand("Author", map { uc $_ } @args);
2106 my $result = @result == 1 ?
2107 $result[0]->as_string :
2109 "No objects found of any type for argument @args\n" :
2111 (map {$_->as_glimpse} @result),
2112 scalar @result, " items found\n",
2114 $CPAN::Frontend->myprint($result);
2117 #-> sub CPAN::Shell::o ;
2119 # CPAN::Shell::o and CPAN::HandleConfig::edit are closely related. 'o
2120 # conf' calls through to CPAN::HandleConfig::edit. 'o conf' should
2121 # probably have been called 'set' and 'o debug' maybe 'set debug' or
2122 # 'debug'; 'o conf ARGS' calls ->edit in CPAN/HandleConfig.pm
2124 my($self,$o_type,@o_what) = @_;
2126 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
2127 if ($o_type eq 'conf') {
2129 ($cfilter) = $o_what[0] =~ m|^/(.*)/$| if @o_what;
2130 if (!@o_what or $cfilter) { # print all things, "o conf"
2132 my $qrfilter = eval 'qr/$cfilter/';
2134 $CPAN::Frontend->myprint("\$CPAN::Config options from ");
2136 if (exists $INC{'CPAN/Config.pm'}) {
2137 push @from, $INC{'CPAN/Config.pm'};
2139 if (exists $INC{'CPAN/MyConfig.pm'}) {
2140 push @from, $INC{'CPAN/MyConfig.pm'};
2142 $CPAN::Frontend->myprint(join " and ", map {"'$_'"} @from);
2143 $CPAN::Frontend->myprint(":\n");
2144 for $k (sort keys %CPAN::HandleConfig::can) {
2145 next unless $k =~ /$qrfilter/;
2146 $v = $CPAN::HandleConfig::can{$k};
2147 $CPAN::Frontend->myprint(sprintf " %-18s [%s]\n", $k, $v);
2149 $CPAN::Frontend->myprint("\n");
2150 for $k (sort keys %CPAN::HandleConfig::keys) {
2151 next unless $k =~ /$qrfilter/;
2152 CPAN::HandleConfig->prettyprint($k);
2154 $CPAN::Frontend->myprint("\n");
2156 if (CPAN::HandleConfig->edit(@o_what)) {
2158 $CPAN::Frontend->myprint(qq{Type 'o conf' to view all configuration }.
2162 } elsif ($o_type eq 'debug') {
2164 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
2167 my($what) = shift @o_what;
2168 if ($what =~ s/^-// && exists $CPAN::DEBUG{$what}) {
2169 $CPAN::DEBUG &= $CPAN::DEBUG ^ $CPAN::DEBUG{$what};
2172 if ( exists $CPAN::DEBUG{$what} ) {
2173 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
2174 } elsif ($what =~ /^\d/) {
2175 $CPAN::DEBUG = $what;
2176 } elsif (lc $what eq 'all') {
2178 for (values %CPAN::DEBUG) {
2181 $CPAN::DEBUG = $max;
2184 for (keys %CPAN::DEBUG) {
2185 next unless lc($_) eq lc($what);
2186 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
2189 $CPAN::Frontend->myprint("unknown argument [$what]\n")
2194 my $raw = "Valid options for debug are ".
2195 join(", ",sort(keys %CPAN::DEBUG), 'all').
2196 qq{ or a number. Completion works on the options. }.
2197 qq{Case is ignored.};
2199 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
2200 $CPAN::Frontend->myprint("\n\n");
2203 $CPAN::Frontend->myprint("Options set for debugging ($CPAN::DEBUG):\n");
2205 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
2206 $v = $CPAN::DEBUG{$k};
2207 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
2208 if $v & $CPAN::DEBUG;
2211 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
2214 $CPAN::Frontend->myprint(qq{
2216 conf set or get configuration variables
2217 debug set or get debugging options
2222 # CPAN::Shell::paintdots_onreload
2223 sub paintdots_onreload {
2226 if ( $_[0] =~ /[Ss]ubroutine ([\w:]+) redefined/ ) {
2230 # $CPAN::Frontend->myprint(".($subr)");
2231 $CPAN::Frontend->myprint(".");
2232 if ($subr =~ /\bshell\b/i) {
2233 # warn "debug[$_[0]]";
2235 # It would be nice if we could detect that a
2236 # subroutine has actually changed, but for now we
2237 # practically always set the GOTOSHELL global
2247 #-> sub CPAN::Shell::hosts ;
2250 my $fullstats = CPAN::FTP->_ftp_statistics();
2251 my $history = $fullstats->{history} || [];
2253 while (my $last = pop @$history) {
2254 my $attempts = $last->{attempts} or next;
2257 $start = $attempts->[-1]{start};
2258 if ($#$attempts > 0) {
2259 for my $i (0..$#$attempts-1) {
2260 my $url = $attempts->[$i]{url} or next;
2265 $start = $last->{start};
2267 next unless $last->{thesiteurl}; # C-C? bad filenames?
2269 $S{end} ||= $last->{end};
2270 my $dltime = $last->{end} - $start;
2271 my $dlsize = $last->{filesize} || 0;
2272 my $url = ref $last->{thesiteurl} ? $last->{thesiteurl}->text : $last->{thesiteurl};
2273 my $s = $S{ok}{$url} ||= {};
2276 $s->{dlsize} += $dlsize/1024;
2278 $s->{dltime} += $dltime;
2281 for my $url (keys %{$S{ok}}) {
2282 next if $S{ok}{$url}{dltime} == 0; # div by zero
2283 push @{$res->{ok}}, [@{$S{ok}{$url}}{qw(n dlsize dltime)},
2284 $S{ok}{$url}{dlsize}/$S{ok}{$url}{dltime},
2288 for my $url (keys %{$S{no}}) {
2289 push @{$res->{no}}, [$S{no}{$url},
2293 my $R = ""; # report
2294 if ($S{start} && $S{end}) {
2295 $R .= sprintf "Log starts: %s\n", $S{start} ? scalar(localtime $S{start}) : "unknown";
2296 $R .= sprintf "Log ends : %s\n", $S{end} ? scalar(localtime $S{end}) : "unknown";
2298 if ($res->{ok} && @{$res->{ok}}) {
2299 $R .= sprintf "\nSuccessful downloads:
2300 N kB secs kB/s url\n";
2302 for (sort { $b->[3] <=> $a->[3] } @{$res->{ok}}) {
2303 $R .= sprintf "%4d %8d %5d %9.1f %s\n", @$_;
2307 if ($res->{no} && @{$res->{no}}) {
2308 $R .= sprintf "\nUnsuccessful downloads:\n";
2310 for (sort { $b->[0] <=> $a->[0] } @{$res->{no}}) {
2311 $R .= sprintf "%4d %s\n", @$_;
2315 $CPAN::Frontend->myprint($R);
2318 # here is where 'reload cpan' is done
2319 #-> sub CPAN::Shell::reload ;
2321 my($self,$command,@arg) = @_;
2323 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
2324 if ($command =~ /^cpan$/i) {
2326 chdir $CPAN::iCwd if $CPAN::iCwd; # may fail
2328 MFILE: for my $f (@relo) {
2329 next unless exists $INC{$f};
2333 $CPAN::Frontend->myprint("($p");
2334 local($SIG{__WARN__}) = paintdots_onreload(\$redef);
2335 $self->_reload_this($f) or $failed++;
2336 my $v = eval "$p\::->VERSION";
2337 $CPAN::Frontend->myprint("v$v)");
2339 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
2341 my $errors = $failed == 1 ? "error" : "errors";
2342 $CPAN::Frontend->mywarn("\n$failed $errors during reload. You better quit ".
2345 } elsif ($command =~ /^index$/i) {
2346 CPAN::Index->force_reload;
2348 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN modules
2349 index re-reads the index files\n});
2353 # reload means only load again what we have loaded before
2354 #-> sub CPAN::Shell::_reload_this ;
2356 my($self,$f,$args) = @_;
2357 CPAN->debug("f[$f]") if $CPAN::DEBUG;
2358 return 1 unless $INC{$f}; # we never loaded this, so we do not
2360 my $pwd = CPAN::anycwd();
2361 CPAN->debug("pwd[$pwd]") if $CPAN::DEBUG;
2363 for my $inc (@INC) {
2364 $file = File::Spec->catfile($inc,split /\//, $f);
2368 CPAN->debug("file[$file]") if $CPAN::DEBUG;
2370 unless ($file && -f $file) {
2371 # this thingie is not in the INC path, maybe CPAN/MyConfig.pm?
2373 unless (CPAN->has_inst("File::Basename")) {
2374 @inc = File::Basename::dirname($file);
2376 # do we ever need this?
2377 @inc = substr($file,0,-length($f)-1); # bring in back to me!
2380 CPAN->debug("file[$file]inc[@inc]") if $CPAN::DEBUG;
2382 $CPAN::Frontend->mywarn("Found no file to reload for '$f'\n");
2385 my $mtime = (stat $file)[9];
2386 $reload->{$f} ||= -1;
2387 my $must_reload = $mtime != $reload->{$f};
2389 $must_reload ||= $args->{reloforce}; # o conf defaults needs this
2391 my $fh = FileHandle->new($file) or
2392 $CPAN::Frontend->mydie("Could not open $file: $!");
2395 my $content = <$fh>;
2396 CPAN->debug(sprintf("reload file[%s] content[%s...]",$file,substr($content,0,128)))
2400 eval "require '$f'";
2405 $reload->{$f} = $mtime;
2407 $CPAN::Frontend->myprint("__unchanged__");
2412 #-> sub CPAN::Shell::mkmyconfig ;
2414 my($self, $cpanpm, %args) = @_;
2415 require CPAN::FirstTime;
2416 my $home = CPAN::HandleConfig::home;
2417 $cpanpm = $INC{'CPAN/MyConfig.pm'} ||
2418 File::Spec->catfile(split /\//, "$home/.cpan/CPAN/MyConfig.pm");
2419 File::Path::mkpath(File::Basename::dirname($cpanpm)) unless -e $cpanpm;
2420 CPAN::HandleConfig::require_myconfig_or_config;
2421 $CPAN::Config ||= {};
2426 keep_source_where => undef,
2429 CPAN::FirstTime::init($cpanpm, %args);
2432 #-> sub CPAN::Shell::_binary_extensions ;
2433 sub _binary_extensions {
2434 my($self) = shift @_;
2435 my(@result,$module,%seen,%need,$headerdone);
2436 for $module ($self->expand('Module','/./')) {
2437 my $file = $module->cpan_file;
2438 next if $file eq "N/A";
2439 next if $file =~ /^Contact Author/;
2440 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
2441 next if $dist->isa_perl;
2442 next unless $module->xs_file;
2444 $CPAN::Frontend->myprint(".");
2445 push @result, $module;
2447 # print join " | ", @result;
2448 $CPAN::Frontend->myprint("\n");
2452 #-> sub CPAN::Shell::recompile ;
2454 my($self) = shift @_;
2455 my($module,@module,$cpan_file,%dist);
2456 @module = $self->_binary_extensions();
2457 for $module (@module) { # we force now and compile later, so we
2459 $cpan_file = $module->cpan_file;
2460 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
2462 $dist{$cpan_file}++;
2464 for $cpan_file (sort keys %dist) {
2465 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
2466 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
2468 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
2469 # stop a package from recompiling,
2470 # e.g. IO-1.12 when we have perl5.003_10
2474 #-> sub CPAN::Shell::scripts ;
2476 my($self, $arg) = @_;
2477 $CPAN::Frontend->mywarn(">>>> experimental command, currently unsupported <<<<\n\n");
2479 for my $req (qw( HTML::LinkExtor Sort::Versions List::Util )) {
2480 unless ($CPAN::META->has_inst($req)) {
2481 $CPAN::Frontend->mywarn(" $req not available\n");
2484 my $p = HTML::LinkExtor->new();
2485 my $indexfile = "/home/ftp/pub/PAUSE/scripts/new/index.html";
2486 unless (-f $indexfile) {
2487 $CPAN::Frontend->mydie("found no indexfile[$indexfile]\n");
2489 $p->parse_file($indexfile);
2492 if ($arg =~ s|^/(.+)/$|$1|) {
2493 $qrarg = eval 'qr/$arg/'; # hide construct from 5.004
2495 for my $l ($p->links) {
2496 my $tag = shift @$l;
2497 next unless $tag eq "a";
2499 my $href = $att{href};
2500 next unless $href =~ s|^\.\./authors/id/./../||;
2503 if ($href =~ $qrarg) {
2507 if ($href =~ /\Q$arg\E/) {
2515 # now filter for the latest version if there is more than one of a name
2521 $stems{$stem} ||= [];
2522 push @{$stems{$stem}}, $href;
2524 for (sort keys %stems) {
2526 if (@{$stems{$_}} > 1) {
2527 $highest = List::Util::reduce {
2528 Sort::Versions::versioncmp($a,$b) > 0 ? $a : $b
2531 $highest = $stems{$_}[0];
2533 $CPAN::Frontend->myprint("$highest\n");
2537 #-> sub CPAN::Shell::report ;
2539 my($self,@args) = @_;
2540 unless ($CPAN::META->has_inst("CPAN::Reporter")) {
2541 $CPAN::Frontend->mydie("CPAN::Reporter not installed; cannot continue");
2543 local $CPAN::Config->{test_report} = 1;
2544 $self->force("test",@args); # force is there so that the test be
2545 # re-run (as documented)
2548 # compare with is_tested
2549 #-> sub CPAN::Shell::install_tested
2550 sub install_tested {
2551 my($self,@some) = @_;
2552 $CPAN::Frontend->mywarn("install_tested() must not be called with arguments.\n"),
2554 CPAN::Index->reload;
2556 for my $b (reverse $CPAN::META->_list_sorted_descending_is_tested) {
2557 my $yaml = "$b.yml";
2559 $CPAN::Frontend->mywarn("No YAML file for $b available, skipping\n");
2562 my $yaml_content = CPAN->_yaml_loadfile($yaml);
2563 my $id = $yaml_content->[0]{distribution}{ID};
2565 $CPAN::Frontend->mywarn("No ID found in '$yaml', skipping\n");
2568 my $do = CPAN::Shell->expandany($id);
2570 $CPAN::Frontend->mywarn("Could not expand ID '$id', skipping\n");
2573 unless ($do->{build_dir}) {
2574 $CPAN::Frontend->mywarn("Distro '$id' has no build_dir, skipping\n");
2577 unless ($do->{build_dir} eq $b) {
2578 $CPAN::Frontend->mywarn("Distro '$id' has build_dir '$do->{build_dir}' but expected '$b', skipping\n");
2584 $CPAN::Frontend->mywarn("No tested distributions found.\n"),
2585 return unless @some;
2587 @some = grep { $_->{make_test} && ! $_->{make_test}->failed } @some;
2588 $CPAN::Frontend->mywarn("No distributions tested with this build of perl found.\n"),
2589 return unless @some;
2591 # @some = grep { not $_->uptodate } @some;
2592 # $CPAN::Frontend->mywarn("No non-uptodate distributions tested with this build of perl found.\n"),
2593 # return unless @some;
2595 CPAN->debug("some[@some]");
2597 my $id = $d->can("pretty_id") ? $d->pretty_id : $d->id;
2598 $CPAN::Frontend->myprint("install_tested: Running for $id\n");
2599 $CPAN::Frontend->mysleep(1);
2604 #-> sub CPAN::Shell::upgrade ;
2606 my($self,@args) = @_;
2607 $self->install($self->r(@args));
2610 #-> sub CPAN::Shell::_u_r_common ;
2612 my($self) = shift @_;
2613 my($what) = shift @_;
2614 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
2615 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
2616 $what && $what =~ /^[aru]$/;
2618 @args = '/./' unless @args;
2619 my(@result,$module,%seen,%need,$headerdone,
2620 $version_undefs,$version_zeroes,
2621 @version_undefs,@version_zeroes);
2622 $version_undefs = $version_zeroes = 0;
2623 my $sprintf = "%s%-25s%s %9s %9s %s\n";
2624 my @expand = $self->expand('Module',@args);
2625 if ($CPAN::DEBUG) { # Looks like noise to me, was very useful for debugging
2626 # for metadata cache
2627 my $expand = scalar @expand;
2628 $CPAN::Frontend->myprint(sprintf "%d matches in the database, time[%d]\n", $expand, time);
2632 # hard to believe that the more complex sorting can lead to
2633 # stack curruptions on older perl
2634 @sexpand = sort {$a->id cmp $b->id} @expand;
2641 $a->[1]{ID} cmp $b->[1]{ID},
2643 [$_->_is_representative_module,
2649 $CPAN::Frontend->myprint(sprintf "sorted at time[%d]\n", time);
2652 MODULE: for $module (@sexpand) {
2653 my $file = $module->cpan_file;
2654 next MODULE unless defined $file; # ??
2655 $file =~ s!^./../!!;
2656 my($latest) = $module->cpan_version;
2657 my($inst_file) = $module->inst_file;
2658 CPAN->debug("file[$file]latest[$latest]") if $CPAN::DEBUG;
2660 return if $CPAN::Signal;
2662 eval { # version.pm involved!
2665 $have = $module->inst_version;
2666 } elsif ($what eq "r") {
2667 $have = $module->inst_version;
2669 if ($have eq "undef") {
2671 push @version_undefs, $module->as_glimpse;
2672 } elsif (CPAN::Version->vcmp($have,0)==0) {
2674 push @version_zeroes, $module->as_glimpse;
2676 ++$next_MODULE unless CPAN::Version->vgt($latest, $have);
2677 # to be pedantic we should probably say:
2678 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
2679 # to catch the case where CPAN has a version 0 and we have a version undef
2680 } elsif ($what eq "u") {
2686 } elsif ($what eq "r") {
2688 } elsif ($what eq "u") {
2693 next MODULE if $next_MODULE;
2695 $CPAN::Frontend->mywarn
2696 (sprintf("Error while comparing cpan/installed versions of '%s':
2703 (defined $have ? $have : "[UNDEFINED]"),
2704 (ref $have ? ref $have : ""),
2706 (ref $latest ? ref $latest : ""),
2710 return if $CPAN::Signal; # this is sometimes lengthy
2713 push @result, sprintf "%s %s\n", $module->id, $have;
2714 } elsif ($what eq "r") {
2715 push @result, $module->id;
2716 next MODULE if $seen{$file}++;
2717 } elsif ($what eq "u") {
2718 push @result, $module->id;
2719 next MODULE if $seen{$file}++;
2720 next MODULE if $file =~ /^Contact/;
2722 unless ($headerdone++) {
2723 $CPAN::Frontend->myprint("\n");
2724 $CPAN::Frontend->myprint(sprintf(
2727 "Package namespace",
2739 $CPAN::META->has_inst("Term::ANSIColor")
2741 $module->description
2743 $color_on = Term::ANSIColor::color("green");
2744 $color_off = Term::ANSIColor::color("reset");
2746 $CPAN::Frontend->myprint(sprintf $sprintf,
2753 $need{$module->id}++;
2757 $CPAN::Frontend->myprint("No modules found for @args\n");
2758 } elsif ($what eq "r") {
2759 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
2763 if ($version_zeroes) {
2764 my $s_has = $version_zeroes > 1 ? "s have" : " has";
2765 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
2766 qq{a version number of 0\n});
2767 if ($CPAN::Config->{show_zero_versions}) {
2769 $CPAN::Frontend->myprint(qq{ they are\n\t@version_zeroes\n});
2770 $CPAN::Frontend->myprint(qq{(use 'o conf show_zero_versions 0' }.
2771 qq{to hide them)\n});
2773 $CPAN::Frontend->myprint(qq{(use 'o conf show_zero_versions 1' }.
2774 qq{to show them)\n});
2777 if ($version_undefs) {
2778 my $s_has = $version_undefs > 1 ? "s have" : " has";
2779 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
2780 qq{parseable version number\n});
2781 if ($CPAN::Config->{show_unparsable_versions}) {
2783 $CPAN::Frontend->myprint(qq{ they are\n\t@version_undefs\n});
2784 $CPAN::Frontend->myprint(qq{(use 'o conf show_unparsable_versions 0' }.
2785 qq{to hide them)\n});
2787 $CPAN::Frontend->myprint(qq{(use 'o conf show_unparsable_versions 1' }.
2788 qq{to show them)\n});
2795 #-> sub CPAN::Shell::r ;
2797 shift->_u_r_common("r",@_);
2800 #-> sub CPAN::Shell::u ;
2802 shift->_u_r_common("u",@_);
2805 #-> sub CPAN::Shell::failed ;
2807 my($self,$only_id,$silent) = @_;
2809 DIST: for my $d ($CPAN::META->all_objects("CPAN::Distribution")) {
2811 NAY: for my $nosayer ( # order matters!
2820 next unless exists $d->{$nosayer};
2821 next unless defined $d->{$nosayer};
2823 UNIVERSAL::can($d->{$nosayer},"failed") ?
2824 $d->{$nosayer}->failed :
2825 $d->{$nosayer} =~ /^NO/
2827 next NAY if $only_id && $only_id != (
2828 UNIVERSAL::can($d->{$nosayer},"commandid")
2830 $d->{$nosayer}->commandid
2832 $CPAN::CurrentCommandId
2837 next DIST unless $failed;
2841 # " %-45s: %s %s\n",
2844 UNIVERSAL::can($d->{$failed},"failed") ?
2846 $d->{$failed}->commandid,
2849 $d->{$failed}->text,
2850 $d->{$failed}{TIME}||0,
2863 $scope = "this command";
2864 } elsif ($CPAN::Index::HAVE_REANIMATED) {
2865 $scope = "this or a previous session";
2866 # it might be nice to have a section for previous session and
2869 $scope = "this session";
2876 map { sprintf "%5d %-45s: %s %s\n", @$_ }
2877 sort { $a->[0] <=> $b->[0] } @failed;
2880 map { sprintf " %-45s: %s %s\n", @$_[1..3] }
2887 $CPAN::Frontend->myprint("Failed during $scope:\n$print");
2888 } elsif (!$only_id || !$silent) {
2889 $CPAN::Frontend->myprint("Nothing failed in $scope\n");
2893 # XXX intentionally undocumented because completely bogus, unportable,
2896 #-> sub CPAN::Shell::status ;
2899 require Devel::Size;
2900 my $ps = FileHandle->new;
2901 open $ps, "/proc/$$/status";
2904 next unless /VmSize:\s+(\d+)/;
2908 $CPAN::Frontend->mywarn(sprintf(
2909 "%-27s %6d\n%-27s %6d\n",
2913 Devel::Size::total_size($CPAN::META)/1024,
2915 for my $k (sort keys %$CPAN::META) {
2916 next unless substr($k,0,4) eq "read";
2917 warn sprintf " %-26s %6d\n", $k, Devel::Size::total_size($CPAN::META->{$k})/1024;
2918 for my $k2 (sort keys %{$CPAN::META->{$k}}) {
2919 warn sprintf " %-25s %6d (keys: %6d)\n",
2921 Devel::Size::total_size($CPAN::META->{$k}{$k2})/1024,
2922 scalar keys %{$CPAN::META->{$k}{$k2}};
2927 # compare with install_tested
2928 #-> sub CPAN::Shell::is_tested
2931 CPAN::Index->reload;
2932 for my $b (reverse $CPAN::META->_list_sorted_descending_is_tested) {
2934 if ($CPAN::META->{is_tested}{$b}) {
2935 $time = scalar(localtime $CPAN::META->{is_tested}{$b});
2937 $time = scalar localtime;
2940 $CPAN::Frontend->myprint(sprintf "%s %s\n", $time, $b);
2944 #-> sub CPAN::Shell::autobundle ;
2947 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
2948 my(@bundle) = $self->_u_r_common("a",@_);
2949 my($todir) = File::Spec->catdir($CPAN::Config->{'cpan_home'},"Bundle");
2950 File::Path::mkpath($todir);
2951 unless (-d $todir) {
2952 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
2955 my($y,$m,$d) = (localtime)[5,4,3];
2959 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
2960 my($to) = File::Spec->catfile($todir,"$me.pm");
2962 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
2963 $to = File::Spec->catfile($todir,"$me.pm");
2965 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
2967 "package Bundle::$me;\n\n",
2968 "\$VERSION = '0.01';\n\n",
2972 "Bundle::$me - Snapshot of installation on ",
2973 $Config::Config{'myhostname'},
2976 "\n\n=head1 SYNOPSIS\n\n",
2977 "perl -MCPAN -e 'install Bundle::$me'\n\n",
2978 "=head1 CONTENTS\n\n",
2979 join("\n", @bundle),
2980 "\n\n=head1 CONFIGURATION\n\n",
2982 "\n\n=head1 AUTHOR\n\n",
2983 "This Bundle has been generated automatically ",
2984 "by the autobundle routine in CPAN.pm.\n",
2987 $CPAN::Frontend->myprint("\nWrote bundle file
2991 #-> sub CPAN::Shell::expandany ;
2994 CPAN->debug("s[$s]") if $CPAN::DEBUG;
2995 if ($s =~ m|/| or substr($s,-1,1) eq ".") { # looks like a file or a directory
2996 $s = CPAN::Distribution->normalize($s);
2997 return $CPAN::META->instance('CPAN::Distribution',$s);
2998 # Distributions spring into existence, not expand
2999 } elsif ($s =~ m|^Bundle::|) {
3000 $self->local_bundles; # scanning so late for bundles seems
3001 # both attractive and crumpy: always
3002 # current state but easy to forget
3004 return $self->expand('Bundle',$s);
3006 return $self->expand('Module',$s)
3007 if $CPAN::META->exists('CPAN::Module',$s);
3012 #-> sub CPAN::Shell::expand ;
3015 my($type,@args) = @_;
3016 CPAN->debug("type[$type]args[@args]") if $CPAN::DEBUG;
3017 my $class = "CPAN::$type";
3018 my $methods = ['id'];
3019 for my $meth (qw(name)) {
3020 next unless $class->can($meth);
3021 push @$methods, $meth;
3023 $self->expand_by_method($class,$methods,@args);
3026 #-> sub CPAN::Shell::expand_by_method ;
3027 sub expand_by_method {
3029 my($class,$methods,@args) = @_;
3032 my($regex,$command);
3033 if ($arg =~ m|^/(.*)/$|) {
3035 # FIXME: there seem to be some ='s in the author data, which trigger
3036 # a failure here. This needs to be contemplated.
3037 # } elsif ($arg =~ m/=/) {
3041 CPAN->debug(sprintf "class[%s]regex[%s]command[%s]",
3043 defined $regex ? $regex : "UNDEFINED",
3044 defined $command ? $command : "UNDEFINED",
3046 if (defined $regex) {
3047 if (CPAN::_sqlite_running) {
3048 CPAN::Index->reload;
3049 $CPAN::SQLite->search($class, $regex);
3052 $CPAN::META->all_objects($class)
3054 unless ($obj && UNIVERSAL::can($obj,"id") && $obj->id) {
3055 # BUG, we got an empty object somewhere
3056 require Data::Dumper;
3057 CPAN->debug(sprintf(
3058 "Bug in CPAN: Empty id on obj[%s][%s]",
3060 Data::Dumper::Dumper($obj)
3064 for my $method (@$methods) {
3065 my $match = eval {$obj->$method() =~ /$regex/i};
3067 my($err) = $@ =~ /^(.+) at .+? line \d+\.$/;
3068 $err ||= $@; # if we were too restrictive above
3069 $CPAN::Frontend->mydie("$err\n");
3076 } elsif ($command) {
3077 die "equal sign in command disabled (immature interface), ".
3079 ! \$CPAN::Shell::ADVANCED_QUERY=1
3080 to enable it. But please note, this is HIGHLY EXPERIMENTAL code
3081 that may go away anytime.\n"
3082 unless $ADVANCED_QUERY;
3083 my($method,$criterion) = $arg =~ /(.+?)=(.+)/;
3084 my($matchcrit) = $criterion =~ m/^~(.+)/;
3088 $CPAN::META->all_objects($class)
3090 my $lhs = $self->$method() or next; # () for 5.00503
3092 push @m, $self if $lhs =~ m/$matchcrit/;
3094 push @m, $self if $lhs eq $criterion;
3099 if ( $class eq 'CPAN::Bundle' ) {
3100 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
3101 } elsif ($class eq "CPAN::Distribution") {
3102 $xarg = CPAN::Distribution->normalize($arg);
3106 if ($CPAN::META->exists($class,$xarg)) {
3107 $obj = $CPAN::META->instance($class,$xarg);
3108 } elsif ($CPAN::META->exists($class,$arg)) {
3109 $obj = $CPAN::META->instance($class,$arg);
3116 @m = sort {$a->id cmp $b->id} @m;
3117 if ( $CPAN::DEBUG ) {
3118 my $wantarray = wantarray;
3119 my $join_m = join ",", map {$_->id} @m;
3120 # $self->debug("wantarray[$wantarray]join_m[$join_m]");
3121 my $count = scalar @m;
3122 $self->debug("class[$class]wantarray[$wantarray]count m[$count]");
3124 return wantarray ? @m : $m[0];
3127 #-> sub CPAN::Shell::format_result ;
3130 my($type,@args) = @_;
3131 @args = '/./' unless @args;
3132 my(@result) = $self->expand($type,@args);
3133 my $result = @result == 1 ?
3134 $result[0]->as_string :
3136 "No objects of type $type found for argument @args\n" :
3138 (map {$_->as_glimpse} @result),
3139 scalar @result, " items found\n",
3144 #-> sub CPAN::Shell::report_fh ;
3146 my $installation_report_fh;
3147 my $previously_noticed = 0;
3150 return $installation_report_fh if $installation_report_fh;
3151 if ($CPAN::META->has_usable("File::Temp")) {
3152 $installation_report_fh
3154 dir => File::Spec->tmpdir,
3155 template => 'cpan_install_XXXX',
3160 unless ( $installation_report_fh ) {
3161 warn("Couldn't open installation report file; " .
3162 "no report file will be generated."
3163 ) unless $previously_noticed++;
3169 # The only reason for this method is currently to have a reliable
3170 # debugging utility that reveals which output is going through which
3171 # channel. No, I don't like the colors ;-)
3173 # to turn colordebugging on, write
3174 # cpan> o conf colorize_output 1
3176 #-> sub CPAN::Shell::colorize_output ;
3178 my $print_ornamented_have_warned = 0;
3179 sub colorize_output {
3180 my $colorize_output = $CPAN::Config->{colorize_output};
3181 if ($colorize_output && !$CPAN::META->has_inst("Term::ANSIColor")) {
3182 unless ($print_ornamented_have_warned++) {
3183 # no myprint/mywarn within myprint/mywarn!
3184 warn "Colorize_output is set to true but Term::ANSIColor is not
3185 installed. To activate colorized output, please install Term::ANSIColor.\n\n";
3187 $colorize_output = 0;
3189 return $colorize_output;
3194 #-> sub CPAN::Shell::print_ornamented ;
3195 sub print_ornamented {
3196 my($self,$what,$ornament) = @_;
3197 return unless defined $what;
3199 local $| = 1; # Flush immediately
3200 if ( $CPAN::Be_Silent ) {
3201 print {report_fh()} $what;
3204 my $swhat = "$what"; # stringify if it is an object
3205 if ($CPAN::Config->{term_is_latin}) {
3206 # note: deprecated, need to switch to $LANG and $LC_*
3209 =~ s{([\xC0-\xDF])([\x80-\xBF])}{chr(ord($1)<<6&0xC0|ord($2)&0x3F)}eg; #};
3211 if ($self->colorize_output) {
3212 if ( $CPAN::DEBUG && $swhat =~ /^Debug\(/ ) {
3213 # if you want to have this configurable, please file a bugreport
3214 $ornament = $CPAN::Config->{colorize_debug} || "black on_cyan";
3216 my $color_on = eval { Term::ANSIColor::color($ornament) } || "";
3218 print "Term::ANSIColor rejects color[$ornament]: $@\n
3219 Please choose a different color (Hint: try 'o conf init /color/')\n";
3221 # GGOLDBACH/Test-GreaterVersion-0.008 broke without this
3222 # $trailer construct. We want the newline be the last thing if
3223 # there is a newline at the end ensuring that the next line is
3224 # empty for other players
3226 $trailer = $1 if $swhat =~ s/([\r\n]+)\z//;
3229 Term::ANSIColor::color("reset"),
3236 #-> sub CPAN::Shell::myprint ;
3238 # where is myprint/mywarn/Frontend/etc. documented? Where to use what?
3239 # I think, we send everything to STDOUT and use print for normal/good
3240 # news and warn for news that need more attention. Yes, this is our
3241 # working contract for now.
3243 my($self,$what) = @_;
3244 $self->print_ornamented($what,
3245 $CPAN::Config->{colorize_print}||'bold blue on_white',
3250 my($self,$category,$what) = @_;
3251 my $vname = $category . "_verbosity";
3252 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
3253 if (!$CPAN::Config->{$vname}
3254 || $CPAN::Config->{$vname} =~ /^v/
3256 $CPAN::Frontend->myprint($what);
3260 #-> sub CPAN::Shell::myexit ;
3262 my($self,$what) = @_;
3263 $self->myprint($what);
3267 #-> sub CPAN::Shell::mywarn ;
3269 my($self,$what) = @_;
3270 $self->print_ornamented($what, $CPAN::Config->{colorize_warn}||'bold red on_white');
3273 # only to be used for shell commands
3274 #-> sub CPAN::Shell::mydie ;
3276 my($self,$what) = @_;
3277 $self->mywarn($what);
3279 # If it is the shell, we want the following die to be silent,
3280 # but if it is not the shell, we would need a 'die $what'. We need
3281 # to take care that only shell commands use mydie. Is this
3287 # sub CPAN::Shell::colorable_makemaker_prompt ;
3288 sub colorable_makemaker_prompt {
3290 if (CPAN::Shell->colorize_output) {
3291 my $ornament = $CPAN::Config->{colorize_print}||'bold blue on_white';
3292 my $color_on = eval { Term::ANSIColor::color($ornament); } || "";
3295 my $ans = ExtUtils::MakeMaker::prompt($foo,$bar);
3296 if (CPAN::Shell->colorize_output) {
3297 print Term::ANSIColor::color('reset');
3302 # use this only for unrecoverable errors!
3303 #-> sub CPAN::Shell::unrecoverable_error ;
3304 sub unrecoverable_error {
3305 my($self,$what) = @_;
3306 my @lines = split /\n/, $what;
3308 for my $l (@lines) {
3309 $longest = length $l if length $l > $longest;
3311 $longest = 62 if $longest > 62;
3312 for my $l (@lines) {
3313 if ($l =~ /^\s*$/) {
3318 if (length $l < 66) {
3319 $l = pack "A66 A*", $l, "<==";
3323 unshift @lines, "\n";
3324 $self->mydie(join "", @lines);
3327 #-> sub CPAN::Shell::mysleep ;
3329 my($self, $sleep) = @_;
3330 if (CPAN->has_inst("Time::HiRes")) {
3331 Time::HiRes::sleep($sleep);
3333 sleep($sleep < 1 ? 1 : int($sleep + 0.5));
3337 #-> sub CPAN::Shell::setup_output ;
3339 return if -t STDOUT;
3340 my $odef = select STDERR;
3347 #-> sub CPAN::Shell::rematein ;
3348 # RE-adme||MA-ke||TE-st||IN-stall : nearly everything runs through here
3351 my($meth,@some) = @_;
3353 while($meth =~ /^(ff?orce|notest)$/) {
3354 push @pragma, $meth;
3355 $meth = shift @some or
3356 $CPAN::Frontend->mydie("Pragma $pragma[-1] used without method: ".
3360 CPAN->debug("pragma[@pragma]meth[$meth]some[@some]") if $CPAN::DEBUG;
3362 # Here is the place to set "test_count" on all involved parties to
3363 # 0. We then can pass this counter on to the involved
3364 # distributions and those can refuse to test if test_count > X. In
3365 # the first stab at it we could use a 1 for "X".
3367 # But when do I reset the distributions to start with 0 again?
3368 # Jost suggested to have a random or cycling interaction ID that
3369 # we pass through. But the ID is something that is just left lying
3370 # around in addition to the counter, so I'd prefer to set the
3371 # counter to 0 now, and repeat at the end of the loop. But what
3372 # about dependencies? They appear later and are not reset, they
3373 # enter the queue but not its copy. How do they get a sensible
3376 # With configure_requires, "get" is vulnerable in recursion.
3378 my $needs_recursion_protection = "get|make|test|install";
3380 # construct the queue
3382 STHING: foreach $s (@some) {
3385 CPAN->debug("s is an object[$s]") if $CPAN::DEBUG;
3387 } elsif ($s =~ m|[\$\@\%]|) { # looks like a perl variable
3388 } elsif ($s =~ m|^/|) { # looks like a regexp
3389 if (substr($s,-1,1) eq ".") {
3390 $obj = CPAN::Shell->expandany($s);
3392 $CPAN::Frontend->mywarn("Sorry, $meth with a regular expression is ".
3393 "not supported.\nRejecting argument '$s'\n");
3394 $CPAN::Frontend->mysleep(2);
3397 } elsif ($meth eq "ls") {
3398 $self->globls($s,\@pragma);
3401 CPAN->debug("calling expandany [$s]") if $CPAN::DEBUG;
3402 $obj = CPAN::Shell->expandany($s);
3405 } elsif (ref $obj) {
3406 if ($meth =~ /^($needs_recursion_protection)$/) {
3407 # it would be silly to check for recursion for look or dump
3408 # (we are in CPAN::Shell::rematein)
3409 CPAN->debug("Going to test against recursion") if $CPAN::DEBUG;
3410 eval { $obj->color_cmd_tmps(0,1); };
3413 and $@->isa("CPAN::Exception::RecursiveDependency")) {
3414 $CPAN::Frontend->mywarn($@);
3418 Carp::confess(sprintf "DEBUG: \$\@[%s]ref[%s]", $@, ref $@);
3424 CPAN::Queue->queue_item(qmod => $obj->id, reqtype => "c");
3426 } elsif ($CPAN::META->exists('CPAN::Author',uc($s))) {
3427 $obj = $CPAN::META->instance('CPAN::Author',uc($s));
3428 if ($meth =~ /^(dump|ls|reports)$/) {
3431 $CPAN::Frontend->mywarn(
3433 "Don't be silly, you can't $meth ",
3437 $CPAN::Frontend->mysleep(2);
3439 } elsif ($s =~ m|[\$\@\%]| && $meth eq "dump") {
3440 CPAN::InfoObj->dump($s);
3443 ->mywarn(qq{Warning: Cannot $meth $s, }.
3444 qq{don't know what it is.
3449 to find objects with matching identifiers.
3451 $CPAN::Frontend->mysleep(2);
3455 # queuerunner (please be warned: when I started to change the
3456 # queue to hold objects instead of names, I made one or two
3457 # mistakes and never found which. I reverted back instead)
3458 QITEM: while (my $q = CPAN::Queue->first) {
3460 my $s = $q->as_string;
3461 my $reqtype = $q->reqtype || "";
3462 $obj = CPAN::Shell->expandany($s);
3464 # don't know how this can happen, maybe we should panic,
3465 # but maybe we get a solution from the first user who hits
3466 # this unfortunate exception?
3467 $CPAN::Frontend->mywarn("Warning: Could not expand string '$s' ".
3468 "to an object. Skipping.\n");
3469 $CPAN::Frontend->mysleep(5);
3470 CPAN::Queue->delete_first($s);
3473 $obj->{reqtype} ||= "";
3475 # force debugging because CPAN::SQLite somehow delivers us
3478 # local $CPAN::DEBUG = 1024; # Shell; probably fixed now
3480 CPAN->debug("s[$s]obj-reqtype[$obj->{reqtype}]".
3481 "q-reqtype[$reqtype]") if $CPAN::DEBUG;
3483 if ($obj->{reqtype}) {
3484 if ($obj->{reqtype} eq "b" && $reqtype =~ /^[rc]$/) {
3485 $obj->{reqtype} = $reqtype;
3487 exists $obj->{install}
3490 UNIVERSAL::can($obj->{install},"failed") ?
3491 $obj->{install}->failed :
3492 $obj->{install} =~ /^NO/
3495 delete $obj->{install};
3496 $CPAN::Frontend->mywarn
3497 ("Promoting $obj->{ID} from 'build_requires' to 'requires'");
3501 $obj->{reqtype} = $reqtype;
3504 for my $pragma (@pragma) {
3507 $obj->can($pragma)) {
3508 $obj->$pragma($meth);
3511 if (UNIVERSAL::can($obj, 'called_for')) {
3512 $obj->called_for($s);
3514 CPAN->debug(qq{pragma[@pragma]meth[$meth]}.
3515 qq{ID[$obj->{ID}]}) if $CPAN::DEBUG;
3518 if ($meth =~ /^(report)$/) { # they came here with a pragma?
3520 } elsif (! UNIVERSAL::can($obj,$meth)) {
3522 my $serialized = "";
3524 } elsif ($CPAN::META->has_inst("YAML::Syck")) {
3525 $serialized = YAML::Syck::Dump($obj);
3526 } elsif ($CPAN::META->has_inst("YAML")) {
3527 $serialized = YAML::Dump($obj);
3528 } elsif ($CPAN::META->has_inst("Data::Dumper")) {
3529 $serialized = Data::Dumper::Dumper($obj);
3532 $serialized = overload::StrVal($obj);
3534 CPAN->debug("Going to panic. meth[$meth]s[$s]") if $CPAN::DEBUG;
3535 $CPAN::Frontend->mydie("Panic: obj[$serialized] cannot meth[$meth]");
3536 } elsif ($obj->$meth()) {
3537 CPAN::Queue->delete($s);
3538 CPAN->debug("From queue deleted. meth[$meth]s[$s]") if $CPAN::DEBUG;
3540 CPAN->debug("Failed. pragma[@pragma]meth[$meth]") if $CPAN::DEBUG;
3544 for my $pragma (@pragma) {
3545 my $unpragma = "un$pragma";
3546 if ($obj->can($unpragma)) {
3550 if ($CPAN::Config->{halt_on_failure}
3552 CPAN::Distrostatus::something_has_just_failed()
3554 $CPAN::Frontend->mywarn("Stopping: '$meth' failed for '$s'.\n");
3555 CPAN::Queue->nullify_queue;
3558 CPAN::Queue->delete_first($s);
3560 if ($meth =~ /^($needs_recursion_protection)$/) {
3561 for my $obj (@qcopy) {
3562 $obj->color_cmd_tmps(0,0);
3567 #-> sub CPAN::Shell::recent ;
3570 if ($CPAN::META->has_inst("XML::LibXML")) {
3571 my $url = $CPAN::Defaultrecent;
3572 $CPAN::Frontend->myprint("Going to fetch '$url'\n");
3573 unless ($CPAN::META->has_usable("LWP")) {
3574 $CPAN::Frontend->mydie("LWP not installed; cannot continue");
3576 CPAN::LWP::UserAgent->config;
3578 eval { $Ua = CPAN::LWP::UserAgent->new; };
3580 $CPAN::Frontend->mydie("CPAN::LWP::UserAgent->new dies with $@\n");
3582 my $resp = $Ua->get($url);
3583 unless ($resp->is_success) {
3584 $CPAN::Frontend->mydie(sprintf "Could not download '%s': %s\n", $url, $resp->code);
3586 $CPAN::Frontend->myprint("DONE\n\n");
3587 my $xml = XML::LibXML->new->parse_string($resp->content);
3589 my $s = $xml->serialize(2);
3590 $s =~ s/\n\s*\n/\n/g;
3591 $CPAN::Frontend->myprint($s);
3595 if ($url =~ /winnipeg/) {
3596 my $pubdate = $xml->findvalue("/rss/channel/pubDate");
3597 $CPAN::Frontend->myprint(" pubDate: $pubdate\n\n");
3598 for my $eitem ($xml->findnodes("/rss/channel/item")) {
3599 my $distro = $eitem->findvalue("enclosure/\@url");
3600 $distro =~ s|.*?/authors/id/./../||;
3601 my $size = $eitem->findvalue("enclosure/\@length");
3602 my $desc = $eitem->findvalue("description");
3603 $desc =~ s/.+? - //;
3604 $CPAN::Frontend->myprint("$distro [$size b]\n $desc\n");
3605 push @distros, $distro;
3607 } elsif ($url =~ /search.*uploads.rdf/) {
3608 # xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
3609 # xmlns="http://purl.org/rss/1.0/"
3610 # xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
3611 # xmlns:dc="http://purl.org/dc/elements/1.1/"
3612 # xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
3613 # xmlns:admin="http://webns.net/mvcb/"
3616 my $dc_date = $xml->findvalue("//*[local-name(.) = 'RDF']/*[local-name(.) = 'channel']/*[local-name(.) = 'date']");
3617 $CPAN::Frontend->myprint(" dc:date: $dc_date\n\n");
3618 my $finish_eitem = 0;
3619 local $SIG{INT} = sub { $finish_eitem = 1 };
3620 EITEM: for my $eitem ($xml->findnodes("//*[local-name(.) = 'RDF']/*[local-name(.) = 'item']")) {
3621 my $distro = $eitem->findvalue("\@rdf:about");
3622 $distro =~ s|.*~||; # remove up to the tilde before the name
3623 $distro =~ s|/$||; # remove trailing slash
3624 $distro =~ s|([^/]+)|\U$1\E|; # upcase the name
3625 my $author = uc $1 or die "distro[$distro] without author, cannot continue";
3626 my $desc = $eitem->findvalue("*[local-name(.) = 'description']");
3628 SUBDIRTEST: while () {
3629 last SUBDIRTEST if ++$i >= 6; # half a dozen must do!
3630 if (my @ret = $self->globls("$distro*")) {
3631 @ret = grep {$_->[2] !~ /meta/} @ret;
3632 @ret = grep {length $_->[2]} @ret;
3634 $distro = "$author/$ret[0][2]";
3638 $distro =~ s|/|/*/|; # allow it to reside in a subdirectory
3641 next EITEM if $distro =~ m|\*|; # did not find the thing
3642 $CPAN::Frontend->myprint("____$desc\n");
3643 push @distros, $distro;
3644 last EITEM if $finish_eitem;
3649 # deprecated old version
3650 $CPAN::Frontend->mydie("no XML::LibXML installed, cannot continue\n");
3654 #-> sub CPAN::Shell::smoke ;
3657 my $distros = $self->recent;
3658 DISTRO: for my $distro (@$distros) {
3659 next if $distro =~ m|/Bundle-|; # XXX crude heuristic to skip bundles
3660 $CPAN::Frontend->myprint(sprintf "Going to download and test '$distro'\n");
3663 local $SIG{INT} = sub { $skip = 1 };
3665 $CPAN::Frontend->myprint(sprintf "\r%2d (Hit ^C to skip)", 10-$_);
3668 $CPAN::Frontend->myprint(" skipped\n");
3673 $CPAN::Frontend->myprint("\r \n"); # leave the dirty line with a newline
3674 $self->test($distro);
3679 # set up the dispatching methods
3681 for my $command (qw(
3698 *$command = sub { shift->rematein($command, @_); };
3702 package CPAN::LWP::UserAgent;
3706 return if $SETUPDONE;
3707 if ($CPAN::META->has_usable('LWP::UserAgent')) {
3708 require LWP::UserAgent;
3709 @ISA = qw(Exporter LWP::UserAgent);
3712 $CPAN::Frontend->mywarn(" LWP::UserAgent not available\n");
3716 sub get_basic_credentials {
3717 my($self, $realm, $uri, $proxy) = @_;
3718 if ($USER && $PASSWD) {
3719 return ($USER, $PASSWD);
3722 ($USER,$PASSWD) = $self->get_proxy_credentials();
3724 ($USER,$PASSWD) = $self->get_non_proxy_credentials();
3726 return($USER,$PASSWD);
3729 sub get_proxy_credentials {
3731 my ($user, $password);
3732 if ( defined $CPAN::Config->{proxy_user} ) {
3733 $user = $CPAN::Config->{proxy_user};
3734 $password = $CPAN::Config->{proxy_pass} || "";
3735 return ($user, $password);
3737 my $username_prompt = "\nProxy authentication needed!
3738 (Note: to permanently configure username and password run
3739 o conf proxy_user your_username
3740 o conf proxy_pass your_password
3742 ($user, $password) =
3743 _get_username_and_password_from_user($username_prompt);
3744 return ($user,$password);
3747 sub get_non_proxy_credentials {
3749 my ($user,$password);
3750 if ( defined $CPAN::Config->{username} ) {
3751 $user = $CPAN::Config->{username};
3752 $password = $CPAN::Config->{password} || "";
3753 return ($user, $password);
3755 my $username_prompt = "\nAuthentication needed!
3756 (Note: to permanently configure username and password run
3757 o conf username your_username
3758 o conf password your_password
3761 ($user, $password) =
3762 _get_username_and_password_from_user($username_prompt);
3763 return ($user,$password);
3766 sub _get_username_and_password_from_user {
3767 my $username_message = shift;
3768 my ($username,$password);
3770 ExtUtils::MakeMaker->import(qw(prompt));
3771 $username = prompt($username_message);
3772 if ($CPAN::META->has_inst("Term::ReadKey")) {
3773 Term::ReadKey::ReadMode("noecho");
3776 $CPAN::Frontend->mywarn(
3777 "Warning: Term::ReadKey seems not to be available, your password will be echoed to the terminal!\n"
3780 $password = prompt("Password:");
3782 if ($CPAN::META->has_inst("Term::ReadKey")) {
3783 Term::ReadKey::ReadMode("restore");
3785 $CPAN::Frontend->myprint("\n\n");
3786 return ($username,$password);
3789 # mirror(): Its purpose is to deal with proxy authentication. When we
3790 # call SUPER::mirror, we relly call the mirror method in
3791 # LWP::UserAgent. LWP::UserAgent will then call
3792 # $self->get_basic_credentials or some equivalent and this will be
3793 # $self->dispatched to our own get_basic_credentials method.
3795 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
3797 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
3798 # although we have gone through our get_basic_credentials, the proxy
3799 # server refuses to connect. This could be a case where the username or
3800 # password has changed in the meantime, so I'm trying once again without
3801 # $USER and $PASSWD to give the get_basic_credentials routine another
3802 # chance to set $USER and $PASSWD.
3804 # mirror(): Its purpose is to deal with proxy authentication. When we
3805 # call SUPER::mirror, we relly call the mirror method in
3806 # LWP::UserAgent. LWP::UserAgent will then call
3807 # $self->get_basic_credentials or some equivalent and this will be
3808 # $self->dispatched to our own get_basic_credentials method.
3810 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
3812 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
3813 # although we have gone through our get_basic_credentials, the proxy
3814 # server refuses to connect. This could be a case where the username or
3815 # password has changed in the meantime, so I'm trying once again without
3816 # $USER and $PASSWD to give the get_basic_credentials routine another
3817 # chance to set $USER and $PASSWD.
3820 my($self,$url,$aslocal) = @_;
3821 my $result = $self->SUPER::mirror($url,$aslocal);
3822 if ($result->code == 407) {
3825 $result = $self->SUPER::mirror($url,$aslocal);
3833 #-> sub CPAN::FTP::ftp_statistics
3834 # if they want to rewrite, they need to pass in a filehandle
3835 sub _ftp_statistics {
3837 my $locktype = $fh ? LOCK_EX : LOCK_SH;
3838 $fh ||= FileHandle->new;
3839 my $file = File::Spec->catfile($CPAN::Config->{cpan_home},"FTPstats.yml");
3840 open $fh, "+>>$file" or $CPAN::Frontend->mydie("Could not open '$file': $!");
3843 while (!CPAN::_flock($fh, $locktype|LOCK_NB)) {
3844 $waitstart ||= localtime();
3846 $CPAN::Frontend->mywarn("Waiting for a read lock on '$file' (since $waitstart)\n");
3848 $CPAN::Frontend->mysleep($sleep);
3851 } elsif ($sleep <=6) {
3855 my $stats = eval { CPAN->_yaml_loadfile($file); };
3858 if (ref $@ eq "CPAN::Exception::yaml_not_installed") {
3859 $CPAN::Frontend->myprint("Warning (usually harmless): $@");
3861 } elsif (ref $@ eq "CPAN::Exception::yaml_process_error") {
3862 $CPAN::Frontend->mydie($@);
3865 $CPAN::Frontend->mydie($@);
3871 #-> sub CPAN::FTP::_mytime
3873 if (CPAN->has_inst("Time::HiRes")) {
3874 return Time::HiRes::time();
3880 #-> sub CPAN::FTP::_new_stats
3882 my($self,$file) = @_;
3891 #-> sub CPAN::FTP::_add_to_statistics
3892 sub _add_to_statistics {
3893 my($self,$stats) = @_;
3894 my $yaml_module = CPAN::_yaml_module;
3895 $self->debug("yaml_module[$yaml_module]") if $CPAN::DEBUG;
3896 if ($CPAN::META->has_inst($yaml_module)) {
3897 $stats->{thesiteurl} = $ThesiteURL;
3898 $stats->{end} = CPAN::FTP::_mytime();
3899 my $fh = FileHandle->new;
3903 @debug = $time if $sdebug;
3904 my $fullstats = $self->_ftp_statistics($fh);
3906 $fullstats->{history} ||= [];
3907 push @debug, scalar @{$fullstats->{history}} if $sdebug;
3908 push @debug, time if $sdebug;
3909 push @{$fullstats->{history}}, $stats;
3910 # YAML.pm 0.62 is unacceptably slow with 999;
3911 # YAML::Syck 0.82 has no noticable performance problem with 999;
3912 my $ftpstats_size = $CPAN::Config->{ftpstats_size} || 99;
3913 my $ftpstats_period = $CPAN::Config->{ftpstats_period} || 14;
3915 @{$fullstats->{history}} > $ftpstats_size
3916 || $time - $fullstats->{history}[0]{start} > 86400*$ftpstats_period
3918 shift @{$fullstats->{history}}
3920 push @debug, scalar @{$fullstats->{history}} if $sdebug;
3921 push @debug, time if $sdebug;
3922 push @debug, scalar localtime($fullstats->{history}[0]{start}) if $sdebug;
3923 # need no eval because if this fails, it is serious
3924 my $sfile = File::Spec->catfile($CPAN::Config->{cpan_home},"FTPstats.yml");
3925 CPAN->_yaml_dumpfile("$sfile.$$",$fullstats);
3927 local $CPAN::DEBUG = 512; # FTP
3929 CPAN->debug(sprintf("DEBUG history: before_read[%d]before[%d]at[%d]".
3930 "after[%d]at[%d]oldest[%s]dumped backat[%d]",
3934 # Win32 cannot rename a file to an existing filename
3935 unlink($sfile) if ($^O eq 'MSWin32');
3936 _copy_stat($sfile, "$sfile.$$") if -e $sfile;
3937 rename "$sfile.$$", $sfile
3938 or $CPAN::Frontend->mydie("Could not rename '$sfile.$$' to '$sfile': $!\n");
3942 # Copy some stat information (owner, group, mode and) from one file to
3944 # This is a utility function which might be moved to a utility repository.
3945 #-> sub CPAN::FTP::_copy_stat
3947 my($src, $dest) = @_;
3948 my @stat = stat($src);
3950 $CPAN::Frontend->mywarn("Can't stat '$src': $!\n");
3955 chmod $stat[2], $dest
3956 or $CPAN::Frontend->mywarn("Can't chmod '$dest' to " . sprintf("0%o", $stat[2]) . ": $!\n");
3960 chown $stat[4], $stat[5], $dest
3962 my $save_err = $!; # otherwise it's lost in the get... calls
3963 $CPAN::Frontend->mywarn("Can't chown '$dest' to " .
3964 (getpwuid($stat[4]))[0] . "/" .
3965 (getgrgid($stat[5]))[0] . ": $save_err\n"
3972 # if file is CHECKSUMS, suggest the place where we got the file to be
3973 # checked from, maybe only for young files?
3974 #-> sub CPAN::FTP::_recommend_url_for
3975 sub _recommend_url_for {
3976 my($self, $file) = @_;
3977 my $urllist = $self->_get_urllist;
3978 if ($file =~ s|/CHECKSUMS(.gz)?$||) {
3979 my $fullstats = $self->_ftp_statistics();
3980 my $history = $fullstats->{history} || [];
3981 while (my $last = pop @$history) {
3982 last if $last->{end} - time > 3600; # only young results are interesting
3983 next unless $last->{file}; # dirname of nothing dies!
3984 next unless $file eq File::Basename::dirname($last->{file});
3985 return $last->{thesiteurl};
3988 if ($CPAN::Config->{randomize_urllist}
3990 rand(1) < $CPAN::Config->{randomize_urllist}
3992 $urllist->[int rand scalar @$urllist];
3998 #-> sub CPAN::FTP::_get_urllist
4001 $CPAN::Config->{urllist} ||= [];
4002 unless (ref $CPAN::Config->{urllist} eq 'ARRAY') {
4003 $CPAN::Frontend->mywarn("Malformed urllist; ignoring. Configuration file corrupt?\n");
4004 $CPAN::Config->{urllist} = [];
4006 my @urllist = grep { defined $_ and length $_ } @{$CPAN::Config->{urllist}};
4007 for my $u (@urllist) {
4008 CPAN->debug("u[$u]") if $CPAN::DEBUG;
4009 if (UNIVERSAL::can($u,"text")) {
4010 $u->{TEXT} .= "/" unless substr($u->{TEXT},-1) eq "/";
4012 $u .= "/" unless substr($u,-1) eq "/";
4013 $u = CPAN::URL->new(TEXT => $u, FROM => "USER");
4019 #-> sub CPAN::FTP::ftp_get ;
4021 my($class,$host,$dir,$file,$target) = @_;
4023 qq[Going to fetch file [$file] from dir [$dir]
4024 on host [$host] as local [$target]\n]
4026 my $ftp = Net::FTP->new($host);
4028 $CPAN::Frontend->mywarn(" Could not connect to host '$host' with Net::FTP\n");
4031 return 0 unless defined $ftp;
4032 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
4033 $class->debug(qq[Going to login("anonymous","$Config::Config{cf_email}")]);
4034 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ) {
4035 my $msg = $ftp->message;
4036 $CPAN::Frontend->mywarn(" Couldn't login on $host: $msg");
4039 unless ( $ftp->cwd($dir) ) {
4040 my $msg = $ftp->message;
4041 $CPAN::Frontend->mywarn(" Couldn't cwd $dir: $msg");
4045 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
4046 unless ( $ftp->get($file,$target) ) {
4047 my $msg = $ftp->message;
4048 $CPAN::Frontend->mywarn(" Couldn't fetch $file from $host: $msg");
4051 $ftp->quit; # it's ok if this fails
4055 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
4057 # > *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
4058 # > --- /tmp/cp Wed Sep 24 13:26:40 1997
4060 # > *** 1562,1567 ****
4061 # > --- 1562,1580 ----
4062 # > return 1 if substr($url,0,4) eq "file";
4063 # > return 1 unless $url =~ m|://([^/]+)|;
4065 # > + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
4067 # > + $proxy =~ m|://([^/:]+)|;
4069 # > + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
4070 # > + if ($noproxy) {
4071 # > + if ($host !~ /$noproxy$/) {
4072 # > + $host = $proxy;
4075 # > + $host = $proxy;
4078 # > require Net::Ping;
4079 # > return 1 unless $Net::Ping::VERSION >= 2;
4083 #-> sub CPAN::FTP::localize ;
4085 my($self,$file,$aslocal,$force) = @_;
4087 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
4088 unless defined $aslocal;
4089 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
4092 if ($^O eq 'MacOS') {
4093 # Comment by AK on 2000-09-03: Uniq short filenames would be
4094 # available in CHECKSUMS file
4095 my($name, $path) = File::Basename::fileparse($aslocal, '');
4096 if (length($name) > 31) {
4107 my $size = 31 - length($suf);
4108 while (length($name) > $size) {
4112 $aslocal = File::Spec->catfile($path, $name);
4116 if (-f $aslocal && -r _ && !($force & 1)) {
4118 if ($size = -s $aslocal) {
4119 $self->debug("aslocal[$aslocal]size[$size]") if $CPAN::DEBUG;
4122 # empty file from a previous unsuccessful attempt to download it
4124 $CPAN::Frontend->mydie("Found a zero-length '$aslocal' that I ".
4125 "could not remove.");
4128 my($maybe_restore) = 0;
4130 rename $aslocal, "$aslocal.bak$$";
4134 my($aslocal_dir) = File::Basename::dirname($aslocal);
4135 $self->mymkpath($aslocal_dir); # too early for file URLs / RT #28438
4136 # Inheritance is not easier to manage than a few if/else branches
4137 if ($CPAN::META->has_usable('LWP::UserAgent')) {
4139 CPAN::LWP::UserAgent->config;
4140 eval {$Ua = CPAN::LWP::UserAgent->new;}; # Why is has_usable still not fit enough?
4142 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n")
4146 $Ua->proxy('ftp', $var)
4147 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
4148 $Ua->proxy('http', $var)
4149 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
4151 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
4155 for my $prx (qw(ftp_proxy http_proxy no_proxy)) {
4156 $ENV{$prx} = $CPAN::Config->{$prx} if $CPAN::Config->{$prx};
4159 # Try the list of urls for each single object. We keep a record
4160 # where we did get a file from
4161 my(@reordered,$last);
4162 my $ccurllist = $self->_get_urllist;
4163 $last = $#$ccurllist;
4164 if ($force & 2) { # local cpans probably out of date, don't reorder
4165 @reordered = (0..$last);
4169 (substr($ccurllist->[$b],0,4) eq "file")
4171 (substr($ccurllist->[$a],0,4) eq "file")
4173 defined($ThesiteURL)
4175 ($ccurllist->[$b] eq $ThesiteURL)
4177 ($ccurllist->[$a] eq $ThesiteURL)
4182 $self->debug("Themethod[$Themethod]reordered[@reordered]") if $CPAN::DEBUG;
4188 ["dleasy", "http","defaultsites"],
4189 ["dlhard", "http","defaultsites"],
4190 ["dleasy", "ftp", "defaultsites"],
4191 ["dlhard", "ftp", "defaultsites"],
4192 ["dlhardest","", "defaultsites"],
4195 @levels = grep {$_->[0] eq $Themethod} @all_levels;
4196 push @levels, grep {$_->[0] ne $Themethod} @all_levels;
4198 @levels = @all_levels;
4200 @levels = qw/dleasy/ if $^O eq 'MacOS';
4202 local $ENV{FTP_PASSIVE} =
4203 exists $CPAN::Config->{ftp_passive} ?
4204 $CPAN::Config->{ftp_passive} : 1;
4206 my $stats = $self->_new_stats($file);
4207 for ($CPAN::Config->{connect_to_internet_ok}) {
4208 $connect_to_internet_ok = $_ if not defined $connect_to_internet_ok and defined $_;
4210 LEVEL: for $levelno (0..$#levels) {
4211 my $level_tuple = $levels[$levelno];
4212 my($level,$scheme,$sitetag) = @$level_tuple;
4213 my $defaultsites = $sitetag && $sitetag eq "defaultsites";
4215 if ($defaultsites) {
4216 unless (defined $connect_to_internet_ok) {
4217 $CPAN::Frontend->myprint(sprintf qq{
4218 I would like to connect to one of the following sites to get '%s':
4223 join("",map { " ".$_->text."\n" } @CPAN::Defaultsites),
4225 my $answer = CPAN::Shell::colorable_makemaker_prompt("Is it OK to try to connect to the Internet?", "yes");
4226 if ($answer =~ /^y/i) {
4227 $connect_to_internet_ok = 1;
4229 $connect_to_internet_ok = 0;
4232 if ($connect_to_internet_ok) {
4233 @urllist = @CPAN::Defaultsites;
4236 $CPAN::Frontend->mywarn(sprintf qq{
4238 You have not configured a urllist and did not allow to connect to the
4239 internet. I will continue but it is very likely that we will face
4240 problems. If this happens, please consider to call either
4242 o conf init connect_to_internet_ok
4246 Sleeping $sleep seconds now.
4248 $CPAN::Frontend->mysleep($sleep);
4252 my @host_seq = $level =~ /dleasy/ ?
4253 @reordered : 0..$last; # reordered has file and $Thesiteurl first
4254 @urllist = map { $ccurllist->[$_] } @host_seq;
4256 $self->debug("synth. urllist[@urllist]") if $CPAN::DEBUG;
4257 my $aslocal_tempfile = $aslocal . ".tmp" . $$;
4258 if (my $recommend = $self->_recommend_url_for($file)) {
4259 @urllist = grep { $_ ne $recommend } @urllist;
4260 unshift @urllist, $recommend;
4262 $self->debug("synth. urllist[@urllist]") if $CPAN::DEBUG;
4263 $ret = $self->hostdlxxx($level,$scheme,\@urllist,$file,$aslocal_tempfile,$stats);
4265 CPAN->debug("ret[$ret]aslocal[$aslocal]") if $CPAN::DEBUG;
4266 if ($ret eq $aslocal_tempfile) {
4267 # if we got it exactly as we asked for, only then we
4269 rename $aslocal_tempfile, $aslocal
4270 or $CPAN::Frontend->mydie("Error while trying to rename ".
4271 "'$ret' to '$aslocal': $!");
4274 $Themethod = $level;
4276 # utime $now, $now, $aslocal; # too bad, if we do that, we
4277 # might alter a local mirror
4278 $self->debug("level[$level]") if $CPAN::DEBUG;
4281 unlink $aslocal_tempfile;
4282 last if $CPAN::Signal; # need to cleanup
4286 $stats->{filesize} = -s $ret;
4288 $self->debug("before _add_to_statistics") if $CPAN::DEBUG;
4289 $self->_add_to_statistics($stats);
4290 $self->debug("after _add_to_statistics") if $CPAN::DEBUG;
4292 unlink "$aslocal.bak$$";
4295 unless ($CPAN::Signal) {
4298 if (@{$CPAN::Config->{urllist}}) {
4300 qq{Please check, if the URLs I found in your configuration file \(}.
4301 join(", ", @{$CPAN::Config->{urllist}}).
4304 push @mess, qq{Your urllist is empty!};
4306 push @mess, qq{The urllist can be edited.},
4307 qq{E.g. with 'o conf urllist push ftp://myurl/'};
4308 $CPAN::Frontend->mywarn(Text::Wrap::wrap("","","@mess"). "\n\n");
4309 $CPAN::Frontend->mywarn("Could not fetch $file\n");
4310 $CPAN::Frontend->mysleep(2);
4312 if ($maybe_restore) {
4313 rename "$aslocal.bak$$", $aslocal;
4314 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
4315 $self->ls($aslocal));
4322 my($self, $aslocal_dir) = @_;
4323 File::Path::mkpath($aslocal_dir);
4324 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
4325 qq{directory "$aslocal_dir".
4326 I\'ll continue, but if you encounter problems, they may be due
4327 to insufficient permissions.\n}) unless -w $aslocal_dir;
4335 $h = [ grep /^\Q$scheme\E:/, @$h ] if $scheme;
4336 my $method = "host$level";
4337 $self->$method($h, @_);
4341 my($self,$stats,$method,$url) = @_;
4342 push @{$stats->{attempts}}, {
4349 # package CPAN::FTP;
4351 my($self,$host_seq,$file,$aslocal,$stats) = @_;
4353 HOSTEASY: for $ro_url (@$host_seq) {
4354 $self->_set_attempt($stats,"dleasy",$ro_url);
4355 my $url .= "$ro_url$file";
4356 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
4357 if ($url =~ /^file:/) {
4359 if ($CPAN::META->has_inst('URI::URL')) {
4360 my $u = URI::URL->new($url);
4362 } else { # works only on Unix, is poorly constructed, but
4363 # hopefully better than nothing.
4364 # RFC 1738 says fileurl BNF is
4365 # fileurl = "file://" [ host | "localhost" ] "/" fpath
4366 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
4368 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
4369 $l =~ s|^file:||; # assume they
4373 if ! -f $l && $l =~ m|^/\w:|; # e.g. /P:
4375 $self->debug("local file[$l]") if $CPAN::DEBUG;
4376 if ( -f $l && -r _) {
4377 $ThesiteURL = $ro_url;
4380 if ($l =~ /(.+)\.gz$/) {
4382 if ( -f $ungz && -r _) {
4383 $ThesiteURL = $ro_url;
4387 # Maybe mirror has compressed it?
4389 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
4390 eval { CPAN::Tarzip->new("$l.gz")->gunzip($aslocal) };
4392 $ThesiteURL = $ro_url;
4396 $CPAN::Frontend->mywarn("Could not find '$l'\n");
4398 $self->debug("it was not a file URL") if $CPAN::DEBUG;
4399 if ($CPAN::META->has_usable('LWP')) {
4400 $CPAN::Frontend->myprint("Fetching with LWP:
4404 CPAN::LWP::UserAgent->config;
4405 eval { $Ua = CPAN::LWP::UserAgent->new; };
4407 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n");
4410 my $res = $Ua->mirror($url, $aslocal);
4411 if ($res->is_success) {
4412 $ThesiteURL = $ro_url;
4414 utime $now, $now, $aslocal; # download time is more
4415 # important than upload
4418 } elsif ($url !~ /\.gz(?!\n)\Z/) {
4419 my $gzurl = "$url.gz";
4420 $CPAN::Frontend->myprint("Fetching with LWP:
4423 $res = $Ua->mirror($gzurl, "$aslocal.gz");
4424 if ($res->is_success) {
4425 if (eval {CPAN::Tarzip->new("$aslocal.gz")->gunzip($aslocal)}) {
4426 $ThesiteURL = $ro_url;
4431 $CPAN::Frontend->myprint(sprintf(
4432 "LWP failed with code[%s] message[%s]\n",
4436 # Alan Burlison informed me that in firewall environments
4437 # Net::FTP can still succeed where LWP fails. So we do not
4438 # skip Net::FTP anymore when LWP is available.
4441 $CPAN::Frontend->mywarn(" LWP not available\n");
4443 return if $CPAN::Signal;
4444 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
4445 # that's the nice and easy way thanks to Graham
4446 $self->debug("recognized ftp") if $CPAN::DEBUG;
4447 my($host,$dir,$getfile) = ($1,$2,$3);
4448 if ($CPAN::META->has_usable('Net::FTP')) {
4450 $CPAN::Frontend->myprint("Fetching with Net::FTP:
4453 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
4454 "aslocal[$aslocal]") if $CPAN::DEBUG;
4455 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
4456 $ThesiteURL = $ro_url;
4459 if ($aslocal !~ /\.gz(?!\n)\Z/) {
4460 my $gz = "$aslocal.gz";
4461 $CPAN::Frontend->myprint("Fetching with Net::FTP
4464 if (CPAN::FTP->ftp_get($host,
4468 eval{CPAN::Tarzip->new($gz)->gunzip($aslocal)}
4470 $ThesiteURL = $ro_url;
4476 CPAN->debug("Net::FTP does not count as usable atm") if $CPAN::DEBUG;
4480 UNIVERSAL::can($ro_url,"text")
4482 $ro_url->{FROM} eq "USER"
4484 ##address #17973: default URLs should not try to override
4485 ##user-defined URLs just because LWP is not available
4486 my $ret = $self->hostdlhard([$ro_url],$file,$aslocal,$stats);
4487 return $ret if $ret;
4489 return if $CPAN::Signal;
4493 # package CPAN::FTP;
4495 my($self,$host_seq,$file,$aslocal,$stats) = @_;
4497 # Came back if Net::FTP couldn't establish connection (or
4498 # failed otherwise) Maybe they are behind a firewall, but they
4499 # gave us a socksified (or other) ftp program...
4502 my($devnull) = $CPAN::Config->{devnull} || "";
4504 my($aslocal_dir) = File::Basename::dirname($aslocal);
4505 File::Path::mkpath($aslocal_dir);
4506 HOSTHARD: for $ro_url (@$host_seq) {
4507 $self->_set_attempt($stats,"dlhard",$ro_url);
4508 my $url = "$ro_url$file";
4509 my($proto,$host,$dir,$getfile);
4511 # Courtesy Mark Conty mark_conty@cargill.com change from
4512 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
4514 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
4515 # proto not yet used
4516 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
4518 next HOSTHARD; # who said, we could ftp anything except ftp?
4520 next HOSTHARD if $proto eq "file"; # file URLs would have had
4521 # success above. Likely a bogus URL
4523 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
4525 # Try the most capable first and leave ncftp* for last as it only
4527 my $proxy_vars = $self->_proxy_vars($ro_url);
4528 DLPRG: for my $f (qw(curl wget lynx ncftpget ncftp)) {
4529 my $funkyftp = CPAN::HandleConfig->safe_quote($CPAN::Config->{$f});
4530 next unless defined $funkyftp;
4531 next if $funkyftp =~ /^\s*$/;
4533 my($asl_ungz, $asl_gz);
4534 ($asl_ungz = $aslocal) =~ s/\.gz//;
4535 $asl_gz = "$asl_ungz.gz";
4537 my($src_switch) = "";
4539 my($stdout_redir) = " > $asl_ungz";
4541 $src_switch = " -source";
4542 } elsif ($f eq "ncftp") {
4543 $src_switch = " -c";
4544 } elsif ($f eq "wget") {
4545 $src_switch = " -O $asl_ungz";
4547 } elsif ($f eq 'curl') {
4548 $src_switch = ' -L -f -s -S --netrc-optional';
4549 if ($proxy_vars->{http_proxy}) {
4550 $src_switch .= qq{ -U "$proxy_vars->{proxy_user}:$proxy_vars->{proxy_pass}" -x "$proxy_vars->{http_proxy}"};
4554 if ($f eq "ncftpget") {
4555 $chdir = "cd $aslocal_dir && ";
4558 $CPAN::Frontend->myprint(
4560 Trying with "$funkyftp$src_switch" to get
4564 "$chdir$funkyftp$src_switch \"$url\" $devnull$stdout_redir";
4565 $self->debug("system[$system]") if $CPAN::DEBUG;
4566 my($wstatus) = system($system);
4568 # lynx returns 0 when it fails somewhere
4570 my $content = do { local *FH;
4571 open FH, $asl_ungz or die;
4574 if ($content =~ /^<.*(<title>[45]|Error [45])/si) {
4575 $CPAN::Frontend->mywarn(qq{
4576 No success, the file that lynx has downloaded looks like an error message:
4579 $CPAN::Frontend->mysleep(1);
4583 $CPAN::Frontend->myprint(qq{
4584 No success, the file that lynx has downloaded is an empty file.
4589 if ($wstatus == 0) {
4592 } elsif ($asl_ungz ne $aslocal) {
4593 # test gzip integrity
4594 if (eval{CPAN::Tarzip->new($asl_ungz)->gtest}) {
4595 # e.g. foo.tar is gzipped --> foo.tar.gz
4596 rename $asl_ungz, $aslocal;
4598 eval{CPAN::Tarzip->new($asl_gz)->gzip($asl_ungz)};
4601 $ThesiteURL = $ro_url;
4603 } elsif ($url !~ /\.gz(?!\n)\Z/) {
4605 -f $asl_ungz && -s _ == 0;
4606 my $gz = "$aslocal.gz";
4607 my $gzurl = "$url.gz";
4608 $CPAN::Frontend->myprint(
4610 Trying with "$funkyftp$src_switch" to get
4613 my($system) = "$funkyftp$src_switch \"$url.gz\" $devnull > $asl_gz";
4614 $self->debug("system[$system]") if $CPAN::DEBUG;
4616 if (($wstatus = system($system)) == 0
4620 # test gzip integrity
4621 my $ct = eval{CPAN::Tarzip->new($asl_gz)};
4622 if ($ct && $ct->gtest) {
4623 $ct->gunzip($aslocal);
4625 # somebody uncompressed file for us?
4626 rename $asl_ungz, $aslocal;
4628 $ThesiteURL = $ro_url;
4631 unlink $asl_gz if -f $asl_gz;
4634 my $estatus = $wstatus >> 8;
4635 my $size = -f $aslocal ?
4636 ", left\n$aslocal with size ".-s _ :
4637 "\nWarning: expected file [$aslocal] doesn't exist";
4638 $CPAN::Frontend->myprint(qq{
4639 System call "$system"
4640 returned status $estatus (wstat $wstatus)$size
4643 return if $CPAN::Signal;
4644 } # transfer programs
4648 #-> CPAN::FTP::_proxy_vars
4650 my($self,$url) = @_;
4652 my $http_proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
4654 my($host) = $url =~ m|://([^/:]+)|;
4656 my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'} || "";
4657 my @noproxy = split /\s*,\s*/, $noproxy;
4659 DOMAIN: for my $domain (@noproxy) {
4660 if ($host =~ /\Q$domain\E$/) { # cf. LWP::UserAgent
4666 $CPAN::Frontend->mywarn(" Could not determine host from http_proxy '$http_proxy'\n");
4670 &CPAN::LWP::UserAgent::get_proxy_credentials();
4672 proxy_user => $user,
4673 proxy_pass => $pass,
4674 http_proxy => $http_proxy
4681 # package CPAN::FTP;
4683 my($self,$host_seq,$file,$aslocal,$stats) = @_;
4685 return unless @$host_seq;
4687 my($aslocal_dir) = File::Basename::dirname($aslocal);
4688 File::Path::mkpath($aslocal_dir);
4689 my $ftpbin = $CPAN::Config->{ftp};
4690 unless ($ftpbin && length $ftpbin && MM->maybe_command($ftpbin)) {
4691 $CPAN::Frontend->myprint("No external ftp command available\n\n");
4694 $CPAN::Frontend->mywarn(qq{
4695 As a last ressort we now switch to the external ftp command '$ftpbin'
4698 Doing so often leads to problems that are hard to diagnose.
4700 If you're victim of such problems, please consider unsetting the ftp
4701 config variable with
4707 $CPAN::Frontend->mysleep(2);
4708 HOSTHARDEST: for $ro_url (@$host_seq) {
4709 $self->_set_attempt($stats,"dlhardest",$ro_url);
4710 my $url = "$ro_url$file";
4711 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
4712 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
4715 my($host,$dir,$getfile) = ($1,$2,$3);
4717 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
4718 $ctime,$blksize,$blocks) = stat($aslocal);
4719 $timestamp = $mtime ||= 0;
4720 my($netrc) = CPAN::FTP::netrc->new;
4721 my($netrcfile) = $netrc->netrc;
4722 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
4723 my $targetfile = File::Basename::basename($aslocal);
4729 map("cd $_", split /\//, $dir), # RFC 1738
4731 "get $getfile $targetfile",
4735 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
4736 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
4737 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
4739 $netrc->contains($host))) if $CPAN::DEBUG;
4740 if ($netrc->protected) {
4741 my $dialog = join "", map { " $_\n" } @dialog;
4743 if ($netrc->contains($host)) {
4744 $netrc_explain = "Relying that your .netrc entry for '$host' ".
4745 "manages the login";
4747 $netrc_explain = "Relying that your default .netrc entry ".
4748 "manages the login";
4750 $CPAN::Frontend->myprint(qq{
4751 Trying with external ftp to get
4754 Going to send the dialog
4758 $self->talk_ftp("$ftpbin$verbose $host",
4760 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
4761 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
4763 if ($mtime > $timestamp) {
4764 $CPAN::Frontend->myprint("GOT $aslocal\n");
4765 $ThesiteURL = $ro_url;
4768 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
4770 return if $CPAN::Signal;
4772 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
4773 qq{correctly protected.\n});
4776 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
4777 nor does it have a default entry\n");
4780 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
4781 # then and login manually to host, using e-mail as
4783 $CPAN::Frontend->myprint(qq{Issuing "$ftpbin$verbose -n"\n});
4787 "user anonymous $Config::Config{'cf_email'}"
4789 my $dialog = join "", map { " $_\n" } @dialog;
4790 $CPAN::Frontend->myprint(qq{
4791 Trying with external ftp to get
4793 Going to send the dialog
4797 $self->talk_ftp("$ftpbin$verbose -n", @dialog);
4798 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
4799 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
4801 if ($mtime > $timestamp) {
4802 $CPAN::Frontend->myprint("GOT $aslocal\n");
4803 $ThesiteURL = $ro_url;
4806 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
4808 return if $CPAN::Signal;
4809 $CPAN::Frontend->mywarn("Can't access URL $url.\n\n");
4810 $CPAN::Frontend->mysleep(2);
4814 # package CPAN::FTP;
4816 my($self,$command,@dialog) = @_;
4817 my $fh = FileHandle->new;
4818 $fh->open("|$command") or die "Couldn't open ftp: $!";
4819 foreach (@dialog) { $fh->print("$_\n") }
4820 $fh->close; # Wait for process to complete
4822 my $estatus = $wstatus >> 8;
4823 $CPAN::Frontend->myprint(qq{
4824 Subprocess "|$command"
4825 returned status $estatus (wstat $wstatus)
4829 # find2perl needs modularization, too, all the following is stolen
4833 my($self,$name) = @_;
4834 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
4835 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
4837 my($perms,%user,%group);
4841 $blocks = int(($blocks + 1) / 2);
4844 $blocks = int(($sizemm + 1023) / 1024);
4847 if (-f _) { $perms = '-'; }
4848 elsif (-d _) { $perms = 'd'; }
4849 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
4850 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
4851 elsif (-p _) { $perms = 'p'; }
4852 elsif (-S _) { $perms = 's'; }
4853 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
4855 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
4856 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
4857 my $tmpmode = $mode;
4858 my $tmp = $rwx[$tmpmode & 7];
4860 $tmp = $rwx[$tmpmode & 7] . $tmp;
4862 $tmp = $rwx[$tmpmode & 7] . $tmp;
4863 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
4864 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
4865 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
4868 my $user = $user{$uid} || $uid; # too lazy to implement lookup
4869 my $group = $group{$gid} || $gid;
4871 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
4873 my($moname) = $moname[$mon];
4874 if (-M _ > 365.25 / 2) {
4875 $timeyear = $year + 1900;
4878 $timeyear = sprintf("%02d:%02d", $hour, $min);
4881 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
4895 package CPAN::FTP::netrc;
4898 # package CPAN::FTP::netrc;
4901 my $home = CPAN::HandleConfig::home;
4902 my $file = File::Spec->catfile($home,".netrc");
4904 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
4905 $atime,$mtime,$ctime,$blksize,$blocks)
4910 my($fh,@machines,$hasdefault);
4912 $fh = FileHandle->new or die "Could not create a filehandle";
4914 if($fh->open($file)) {
4915 $protected = ($mode & 077) == 0;
4917 NETRC: while (<$fh>) {
4918 my(@tokens) = split " ", $_;
4919 TOKEN: while (@tokens) {
4920 my($t) = shift @tokens;
4921 if ($t eq "default") {
4925 last TOKEN if $t eq "macdef";
4926 if ($t eq "machine") {
4927 push @machines, shift @tokens;
4932 $file = $hasdefault = $protected = "";
4936 'mach' => [@machines],
4938 'hasdefault' => $hasdefault,
4939 'protected' => $protected,
4943 # CPAN::FTP::netrc::hasdefault;
4944 sub hasdefault { shift->{'hasdefault'} }
4945 sub netrc { shift->{'netrc'} }
4946 sub protected { shift->{'protected'} }
4948 my($self,$mach) = @_;
4949 for ( @{$self->{'mach'}} ) {
4950 return 1 if $_ eq $mach;
4955 package CPAN::Complete;
4959 my($text, $line, $start, $end) = @_;
4960 my(@perlret) = cpl($text, $line, $start);
4961 # find longest common match. Can anybody show me how to peruse
4962 # T::R::Gnu to have this done automatically? Seems expensive.
4963 return () unless @perlret;
4964 my($newtext) = $text;
4965 for (my $i = length($text)+1;;$i++) {
4966 last unless length($perlret[0]) && length($perlret[0]) >= $i;
4967 my $try = substr($perlret[0],0,$i);
4968 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
4969 # warn "try[$try]tries[@tries]";
4970 if (@tries == @perlret) {
4976 ($newtext,@perlret);
4979 #-> sub CPAN::Complete::cpl ;
4981 my($word,$line,$pos) = @_;
4985 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
4987 if ($line =~ s/^((?:notest|f?force)\s*)//) {
4991 if ($pos == 0 || $line =~ /^(?:h(?:elp)?|\?)\s/) {
4992 @return = grep /^\Q$word\E/, @CPAN::Complete::COMMANDS;
4993 } elsif ( $line !~ /^[\!abcdghimorutl]/ ) {
4995 } elsif ($line =~ /^(a|ls)\s/) {
4996 @return = cplx('CPAN::Author',uc($word));
4997 } elsif ($line =~ /^b\s/) {
4998 CPAN::Shell->local_bundles;
4999 @return = cplx('CPAN::Bundle',$word);
5000 } elsif ($line =~ /^d\s/) {
5001 @return = cplx('CPAN::Distribution',$word);
5002 } elsif ($line =~ m/^(
5003 [mru]|make|clean|dump|get|test|install|readme|look|cvs_import|perldoc|recent
5005 if ($word =~ /^Bundle::/) {
5006 CPAN::Shell->local_bundles;
5008 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
5009 } elsif ($line =~ /^i\s/) {
5010 @return = cpl_any($word);
5011 } elsif ($line =~ /^reload\s/) {
5012 @return = cpl_reload($word,$line,$pos);
5013 } elsif ($line =~ /^o\s/) {
5014 @return = cpl_option($word,$line,$pos);
5015 } elsif ($line =~ m/^\S+\s/ ) {
5016 # fallback for future commands and what we have forgotten above
5017 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
5024 #-> sub CPAN::Complete::cplx ;
5026 my($class, $word) = @_;
5027 if (CPAN::_sqlite_running) {
5028 $CPAN::SQLite->search($class, "^\Q$word\E");
5030 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
5033 #-> sub CPAN::Complete::cpl_any ;
5037 cplx('CPAN::Author',$word),
5038 cplx('CPAN::Bundle',$word),
5039 cplx('CPAN::Distribution',$word),
5040 cplx('CPAN::Module',$word),
5044 #-> sub CPAN::Complete::cpl_reload ;
5046 my($word,$line,$pos) = @_;
5048 my(@words) = split " ", $line;
5049 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
5050 my(@ok) = qw(cpan index);
5051 return @ok if @words == 1;
5052 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
5055 #-> sub CPAN::Complete::cpl_option ;
5057 my($word,$line,$pos) = @_;
5059 my(@words) = split " ", $line;
5060 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
5061 my(@ok) = qw(conf debug);
5062 return @ok if @words == 1;
5063 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
5065 } elsif ($words[1] eq 'index') {
5067 } elsif ($words[1] eq 'conf') {
5068 return CPAN::HandleConfig::cpl(@_);
5069 } elsif ($words[1] eq 'debug') {
5070 return sort grep /^\Q$word\E/i,
5071 sort keys %CPAN::DEBUG, 'all';
5075 package CPAN::Index;
5078 #-> sub CPAN::Index::force_reload ;
5081 $CPAN::Index::LAST_TIME = 0;
5085 #-> sub CPAN::Index::reload ;
5087 my($self,$force) = @_;
5090 # XXX check if a newer one is available. (We currently read it
5091 # from time to time)
5092 for ($CPAN::Config->{index_expire}) {
5093 $_ = 0.001 unless $_ && $_ > 0.001;
5095 unless (1 || $CPAN::Have_warned->{readmetadatacache}++) {
5096 # debug here when CPAN doesn't seem to read the Metadata
5098 Carp::cluck("META-PROTOCOL[$CPAN::META->{PROTOCOL}]");
5100 unless ($CPAN::META->{PROTOCOL}) {
5101 $self->read_metadata_cache;
5102 $CPAN::META->{PROTOCOL} ||= "1.0";
5104 if ( $CPAN::META->{PROTOCOL} < PROTOCOL ) {
5105 # warn "Setting last_time to 0";
5106 $LAST_TIME = 0; # No warning necessary
5108 if ($LAST_TIME + $CPAN::Config->{index_expire}*86400 > $time
5111 # CPAN->debug("LAST_TIME[$LAST_TIME]index_expire[$CPAN::Config->{index_expire}]time[$time]");
5113 # IFF we are developing, it helps to wipe out the memory
5114 # between reloads, otherwise it is not what a user expects.
5115 undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
5116 $CPAN::META = CPAN->new;
5119 local $LAST_TIME = $time;
5120 local $CPAN::META->{PROTOCOL} = PROTOCOL;
5122 my $needshort = $^O eq "dos";
5124 $self->rd_authindex($self
5126 "authors/01mailrc.txt.gz",
5128 File::Spec->catfile('authors', '01mailrc.gz') :
5129 File::Spec->catfile('authors', '01mailrc.txt.gz'),
5132 $debug = "timing reading 01[".($t2 - $time)."]";
5134 return if $CPAN::Signal; # this is sometimes lengthy
5135 $self->rd_modpacks($self
5137 "modules/02packages.details.txt.gz",
5139 File::Spec->catfile('modules', '02packag.gz') :
5140 File::Spec->catfile('modules', '02packages.details.txt.gz'),
5143 $debug .= "02[".($t2 - $time)."]";
5145 return if $CPAN::Signal; # this is sometimes lengthy
5146 $self->rd_modlist($self
5148 "modules/03modlist.data.gz",
5150 File::Spec->catfile('modules', '03mlist.gz') :
5151 File::Spec->catfile('modules', '03modlist.data.gz'),
5153 $self->write_metadata_cache;
5155 $debug .= "03[".($t2 - $time)."]";
5157 CPAN->debug($debug) if $CPAN::DEBUG;
5159 if ($CPAN::Config->{build_dir_reuse}) {
5160 $self->reanimate_build_dir;
5162 if (CPAN::_sqlite_running) {
5163 $CPAN::SQLite->reload(time => $time, force => $force)
5167 $CPAN::META->{PROTOCOL} = PROTOCOL;
5170 #-> sub CPAN::Index::reanimate_build_dir ;
5171 sub reanimate_build_dir {
5173 unless ($CPAN::META->has_inst($CPAN::Config->{yaml_module}||"YAML")) {
5176 return if $HAVE_REANIMATED++;
5177 my $d = $CPAN::Config->{build_dir};
5178 my $dh = DirHandle->new;
5179 opendir $dh, $d or return; # does not exist
5184 my @candidates = map { $_->[0] }
5185 sort { $b->[1] <=> $a->[1] }
5186 map { [ $_, -M File::Spec->catfile($d,$_) ] }
5187 grep {/\.yml$/} readdir $dh;
5188 unless (@candidates) {
5189 $CPAN::Frontend->myprint("Build_dir empty, nothing to restore\n");
5192 $CPAN::Frontend->myprint
5193 (sprintf("Going to read %d yaml file%s from %s/\n",
5195 @candidates==1 ? "" : "s",
5196 $CPAN::Config->{build_dir}
5198 my $start = CPAN::FTP::_mytime;
5199 DISTRO: for $i (0..$#candidates) {
5200 my $dirent = $candidates[$i];
5201 my $y = eval {CPAN->_yaml_loadfile(File::Spec->catfile($d,$dirent))};
5203 warn "Error while parsing file '$dirent'; error: '$@'";
5207 if ($c && CPAN->_perl_fingerprint($c->{perl})) {
5208 my $key = $c->{distribution}{ID};
5209 for my $k (keys %{$c->{distribution}}) {
5210 if ($c->{distribution}{$k}
5211 && ref $c->{distribution}{$k}
5212 && UNIVERSAL::isa($c->{distribution}{$k},"CPAN::Distrostatus")) {
5213 $c->{distribution}{$k}{COMMANDID} = $i - @candidates;
5217 #we tried to restore only if element already
5218 #exists; but then we do not work with metadata
5221 = $CPAN::META->{readwrite}{'CPAN::Distribution'}{$key}
5222 = $c->{distribution};
5223 for my $skipper (qw(
5225 configure_requires_later
5226 configure_requires_later_for
5234 negative_prefs_cache
5236 delete $do->{$skipper};
5238 if ($do->tested_ok_but_not_installed) {
5239 $CPAN::META->is_tested($do->{build_dir},$do->{make_test}{TIME});
5244 while (($painted/76) < ($i/@candidates)) {
5245 $CPAN::Frontend->myprint(".");
5249 my $took = CPAN::FTP::_mytime - $start;
5250 $CPAN::Frontend->myprint(sprintf(
5251 "DONE\nRestored the state of %s (in %.4f secs)\n",
5252 $restored || "none",
5258 #-> sub CPAN::Index::reload_x ;
5260 my($cl,$wanted,$localname,$force) = @_;
5261 $force |= 2; # means we're dealing with an index here
5262 CPAN::HandleConfig->load; # we should guarantee loading wherever
5263 # we rely on Config XXX
5264 $localname ||= $wanted;
5265 my $abs_wanted = File::Spec->catfile($CPAN::Config->{'keep_source_where'},
5269 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
5272 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
5273 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
5274 qq{day$s. I\'ll use that.});
5277 $force |= 1; # means we're quite serious about it.
5279 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
5282 #-> sub CPAN::Index::rd_authindex ;
5284 my($cl, $index_target) = @_;
5285 return unless defined $index_target;
5286 return if CPAN::_sqlite_running;
5288 $CPAN::Frontend->myprint("Going to read $index_target\n");
5290 tie *FH, 'CPAN::Tarzip', $index_target;
5293 push @lines, split /\012/ while <FH>;
5297 my($userid,$fullname,$email) =
5298 m/alias\s+(\S+)\s+\"([^\"\<]*)\s+\<(.*)\>\"/;
5299 $fullname ||= $email;
5300 if ($userid && $fullname && $email) {
5301 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
5302 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
5304 CPAN->debug(sprintf "line[%s]", $_) if $CPAN::DEBUG;
5307 while (($painted/76) < ($i/@lines)) {
5308 $CPAN::Frontend->myprint(".");
5311 return if $CPAN::Signal;
5313 $CPAN::Frontend->myprint("DONE\n");
5317 my($self,$dist) = @_;
5318 $dist = $self->{'id'} unless defined $dist;
5319 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
5323 #-> sub CPAN::Index::rd_modpacks ;
5325 my($self, $index_target) = @_;
5326 return unless defined $index_target;
5327 return if CPAN::_sqlite_running;
5328 $CPAN::Frontend->myprint("Going to read $index_target\n");
5329 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
5331 CPAN->debug(sprintf "start[%d]", time) if $CPAN::DEBUG;
5334 while (my $bytes = $fh->READ(\$chunk,8192)) {
5337 my @lines = split /\012/, $slurp;
5338 CPAN->debug(sprintf "end[%d]", time) if $CPAN::DEBUG;
5341 my($line_count,$last_updated);
5343 my $shift = shift(@lines);
5344 last if $shift =~ /^\s*$/;
5345 $shift =~ /^Line-Count:\s+(\d+)/ and $line_count = $1;
5346 $shift =~ /^Last-Updated:\s+(.+)/ and $last_updated = $1;
5348 CPAN->debug("line_count[$line_count]last_updated[$last_updated]") if $CPAN::DEBUG;
5349 if (not defined $line_count) {
5351 $CPAN::Frontend->mywarn(qq{Warning: Your $index_target does not contain a Line-Count header.
5352 Please check the validity of the index file by comparing it to more
5353 than one CPAN mirror. I'll continue but problems seem likely to
5357 $CPAN::Frontend->mysleep(5);
5358 } elsif ($line_count != scalar @lines) {
5360 $CPAN::Frontend->mywarn(sprintf qq{Warning: Your %s
5361 contains a Line-Count header of %d but I see %d lines there. Please
5362 check the validity of the index file by comparing it to more than one
5363 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
5364 $index_target, $line_count, scalar(@lines));
5367 if (not defined $last_updated) {
5369 $CPAN::Frontend->mywarn(qq{Warning: Your $index_target does not contain a Last-Updated header.
5370 Please check the validity of the index file by comparing it to more
5371 than one CPAN mirror. I'll continue but problems seem likely to
5375 $CPAN::Frontend->mysleep(5);
5379 ->myprint(sprintf qq{ Database was generated on %s\n},
5381 $DATE_OF_02 = $last_updated;
5384 if ($CPAN::META->has_inst('HTTP::Date')) {
5386 $age -= HTTP::Date::str2time($last_updated);
5388 $CPAN::Frontend->mywarn(" HTTP::Date not available\n");
5389 require Time::Local;
5390 my(@d) = $last_updated =~ / (\d+) (\w+) (\d+) (\d+):(\d+):(\d+) /;
5391 $d[1] = index("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", $d[1])/4;
5392 $age -= $d[1]>=0 ? Time::Local::timegm(@d[5,4,3,0,1,2]) : 0;
5399 qq{Warning: This index file is %d days old.
5400 Please check the host you chose as your CPAN mirror for staleness.
5401 I'll continue but problems seem likely to happen.\a\n},
5404 } elsif ($age < -1) {
5408 qq{Warning: Your system date is %d days behind this index file!
5410 Timestamp index file: %s
5411 Please fix your system time, problems with the make command expected.\n},
5421 # A necessity since we have metadata_cache: delete what isn't
5423 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
5424 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
5429 # before 1.56 we split into 3 and discarded the rest. From
5430 # 1.57 we assign remaining text to $comment thus allowing to
5431 # influence isa_perl
5432 my($mod,$version,$dist,$comment) = split " ", $_, 4;
5433 unless ($mod && defined $version && $dist) {
5434 $CPAN::Frontend->mywarn("Could not split line[$_]\n");
5437 my($bundle,$id,$userid);
5439 if ($mod eq 'CPAN' &&
5441 CPAN::Queue->exists('Bundle::CPAN') ||
5442 CPAN::Queue->exists('CPAN')
5446 if ($version > $CPAN::VERSION) {
5447 $CPAN::Frontend->mywarn(qq{
5448 New CPAN.pm version (v$version) available.
5449 [Currently running version is v$CPAN::VERSION]
5450 You might want to try
5453 to both upgrade CPAN.pm and run the new version without leaving
5454 the current session.
5457 $CPAN::Frontend->mysleep(2);
5458 $CPAN::Frontend->myprint(qq{\n});
5460 last if $CPAN::Signal;
5461 } elsif ($mod =~ /^Bundle::(.*)/) {
5466 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
5467 # Let's make it a module too, because bundles have so much
5468 # in common with modules.
5470 # Changed in 1.57_63: seems like memory bloat now without
5471 # any value, so commented out
5473 # $CPAN::META->instance('CPAN::Module',$mod);
5477 # instantiate a module object
5478 $id = $CPAN::META->instance('CPAN::Module',$mod);
5482 # Although CPAN prohibits same name with different version the
5483 # indexer may have changed the version for the same distro
5484 # since the last time ("Force Reindexing" feature)
5485 if ($id->cpan_file ne $dist
5487 $id->cpan_version ne $version
5489 $userid = $id->userid || $self->userid($dist);
5491 'CPAN_USERID' => $userid,
5492 'CPAN_VERSION' => $version,
5493 'CPAN_FILE' => $dist,
5497 # instantiate a distribution object
5498 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
5499 # we do not need CONTAINSMODS unless we do something with
5500 # this dist, so we better produce it on demand.
5502 ## my $obj = $CPAN::META->instance(
5503 ## 'CPAN::Distribution' => $dist
5505 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
5507 $CPAN::META->instance(
5508 'CPAN::Distribution' => $dist
5510 'CPAN_USERID' => $userid,
5511 'CPAN_COMMENT' => $comment,
5515 for my $name ($mod,$dist) {
5516 # $self->debug("exists name[$name]") if $CPAN::DEBUG;
5517 $exists{$name} = undef;
5521 while (($painted/76) < ($i/@lines)) {
5522 $CPAN::Frontend->myprint(".");
5525 return if $CPAN::Signal;
5527 $CPAN::Frontend->myprint("DONE\n");
5529 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
5530 for my $o ($CPAN::META->all_objects($class)) {
5531 next if exists $exists{$o->{ID}};
5532 $CPAN::META->delete($class,$o->{ID});
5533 # CPAN->debug("deleting ID[$o->{ID}] in class[$class]")
5540 #-> sub CPAN::Index::rd_modlist ;
5542 my($cl,$index_target) = @_;
5543 return unless defined $index_target;
5544 return if CPAN::_sqlite_running;
5545 $CPAN::Frontend->myprint("Going to read $index_target\n");
5546 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
5550 while (my $bytes = $fh->READ(\$chunk,8192)) {
5553 my @eval2 = split /\012/, $slurp;
5556 my $shift = shift(@eval2);
5557 if ($shift =~ /^Date:\s+(.*)/) {
5558 if ($DATE_OF_03 eq $1) {
5559 $CPAN::Frontend->myprint("Unchanged.\n");
5564 last if $shift =~ /^\s*$/;
5566 push @eval2, q{CPAN::Modulelist->data;};
5568 my($compmt) = Safe->new("CPAN::Safe1");
5569 my($eval2) = join("\n", @eval2);
5570 CPAN->debug(sprintf "length of eval2[%d]", length $eval2) if $CPAN::DEBUG;
5571 my $ret = $compmt->reval($eval2);
5572 Carp::confess($@) if $@;
5573 return if $CPAN::Signal;
5575 my $until = keys(%$ret);
5577 CPAN->debug(sprintf "until[%d]", $until) if $CPAN::DEBUG;
5579 my $obj = $CPAN::META->instance("CPAN::Module",$_);
5580 delete $ret->{$_}{modid}; # not needed here, maybe elsewhere
5581 $obj->set(%{$ret->{$_}});
5583 while (($painted/76) < ($i/$until)) {
5584 $CPAN::Frontend->myprint(".");
5587 return if $CPAN::Signal;
5589 $CPAN::Frontend->myprint("DONE\n");
5592 #-> sub CPAN::Index::write_metadata_cache ;
5593 sub write_metadata_cache {
5595 return unless $CPAN::Config->{'cache_metadata'};
5596 return if CPAN::_sqlite_running;
5597 return unless $CPAN::META->has_usable("Storable");
5599 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
5600 CPAN::Distribution)) {
5601 $cache->{$k} = $CPAN::META->{readonly}{$k}; # unsafe meta access, ok
5603 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
5604 $cache->{last_time} = $LAST_TIME;
5605 $cache->{DATE_OF_02} = $DATE_OF_02;
5606 $cache->{PROTOCOL} = PROTOCOL;
5607 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
5608 eval { Storable::nstore($cache, $metadata_file) };
5609 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
5612 #-> sub CPAN::Index::read_metadata_cache ;
5613 sub read_metadata_cache {
5615 return unless $CPAN::Config->{'cache_metadata'};
5616 return if CPAN::_sqlite_running;
5617 return unless $CPAN::META->has_usable("Storable");
5618 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
5619 return unless -r $metadata_file and -f $metadata_file;
5620 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
5622 eval { $cache = Storable::retrieve($metadata_file) };
5623 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
5624 if (!$cache || !UNIVERSAL::isa($cache, 'HASH')) {
5628 if (exists $cache->{PROTOCOL}) {
5629 if (PROTOCOL > $cache->{PROTOCOL}) {
5630 $CPAN::Frontend->mywarn(sprintf("Ignoring Metadata cache written ".
5631 "with protocol v%s, requiring v%s\n",
5638 $CPAN::Frontend->mywarn("Ignoring Metadata cache written ".
5639 "with protocol v1.0\n");
5644 while(my($class,$v) = each %$cache) {
5645 next unless $class =~ /^CPAN::/;
5646 $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok
5647 while (my($id,$ro) = each %$v) {
5648 $CPAN::META->{readwrite}{$class}{$id} ||=
5649 $class->new(ID=>$id, RO=>$ro);
5654 unless ($clcnt) { # sanity check
5655 $CPAN::Frontend->myprint("Warning: Found no data in $metadata_file\n");
5658 if ($idcnt < 1000) {
5659 $CPAN::Frontend->myprint("Warning: Found only $idcnt objects ".
5660 "in $metadata_file\n");
5663 $CPAN::META->{PROTOCOL} ||=
5664 $cache->{PROTOCOL}; # reading does not up or downgrade, but it
5665 # does initialize to some protocol
5666 $LAST_TIME = $cache->{last_time};
5667 $DATE_OF_02 = $cache->{DATE_OF_02};
5668 $CPAN::Frontend->myprint(" Database was generated on $DATE_OF_02\n")
5669 if defined $DATE_OF_02; # An old cache may not contain DATE_OF_02
5673 package CPAN::InfoObj;
5679 exists $self->{RO} and return $self->{RO};
5682 #-> sub CPAN::InfoObj::cpan_userid
5687 return $ro->{CPAN_USERID} || "N/A";
5689 $self->debug("ID[$self->{ID}]");
5690 # N/A for bundles found locally
5695 sub id { shift->{ID}; }
5697 #-> sub CPAN::InfoObj::new ;
5699 my $this = bless {}, shift;
5704 # The set method may only be used by code that reads index data or
5705 # otherwise "objective" data from the outside world. All session
5706 # related material may do anything else with instance variables but
5707 # must not touch the hash under the RO attribute. The reason is that
5708 # the RO hash gets written to Metadata file and is thus persistent.
5710 #-> sub CPAN::InfoObj::safe_chdir ;
5712 my($self,$todir) = @_;
5713 # we die if we cannot chdir and we are debuggable
5714 Carp::confess("safe_chdir called without todir argument")
5715 unless defined $todir and length $todir;
5717 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
5721 unless (-x $todir) {
5722 unless (chmod 0755, $todir) {
5723 my $cwd = CPAN::anycwd();
5724 $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
5725 "permission to change the permission; cannot ".
5726 "chdir to '$todir'\n");
5727 $CPAN::Frontend->mysleep(5);
5728 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
5729 qq{to todir[$todir]: $!});
5733 $CPAN::Frontend->mydie("Directory '$todir' has gone. Cannot continue.\n");
5736 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
5739 my $cwd = CPAN::anycwd();
5740 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
5741 qq{to todir[$todir] (a chmod has been issued): $!});
5746 #-> sub CPAN::InfoObj::set ;
5748 my($self,%att) = @_;
5749 my $class = ref $self;
5751 # This must be ||=, not ||, because only if we write an empty
5752 # reference, only then the set method will write into the readonly
5753 # area. But for Distributions that spring into existence, maybe
5754 # because of a typo, we do not like it that they are written into
5755 # the readonly area and made permanent (at least for a while) and
5756 # that is why we do not "allow" other places to call ->set.
5757 unless ($self->id) {
5758 CPAN->debug("Bug? Empty ID, rejecting");
5761 my $ro = $self->{RO} =
5762 $CPAN::META->{readonly}{$class}{$self->id} ||= {};
5764 while (my($k,$v) = each %att) {
5769 #-> sub CPAN::InfoObj::as_glimpse ;
5773 my $class = ref($self);
5774 $class =~ s/^CPAN:://;
5775 my $id = $self->can("pretty_id") ? $self->pretty_id : $self->{ID};
5776 push @m, sprintf "%-15s %s\n", $class, $id;
5780 #-> sub CPAN::InfoObj::as_string ;
5784 my $class = ref($self);
5785 $class =~ s/^CPAN:://;
5786 push @m, $class, " id = $self->{ID}\n";
5788 unless ($ro = $self->ro) {
5789 if (substr($self->{ID},-1,1) eq ".") { # directory
5792 $CPAN::Frontend->mywarn("Unknown object $self->{ID}\n");
5793 $CPAN::Frontend->mysleep(5);
5797 for (sort keys %$ro) {
5798 # next if m/^(ID|RO)$/;
5800 if ($_ eq "CPAN_USERID") {
5802 $extra .= $self->fullname;
5803 my $email; # old perls!
5804 if ($email = $CPAN::META->instance("CPAN::Author",
5807 $extra .= " <$email>";
5809 $extra .= " <no email>";
5812 } elsif ($_ eq "FULLNAME") { # potential UTF-8 conversion
5813 push @m, sprintf " %-12s %s\n", $_, $self->fullname;
5816 next unless defined $ro->{$_};
5817 push @m, sprintf " %-12s %s%s\n", $_, $ro->{$_}, $extra;
5819 KEY: for (sort keys %$self) {
5820 next if m/^(ID|RO)$/;
5821 unless (defined $self->{$_}) {
5825 if (ref($self->{$_}) eq "ARRAY") {
5826 push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
5827 } elsif (ref($self->{$_}) eq "HASH") {
5829 if (/^CONTAINSMODS$/) {
5830 $value = join(" ",sort keys %{$self->{$_}});
5831 } elsif (/^prereq_pm$/) {
5833 my $v = $self->{$_};
5834 for my $x (sort keys %$v) {
5836 for my $y (sort keys %{$v->{$x}}) {
5837 push @svalue, "$y=>$v->{$x}{$y}";
5839 push @value, "$x\:" . join ",", @svalue if @svalue;
5841 $value = join ";", @value;
5843 $value = $self->{$_};
5851 push @m, sprintf " %-12s %s\n", $_, $self->{$_};
5857 #-> sub CPAN::InfoObj::fullname ;
5860 $CPAN::META->instance("CPAN::Author",$self->cpan_userid)->fullname;
5863 #-> sub CPAN::InfoObj::dump ;
5865 my($self, $what) = @_;
5866 unless ($CPAN::META->has_inst("Data::Dumper")) {
5867 $CPAN::Frontend->mydie("dump command requires Data::Dumper installed");
5869 local $Data::Dumper::Sortkeys;
5870 $Data::Dumper::Sortkeys = 1;
5871 my $out = Data::Dumper::Dumper($what ? eval $what : $self);
5872 if (length $out > 100000) {
5873 my $fh_pager = FileHandle->new;
5874 local($SIG{PIPE}) = "IGNORE";
5875 my $pager = $CPAN::Config->{'pager'} || "cat";
5876 $fh_pager->open("|$pager")
5877 or die "Could not open pager $pager\: $!";
5878 $fh_pager->print($out);
5881 $CPAN::Frontend->myprint($out);
5885 package CPAN::Author;
5888 #-> sub CPAN::Author::force
5894 #-> sub CPAN::Author::force
5897 delete $self->{force};
5900 #-> sub CPAN::Author::id
5903 my $id = $self->{ID};
5904 $CPAN::Frontend->mydie("Illegal author id[$id]") unless $id =~ /^[A-Z]/;
5908 #-> sub CPAN::Author::as_glimpse ;
5912 my $class = ref($self);
5913 $class =~ s/^CPAN:://;
5914 push @m, sprintf(qq{%-15s %s ("%s" <%s>)\n},
5922 #-> sub CPAN::Author::fullname ;
5924 shift->ro->{FULLNAME};
5928 #-> sub CPAN::Author::email ;
5929 sub email { shift->ro->{EMAIL}; }
5931 #-> sub CPAN::Author::ls ;
5934 my $glob = shift || "";
5935 my $silent = shift || 0;
5938 # adapted from CPAN::Distribution::verifyCHECKSUM ;
5939 my(@csf); # chksumfile
5940 @csf = $self->id =~ /(.)(.)(.*)/;
5941 $csf[1] = join "", @csf[0,1];
5942 $csf[2] = join "", @csf[1,2]; # ("A","AN","ANDK")
5944 @dl = $self->dir_listing([$csf[0],"CHECKSUMS"], 0, 1);
5945 unless (grep {$_->[2] eq $csf[1]} @dl) {
5946 $CPAN::Frontend->myprint("Directory $csf[1]/ does not exist\n") unless $silent ;
5949 @dl = $self->dir_listing([@csf[0,1],"CHECKSUMS"], 0, 1);
5950 unless (grep {$_->[2] eq $csf[2]} @dl) {
5951 $CPAN::Frontend->myprint("Directory $id/ does not exist\n") unless $silent;
5954 @dl = $self->dir_listing([@csf,"CHECKSUMS"], 1, 1);
5956 if ($CPAN::META->has_inst("Text::Glob")) {
5957 my $rglob = Text::Glob::glob_to_regex($glob);
5958 @dl = grep { $_->[2] =~ /$rglob/ } @dl;
5960 $CPAN::Frontend->mydie("Text::Glob not installed, cannot proceed");
5963 unless ($silent >= 2) {
5964 $CPAN::Frontend->myprint(join "", map {
5965 sprintf("%8d %10s %s/%s\n", $_->[0], $_->[1], $id, $_->[2])
5966 } sort { $a->[2] cmp $b->[2] } @dl);
5971 # returns an array of arrays, the latter contain (size,mtime,filename)
5972 #-> sub CPAN::Author::dir_listing ;
5975 my $chksumfile = shift;
5976 my $recursive = shift;
5977 my $may_ftp = shift;
5980 File::Spec->catfile($CPAN::Config->{keep_source_where},
5981 "authors", "id", @$chksumfile);
5985 # Purge and refetch old (pre-PGP) CHECKSUMS; they are a security
5986 # hazard. (Without GPG installed they are not that much better,
5988 $fh = FileHandle->new;
5989 if (open($fh, $lc_want)) {
5990 my $line = <$fh>; close $fh;
5991 unlink($lc_want) unless $line =~ /PGP/;
5995 # connect "force" argument with "index_expire".
5996 my $force = $self->{force};
5997 if (my @stat = stat $lc_want) {
5998 $force ||= $stat[9] + $CPAN::Config->{index_expire}*86400 <= time;
6002 $lc_file = CPAN::FTP->localize(
6003 "authors/id/@$chksumfile",
6008 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
6009 $chksumfile->[-1] .= ".gz";
6010 $lc_file = CPAN::FTP->localize("authors/id/@$chksumfile",
6013 $lc_file =~ s{\.gz(?!\n)\Z}{}; #};
6014 eval{CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file)};
6020 $lc_file = $lc_want;
6021 # we *could* second-guess and if the user has a file: URL,
6022 # then we could look there. But on the other hand, if they do
6023 # have a file: URL, wy did they choose to set
6024 # $CPAN::Config->{show_upload_date} to false?
6027 # adapted from CPAN::Distribution::CHECKSUM_check_file ;
6028 $fh = FileHandle->new;
6030 if (open $fh, $lc_file) {
6033 $eval =~ s/\015?\012/\n/g;
6035 my($compmt) = Safe->new();
6036 $cksum = $compmt->reval($eval);
6038 rename $lc_file, "$lc_file.bad";
6039 Carp::confess($@) if $@;
6041 } elsif ($may_ftp) {
6042 Carp::carp "Could not open '$lc_file' for reading.";
6044 # Maybe should warn: "You may want to set show_upload_date to a true value"
6048 for $f (sort keys %$cksum) {
6049 if (exists $cksum->{$f}{isdir}) {
6051 my(@dir) = @$chksumfile;
6053 push @dir, $f, "CHECKSUMS";
6055 [$_->[0], $_->[1], "$f/$_->[2]"]
6056 } $self->dir_listing(\@dir,1,$may_ftp);
6058 push @result, [ 0, "-", $f ];
6062 ($cksum->{$f}{"size"}||0),
6063 $cksum->{$f}{"mtime"}||"---",
6071 #-> sub CPAN::Author::reports
6073 $CPAN::Frontend->mywarn("reports on authors not implemented.
6074 Please file a bugreport if you need this.\n");
6077 package CPAN::Distribution;
6080 use CPAN::Distroprefs;
6085 my $ro = $self->ro or return;
6089 #-> CPAN::Distribution::undelay
6093 "configure_requires_later",
6094 "configure_requires_later_for",
6098 delete $self->{$delayer};
6102 #-> CPAN::Distribution::is_dot_dist
6105 return substr($self->id,-1,1) eq ".";
6108 # add the A/AN/ stuff
6109 #-> CPAN::Distribution::normalize
6112 $s = $self->id unless defined $s;
6113 if (substr($s,-1,1) eq ".") {
6114 # using a global because we are sometimes called as static method
6115 if (!$CPAN::META->{LOCK}
6116 && !$CPAN::Have_warned->{"$s is unlocked"}++
6118 $CPAN::Frontend->mywarn("You are visiting the local directory
6120 without lock, take care that concurrent processes do not do likewise.\n");
6121 $CPAN::Frontend->mysleep(1);
6124 $s = "$CPAN::iCwd/.";
6125 } elsif (File::Spec->file_name_is_absolute($s)) {
6126 } elsif (File::Spec->can("rel2abs")) {
6127 $s = File::Spec->rel2abs($s);
6129 $CPAN::Frontend->mydie("Your File::Spec is too old, please upgrade File::Spec");
6131 CPAN->debug("s[$s]") if $CPAN::DEBUG;
6132 unless ($CPAN::META->exists("CPAN::Distribution", $s)) {
6133 for ($CPAN::META->instance("CPAN::Distribution", $s)) {
6134 $_->{build_dir} = $s;
6135 $_->{archived} = "local_directory";
6136 $_->{unwrapped} = CPAN::Distrostatus->new("YES -- local_directory");
6142 $s !~ m|[A-Z]/[A-Z-]{2}/[A-Z-]{2,}/|
6144 return $s if $s =~ m:^N/A|^Contact Author: ;
6145 $s =~ s|^(.)(.)([^/]*/)(.+)$|$1/$1$2/$1$2$3$4|;
6146 CPAN->debug("s[$s]") if $CPAN::DEBUG;
6151 #-> sub CPAN::Distribution::author ;
6155 if (substr($self->id,-1,1) eq ".") {
6156 $authorid = "LOCAL";
6158 ($authorid) = $self->pretty_id =~ /^([\w\-]+)/;
6160 CPAN::Shell->expand("Author",$authorid);
6163 # tries to get the yaml from CPAN instead of the distro itself:
6164 # EXPERIMENTAL, UNDOCUMENTED AND UNTESTED, for Tels
6167 my $meta = $self->pretty_id;
6168 $meta =~ s/\.(tar.gz|tgz|zip|tar.bz2)/.meta/;
6169 my(@ls) = CPAN::Shell->globls($meta);
6170 my $norm = $self->normalize($meta);
6174 File::Spec->catfile(
6175 $CPAN::Config->{keep_source_where},
6180 $self->debug("Doing localize") if $CPAN::DEBUG;
6181 unless ($local_file =
6182 CPAN::FTP->localize("authors/id/$norm",
6184 $CPAN::Frontend->mydie("Giving up on downloading yaml file '$local_wanted'\n");
6186 my $yaml = CPAN->_yaml_loadfile($local_file)->[0];
6189 #-> sub CPAN::Distribution::cpan_userid
6192 if ($self->{ID} =~ m{[A-Z]/[A-Z\-]{2}/([A-Z\-]+)/}) {
6195 return $self->SUPER::cpan_userid;
6198 #-> sub CPAN::Distribution::pretty_id
6202 return $id unless $id =~ m|^./../|;
6206 #-> sub CPAN::Distribution::base_id
6209 my $id = $self->pretty_id();
6210 my $base_id = File::Basename::basename($id);
6211 $base_id =~ s{\.(?:tar\.(bz2|gz|Z)|t(?:gz|bz)|zip)$}{}i;
6215 #-> sub CPAN::Distribution::tested_ok_but_not_installed
6216 sub tested_ok_but_not_installed {
6220 && $self->{build_dir}
6221 && (UNIVERSAL::can($self->{make_test},"failed") ?
6222 ! $self->{make_test}->failed :
6223 $self->{make_test} =~ /^YES/
6228 $self->{install}->failed
6234 # mark as dirty/clean for the sake of recursion detection. $color=1
6235 # means "in use", $color=0 means "not in use anymore". $color=2 means
6236 # we have determined prereqs now and thus insist on passing this
6237 # through (at least) once again.
6239 #-> sub CPAN::Distribution::color_cmd_tmps ;
6240 sub color_cmd_tmps {
6242 my($depth) = shift || 0;
6243 my($color) = shift || 0;
6244 my($ancestors) = shift || [];
6245 # a distribution needs to recurse into its prereq_pms
6247 return if exists $self->{incommandcolor}
6249 && $self->{incommandcolor}==$color;
6250 if ($depth>=$CPAN::MAX_RECURSION) {
6251 die(CPAN::Exception::RecursiveDependency->new($ancestors));
6253 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
6254 my $prereq_pm = $self->prereq_pm;
6255 if (defined $prereq_pm) {
6256 PREREQ: for my $pre (keys %{$prereq_pm->{requires}||{}},
6257 keys %{$prereq_pm->{build_requires}||{}}) {
6258 next PREREQ if $pre eq "perl";
6260 unless ($premo = CPAN::Shell->expand("Module",$pre)) {
6261 $CPAN::Frontend->mywarn("prerequisite module[$pre] not known\n");
6262 $CPAN::Frontend->mysleep(2);
6265 $premo->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
6269 delete $self->{sponsored_mods};
6271 # as we are at the end of a command, we'll give up this
6272 # reminder of a broken test. Other commands may test this guy
6273 # again. Maybe 'badtestcnt' should be renamed to
6274 # 'make_test_failed_within_command'?
6275 delete $self->{badtestcnt};
6277 $self->{incommandcolor} = $color;
6280 #-> sub CPAN::Distribution::as_string ;
6283 $self->containsmods;
6285 $self->SUPER::as_string(@_);
6288 #-> sub CPAN::Distribution::containsmods ;
6291 return keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
6292 my $dist_id = $self->{ID};
6293 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
6294 my $mod_file = $mod->cpan_file or next;
6295 my $mod_id = $mod->{ID} or next;
6296 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
6298 if ($CPAN::Signal) {
6299 delete $self->{CONTAINSMODS};
6302 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
6304 keys %{$self->{CONTAINSMODS}||={}};
6307 #-> sub CPAN::Distribution::upload_date ;
6310 return $self->{UPLOAD_DATE} if exists $self->{UPLOAD_DATE};
6311 my(@local_wanted) = split(/\//,$self->id);
6312 my $filename = pop @local_wanted;
6313 push @local_wanted, "CHECKSUMS";
6314 my $author = CPAN::Shell->expand("Author",$self->cpan_userid);
6315 return unless $author;
6316 my @dl = $author->dir_listing(\@local_wanted,0,$CPAN::Config->{show_upload_date});
6318 my($dirent) = grep { $_->[2] eq $filename } @dl;
6319 # warn sprintf "dirent[%s]id[%s]", $dirent, $self->id;
6320 return unless $dirent->[1];
6321 return $self->{UPLOAD_DATE} = $dirent->[1];
6324 #-> sub CPAN::Distribution::uptodate ;
6328 foreach $c ($self->containsmods) {
6329 my $obj = CPAN::Shell->expandany($c);
6330 unless ($obj->uptodate) {
6331 my $id = $self->pretty_id;
6332 $self->debug("$id not uptodate due to $c") if $CPAN::DEBUG;
6339 #-> sub CPAN::Distribution::called_for ;
6342 $self->{CALLED_FOR} = $id if defined $id;
6343 return $self->{CALLED_FOR};
6346 #-> sub CPAN::Distribution::get ;
6349 $self->debug("checking goto id[$self->{ID}]") if $CPAN::DEBUG;
6350 if (my $goto = $self->prefs->{goto}) {
6351 $CPAN::Frontend->mywarn
6353 "delegating to '%s' as specified in prefs file '%s' doc %d\n",
6355 $self->{prefs_file},
6356 $self->{prefs_file_doc},
6358 return $self->goto($goto);
6360 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
6362 : ($ENV{PERLLIB} || "");
6363 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
6364 $CPAN::META->set_perl5lib;
6365 local $ENV{MAKEFLAGS}; # protect us from outer make calls
6369 my $goodbye_message;
6370 $self->debug("checking disabled id[$self->{ID}]") if $CPAN::DEBUG;
6371 if ($self->prefs->{disabled} && ! $self->{force_update}) {
6373 "Disabled via prefs file '%s' doc %d",
6374 $self->{prefs_file},
6375 $self->{prefs_file_doc},
6378 $self->{unwrapped} = CPAN::Distrostatus->new("NO $why");
6379 $goodbye_message = "[disabled] -- NA $why";
6380 # note: not intended to be persistent but at least visible
6381 # during this session
6383 if (exists $self->{build_dir} && -d $self->{build_dir}
6384 && ($self->{modulebuild}||$self->{writemakefile})
6386 # this deserves print, not warn:
6387 $CPAN::Frontend->myprint(" Has already been unwrapped into directory ".
6388 "$self->{build_dir}\n"
6393 # although we talk about 'force' we shall not test on
6394 # force directly. New model of force tries to refrain from
6395 # direct checking of force.
6396 exists $self->{unwrapped} and (
6397 UNIVERSAL::can($self->{unwrapped},"failed") ?
6398 $self->{unwrapped}->failed :
6399 $self->{unwrapped} =~ /^NO/
6401 and push @e, "Unwrapping had some problem, won't try again without force";
6404 $CPAN::Frontend->mywarn(join "", map {"$_\n"} @e);
6405 if ($goodbye_message) {
6406 $self->goodbye($goodbye_message);
6411 my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
6414 unless ($self->{build_dir} && -d $self->{build_dir}) {
6415 $self->get_file_onto_local_disk;
6416 return if $CPAN::Signal;
6417 $self->check_integrity;
6418 return if $CPAN::Signal;
6419 (my $packagedir,$local_file) = $self->run_preps_on_packagedir;
6420 if (exists $self->{writemakefile} && ref $self->{writemakefile}
6421 && $self->{writemakefile}->can("failed") &&
6422 $self->{writemakefile}->failed) {
6425 $packagedir ||= $self->{build_dir};
6426 $self->{build_dir} = $packagedir;
6429 if ($CPAN::Signal) {
6430 $self->safe_chdir($sub_wd);
6433 return $self->choose_MM_or_MB($local_file);
6436 #-> CPAN::Distribution::get_file_onto_local_disk
6437 sub get_file_onto_local_disk {
6440 return if $self->is_dot_dist;
6443 File::Spec->catfile(
6444 $CPAN::Config->{keep_source_where},
6447 split(/\//,$self->id)
6450 $self->debug("Doing localize") if $CPAN::DEBUG;
6451 unless ($local_file =
6452 CPAN::FTP->localize("authors/id/$self->{ID}",
6455 if ($CPAN::Index::DATE_OF_02) {
6456 $note = "Note: Current database in memory was generated ".
6457 "on $CPAN::Index::DATE_OF_02\n";
6459 $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n$note");
6462 $self->debug("local_wanted[$local_wanted]local_file[$local_file]") if $CPAN::DEBUG;
6463 $self->{localfile} = $local_file;
6467 #-> CPAN::Distribution::check_integrity
6468 sub check_integrity {
6471 return if $self->is_dot_dist;
6472 if ($CPAN::META->has_inst("Digest::SHA")) {
6473 $self->debug("Digest::SHA is installed, verifying");
6474 $self->verifyCHECKSUM;
6476 $self->debug("Digest::SHA is NOT installed");
6480 #-> CPAN::Distribution::run_preps_on_packagedir
6481 sub run_preps_on_packagedir {
6483 return if $self->is_dot_dist;
6485 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
6486 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
6487 $self->safe_chdir($builddir);
6488 $self->debug("Removing tmp-$$") if $CPAN::DEBUG;
6489 File::Path::rmtree("tmp-$$");
6490 unless (mkdir "tmp-$$", 0755) {
6491 $CPAN::Frontend->unrecoverable_error(<<EOF);
6492 Couldn't mkdir '$builddir/tmp-$$': $!
6494 Cannot continue: Please find the reason why I cannot make the
6497 and fix the problem, then retry.
6501 if ($CPAN::Signal) {
6504 $self->safe_chdir("tmp-$$");
6509 my $local_file = $self->{localfile};
6510 my $ct = eval{CPAN::Tarzip->new($local_file)};
6512 $self->{unwrapped} = CPAN::Distrostatus->new("NO");
6513 delete $self->{build_dir};
6516 if ($local_file =~ /(\.tar\.(bz2|gz|Z)|\.tgz)(?!\n)\Z/i) {
6517 $self->{was_uncompressed}++ unless eval{$ct->gtest()};
6518 $self->untar_me($ct);
6519 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
6520 $self->unzip_me($ct);
6522 $self->{was_uncompressed}++ unless $ct->gtest();
6523 $local_file = $self->handle_singlefile($local_file);
6526 # we are still in the tmp directory!
6527 # Let's check if the package has its own directory.
6528 my $dh = DirHandle->new(File::Spec->curdir)
6529 or Carp::croak("Couldn't opendir .: $!");
6530 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
6531 if (grep { $_ eq "pax_global_header" } @readdir) {
6532 $CPAN::Frontend->mywarn("Your (un)tar seems to have extracted a file named 'pax_global_header'
6533 from the tarball '$local_file'.
6534 This is almost certainly an error. Please upgrade your tar.
6535 I'll ignore this file for now.
6536 See also http://rt.cpan.org/Ticket/Display.html?id=38932\n");
6537 $CPAN::Frontend->mysleep(5);
6538 @readdir = grep { $_ ne "pax_global_header" } @readdir;
6542 # XXX here we want in each branch File::Temp to protect all build_dir directories
6543 if (CPAN->has_usable("File::Temp")) {
6547 if (@readdir == 1 && -d $readdir[0]) {
6548 $tdir_base = $readdir[0];
6549 $from_dir = File::Spec->catdir(File::Spec->curdir,$readdir[0]);
6551 unless ($dh2 = DirHandle->new($from_dir)) {
6552 my($mode) = (stat $from_dir)[2];
6555 "Couldn't opendir '%s', mode '%o': %s",
6560 $CPAN::Frontend->mywarn("$why\n");
6561 $self->{writemakefile} = CPAN::Distrostatus->new("NO -- $why");
6564 @dirents = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh2->read; ### MAC??
6566 my $userid = $self->cpan_userid;
6567 CPAN->debug("userid[$userid]");
6568 if (!$userid or $userid eq "N/A") {
6571 $tdir_base = $userid;
6572 $from_dir = File::Spec->curdir;
6573 @dirents = @readdir;
6575 $packagedir = File::Temp::tempdir(
6576 "$tdir_base-XXXXXX",
6581 for $f (@dirents) { # is already without "." and ".."
6582 my $from = File::Spec->catdir($from_dir,$f);
6583 my $to = File::Spec->catdir($packagedir,$f);
6584 unless (File::Copy::move($from,$to)) {
6586 $from = File::Spec->rel2abs($from);
6587 Carp::confess("Couldn't move $from to $to: $err");
6590 } else { # older code below, still better than nothing when there is no File::Temp
6592 if (@readdir == 1 && -d $readdir[0]) {
6593 $distdir = $readdir[0];
6594 $packagedir = File::Spec->catdir($builddir,$distdir);
6595 $self->debug("packagedir[$packagedir]builddir[$builddir]distdir[$distdir]")
6597 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
6599 File::Path::rmtree($packagedir);
6600 unless (File::Copy::move($distdir,$packagedir)) {
6601 $CPAN::Frontend->unrecoverable_error(<<EOF);
6602 Couldn't move '$distdir' to '$packagedir': $!
6604 Cannot continue: Please find the reason why I cannot move
6605 $builddir/tmp-$$/$distdir
6608 and fix the problem, then retry
6612 $self->debug(sprintf("moved distdir[%s] to packagedir[%s] -e[%s]-d[%s]",
6619 my $userid = $self->cpan_userid;
6620 CPAN->debug("userid[$userid]") if $CPAN::DEBUG;
6621 if (!$userid or $userid eq "N/A") {
6624 my $pragmatic_dir = $userid . '000';
6625 $pragmatic_dir =~ s/\W_//g;
6626 $pragmatic_dir++ while -d "../$pragmatic_dir";
6627 $packagedir = File::Spec->catdir($builddir,$pragmatic_dir);
6628 $self->debug("packagedir[$packagedir]") if $CPAN::DEBUG;
6629 File::Path::mkpath($packagedir);
6631 for $f (@readdir) { # is already without "." and ".."
6632 my $to = File::Spec->catdir($packagedir,$f);
6633 File::Copy::move($f,$to) or Carp::confess("Couldn't move $f to $to: $!");
6637 $self->{build_dir} = $packagedir;
6638 $self->safe_chdir($builddir);
6639 File::Path::rmtree("tmp-$$");
6641 $self->safe_chdir($packagedir);
6642 $self->_signature_business();
6643 $self->safe_chdir($builddir);
6645 return($packagedir,$local_file);
6648 #-> sub CPAN::Distribution::parse_meta_yml ;
6649 sub parse_meta_yml {
6651 my $build_dir = $self->{build_dir} or die "PANIC: cannot parse yaml without a build_dir";
6652 my $yaml = File::Spec->catfile($build_dir,"META.yml");
6653 $self->debug("yaml[$yaml]") if $CPAN::DEBUG;
6654 return unless -f $yaml;
6657 require Parse::CPAN::Meta;
6658 $early_yaml = Parse::CPAN::Meta::LoadFile($yaml)->[0];
6660 unless ($early_yaml) {
6661 eval { $early_yaml = CPAN->_yaml_loadfile($yaml)->[0]; };
6663 unless ($early_yaml) {
6669 #-> sub CPAN::Distribution::satisfy_requires ;
6670 sub satisfy_requires {
6672 if (my @prereq = $self->unsat_prereq("later")) {
6673 if ($prereq[0][0] eq "perl") {
6674 my $need = "requires perl '$prereq[0][1]'";
6675 my $id = $self->pretty_id;
6676 $CPAN::Frontend->mywarn("$id $need; you have only $]; giving up\n");
6677 $self->{make} = CPAN::Distrostatus->new("NO $need");
6678 $self->store_persistent_state;
6679 die "[prereq] -- NOT OK\n";
6681 my $follow = eval { $self->follow_prereqs("later",@prereq); };
6684 # signal success to the queuerunner
6686 } elsif ($@ && ref $@ && $@->isa("CPAN::Exception::RecursiveDependency")) {
6687 $CPAN::Frontend->mywarn($@);
6688 die "[depend] -- NOT OK\n";
6694 #-> sub CPAN::Distribution::satisfy_configure_requires ;
6695 sub satisfy_configure_requires {
6697 my $enable_configure_requires = 1;
6698 if (!$enable_configure_requires) {
6700 # if we return 1 here, everything is as before we introduced
6701 # configure_requires that means, things with
6702 # configure_requires simply fail, all others succeed
6704 my @prereq = $self->unsat_prereq("configure_requires_later") or return 1;
6705 if ($self->{configure_requires_later}) {
6706 for my $k (keys %{$self->{configure_requires_later_for}||{}}) {
6707 if ($self->{configure_requires_later_for}{$k}>1) {
6708 # we must not come here a second time
6709 $CPAN::Frontend->mywarn("Panic: Some prerequisites is not available, please investigate...");
6711 $CPAN::Frontend->mydie
6714 ({self=>$self, prereq=>\@prereq})
6719 if ($prereq[0][0] eq "perl") {
6720 my $need = "requires perl '$prereq[0][1]'";
6721 my $id = $self->pretty_id;
6722 $CPAN::Frontend->mywarn("$id $need; you have only $]; giving up\n");
6723 $self->{make} = CPAN::Distrostatus->new("NO $need");
6724 $self->store_persistent_state;
6725 return $self->goodbye("[prereq] -- NOT OK");
6728 $self->follow_prereqs("configure_requires_later", @prereq);
6733 } elsif ($@ && ref $@ && $@->isa("CPAN::Exception::RecursiveDependency")) {
6734 $CPAN::Frontend->mywarn($@);
6735 return $self->goodbye("[depend] -- NOT OK");
6738 die "never reached";
6741 #-> sub CPAN::Distribution::choose_MM_or_MB ;
6742 sub choose_MM_or_MB {
6743 my($self,$local_file) = @_;
6744 $self->satisfy_configure_requires() or return;
6745 my($mpl) = File::Spec->catfile($self->{build_dir},"Makefile.PL");
6746 my($mpl_exists) = -f $mpl;
6747 unless ($mpl_exists) {
6748 # NFS has been reported to have racing problems after the
6749 # renaming of a directory in some environments.
6751 $CPAN::Frontend->mysleep(1);
6752 my $mpldh = DirHandle->new($self->{build_dir})
6753 or Carp::croak("Couldn't opendir $self->{build_dir}: $!");
6754 $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read;
6757 my $prefer_installer = "eumm"; # eumm|mb
6758 if (-f File::Spec->catfile($self->{build_dir},"Build.PL")) {
6759 if ($mpl_exists) { # they *can* choose
6760 if ($CPAN::META->has_inst("Module::Build")) {
6761 $prefer_installer = CPAN::HandleConfig->prefs_lookup($self,
6762 q{prefer_installer});
6765 $prefer_installer = "mb";
6768 return unless $self->patch;
6769 if (lc($prefer_installer) eq "rand") {
6770 $prefer_installer = rand()<.5 ? "eumm" : "mb";
6772 if (lc($prefer_installer) eq "mb") {
6773 $self->{modulebuild} = 1;
6774 } elsif ($self->{archived} eq "patch") {
6775 # not an edge case, nothing to install for sure
6776 my $why = "A patch file cannot be installed";
6777 $CPAN::Frontend->mywarn("Refusing to handle this file: $why\n");
6778 $self->{writemakefile} = CPAN::Distrostatus->new("NO $why");
6779 } elsif (! $mpl_exists) {
6780 $self->_edge_cases($mpl,$local_file);
6782 if ($self->{build_dir}
6784 $CPAN::Config->{build_dir_reuse}
6786 $self->store_persistent_state;
6791 #-> CPAN::Distribution::store_persistent_state
6792 sub store_persistent_state {
6794 my $dir = $self->{build_dir};
6795 unless (File::Spec->canonpath(File::Basename::dirname($dir))
6796 eq File::Spec->canonpath($CPAN::Config->{build_dir})) {
6797 $CPAN::Frontend->mywarn("Directory '$dir' not below $CPAN::Config->{build_dir}, ".
6798 "will not store persistent state\n");
6801 my $file = sprintf "%s.yml", $dir;
6802 my $yaml_module = CPAN::_yaml_module;
6803 if ($CPAN::META->has_inst($yaml_module)) {
6804 CPAN->_yaml_dumpfile(
6808 perl => CPAN::_perl_fingerprint,
6809 distribution => $self,
6813 $CPAN::Frontend->myprint("Warning (usually harmless): '$yaml_module' not installed, ".
6814 "will not store persistent state\n");
6818 #-> CPAN::Distribution::try_download
6820 my($self,$patch) = @_;
6821 my $norm = $self->normalize($patch);
6823 File::Spec->catfile(
6824 $CPAN::Config->{keep_source_where},
6829 $self->debug("Doing localize") if $CPAN::DEBUG;
6830 return CPAN::FTP->localize("authors/id/$norm",
6835 my $stdpatchargs = "";
6836 #-> CPAN::Distribution::patch
6839 $self->debug("checking patches id[$self->{ID}]") if $CPAN::DEBUG;
6840 my $patches = $self->prefs->{patches};
6842 $self->debug("patches[$patches]") if $CPAN::DEBUG;
6844 return unless @$patches;
6845 $self->safe_chdir($self->{build_dir});
6846 CPAN->debug("patches[$patches]") if $CPAN::DEBUG;
6847 my $patchbin = $CPAN::Config->{patch};
6848 unless ($patchbin && length $patchbin) {
6849 $CPAN::Frontend->mydie("No external patch command configured\n\n".
6850 "Please run 'o conf init /patch/'\n\n");
6852 unless (MM->maybe_command($patchbin)) {
6853 $CPAN::Frontend->mydie("No external patch command available\n\n".
6854 "Please run 'o conf init /patch/'\n\n");
6856 $patchbin = CPAN::HandleConfig->safe_quote($patchbin);
6857 local $ENV{PATCH_GET} = 0; # formerly known as -g0
6858 unless ($stdpatchargs) {
6859 my $system = "$patchbin --version |";
6861 open FH, $system or die "Could not fork '$system': $!";
6864 PARSEVERSION: while (<FH>) {
6865 if (/^patch\s+([\d\.]+)/) {
6871 $stdpatchargs = "-N --fuzz=3";
6873 $stdpatchargs = "-N";
6876 my $countedpatches = @$patches == 1 ? "1 patch" : (scalar @$patches . " patches");
6877 $CPAN::Frontend->myprint("Going to apply $countedpatches:\n");
6878 for my $patch (@$patches) {
6879 unless (-f $patch) {
6880 if (my $trydl = $self->try_download($patch)) {
6883 my $fail = "Could not find patch '$patch'";
6884 $CPAN::Frontend->mywarn("$fail; cannot continue\n");
6885 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
6886 delete $self->{build_dir};
6890 $CPAN::Frontend->myprint(" $patch\n");
6891 my $readfh = CPAN::Tarzip->TIEHANDLE($patch);
6894 my $ppp = $self->_patch_p_parameter($readfh);
6895 if ($ppp eq "applypatch") {
6896 $pcommand = "$CPAN::Config->{applypatch} -verbose";
6898 my $thispatchargs = join " ", $stdpatchargs, $ppp;
6899 $pcommand = "$patchbin $thispatchargs";
6902 $readfh = CPAN::Tarzip->TIEHANDLE($patch); # open again
6903 my $writefh = FileHandle->new;
6904 $CPAN::Frontend->myprint(" $pcommand\n");
6905 unless (open $writefh, "|$pcommand") {
6906 my $fail = "Could not fork '$pcommand'";
6907 $CPAN::Frontend->mywarn("$fail; cannot continue\n");
6908 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
6909 delete $self->{build_dir};
6912 while (my $x = $readfh->READLINE) {
6915 unless (close $writefh) {
6916 my $fail = "Could not apply patch '$patch'";
6917 $CPAN::Frontend->mywarn("$fail; cannot continue\n");
6918 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
6919 delete $self->{build_dir};
6929 sub _patch_p_parameter {
6932 my $cnt_p0files = 0;
6934 while ($_ = $fh->READLINE) {
6936 $CPAN::Config->{applypatch}
6938 /\#\#\#\# ApplyPatch data follows \#\#\#\#/
6942 next unless /^[\*\+]{3}\s(\S+)/;
6945 $cnt_p0files++ if -f $file;
6946 CPAN->debug("file[$file]cnt_files[$cnt_files]cnt_p0files[$cnt_p0files]")
6949 return "-p1" unless $cnt_files;
6950 return $cnt_files==$cnt_p0files ? "-p0" : "-p1";
6953 #-> sub CPAN::Distribution::_edge_cases
6954 # with "configure" or "Makefile" or single file scripts
6956 my($self,$mpl,$local_file) = @_;
6957 $self->debug(sprintf("makefilepl[%s]anycwd[%s]",
6961 my $build_dir = $self->{build_dir};
6962 my($configure) = File::Spec->catfile($build_dir,"Configure");
6963 if (-f $configure) {
6964 # do we have anything to do?
6965 $self->{configure} = $configure;
6966 } elsif (-f File::Spec->catfile($build_dir,"Makefile")) {
6967 $CPAN::Frontend->mywarn(qq{
6968 Package comes with a Makefile and without a Makefile.PL.
6969 We\'ll try to build it with that Makefile then.
6971 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
6972 $CPAN::Frontend->mysleep(2);
6974 my $cf = $self->called_for || "unknown";
6979 $cf =~ s|[/\\:]||g; # risk of filesystem damage
6980 $cf = "unknown" unless length($cf);
6981 if (my $crap = $self->_contains_crap($build_dir)) {
6982 my $why = qq{Package contains $crap; not recognized as a perl package, giving up};
6983 $CPAN::Frontend->mywarn("$why\n");
6984 $self->{writemakefile} = CPAN::Distrostatus->new(qq{NO -- $why});
6987 $CPAN::Frontend->mywarn(qq{Package seems to come without Makefile.PL.
6988 (The test -f "$mpl" returned false.)
6989 Writing one on our own (setting NAME to $cf)\a\n});
6990 $self->{had_no_makefile_pl}++;
6991 $CPAN::Frontend->mysleep(3);
6993 # Writing our own Makefile.PL
6995 my $exefile_stanza = "";
6996 if ($self->{archived} eq "maybe_pl") {
6997 $exefile_stanza = $self->_exefile_stanza($build_dir,$local_file);
7000 my $fh = FileHandle->new;
7002 or Carp::croak("Could not open >$mpl: $!");
7004 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
7005 # because there was no Makefile.PL supplied.
7006 # Autogenerated on: }.scalar localtime().qq{
7008 use ExtUtils::MakeMaker;
7010 NAME => q[$cf],$exefile_stanza
7017 #-> CPAN;:Distribution::_contains_crap
7018 sub _contains_crap {
7019 my($self,$dir) = @_;
7020 my(@dirs, $dh, @files);
7021 opendir $dh, $dir or return;
7023 for $dirent (readdir $dh) {
7024 next if $dirent =~ /^\.\.?$/;
7025 my $path = File::Spec->catdir($dir,$dirent);
7027 push @dirs, $dirent;
7028 } elsif (-f $path) {
7029 push @files, $dirent;
7032 if (@dirs && @files) {
7033 return "both files[@files] and directories[@dirs]";
7034 } elsif (@files > 2) {
7035 return "several files[@files] but no Makefile.PL or Build.PL";
7040 #-> CPAN;:Distribution::_exefile_stanza
7041 sub _exefile_stanza {
7042 my($self,$build_dir,$local_file) = @_;
7044 my $fh = FileHandle->new;
7045 my $script_file = File::Spec->catfile($build_dir,$local_file);
7046 $fh->open($script_file)
7047 or Carp::croak("Could not open script '$script_file': $!");
7049 # name parsen und prereq
7050 my($state) = "poddir";
7051 my($name, $prereq) = ("", "");
7053 if ($state eq "poddir" && /^=head\d\s+(\S+)/) {
7056 } elsif ($1 eq 'PREREQUISITES') {
7059 } elsif ($state =~ m{^(name|prereq)$}) {
7064 } elsif ($state eq "name") {
7069 } elsif ($state eq "prereq") {
7072 } elsif (/^=cut\b/) {
7079 s{.*<}{}; # strip X<...>
7083 $prereq = join " ", split /\s+/, $prereq;
7084 my($PREREQ_PM) = join("\n", map {
7085 s{.*<}{}; # strip X<...>
7087 if (/[\s\'\"]/) { # prose?
7089 s/[^\w:]$//; # period?
7090 " "x28 . "'$_' => 0,";
7092 } split /\s*,\s*/, $prereq);
7095 my $to_file = File::Spec->catfile($build_dir, $name);
7096 rename $script_file, $to_file
7097 or die "Can't rename $script_file to $to_file: $!";
7101 EXE_FILES => ['$name'],
7108 #-> CPAN::Distribution::_signature_business
7109 sub _signature_business {
7111 my $check_sigs = CPAN::HandleConfig->prefs_lookup($self,
7114 if ($CPAN::META->has_inst("Module::Signature")) {
7115 if (-f "SIGNATURE") {
7116 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
7117 my $rv = Module::Signature::verify();
7118 if ($rv != Module::Signature::SIGNATURE_OK() and
7119 $rv != Module::Signature::SIGNATURE_MISSING()) {
7120 $CPAN::Frontend->mywarn(
7121 qq{\nSignature invalid for }.
7122 qq{distribution file. }.
7123 qq{Please investigate.\n\n}
7127 sprintf(qq{I'd recommend removing %s. Some error occured }.
7128 qq{while checking its signature, so it could }.
7129 qq{be invalid. Maybe you have configured }.
7130 qq{your 'urllist' with a bad URL. Please check this }.
7131 qq{array with 'o conf urllist' and retry. Or }.
7132 qq{examine the distribution in a subshell. Try
7140 $self->{signature_verify} = CPAN::Distrostatus->new("NO");
7141 $CPAN::Frontend->mywarn(Text::Wrap::wrap("","",$wrap));
7142 $CPAN::Frontend->mysleep(5) if $CPAN::Frontend->can("mysleep");
7144 $self->{signature_verify} = CPAN::Distrostatus->new("YES");
7145 $self->debug("Module::Signature has verified") if $CPAN::DEBUG;
7148 $CPAN::Frontend->mywarn(qq{Package came without SIGNATURE\n\n});
7151 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
7156 #-> CPAN::Distribution::untar_me ;
7159 $self->{archived} = "tar";
7160 my $result = eval { $ct->untar() };
7162 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
7164 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- untar failed");
7168 # CPAN::Distribution::unzip_me ;
7171 $self->{archived} = "zip";
7173 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
7175 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- unzip failed");
7180 sub handle_singlefile {
7181 my($self,$local_file) = @_;
7183 if ( $local_file =~ /\.pm(\.(gz|Z))?(?!\n)\Z/ ) {
7184 $self->{archived} = "pm";
7185 } elsif ( $local_file =~ /\.patch(\.(gz|bz2))?(?!\n)\Z/ ) {
7186 $self->{archived} = "patch";
7188 $self->{archived} = "maybe_pl";
7191 my $to = File::Basename::basename($local_file);
7192 if ($to =~ s/\.(gz|Z)(?!\n)\Z//) {
7193 if (eval{CPAN::Tarzip->new($local_file)->gunzip($to)}) {
7194 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
7196 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- uncompressing failed");
7199 if (File::Copy::cp($local_file,".")) {
7200 $self->{unwrapped} = CPAN::Distrostatus->new("YES");
7202 $self->{unwrapped} = CPAN::Distrostatus->new("NO -- copying failed");
7208 #-> sub CPAN::Distribution::new ;
7210 my($class,%att) = @_;
7212 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
7214 my $this = { %att };
7215 return bless $this, $class;
7218 #-> sub CPAN::Distribution::look ;
7222 if ($^O eq 'MacOS') {
7223 $self->Mac::BuildTools::look;
7227 if ( $CPAN::Config->{'shell'} ) {
7228 $CPAN::Frontend->myprint(qq{
7229 Trying to open a subshell in the build directory...
7232 $CPAN::Frontend->myprint(qq{
7233 Your configuration does not define a value for subshells.
7234 Please define it with "o conf shell <your shell>"
7238 my $dist = $self->id;
7240 unless ($dir = $self->dir) {
7243 unless ($dir ||= $self->dir) {
7244 $CPAN::Frontend->mywarn(qq{
7245 Could not determine which directory to use for looking at $dist.
7249 my $pwd = CPAN::anycwd();
7250 $self->safe_chdir($dir);
7251 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
7253 local $ENV{CPAN_SHELL_LEVEL} = $ENV{CPAN_SHELL_LEVEL}||0;
7254 $ENV{CPAN_SHELL_LEVEL} += 1;
7255 my $shell = CPAN::HandleConfig->safe_quote($CPAN::Config->{'shell'});
7257 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
7259 : ($ENV{PERLLIB} || "");
7261 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
7262 $CPAN::META->set_perl5lib;
7263 local $ENV{MAKEFLAGS}; # protect us from outer make calls
7265 unless (system($shell) == 0) {
7267 $CPAN::Frontend->mywarn("Subprocess shell exit code $code\n");
7270 $self->safe_chdir($pwd);
7273 # CPAN::Distribution::cvs_import ;
7277 my $dir = $self->dir;
7279 my $package = $self->called_for;
7280 my $module = $CPAN::META->instance('CPAN::Module', $package);
7281 my $version = $module->cpan_version;
7283 my $userid = $self->cpan_userid;
7285 my $cvs_dir = (split /\//, $dir)[-1];
7286 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
7288 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
7290 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
7291 if ($cvs_site_perl) {
7292 $cvs_dir = "$cvs_site_perl/$cvs_dir";
7294 my $cvs_log = qq{"imported $package $version sources"};
7295 $version =~ s/\./_/g;
7296 # XXX cvs: undocumented and unclear how it was meant to work
7297 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
7298 "$cvs_dir", $userid, "v$version");
7300 my $pwd = CPAN::anycwd();
7301 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
7303 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
7305 $CPAN::Frontend->myprint(qq{@cmd\n});
7306 system(@cmd) == 0 or
7308 $CPAN::Frontend->mydie("cvs import failed");
7309 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
7312 #-> sub CPAN::Distribution::readme ;
7315 my($dist) = $self->id;
7316 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
7317 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
7320 File::Spec->catfile(
7321 $CPAN::Config->{keep_source_where},
7324 split(/\//,"$sans.readme"),
7326 $self->debug("Doing localize") if $CPAN::DEBUG;
7327 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
7329 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
7331 if ($^O eq 'MacOS') {
7332 Mac::BuildTools::launch_file($local_file);
7336 my $fh_pager = FileHandle->new;
7337 local($SIG{PIPE}) = "IGNORE";
7338 my $pager = $CPAN::Config->{'pager'} || "cat";
7339 $fh_pager->open("|$pager")
7340 or die "Could not open pager $pager\: $!";
7341 my $fh_readme = FileHandle->new;
7342 $fh_readme->open($local_file)
7343 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
7344 $CPAN::Frontend->myprint(qq{
7349 $fh_pager->print(<$fh_readme>);
7353 #-> sub CPAN::Distribution::verifyCHECKSUM ;
7354 sub verifyCHECKSUM {
7358 $self->{CHECKSUM_STATUS} ||= "";
7359 $self->{CHECKSUM_STATUS} eq "OK" and push @e, "Checksum was ok";
7360 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
7362 my($lc_want,$lc_file,@local,$basename);
7363 @local = split(/\//,$self->id);
7365 push @local, "CHECKSUMS";
7367 File::Spec->catfile($CPAN::Config->{keep_source_where},
7368 "authors", "id", @local);
7370 if (my $size = -s $lc_want) {
7371 $self->debug("lc_want[$lc_want]size[$size]") if $CPAN::DEBUG;
7372 if ($self->CHECKSUM_check_file($lc_want,1)) {
7373 return $self->{CHECKSUM_STATUS} = "OK";
7376 $lc_file = CPAN::FTP->localize("authors/id/@local",
7379 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
7380 $local[-1] .= ".gz";
7381 $lc_file = CPAN::FTP->localize("authors/id/@local",
7384 $lc_file =~ s/\.gz(?!\n)\Z//;
7385 eval{CPAN::Tarzip->new("$lc_file.gz")->gunzip($lc_file)};
7390 if ($self->CHECKSUM_check_file($lc_file)) {
7391 return $self->{CHECKSUM_STATUS} = "OK";
7395 #-> sub CPAN::Distribution::SIG_check_file ;
7396 sub SIG_check_file {
7397 my($self,$chk_file) = @_;
7398 my $rv = eval { Module::Signature::_verify($chk_file) };
7400 if ($rv == Module::Signature::SIGNATURE_OK()) {
7401 $CPAN::Frontend->myprint("Signature for $chk_file ok\n");
7402 return $self->{SIG_STATUS} = "OK";
7404 $CPAN::Frontend->myprint(qq{\nSignature invalid for }.
7405 qq{distribution file. }.
7406 qq{Please investigate.\n\n}.
7408 $CPAN::META->instance(
7413 my $wrap = qq{I\'d recommend removing $chk_file. Its signature
7414 is invalid. Maybe you have configured your 'urllist' with
7415 a bad URL. Please check this array with 'o conf urllist', and
7418 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
7422 #-> sub CPAN::Distribution::CHECKSUM_check_file ;
7424 # sloppy is 1 when we have an old checksums file that maybe is good
7427 sub CHECKSUM_check_file {
7428 my($self,$chk_file,$sloppy) = @_;
7429 my($cksum,$file,$basename);
7432 $self->debug("chk_file[$chk_file]sloppy[$sloppy]") if $CPAN::DEBUG;
7433 my $check_sigs = CPAN::HandleConfig->prefs_lookup($self,
7436 if ($CPAN::META->has_inst("Module::Signature")) {
7437 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
7438 $self->SIG_check_file($chk_file);
7440 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
7444 $file = $self->{localfile};
7445 $basename = File::Basename::basename($file);
7446 my $fh = FileHandle->new;
7447 if (open $fh, $chk_file) {
7450 $eval =~ s/\015?\012/\n/g;
7452 my($compmt) = Safe->new();
7453 $cksum = $compmt->reval($eval);
7455 rename $chk_file, "$chk_file.bad";
7456 Carp::confess($@) if $@;
7459 Carp::carp "Could not open $chk_file for reading";
7462 if (! ref $cksum or ref $cksum ne "HASH") {
7463 $CPAN::Frontend->mywarn(qq{
7464 Warning: checksum file '$chk_file' broken.
7466 When trying to read that file I expected to get a hash reference
7467 for further processing, but got garbage instead.
7469 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed nonetheless?", "no");
7470 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
7471 $self->{CHECKSUM_STATUS} = "NIL -- CHECKSUMS file broken";
7473 } elsif (exists $cksum->{$basename}{sha256}) {
7474 $self->debug("Found checksum for $basename:" .
7475 "$cksum->{$basename}{sha256}\n") if $CPAN::DEBUG;
7479 my $eq = $self->eq_CHECKSUM($fh,$cksum->{$basename}{sha256});
7481 $fh = CPAN::Tarzip->TIEHANDLE($file);
7484 my $dg = Digest::SHA->new(256);
7487 while ($fh->READ($ref, 4096) > 0) {
7490 my $hexdigest = $dg->hexdigest;
7491 $eq += $hexdigest eq $cksum->{$basename}{'sha256-ungz'};
7495 $CPAN::Frontend->myprint("Checksum for $file ok\n");
7496 return $self->{CHECKSUM_STATUS} = "OK";
7498 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
7499 qq{distribution file. }.
7500 qq{Please investigate.\n\n}.
7502 $CPAN::META->instance(
7507 my $wrap = qq{I\'d recommend removing $file. Its
7508 checksum is incorrect. Maybe you have configured your 'urllist' with
7509 a bad URL. Please check this array with 'o conf urllist', and
7512 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
7514 # former versions just returned here but this seems a
7515 # serious threat that deserves a die
7517 # $CPAN::Frontend->myprint("\n\n");
7521 # close $fh if fileno($fh);
7524 unless ($self->{CHECKSUM_STATUS}) {
7525 $CPAN::Frontend->mywarn(qq{
7526 Warning: No checksum for $basename in $chk_file.
7528 The cause for this may be that the file is very new and the checksum
7529 has not yet been calculated, but it may also be that something is
7530 going awry right now.
7532 my $answer = CPAN::Shell::colorable_makemaker_prompt("Proceed?", "yes");
7533 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.\n");
7535 $self->{CHECKSUM_STATUS} = "NIL -- distro not in CHECKSUMS file";
7540 #-> sub CPAN::Distribution::eq_CHECKSUM ;
7542 my($self,$fh,$expect) = @_;
7543 if ($CPAN::META->has_inst("Digest::SHA")) {
7544 my $dg = Digest::SHA->new(256);
7546 while (read($fh, $data, 4096)) {
7549 my $hexdigest = $dg->hexdigest;
7550 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
7551 return $hexdigest eq $expect;
7556 #-> sub CPAN::Distribution::force ;
7558 # Both CPAN::Modules and CPAN::Distributions know if "force" is in
7559 # effect by autoinspection, not by inspecting a global variable. One
7560 # of the reason why this was chosen to work that way was the treatment
7561 # of dependencies. They should not automatically inherit the force
7562 # status. But this has the downside that ^C and die() will return to
7563 # the prompt but will not be able to reset the force_update
7564 # attributes. We try to correct for it currently in the read_metadata
7565 # routine, and immediately before we check for a Signal. I hope this
7566 # works out in one of v1.57_53ff
7568 # "Force get forgets previous error conditions"
7570 #-> sub CPAN::Distribution::fforce ;
7572 my($self, $method) = @_;
7573 $self->force($method,1);
7576 #-> sub CPAN::Distribution::force ;
7578 my($self, $method,$fforce) = @_;
7596 "prereq_pm_detected",
7610 my $methodmatch = 0;
7612 PHASE: for my $phase (qw(unknown get make test install)) { # order matters
7613 $methodmatch = 1 if $fforce || $phase eq $method;
7614 next unless $methodmatch;
7615 ATTRIBUTE: for my $att (@{$phase_map{$phase}}) {
7616 if ($phase eq "get") {
7617 if (substr($self->id,-1,1) eq "."
7618 && $att =~ /(unwrapped|build_dir|archived)/ ) {
7619 # cannot be undone for local distros
7622 if ($att eq "build_dir"
7623 && $self->{build_dir}
7624 && $CPAN::META->{is_tested}
7626 delete $CPAN::META->{is_tested}{$self->{build_dir}};
7628 } elsif ($phase eq "test") {
7629 if ($att eq "make_test"
7630 && $self->{make_test}
7631 && $self->{make_test}{COMMANDID}
7632 && $self->{make_test}{COMMANDID} == $CPAN::CurrentCommandId
7634 # endless loop too likely
7638 delete $self->{$att};
7639 if ($ldebug || $CPAN::DEBUG) {
7640 # local $CPAN::DEBUG = 16; # Distribution
7641 CPAN->debug(sprintf "id[%s]phase[%s]att[%s]", $self->id, $phase, $att);
7645 if ($method && $method =~ /make|test|install/) {
7646 $self->{force_update} = 1; # name should probably have been force_install
7650 #-> sub CPAN::Distribution::notest ;
7652 my($self, $method) = @_;
7653 # $CPAN::Frontend->mywarn("XDEBUG: set notest for $self $method");
7654 $self->{"notest"}++; # name should probably have been force_install
7657 #-> sub CPAN::Distribution::unnotest ;
7660 # warn "XDEBUG: deleting notest";
7661 delete $self->{notest};
7664 #-> sub CPAN::Distribution::unforce ;
7667 delete $self->{force_update};
7670 #-> sub CPAN::Distribution::isa_perl ;
7673 my $file = File::Basename::basename($self->id);
7674 if ($file =~ m{ ^ perl
7683 \.tar[._-](?:gz|bz2)
7687 } elsif ($self->cpan_comment
7689 $self->cpan_comment =~ /isa_perl\(.+?\)/) {
7695 #-> sub CPAN::Distribution::perl ;
7700 carp __PACKAGE__ . "::perl was called without parameters.";
7702 return CPAN::HandleConfig->safe_quote($CPAN::Perl);
7706 #-> sub CPAN::Distribution::make ;
7709 if (my $goto = $self->prefs->{goto}) {
7710 return $self->goto($goto);
7712 my $make = $self->{modulebuild} ? "Build" : "make";
7713 # Emergency brake if they said install Pippi and get newest perl
7714 if ($self->isa_perl) {
7716 $self->called_for ne $self->id &&
7717 ! $self->{force_update}
7719 # if we die here, we break bundles
7722 qq{The most recent version "%s" of the module "%s"
7723 is part of the perl-%s distribution. To install that, you need to run
7724 force install %s --or--
7727 $CPAN::META->instance(
7736 $self->{make} = CPAN::Distrostatus->new("NO isa perl");
7737 $CPAN::Frontend->mysleep(1);
7741 $CPAN::Frontend->myprint(sprintf "Running %s for %s\n", $make, $self->id);
7743 return if $self->prefs->{disabled} && ! $self->{force_update};
7744 if ($self->{configure_requires_later}) {
7747 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
7749 : ($ENV{PERLLIB} || "");
7750 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
7751 $CPAN::META->set_perl5lib;
7752 local $ENV{MAKEFLAGS}; # protect us from outer make calls
7754 if ($CPAN::Signal) {
7755 delete $self->{force_update};
7762 if (!$self->{archived} || $self->{archived} eq "NO") {
7763 push @e, "Is neither a tar nor a zip archive.";
7766 if (!$self->{unwrapped}
7768 UNIVERSAL::can($self->{unwrapped},"failed") ?
7769 $self->{unwrapped}->failed :
7770 $self->{unwrapped} =~ /^NO/
7772 push @e, "Had problems unarchiving. Please build manually";
7775 unless ($self->{force_update}) {
7776 exists $self->{signature_verify} and
7778 UNIVERSAL::can($self->{signature_verify},"failed") ?
7779 $self->{signature_verify}->failed :
7780 $self->{signature_verify} =~ /^NO/
7782 and push @e, "Did not pass the signature test.";
7785 if (exists $self->{writemakefile} &&
7787 UNIVERSAL::can($self->{writemakefile},"failed") ?
7788 $self->{writemakefile}->failed :
7789 $self->{writemakefile} =~ /^NO/
7791 # XXX maybe a retry would be in order?
7792 my $err = UNIVERSAL::can($self->{writemakefile},"text") ?
7793 $self->{writemakefile}->text :
7794 $self->{writemakefile};
7795 $err =~ s/^NO\s*(--\s+)?//;
7796 $err ||= "Had some problem writing Makefile";
7797 $err .= ", won't make";
7801 if (defined $self->{make}) {
7802 if (UNIVERSAL::can($self->{make},"failed") ?
7803 $self->{make}->failed :
7804 $self->{make} =~ /^NO/) {
7805 if ($self->{force_update}) {
7806 # Trying an already failed 'make' (unless somebody else blocks)
7808 # introduced for turning recursion detection into a distrostatus
7809 my $error = length $self->{make}>3
7810 ? substr($self->{make},3) : "Unknown error";
7811 $CPAN::Frontend->mywarn("Could not make: $error\n");
7812 $self->store_persistent_state;
7816 push @e, "Has already been made";
7817 my $wait_for_prereqs = eval { $self->satisfy_requires };
7818 return 1 if $wait_for_prereqs; # tells queuerunner to continue
7819 return $self->goodbye($@) if $@; # tells queuerunner to stop
7823 my $later = $self->{later} || $self->{configure_requires_later};
7824 if ($later) { # see also undelay
7830 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
7831 $builddir = $self->dir or
7832 $CPAN::Frontend->mydie("PANIC: Cannot determine build directory\n");
7833 unless (chdir $builddir) {
7834 push @e, "Couldn't chdir to '$builddir': $!";
7836 $CPAN::Frontend->mywarn(join "", map {" $_\n"} @e) and return if @e;
7838 if ($CPAN::Signal) {
7839 delete $self->{force_update};
7842 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
7843 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
7845 if ($^O eq 'MacOS') {
7846 Mac::BuildTools::make($self);
7851 while (my($k,$v) = each %ENV) {
7852 next unless defined $v;
7858 if ($self->prefs->{pl}) {
7859 $pl_commandline = $self->prefs->{pl}{commandline};
7861 if ($pl_commandline) {
7862 $system = $pl_commandline;
7864 } elsif ($self->{'configure'}) {
7865 $system = $self->{'configure'};
7866 } elsif ($self->{modulebuild}) {
7867 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
7868 $system = "$perl Build.PL $CPAN::Config->{mbuildpl_arg}";
7870 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
7872 # This needs a handler that can be turned on or off:
7873 # $switch = "-MExtUtils::MakeMaker ".
7874 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
7876 my $makepl_arg = $self->_make_phase_arg("pl");
7877 $ENV{PERL5_CPAN_IS_EXECUTING} = File::Spec->catfile($self->{build_dir},
7879 $system = sprintf("%s%s Makefile.PL%s",
7881 $switch ? " $switch" : "",
7882 $makepl_arg ? " $makepl_arg" : "",
7886 if ($self->prefs->{pl}) {
7887 $pl_env = $self->prefs->{pl}{env};
7890 for my $e (keys %$pl_env) {
7891 $ENV{$e} = $pl_env->{$e};
7894 if (exists $self->{writemakefile}) {
7896 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
7897 my($ret,$pid,$output);
7900 if ($CPAN::Config->{inactivity_timeout}) {
7902 if ($Config::Config{d_alarm}
7904 $Config::Config{d_alarm} eq "define"
7908 $CPAN::Frontend->mywarn("Warning: you have configured the config ".
7909 "variable 'inactivity_timeout' to ".
7910 "'$CPAN::Config->{inactivity_timeout}'. But ".
7911 "on this machine the system call 'alarm' ".
7912 "isn't available. This means that we cannot ".
7913 "provide the feature of intercepting long ".
7914 "waiting code and will turn this feature off.\n"
7916 $CPAN::Config->{inactivity_timeout} = 0;
7919 if ($go_via_alarm) {
7920 if ( $self->_should_report('pl') ) {
7921 ($output, $ret) = CPAN::Reporter::record_command(
7923 $CPAN::Config->{inactivity_timeout},
7925 CPAN::Reporter::grade_PL( $self, $system, $output, $ret );
7929 alarm $CPAN::Config->{inactivity_timeout};
7930 local $SIG{CHLD}; # = sub { wait };
7931 if (defined($pid = fork)) {
7936 # note, this exec isn't necessary if
7937 # inactivity_timeout is 0. On the Mac I'd
7938 # suggest, we set it always to 0.
7942 $CPAN::Frontend->myprint("Cannot fork: $!");
7951 $CPAN::Frontend->myprint($err);
7952 $self->{writemakefile} = CPAN::Distrostatus->new("NO $err");
7954 $self->store_persistent_state;
7955 return $self->goodbye("$system -- TIMED OUT");
7959 if (my $expect_model = $self->_prefs_with_expect("pl")) {
7960 # XXX probably want to check _should_report here and warn
7961 # about not being able to use CPAN::Reporter with expect
7962 $ret = $self->_run_via_expect($system,'writemakefile',$expect_model);
7964 && $self->{writemakefile}
7965 && $self->{writemakefile}->failed) {
7970 elsif ( $self->_should_report('pl') ) {
7971 ($output, $ret) = CPAN::Reporter::record_command($system);
7972 CPAN::Reporter::grade_PL( $self, $system, $output, $ret );
7975 $ret = system($system);
7978 $self->{writemakefile} = CPAN::Distrostatus
7979 ->new("NO '$system' returned status $ret");
7980 $CPAN::Frontend->mywarn("Warning: No success on command[$system]\n");
7981 $self->store_persistent_state;
7982 return $self->goodbye("$system -- NOT OK");
7985 if (-f "Makefile" || -f "Build") {
7986 $self->{writemakefile} = CPAN::Distrostatus->new("YES");
7987 delete $self->{make_clean}; # if cleaned before, enable next
7989 my $makefile = $self->{modulebuild} ? "Build" : "Makefile";
7990 my $why = "No '$makefile' created";
7991 $CPAN::Frontend->mywarn($why);
7992 $self->{writemakefile} = CPAN::Distrostatus
7993 ->new(qq{NO -- $why\n});
7994 $self->store_persistent_state;
7995 return $self->goodbye("$system -- NOT OK");
7998 if ($CPAN::Signal) {
7999 delete $self->{force_update};
8002 my $wait_for_prereqs = eval { $self->satisfy_requires };
8003 return 1 if $wait_for_prereqs; # tells queuerunner to continue
8004 return $self->goodbye($@) if $@; # tells queuerunner to stop
8005 if ($CPAN::Signal) {
8006 delete $self->{force_update};
8009 my $make_commandline;
8010 if ($self->prefs->{make}) {
8011 $make_commandline = $self->prefs->{make}{commandline};
8013 if ($make_commandline) {
8014 $system = $make_commandline;
8015 $ENV{PERL} = CPAN::find_perl;
8017 if ($self->{modulebuild}) {
8018 unless (-f "Build") {
8019 my $cwd = CPAN::anycwd();
8020 $CPAN::Frontend->mywarn("Alert: no Build file available for 'make $self->{id}'".
8021 " in cwd[$cwd]. Danger, Will Robinson!\n");
8022 $CPAN::Frontend->mysleep(5);
8024 $system = join " ", $self->_build_command(), $CPAN::Config->{mbuild_arg};
8026 $system = join " ", $self->_make_command(), $CPAN::Config->{make_arg};
8028 $system =~ s/\s+$//;
8029 my $make_arg = $self->_make_phase_arg("make");
8030 $system = sprintf("%s%s",
8032 $make_arg ? " $make_arg" : "",
8036 if ($self->prefs->{make}) {
8037 $make_env = $self->prefs->{make}{env};
8039 if ($make_env) { # overriding the local ENV of PL, not the outer
8040 # ENV, but unlikely to be a risk
8041 for my $e (keys %$make_env) {
8042 $ENV{$e} = $make_env->{$e};
8045 my $expect_model = $self->_prefs_with_expect("make");
8046 my $want_expect = 0;
8047 if ( $expect_model && @{$expect_model->{talk}} ) {
8048 my $can_expect = $CPAN::META->has_inst("Expect");
8052 $CPAN::Frontend->mywarn("Expect not installed, falling back to ".
8058 # XXX probably want to check _should_report here and
8059 # warn about not being able to use CPAN::Reporter with expect
8060 $system_ok = $self->_run_via_expect($system,'make',$expect_model) == 0;
8062 elsif ( $self->_should_report('make') ) {
8063 my ($output, $ret) = CPAN::Reporter::record_command($system);
8064 CPAN::Reporter::grade_make( $self, $system, $output, $ret );
8065 $system_ok = ! $ret;
8068 $system_ok = system($system) == 0;
8070 $self->introduce_myself;
8072 $CPAN::Frontend->myprint(" $system -- OK\n");
8073 $self->{make} = CPAN::Distrostatus->new("YES");
8075 $self->{writemakefile} ||= CPAN::Distrostatus->new("YES");
8076 $self->{make} = CPAN::Distrostatus->new("NO");
8077 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
8079 $self->store_persistent_state;
8082 # CPAN::Distribution::goodbye ;
8084 my($self,$goodbye) = @_;
8085 my $id = $self->pretty_id;
8086 $CPAN::Frontend->mywarn(" $id\n $goodbye\n");
8090 # CPAN::Distribution::_run_via_expect ;
8091 sub _run_via_expect {
8092 my($self,$system,$phase,$expect_model) = @_;
8093 CPAN->debug("system[$system]expect_model[$expect_model]") if $CPAN::DEBUG;
8094 if ($CPAN::META->has_inst("Expect")) {
8095 my $expo = Expect->new; # expo Expect object;
8096 $expo->spawn($system);
8097 $expect_model->{mode} ||= "deterministic";
8098 if ($expect_model->{mode} eq "deterministic") {
8099 return $self->_run_via_expect_deterministic($expo,$phase,$expect_model);
8100 } elsif ($expect_model->{mode} eq "anyorder") {
8101 return $self->_run_via_expect_anyorder($expo,$phase,$expect_model);
8103 die "Panic: Illegal expect mode: $expect_model->{mode}";
8106 $CPAN::Frontend->mywarn("Expect not installed, falling back to system()\n");
8107 return system($system);
8111 sub _run_via_expect_anyorder {
8112 my($self,$expo,$phase,$expect_model) = @_;
8113 my $timeout = $expect_model->{timeout} || 5;
8114 my $reuse = $expect_model->{reuse};
8115 my @expectacopy = @{$expect_model->{talk}}; # we trash it!
8117 my $timeout_start = time;
8119 my($eof,$ran_into_timeout);
8120 # XXX not up to the full power of expect. one could certainly
8121 # wrap all of the talk pairs into a single expect call and on
8122 # success tweak it and step ahead to the next question. The
8123 # current implementation unnecessarily limits itself to a
8125 my @match = $expo->expect(1,
8130 $ran_into_timeout++;
8137 $but .= $expo->clear_accum;
8140 return $expo->exitstatus();
8141 } elsif ($ran_into_timeout) {
8142 # warn "DEBUG: they are asking a question, but[$but]";
8143 for (my $i = 0; $i <= $#expectacopy; $i+=2) {
8144 my($next,$send) = @expectacopy[$i,$i+1];
8145 my $regex = eval "qr{$next}";
8146 # warn "DEBUG: will compare with regex[$regex].";
8147 if ($but =~ /$regex/) {
8148 # warn "DEBUG: will send send[$send]";
8150 # never allow reusing an QA pair unless they told us
8151 splice @expectacopy, $i, 2 unless $reuse;
8155 my $have_waited = time - $timeout_start;
8156 if ($have_waited < $timeout) {
8157 # warn "DEBUG: have_waited[$have_waited]timeout[$timeout]";
8160 my $why = "could not answer a question during the dialog";
8161 $CPAN::Frontend->mywarn("Failing: $why\n");
8163 CPAN::Distrostatus->new("NO $why");
8169 sub _run_via_expect_deterministic {
8170 my($self,$expo,$phase,$expect_model) = @_;
8171 my $ran_into_timeout;
8173 my $timeout = $expect_model->{timeout} || 15; # currently unsettable
8174 my $expecta = $expect_model->{talk};
8175 EXPECT: for (my $i = 0; $i <= $#$expecta; $i+=2) {
8176 my($re,$send) = @$expecta[$i,$i+1];
8177 CPAN->debug("timeout[$timeout]re[$re]") if $CPAN::DEBUG;
8178 my $regex = eval "qr{$re}";
8179 $expo->expect($timeout,
8181 my $but = $expo->clear_accum;
8182 $CPAN::Frontend->mywarn("EOF (maybe harmless)
8183 expected[$regex]\nbut[$but]\n\n");
8187 my $but = $expo->clear_accum;
8188 $CPAN::Frontend->mywarn("TIMEOUT
8189 expected[$regex]\nbut[$but]\n\n");
8190 $ran_into_timeout++;
8193 if ($ran_into_timeout) {
8194 # note that the caller expects 0 for success
8196 CPAN::Distrostatus->new("NO timeout during expect dialog");
8198 } elsif ($ran_into_eof) {
8204 return $expo->exitstatus();
8207 #-> CPAN::Distribution::_validate_distropref
8208 sub _validate_distropref {
8209 my($self,@args) = @_;
8211 $CPAN::META->has_inst("CPAN::Kwalify")
8213 $CPAN::META->has_inst("Kwalify")
8215 eval {CPAN::Kwalify::_validate("distroprefs",@args);};
8217 $CPAN::Frontend->mywarn($@);
8220 CPAN->debug("not validating '@args'") if $CPAN::DEBUG;
8224 #-> CPAN::Distribution::_find_prefs
8227 my $distroid = $self->pretty_id;
8228 #CPAN->debug("distroid[$distroid]") if $CPAN::DEBUG;
8229 my $prefs_dir = $CPAN::Config->{prefs_dir};
8230 return if $prefs_dir =~ /^\s*$/;
8231 eval { File::Path::mkpath($prefs_dir); };
8233 $CPAN::Frontend->mydie("Cannot create directory $prefs_dir");
8235 my $yaml_module = CPAN::_yaml_module;
8238 if ($CPAN::META->has_inst($yaml_module)) {
8239 $ext_map->{yml} = 'CPAN';
8242 if ($CPAN::META->has_inst("Data::Dumper")) {
8243 push @fallbacks, $ext_map->{dd} = 'Data::Dumper';
8245 if ($CPAN::META->has_inst("Storable")) {
8246 push @fallbacks, $ext_map->{st} = 'Storable';
8250 unless ($self->{have_complained_about_missing_yaml}++) {
8251 $CPAN::Frontend->mywarn("'$yaml_module' not installed, falling back ".
8252 "to @fallbacks to read prefs '$prefs_dir'\n");
8255 unless ($self->{have_complained_about_missing_yaml}++) {
8256 $CPAN::Frontend->mywarn("'$yaml_module' not installed, cannot ".
8257 "read prefs '$prefs_dir'\n");
8261 my $finder = CPAN::Distroprefs->find($prefs_dir, $ext_map);
8262 DIRENT: while (my $result = $finder->next) {
8263 if ($result->is_warning) {
8264 $CPAN::Frontend->mywarn($result->as_string);
8265 $CPAN::Frontend->mysleep(1);
8267 } elsif ($result->is_fatal) {
8268 $CPAN::Frontend->mydie($result->as_string);
8271 my @prefs = @{ $result->prefs };
8273 ELEMENT: for my $y (0..$#prefs) {
8274 my $pref = $prefs[$y];
8275 $self->_validate_distropref($pref->data, $result->abs, $y);
8277 # I don't know why we silently skip when there's no match, but
8278 # complain if there's an empty match hashref, and there's no
8279 # comment explaining why -- hdp, 2008-03-18
8280 unless ($pref->has_any_match) {
8284 unless ($pref->has_valid_subkeys) {
8285 $CPAN::Frontend->mydie(sprintf
8286 "Nonconforming .%s file '%s': " .
8287 "missing match/* subattribute. " .
8288 "Please remove, cannot continue.",
8289 $result->ext, $result->abs,
8295 distribution => $distroid,
8296 perl => \&CPAN::find_perl,
8297 perlconfig => \%Config::Config,
8298 module => sub { [ $self->containsmods ] },
8301 if ($pref->matches($arg)) {
8303 prefs => $pref->data,
8304 prefs_file => $result->abs,
8305 prefs_file_doc => $y,
8314 # CPAN::Distribution::prefs
8317 if (exists $self->{negative_prefs_cache}
8319 $self->{negative_prefs_cache} != $CPAN::CurrentCommandId
8321 delete $self->{negative_prefs_cache};
8322 delete $self->{prefs};
8324 if (exists $self->{prefs}) {
8325 return $self->{prefs}; # XXX comment out during debugging
8327 if ($CPAN::Config->{prefs_dir}) {
8328 CPAN->debug("prefs_dir[$CPAN::Config->{prefs_dir}]") if $CPAN::DEBUG;
8329 my $prefs = $self->_find_prefs();
8330 $prefs ||= ""; # avoid warning next line
8331 CPAN->debug("prefs[$prefs]") if $CPAN::DEBUG;
8333 for my $x (qw(prefs prefs_file prefs_file_doc)) {
8334 $self->{$x} = $prefs->{$x};
8338 File::Basename::basename($self->{prefs_file}),
8339 $self->{prefs_file_doc},
8341 my $filler1 = "_" x 22;
8342 my $filler2 = int(66 - length($bs))/2;
8343 $filler2 = 0 if $filler2 < 0;
8344 $filler2 = " " x $filler2;
8345 $CPAN::Frontend->myprint("
8346 $filler1 D i s t r o P r e f s $filler1
8347 $filler2 $bs $filler2
8349 $CPAN::Frontend->mysleep(1);
8350 return $self->{prefs};
8353 $self->{negative_prefs_cache} = $CPAN::CurrentCommandId;
8354 return $self->{prefs} = +{};
8357 # CPAN::Distribution::_make_phase_arg
8358 sub _make_phase_arg {
8359 my($self, $phase) = @_;
8360 my $_make_phase_arg;
8361 my $prefs = $self->prefs;
8364 && exists $prefs->{$phase}
8365 && exists $prefs->{$phase}{args}
8366 && $prefs->{$phase}{args}
8368 $_make_phase_arg = join(" ",
8369 map {CPAN::HandleConfig
8370 ->safe_quote($_)} @{$prefs->{$phase}{args}},
8374 # cpan[2]> o conf make[TAB]
8375 # make make_install_make_command
8376 # make_arg makepl_arg
8378 # cpan[2]> o conf mbuild[TAB]
8379 # mbuild_arg mbuild_install_build_command
8380 # mbuild_install_arg mbuildpl_arg
8382 my $mantra; # must switch make/mbuild here
8383 if ($self->{modulebuild}) {
8391 test => "_test_arg", # does not really exist but maybe
8392 # will some day and now protects
8393 # us from unini warnings
8394 install => "_install_arg",
8396 my $phase_underscore_meshup = $map{$phase};
8397 my $what = sprintf "%s%s", $mantra, $phase_underscore_meshup;
8399 $_make_phase_arg ||= $CPAN::Config->{$what};
8400 return $_make_phase_arg;
8403 # CPAN::Distribution::_make_command
8410 CPAN::HandleConfig->prefs_lookup($self,
8412 || $Config::Config{make}
8416 # Old style call, without object. Deprecated
8417 Carp::confess("CPAN::_make_command() used as function. Don't Do That.");
8420 CPAN::HandleConfig->prefs_lookup($self,q{make})
8421 || $CPAN::Config->{make}
8422 || $Config::Config{make}
8427 #-> sub CPAN::Distribution::follow_prereqs ;
8428 sub follow_prereqs {
8431 my(@prereq_tuples) = grep {$_->[0] ne "perl"} @_;
8432 return unless @prereq_tuples;
8433 my(@good_prereq_tuples);
8434 for my $p (@prereq_tuples) {
8435 # XXX watch out for foul ones
8436 push @good_prereq_tuples, $p;
8438 my $pretty_id = $self->pretty_id;
8440 b => "build_requires",
8444 my($filler1,$filler2,$filler3,$filler4);
8445 my $unsat = "Unsatisfied dependencies detected during";
8446 my $w = length($unsat) > length($pretty_id) ? length($unsat) : length($pretty_id);
8448 my $r = int(($w - length($unsat))/2);
8449 my $l = $w - length($unsat) - $r;
8450 $filler1 = "-"x4 . " "x$l;
8451 $filler2 = " "x$r . "-"x4 . "\n";
8454 my $r = int(($w - length($pretty_id))/2);
8455 my $l = $w - length($pretty_id) - $r;
8456 $filler3 = "-"x4 . " "x$l;
8457 $filler4 = " "x$r . "-"x4 . "\n";
8460 myprint("$filler1 $unsat $filler2".
8461 "$filler3 $pretty_id $filler4".
8462 join("", map {" $_->[0] \[$map{$_->[1]}]\n"} @good_prereq_tuples),
8465 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
8467 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
8468 my $answer = CPAN::Shell::colorable_makemaker_prompt(
8469 "Shall I follow them and prepend them to the queue
8470 of modules we are processing right now?", "yes");
8471 $follow = $answer =~ /^\s*y/i;
8473 my @prereq = map { $_=>[0] } @good_prereq_tuples;
8476 myprint(" Ignoring dependencies on modules @prereq\n");
8480 # color them as dirty
8481 for my $gp (@good_prereq_tuples) {
8482 # warn "calling color_cmd_tmps(0,1)";
8484 my $any = CPAN::Shell->expandany($p);
8485 $self->{$slot . "_for"}{$any->id}++;
8487 $any->color_cmd_tmps(0,2);
8489 $CPAN::Frontend->mywarn("Warning (maybe a bug): Cannot expand prereq '$p'\n");
8490 $CPAN::Frontend->mysleep(2);
8493 # queue them and re-queue yourself
8494 CPAN::Queue->jumpqueue({qmod => $id, reqtype => $self->{reqtype}},
8495 map {+{qmod=>$_->[0],reqtype=>$_->[1]}} reverse @good_prereq_tuples);
8496 $self->{$slot} = "Delayed until after prerequisites";
8497 return 1; # signal success to the queuerunner
8502 sub _feature_depends {
8504 my $meta_yml = $self->parse_meta_yml();
8505 my $optf = $meta_yml->{optional_features} or return;
8506 if (!ref $optf or ref $optf ne "HASH"){
8507 $CPAN::Frontend->mywarn("The content of optional_features is not a HASH reference. Cannot use it.\n");
8510 my $wantf = $self->prefs->{features} or return;
8511 if (!ref $wantf or ref $wantf ne "ARRAY"){
8512 $CPAN::Frontend->mywarn("The content of 'features' is not an ARRAY reference. Cannot use it.\n");
8516 for my $wf (@$wantf) {
8517 if (my $f = $optf->{$wf}) {
8518 $CPAN::Frontend->myprint("Found the demanded feature '$wf' that ".
8519 "is accompanied by this description:\n".
8523 # configure_requires currently not in the spec, unlikely to be useful anyway
8524 for my $reqtype (qw(configure_requires build_requires requires)) {
8525 my $reqhash = $f->{$reqtype} or next;
8526 while (my($k,$v) = each %$reqhash) {
8527 $dep->{$reqtype}{$k} = $v;
8531 $CPAN::Frontend->mywarn("The demanded feature '$wf' was not ".
8532 "found in the META.yml file".
8540 #-> sub CPAN::Distribution::unsat_prereq ;
8541 # return ([Foo,"r"],[Bar,"b"]) for normal modules
8542 # return ([perl=>5.008]) if we need a newer perl than we are running under
8543 # (sorry for the inconsistency, it was an accident)
8545 my($self,$slot) = @_;
8546 my(%merged,$prereq_pm);
8547 my $prefs_depends = $self->prefs->{depends}||{};
8548 my $feature_depends = $self->_feature_depends();
8549 if ($slot eq "configure_requires_later") {
8550 my $meta_yml = $self->parse_meta_yml();
8551 if (defined $meta_yml && (! ref $meta_yml || ref $meta_yml ne "HASH")) {
8552 $CPAN::Frontend->mywarn("The content of META.yml is defined but not a HASH reference. Cannot use it.\n");
8556 %{$meta_yml->{configure_requires}||{}},
8557 %{$prefs_depends->{configure_requires}||{}},
8558 %{$feature_depends->{configure_requires}||{}},
8560 $prereq_pm = {}; # configure_requires defined as "b"
8561 } elsif ($slot eq "later") {
8562 my $prereq_pm_0 = $self->prereq_pm || {};
8563 for my $reqtype (qw(requires build_requires)) {
8564 $prereq_pm->{$reqtype} = {%{$prereq_pm_0->{$reqtype}||{}}}; # copy to not pollute it
8565 for my $dep ($prefs_depends,$feature_depends) {
8566 for my $k (keys %{$dep->{$reqtype}||{}}) {
8567 $prereq_pm->{$reqtype}{$k} = $dep->{$reqtype}{$k};
8571 %merged = (%{$prereq_pm->{requires}||{}},%{$prereq_pm->{build_requires}||{}});
8573 die "Panic: illegal slot '$slot'";
8576 my @merged = %merged;
8577 CPAN->debug("all merged_prereqs[@merged]") if $CPAN::DEBUG;
8578 NEED: while (my($need_module, $need_version) = each %merged) {
8579 my($available_version,$available_file,$nmo);
8580 if ($need_module eq "perl") {
8581 $available_version = $];
8582 $available_file = CPAN::find_perl;
8584 $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
8585 next if $nmo->uptodate;
8586 $available_file = $nmo->available_file;
8588 # if they have not specified a version, we accept any installed one
8589 if (defined $available_file
8590 and ( # a few quick shortcurcuits
8591 not defined $need_version
8592 or $need_version eq '0' # "==" would trigger warning when not numeric
8593 or $need_version eq "undef"
8598 $available_version = $nmo->available_version;
8601 # We only want to install prereqs if either they're not installed
8602 # or if the installed version is too old. We cannot omit this
8603 # check, because if 'force' is in effect, nobody else will check.
8604 if (defined $available_file) {
8605 my $fulfills_all_version_rqs = $self->_fulfills_all_version_rqs
8606 ($need_module,$available_file,$available_version,$need_version);
8607 next NEED if $fulfills_all_version_rqs;
8610 if ($need_module eq "perl") {
8611 return ["perl", $need_version];
8613 $self->{sponsored_mods}{$need_module} ||= 0;
8614 CPAN->debug("need_module[$need_module]s/s/n[$self->{sponsored_mods}{$need_module}]") if $CPAN::DEBUG;
8615 if (my $sponsoring = $self->{sponsored_mods}{$need_module}++) {
8616 # We have already sponsored it and for some reason it's still
8617 # not available. So we do ... what??
8619 # if we push it again, we have a potential infinite loop
8621 # The following "next" was a very problematic construct.
8622 # It helped a lot but broke some day and had to be
8625 # We must be able to deal with modules that come again and
8626 # again as a prereq and have themselves prereqs and the
8627 # queue becomes long but finally we would find the correct
8628 # order. The RecursiveDependency check should trigger a
8629 # die when it's becoming too weird. Unfortunately removing
8630 # this next breaks many other things.
8632 # The bug that brought this up is described in Todo under
8633 # "5.8.9 cannot install Compress::Zlib"
8635 # next; # this is the next that had to go away
8637 # The following "next NEED" are fine and the error message
8638 # explains well what is going on. For example when the DBI
8639 # fails and consequently DBD::SQLite fails and now we are
8640 # processing CPAN::SQLite. Then we must have a "next" for
8641 # DBD::SQLite. How can we get it and how can we identify
8642 # all other cases we must identify?
8644 my $do = $nmo->distribution;
8645 next NEED unless $do; # not on CPAN
8646 if (CPAN::Version->vcmp($need_version, $nmo->ro->{CPAN_VERSION}) > 0){
8647 $CPAN::Frontend->mywarn("Warning: Prerequisite ".
8648 "'$need_module => $need_version' ".
8649 "for '$self->{ID}' seems ".
8650 "not available according to the indexes\n"
8654 NOSAYER: for my $nosayer (
8663 if ($do->{$nosayer}) {
8664 my $selfid = $self->pretty_id;
8665 my $did = $do->pretty_id;
8666 if (UNIVERSAL::can($do->{$nosayer},"failed") ?
8667 $do->{$nosayer}->failed :
8668 $do->{$nosayer} =~ /^NO/) {
8669 if ($nosayer eq "make_test"
8671 $do->{make_test}{COMMANDID} != $CPAN::CurrentCommandId
8675 $CPAN::Frontend->mywarn("Warning: Prerequisite ".
8676 "'$need_module => $need_version' ".
8677 "for '$selfid' failed when ".
8678 "processing '$did' with ".
8679 "'$nosayer => $do->{$nosayer}'. Continuing, ".
8680 "but chances to succeed are limited.\n"
8682 $CPAN::Frontend->mysleep($sponsoring/10);
8684 } else { # the other guy succeeded
8685 if ($nosayer =~ /^(install|make_test)$/) {
8687 # DMAKI/DateTime-Calendar-Chinese-0.05.tar.gz
8688 # in 2007-03 for 'make install'
8689 # and 2008-04: #30464 (for 'make test')
8690 $CPAN::Frontend->mywarn("Warning: Prerequisite ".
8691 "'$need_module => $need_version' ".
8692 "for '$selfid' already built ".
8693 "but the result looks suspicious. ".
8694 "Skipping another build attempt, ".
8695 "to prevent looping endlessly.\n"
8703 my $needed_as = exists $prereq_pm->{requires}{$need_module} ? "r" : "b";
8704 push @need, [$need_module,$needed_as];
8706 my @unfolded = map { "[".join(",",@$_)."]" } @need;
8707 CPAN->debug("returning from unsat_prereq[@unfolded]") if $CPAN::DEBUG;
8711 sub _fulfills_all_version_rqs {
8712 my($self,$need_module,$available_file,$available_version,$need_version) = @_;
8713 my(@all_requirements) = split /\s*,\s*/, $need_version;
8716 RQ: for my $rq (@all_requirements) {
8717 if ($rq =~ s|>=\s*||) {
8718 } elsif ($rq =~ s|>\s*||) {
8720 if (CPAN::Version->vgt($available_version,$rq)) {
8724 } elsif ($rq =~ s|!=\s*||) {
8726 if (CPAN::Version->vcmp($available_version,$rq)) {
8732 } elsif ($rq =~ m|<=?\s*|) {
8734 $CPAN::Frontend->mywarn("Downgrading not supported (rq[$rq])\n");
8738 if (! CPAN::Version->vgt($rq, $available_version)) {
8741 CPAN->debug(sprintf("need_module[%s]available_file[%s]".
8742 "available_version[%s]rq[%s]ok[%d]",
8746 CPAN::Version->readable($rq),
8750 return $ok == @all_requirements;
8753 #-> sub CPAN::Distribution::read_yaml ;
8756 return $self->{yaml_content} if exists $self->{yaml_content};
8758 unless ($build_dir = $self->{build_dir}) {
8759 # maybe permission on build_dir was missing
8760 $CPAN::Frontend->mywarn("Warning: cannot determine META.yml without a build_dir.\n");
8763 my $yaml = File::Spec->catfile($build_dir,"META.yml");
8764 $self->debug("yaml[$yaml]") if $CPAN::DEBUG;
8765 return unless -f $yaml;
8766 eval { $self->{yaml_content} = CPAN->_yaml_loadfile($yaml)->[0]; };
8768 $CPAN::Frontend->mywarn("Could not read ".
8769 "'$yaml'. Falling back to other ".
8770 "methods to determine prerequisites\n");
8771 return $self->{yaml_content} = undef; # if we die, then we
8772 # cannot read YAML's own
8775 # not "authoritative"
8776 for ($self->{yaml_content}) {
8777 if (defined $_ && (! ref $_ || ref $_ ne "HASH")) {
8778 $CPAN::Frontend->mywarn("META.yml does not seem to be conforming, cannot use it.\n");
8779 $self->{yaml_content} = +{};
8782 if (not exists $self->{yaml_content}{dynamic_config}
8783 or $self->{yaml_content}{dynamic_config}
8785 $self->{yaml_content} = undef;
8787 $self->debug(sprintf "yaml_content[%s]", $self->{yaml_content} || "UNDEF")
8789 return $self->{yaml_content};
8792 #-> sub CPAN::Distribution::prereq_pm ;
8795 $self->{prereq_pm_detected} ||= 0;
8796 CPAN->debug("ID[$self->{ID}]prereq_pm_detected[$self->{prereq_pm_detected}]") if $CPAN::DEBUG;
8797 return $self->{prereq_pm} if $self->{prereq_pm_detected};
8798 return unless $self->{writemakefile} # no need to have succeeded
8799 # but we must have run it
8800 || $self->{modulebuild};
8801 unless ($self->{build_dir}) {
8804 CPAN->debug(sprintf "writemakefile[%s]modulebuild[%s]",
8805 $self->{writemakefile}||"",
8806 $self->{modulebuild}||"",
8809 if (my $yaml = $self->read_yaml) { # often dynamic_config prevents a result here
8810 $req = $yaml->{requires} || {};
8811 $breq = $yaml->{build_requires} || {};
8812 undef $req unless ref $req eq "HASH" && %$req;
8814 if ($yaml->{generated_by} &&
8815 $yaml->{generated_by} =~ /ExtUtils::MakeMaker version ([\d\._]+)/) {
8816 my $eummv = do { local $^W = 0; $1+0; };
8817 if ($eummv < 6.2501) {
8818 # thanks to Slaven for digging that out: MM before
8819 # that could be wrong because it could reflect a
8826 while (my($k,$v) = each %{$req||{}}) {
8829 } elsif ($k =~ /[A-Za-z]/ &&
8831 $CPAN::META->exists("Module",$v)
8833 $CPAN::Frontend->mywarn("Suspicious key-value pair in META.yml's ".
8834 "requires hash: $k => $v; I'll take both ".
8835 "key and value as a module name\n");
8836 $CPAN::Frontend->mysleep(1);
8842 $req = $areq if $do_replace;
8845 unless ($req || $breq) {
8847 unless ( $build_dir = $self->{build_dir} ) {
8850 my $makefile = File::Spec->catfile($build_dir,"Makefile");
8854 $fh = FileHandle->new("<$makefile\0")) {
8855 CPAN->debug("Getting prereq from Makefile") if $CPAN::DEBUG;
8858 last if /MakeMaker post_initialize section/;
8860 \s+PREREQ_PM\s+=>\s+(.+)
8863 # warn "Found prereq expr[$p]";
8865 # Regexp modified by A.Speer to remember actual version of file
8866 # PREREQ_PM hash key wants, then add to
8867 while ( $p =~ m/(?:\s)([\w\:]+)=>(q\[.*?\]|undef),?/g ) {
8868 # In case a prereq is mentioned twice, complain.
8869 if ( defined $req->{$1} ) {
8870 warn "Warning: PREREQ_PM mentions $1 more than once, ".
8871 "last mention wins";
8873 my($m,$n) = ($1,$2);
8874 if ($n =~ /^q\[(.*?)\]$/) {
8883 unless ($req || $breq) {
8884 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
8885 my $buildfile = File::Spec->catfile($build_dir,"Build");
8886 if (-f $buildfile) {
8887 CPAN->debug("Found '$buildfile'") if $CPAN::DEBUG;
8888 my $build_prereqs = File::Spec->catfile($build_dir,"_build","prereqs");
8889 if (-f $build_prereqs) {
8890 CPAN->debug("Getting prerequisites from '$build_prereqs'") if $CPAN::DEBUG;
8891 my $content = do { local *FH;
8892 open FH, $build_prereqs
8893 or $CPAN::Frontend->mydie("Could not open ".
8894 "'$build_prereqs': $!");
8898 my $bphash = eval $content;
8901 $req = $bphash->{requires} || +{};
8902 $breq = $bphash->{build_requires} || +{};
8908 && ! -f "Makefile.PL"
8909 && ! exists $req->{"Module::Build"}
8910 && ! $CPAN::META->has_inst("Module::Build")) {
8911 $CPAN::Frontend->mywarn(" Warning: CPAN.pm discovered Module::Build as ".
8912 "undeclared prerequisite.\n".
8913 " Adding it now as such.\n"
8915 $CPAN::Frontend->mysleep(5);
8916 $req->{"Module::Build"} = 0;
8917 delete $self->{writemakefile};
8919 if ($req || $breq) {
8920 $self->{prereq_pm_detected}++;
8921 return $self->{prereq_pm} = { requires => $req, build_requires => $breq };
8925 #-> sub CPAN::Distribution::test ;
8928 if (my $goto = $self->prefs->{goto}) {
8929 return $self->goto($goto);
8932 return if $self->prefs->{disabled} && ! $self->{force_update};
8933 if ($CPAN::Signal) {
8934 delete $self->{force_update};
8937 # warn "XDEBUG: checking for notest: $self->{notest} $self";
8938 if ($self->{notest}) {
8939 $CPAN::Frontend->myprint("Skipping test because of notest pragma\n");
8943 my $make = $self->{modulebuild} ? "Build" : "make";
8945 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
8947 : ($ENV{PERLLIB} || "");
8949 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
8950 $CPAN::META->set_perl5lib;
8951 local $ENV{MAKEFLAGS}; # protect us from outer make calls
8953 $CPAN::Frontend->myprint("Running $make test\n");
8957 if ($self->{make} or $self->{later}) {
8961 "Make had some problems, won't test";
8964 exists $self->{make} and
8966 UNIVERSAL::can($self->{make},"failed") ?
8967 $self->{make}->failed :
8968 $self->{make} =~ /^NO/
8969 ) and push @e, "Can't test without successful make";
8970 $self->{badtestcnt} ||= 0;
8971 if ($self->{badtestcnt} > 0) {
8972 require Data::Dumper;
8973 CPAN->debug(sprintf "NOREPEAT[%s]", Data::Dumper::Dumper($self)) if $CPAN::DEBUG;
8974 push @e, "Won't repeat unsuccessful test during this command";
8977 push @e, $self->{later} if $self->{later};
8978 push @e, $self->{configure_requires_later} if $self->{configure_requires_later};
8980 if (exists $self->{build_dir}) {
8981 if (exists $self->{make_test}) {
8983 UNIVERSAL::can($self->{make_test},"failed") ?
8984 $self->{make_test}->failed :
8985 $self->{make_test} =~ /^NO/
8988 UNIVERSAL::can($self->{make_test},"commandid")
8990 $self->{make_test}->commandid == $CPAN::CurrentCommandId
8992 push @e, "Has already been tested within this command";
8995 push @e, "Has already been tested successfully";
8996 # if global "is_tested" has been cleared, we need to mark this to
8997 # be added to PERL5LIB if not already installed
8998 if ($self->tested_ok_but_not_installed) {
8999 $CPAN::META->is_tested($self->{build_dir},$self->{make_test}{TIME});
9004 push @e, "Has no own directory";
9006 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
9007 unless (chdir $self->{build_dir}) {
9008 push @e, "Couldn't chdir to '$self->{build_dir}': $!";
9010 $CPAN::Frontend->mywarn(join "", map {" $_\n"} @e) and return if @e;
9012 $self->debug("Changed directory to $self->{build_dir}")
9015 if ($^O eq 'MacOS') {
9016 Mac::BuildTools::make_test($self);
9020 if ($self->{modulebuild}) {
9021 my $thm = CPAN::Shell->expand("Module","Test::Harness");
9022 my $v = $thm->inst_version;
9023 if (CPAN::Version->vlt($v,2.62)) {
9024 # XXX Eric Wilhelm reported this as a bug: klapperl:
9025 # Test::Harness 3.0 self-tests, so that should be 'unless
9026 # installing Test::Harness'
9027 unless ($self->id eq $thm->distribution->id) {
9028 $CPAN::Frontend->mywarn(qq{The version of your Test::Harness is only
9029 '$v', you need at least '2.62'. Please upgrade your Test::Harness.\n});
9030 $self->{make_test} = CPAN::Distrostatus->new("NO Test::Harness too old");
9036 if ( ! $self->{force_update} ) {
9037 # bypass actual tests if "trust_test_report_history" and have a report
9038 my $have_tested_fcn;
9039 if ( $CPAN::Config->{trust_test_report_history}
9040 && $CPAN::META->has_inst("CPAN::Reporter::History")
9041 && ( $have_tested_fcn = CPAN::Reporter::History->can("have_tested" ))) {
9042 if ( my @reports = $have_tested_fcn->( dist => $self->base_id ) ) {
9043 # Do nothing if grade was DISCARD
9044 if ( $reports[-1]->{grade} =~ /^(?:PASS|UNKNOWN)$/ ) {
9045 $self->{make_test} = CPAN::Distrostatus->new("YES");
9046 # if global "is_tested" has been cleared, we need to mark this to
9047 # be added to PERL5LIB if not already installed
9048 if ($self->tested_ok_but_not_installed) {
9049 $CPAN::META->is_tested($self->{build_dir},$self->{make_test}{TIME});
9051 $CPAN::Frontend->myprint("Found prior test report -- OK\n");
9054 elsif ( $reports[-1]->{grade} =~ /^(?:FAIL|NA)$/ ) {
9055 $self->{make_test} = CPAN::Distrostatus->new("NO");
9056 $self->{badtestcnt}++;
9057 $CPAN::Frontend->mywarn("Found prior test report -- NOT OK\n");
9065 my $prefs_test = $self->prefs->{test};
9067 = exists $prefs_test->{commandline} ? $prefs_test->{commandline} : "") {
9068 $system = $commandline;
9069 $ENV{PERL} = CPAN::find_perl;
9070 } elsif ($self->{modulebuild}) {
9071 $system = sprintf "%s test", $self->_build_command();
9072 unless (-e "Build") {
9073 my $id = $self->pretty_id;
9074 $CPAN::Frontend->mywarn("Alert: no 'Build' file found while trying to test '$id'");
9077 $system = join " ", $self->_make_command(), "test";
9079 my $make_test_arg = $self->_make_phase_arg("test");
9080 $system = sprintf("%s%s",
9082 $make_test_arg ? " $make_test_arg" : "",
9086 while (my($k,$v) = each %ENV) {
9087 next unless defined $v;
9092 if ($self->prefs->{test}) {
9093 $test_env = $self->prefs->{test}{env};
9096 for my $e (keys %$test_env) {
9097 $ENV{$e} = $test_env->{$e};
9100 my $expect_model = $self->_prefs_with_expect("test");
9101 my $want_expect = 0;
9102 if ( $expect_model && @{$expect_model->{talk}} ) {
9103 my $can_expect = $CPAN::META->has_inst("Expect");
9107 $CPAN::Frontend->mywarn("Expect not installed, falling back to ".
9108 "testing without\n");
9112 if ($self->_should_report('test')) {
9113 $CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is currently ".
9114 "not supported when distroprefs specify ".
9115 "an interactive test\n");
9117 $tests_ok = $self->_run_via_expect($system,'test',$expect_model) == 0;
9118 } elsif ( $self->_should_report('test') ) {
9119 $tests_ok = CPAN::Reporter::test($self, $system);
9121 $tests_ok = system($system) == 0;
9123 $self->introduce_myself;
9128 # local $CPAN::DEBUG = 16; # Distribution
9129 for my $m (keys %{$self->{sponsored_mods}}) {
9130 next unless $self->{sponsored_mods}{$m} > 0;
9131 my $m_obj = CPAN::Shell->expand("Module",$m) or next;
9132 # XXX we need available_version which reflects
9133 # $ENV{PERL5LIB} so that already tested but not yet
9134 # installed modules are counted.
9135 my $available_version = $m_obj->available_version;
9136 my $available_file = $m_obj->available_file;
9137 if ($available_version &&
9138 !CPAN::Version->vlt($available_version,$self->{prereq_pm}{$m})
9140 CPAN->debug("m[$m] good enough available_version[$available_version]")
9142 } elsif ($available_file
9144 !$self->{prereq_pm}{$m}
9146 $self->{prereq_pm}{$m} == 0
9149 # lex Class::Accessor::Chained::Fast which has no $VERSION
9150 CPAN->debug("m[$m] have available_file[$available_file]")
9158 my $which = join ",", @prereq;
9159 my $but = $cnt == 1 ? "one dependency not OK ($which)" :
9160 "$cnt dependencies missing ($which)";
9161 $CPAN::Frontend->mywarn("Tests succeeded but $but\n");
9162 $self->{make_test} = CPAN::Distrostatus->new("NO $but");
9163 $self->store_persistent_state;
9164 return $self->goodbye("[dependencies] -- NA");
9168 $CPAN::Frontend->myprint(" $system -- OK\n");
9169 $self->{make_test} = CPAN::Distrostatus->new("YES");
9170 $CPAN::META->is_tested($self->{build_dir},$self->{make_test}{TIME});
9171 # probably impossible to need the next line because badtestcnt
9172 # has a lifespan of one command
9173 delete $self->{badtestcnt};
9175 $self->{make_test} = CPAN::Distrostatus->new("NO");
9176 $self->{badtestcnt}++;
9177 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
9178 CPAN::Shell->optprint
9181 ("//hint// to see the cpan-testers results for installing this module, try:
9185 $self->store_persistent_state;
9188 sub _prefs_with_expect {
9189 my($self,$where) = @_;
9190 return unless my $prefs = $self->prefs;
9191 return unless my $where_prefs = $prefs->{$where};
9192 if ($where_prefs->{expect}) {
9194 mode => "deterministic",
9196 talk => $where_prefs->{expect},
9198 } elsif ($where_prefs->{"eexpect"}) {
9199 return $where_prefs->{"eexpect"};
9204 #-> sub CPAN::Distribution::clean ;
9207 my $make = $self->{modulebuild} ? "Build" : "make";
9208 $CPAN::Frontend->myprint("Running $make clean\n");
9209 unless (exists $self->{archived}) {
9210 $CPAN::Frontend->mywarn("Distribution seems to have never been unzipped".
9211 "/untarred, nothing done\n");
9214 unless (exists $self->{build_dir}) {
9215 $CPAN::Frontend->mywarn("Distribution has no own directory, nothing to do.\n");
9218 if (exists $self->{writemakefile}
9219 and $self->{writemakefile}->failed
9221 $CPAN::Frontend->mywarn("No Makefile, don't know how to 'make clean'\n");
9226 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
9227 push @e, "make clean already called once";
9228 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
9230 chdir $self->{build_dir} or
9231 Carp::confess("Couldn't chdir to $self->{build_dir}: $!");
9232 $self->debug("Changed directory to $self->{build_dir}") if $CPAN::DEBUG;
9234 if ($^O eq 'MacOS') {
9235 Mac::BuildTools::make_clean($self);
9240 if ($self->{modulebuild}) {
9241 unless (-f "Build") {
9242 my $cwd = CPAN::anycwd();
9243 $CPAN::Frontend->mywarn("Alert: no Build file available for 'clean $self->{id}".
9244 " in cwd[$cwd]. Danger, Will Robinson!");
9245 $CPAN::Frontend->mysleep(5);
9247 $system = sprintf "%s clean", $self->_build_command();
9249 $system = join " ", $self->_make_command(), "clean";
9251 my $system_ok = system($system) == 0;
9252 $self->introduce_myself;
9254 $CPAN::Frontend->myprint(" $system -- OK\n");
9258 # Jost Krieger pointed out that this "force" was wrong because
9259 # it has the effect that the next "install" on this distribution
9260 # will untar everything again. Instead we should bring the
9261 # object's state back to where it is after untarring.
9272 $self->{make_clean} = CPAN::Distrostatus->new("YES");
9275 # Hmmm, what to do if make clean failed?
9277 $self->{make_clean} = CPAN::Distrostatus->new("NO");
9278 $CPAN::Frontend->mywarn(qq{ $system -- NOT OK\n});
9280 # 2006-02-27: seems silly to me to force a make now
9281 # $self->force("make"); # so that this directory won't be used again
9284 $self->store_persistent_state;
9287 #-> sub CPAN::Distribution::goto ;
9289 my($self,$goto) = @_;
9290 $goto = $self->normalize($goto);
9292 "Goto '$goto' via prefs file '%s' doc %d",
9293 $self->{prefs_file},
9294 $self->{prefs_file_doc},
9296 $self->{unwrapped} = CPAN::Distrostatus->new("NO $why");
9297 # 2007-07-16 akoenig : Better than NA would be if we could inherit
9298 # the status of the $goto distro but given the exceptional nature
9299 # of 'goto' I feel reluctant to implement it
9300 my $goodbye_message = "[goto] -- NA $why";
9301 $self->goodbye($goodbye_message);
9303 # inject into the queue
9305 CPAN::Queue->delete($self->id);
9306 CPAN::Queue->jumpqueue({qmod => $goto, reqtype => $self->{reqtype}});
9308 # and run where we left off
9310 my($method) = (caller(1))[3];
9311 CPAN->instance("CPAN::Distribution",$goto)->$method();
9312 CPAN::Queue->delete_first($goto);
9315 #-> sub CPAN::Distribution::install ;
9318 if (my $goto = $self->prefs->{goto}) {
9319 return $self->goto($goto);
9321 unless ($self->{badtestcnt}) {
9324 if ($CPAN::Signal) {
9325 delete $self->{force_update};
9328 my $make = $self->{modulebuild} ? "Build" : "make";
9329 $CPAN::Frontend->myprint("Running $make install\n");
9332 if ($self->{make} or $self->{later}) {
9336 "Make had some problems, won't install";
9339 exists $self->{make} and
9341 UNIVERSAL::can($self->{make},"failed") ?
9342 $self->{make}->failed :
9343 $self->{make} =~ /^NO/
9345 push @e, "Make had returned bad status, install seems impossible";
9347 if (exists $self->{build_dir}) {
9349 push @e, "Has no own directory";
9352 if (exists $self->{make_test} and
9354 UNIVERSAL::can($self->{make_test},"failed") ?
9355 $self->{make_test}->failed :
9356 $self->{make_test} =~ /^NO/
9358 if ($self->{force_update}) {
9359 $self->{make_test}->text("FAILED but failure ignored because ".
9360 "'force' in effect");
9362 push @e, "make test had returned bad status, ".
9363 "won't install without force"
9366 if (exists $self->{install}) {
9367 if (UNIVERSAL::can($self->{install},"text") ?
9368 $self->{install}->text eq "YES" :
9369 $self->{install} =~ /^YES/
9371 $CPAN::Frontend->myprint(" Already done\n");
9372 $CPAN::META->is_installed($self->{build_dir});
9375 # comment in Todo on 2006-02-11; maybe retry?
9376 push @e, "Already tried without success";
9380 push @e, $self->{later} if $self->{later};
9381 push @e, $self->{configure_requires_later} if $self->{configure_requires_later};
9383 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
9384 unless (chdir $self->{build_dir}) {
9385 push @e, "Couldn't chdir to '$self->{build_dir}': $!";
9387 $CPAN::Frontend->mywarn(join "", map {" $_\n"} @e) and return if @e;
9389 $self->debug("Changed directory to $self->{build_dir}")
9392 if ($^O eq 'MacOS') {
9393 Mac::BuildTools::make_install($self);
9398 if (my $commandline = $self->prefs->{install}{commandline}) {
9399 $system = $commandline;
9400 $ENV{PERL} = CPAN::find_perl;
9401 } elsif ($self->{modulebuild}) {
9402 my($mbuild_install_build_command) =
9403 exists $CPAN::HandleConfig::keys{mbuild_install_build_command} &&
9404 $CPAN::Config->{mbuild_install_build_command} ?
9405 $CPAN::Config->{mbuild_install_build_command} :
9406 $self->_build_command();
9407 $system = sprintf("%s install %s",
9408 $mbuild_install_build_command,
9409 $CPAN::Config->{mbuild_install_arg},
9412 my($make_install_make_command) =
9413 CPAN::HandleConfig->prefs_lookup($self,
9414 q{make_install_make_command})
9415 || $self->_make_command();
9416 $system = sprintf("%s install %s",
9417 $make_install_make_command,
9418 $CPAN::Config->{make_install_arg},
9422 my($stderr) = $^O eq "MSWin32" ? "" : " 2>&1 ";
9423 my $brip = CPAN::HandleConfig->prefs_lookup($self,
9424 q{build_requires_install_policy});
9427 my $reqtype = $self->{reqtype} ||= "c"; # in doubt it was a command
9428 my $want_install = "yes";
9429 if ($reqtype eq "b") {
9430 if ($brip eq "no") {
9431 $want_install = "no";
9432 } elsif ($brip =~ m|^ask/(.+)|) {
9434 $default = "yes" unless $default =~ /^(y|n)/i;
9436 CPAN::Shell::colorable_makemaker_prompt
9437 ("$id is just needed temporarily during building or testing. ".
9438 "Do you want to install it permanently? (Y/n)",
9442 unless ($want_install =~ /^y/i) {
9443 my $is_only = "is only 'build_requires'";
9444 $CPAN::Frontend->mywarn("Not installing because $is_only\n");
9445 $self->{install} = CPAN::Distrostatus->new("NO -- $is_only");
9446 delete $self->{force_update};
9449 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
9451 : ($ENV{PERLLIB} || "");
9453 local $ENV{PERL5OPT} = defined $ENV{PERL5OPT} ? $ENV{PERL5OPT} : "";
9454 $CPAN::META->set_perl5lib;
9455 my($pipe) = FileHandle->new("$system $stderr |") || Carp::croak
9456 ("Can't execute $system: $!");
9459 print $_; # intentionally NOT use Frontend->myprint because it
9460 # looks irritating when we markup in color what we
9461 # just pass through from an external program
9465 my $close_ok = $? == 0;
9466 $self->introduce_myself;
9468 $CPAN::Frontend->myprint(" $system -- OK\n");
9469 $CPAN::META->is_installed($self->{build_dir});
9470 $self->{install} = CPAN::Distrostatus->new("YES");
9472 $self->{install} = CPAN::Distrostatus->new("NO");
9473 $CPAN::Frontend->mywarn(" $system -- NOT OK\n");
9475 CPAN::HandleConfig->prefs_lookup($self,
9476 q{make_install_make_command});
9478 $makeout =~ /permission/s
9482 || $mimc eq (CPAN::HandleConfig->prefs_lookup($self,
9486 $CPAN::Frontend->myprint(
9488 qq{ You may have to su }.
9489 qq{to root to install the package\n}.
9490 qq{ (Or you may want to run something like\n}.
9491 qq{ o conf make_install_make_command 'sudo make'\n}.
9492 qq{ to raise your permissions.}
9496 delete $self->{force_update};
9497 $self->store_persistent_state;
9500 sub introduce_myself {
9502 $CPAN::Frontend->myprint(sprintf(" %s\n",$self->pretty_id));
9505 #-> sub CPAN::Distribution::dir ;
9510 #-> sub CPAN::Distribution::perldoc ;
9514 my($dist) = $self->id;
9515 my $package = $self->called_for;
9517 $self->_display_url( $CPAN::Defaultdocs . $package );
9520 #-> sub CPAN::Distribution::_check_binary ;
9522 my ($dist,$shell,$binary) = @_;
9525 $CPAN::Frontend->myprint(qq{ + _check_binary($binary)\n})
9528 if ($CPAN::META->has_inst("File::Which")) {
9529 return File::Which::which($binary);
9532 $pid = open README, "which $binary|"
9533 or $CPAN::Frontend->mywarn(qq{Could not fork 'which $binary': $!\n});
9539 or $CPAN::Frontend->mywarn("Could not run 'which $binary': $!\n")
9543 $CPAN::Frontend->myprint(qq{ + $out \n})
9544 if $CPAN::DEBUG && $out;
9549 #-> sub CPAN::Distribution::_display_url ;
9551 my($self,$url) = @_;
9552 my($res,$saved_file,$pid,$out);
9554 $CPAN::Frontend->myprint(qq{ + _display_url($url)\n})
9557 # should we define it in the config instead?
9558 my $html_converter = "html2text.pl";
9560 my $web_browser = $CPAN::Config->{'lynx'} || undef;
9561 my $web_browser_out = $web_browser
9562 ? CPAN::Distribution->_check_binary($self,$web_browser)
9565 if ($web_browser_out) {
9566 # web browser found, run the action
9567 my $browser = CPAN::HandleConfig->safe_quote($CPAN::Config->{'lynx'});
9568 $CPAN::Frontend->myprint(qq{system[$browser $url]})
9570 $CPAN::Frontend->myprint(qq{
9573 with browser $browser
9575 $CPAN::Frontend->mysleep(1);
9576 system("$browser $url");
9577 if ($saved_file) { 1 while unlink($saved_file) }
9579 # web browser not found, let's try text only
9580 my $html_converter_out =
9581 CPAN::Distribution->_check_binary($self,$html_converter);
9582 $html_converter_out = CPAN::HandleConfig->safe_quote($html_converter_out);
9584 if ($html_converter_out ) {
9585 # html2text found, run it
9586 $saved_file = CPAN::Distribution->_getsave_url( $self, $url );
9587 $CPAN::Frontend->mydie(qq{ERROR: problems while getting $url\n})
9588 unless defined($saved_file);
9591 $pid = open README, "$html_converter $saved_file |"
9592 or $CPAN::Frontend->mydie(qq{
9593 Could not fork '$html_converter $saved_file': $!});
9595 if ($CPAN::META->has_usable("File::Temp")) {
9596 $fh = File::Temp->new(
9597 dir => File::Spec->tmpdir,
9598 template => 'cpan_htmlconvert_XXXX',
9602 $filename = $fh->filename;
9604 $filename = "cpan_htmlconvert_$$.txt";
9605 $fh = FileHandle->new();
9606 open $fh, ">$filename" or die;
9612 $CPAN::Frontend->mydie(qq{Could not run '$html_converter $saved_file': $!});
9613 my $tmpin = $fh->filename;
9614 $CPAN::Frontend->myprint(sprintf(qq{
9616 saved output to %s\n},
9624 or $CPAN::Frontend->mydie(qq{Could not open "$tmpin": $!});
9625 my $fh_pager = FileHandle->new;
9626 local($SIG{PIPE}) = "IGNORE";
9627 my $pager = $CPAN::Config->{'pager'} || "cat";
9628 $fh_pager->open("|$pager")
9629 or $CPAN::Frontend->mydie(qq{
9630 Could not open pager '$pager': $!});
9631 $CPAN::Frontend->myprint(qq{
9636 $CPAN::Frontend->mysleep(1);
9637 $fh_pager->print(<FH>);
9640 # coldn't find the web browser or html converter
9641 $CPAN::Frontend->myprint(qq{
9642 You need to install lynx or $html_converter to use this feature.});
9647 #-> sub CPAN::Distribution::_getsave_url ;
9649 my($dist, $shell, $url) = @_;
9651 $CPAN::Frontend->myprint(qq{ + _getsave_url($url)\n})
9655 if ($CPAN::META->has_usable("File::Temp")) {
9656 $fh = File::Temp->new(
9657 dir => File::Spec->tmpdir,
9658 template => "cpan_getsave_url_XXXX",
9662 $filename = $fh->filename;
9664 $fh = FileHandle->new;
9665 $filename = "cpan_getsave_url_$$.html";
9667 my $tmpin = $filename;
9668 if ($CPAN::META->has_usable('LWP')) {
9669 $CPAN::Frontend->myprint("Fetching with LWP:
9673 CPAN::LWP::UserAgent->config;
9674 eval { $Ua = CPAN::LWP::UserAgent->new; };
9676 $CPAN::Frontend->mywarn("ERROR: CPAN::LWP::UserAgent->new dies with $@\n");
9680 $Ua->proxy('http', $var)
9681 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
9683 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
9686 my $req = HTTP::Request->new(GET => $url);
9687 $req->header('Accept' => 'text/html');
9688 my $res = $Ua->request($req);
9689 if ($res->is_success) {
9690 $CPAN::Frontend->myprint(" + request successful.\n")
9692 print $fh $res->content;
9694 $CPAN::Frontend->myprint(qq{ + saved content to $tmpin \n})
9698 $CPAN::Frontend->myprint(sprintf(
9699 "LWP failed with code[%s], message[%s]\n",
9706 $CPAN::Frontend->mywarn(" LWP not available\n");
9711 #-> sub CPAN::Distribution::_build_command
9712 sub _build_command {
9714 if ($^O eq "MSWin32") { # special code needed at least up to
9715 # Module::Build 0.2611 and 0.2706; a fix
9716 # in M:B has been promised 2006-01-30
9717 my($perl) = $self->perl or $CPAN::Frontend->mydie("Couldn't find executable perl\n");
9718 return "$perl ./Build";
9723 #-> sub CPAN::Distribution::_should_report
9724 sub _should_report {
9725 my($self, $phase) = @_;
9726 die "_should_report() requires a 'phase' argument"
9727 if ! defined $phase;
9730 my $test_report = CPAN::HandleConfig->prefs_lookup($self,
9732 return unless $test_report;
9734 # don't repeat if we cached a result
9735 return $self->{should_report}
9736 if exists $self->{should_report};
9738 # don't report if we generated a Makefile.PL
9739 if ( $self->{had_no_makefile_pl} ) {
9740 $CPAN::Frontend->mywarn(
9741 "Will not send CPAN Testers report with generated Makefile.PL.\n"
9743 return $self->{should_report} = 0;
9747 if ( ! $CPAN::META->has_inst("CPAN::Reporter")) {
9748 $CPAN::Frontend->mywarn(
9749 "CPAN::Reporter not installed. No reports will be sent.\n"
9751 return $self->{should_report} = 0;
9755 my $crv = CPAN::Reporter->VERSION;
9756 if ( CPAN::Version->vlt( $crv, 0.99 ) ) {
9757 # don't cache $self->{should_report} -- need to check each phase
9758 if ( $phase eq 'test' ) {
9762 $CPAN::Frontend->mywarn(
9763 "Reporting on the '$phase' phase requires CPAN::Reporter 0.99, but \n" .
9764 "you only have version $crv\. Only 'test' phase reports will be sent.\n"
9771 if ($self->is_dot_dist) {
9772 $CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is disabled ".
9773 "for local directories\n");
9774 return $self->{should_report} = 0;
9776 if ($self->prefs->{patches}
9778 @{$self->prefs->{patches}}
9782 $CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is disabled ".
9783 "when the source has been patched\n");
9784 return $self->{should_report} = 0;
9787 # proceed and cache success
9788 return $self->{should_report} = 1;
9791 #-> sub CPAN::Distribution::reports
9794 my $pathname = $self->id;
9795 $CPAN::Frontend->myprint("Distribution: $pathname\n");
9797 unless ($CPAN::META->has_inst("CPAN::DistnameInfo")) {
9798 $CPAN::Frontend->mydie("CPAN::DistnameInfo not installed; cannot continue");
9800 unless ($CPAN::META->has_usable("LWP")) {
9801 $CPAN::Frontend->mydie("LWP not installed; cannot continue");
9803 unless ($CPAN::META->has_usable("File::Temp")) {
9804 $CPAN::Frontend->mydie("File::Temp not installed; cannot continue");
9807 my $d = CPAN::DistnameInfo->new($pathname);
9809 my $dist = $d->dist; # "CPAN-DistnameInfo"
9810 my $version = $d->version; # "0.02"
9811 my $maturity = $d->maturity; # "released"
9812 my $filename = $d->filename; # "CPAN-DistnameInfo-0.02.tar.gz"
9813 my $cpanid = $d->cpanid; # "GBARR"
9814 my $distvname = $d->distvname; # "CPAN-DistnameInfo-0.02"
9816 my $url = sprintf "http://www.cpantesters.org/show/%s.yaml", $dist;
9818 CPAN::LWP::UserAgent->config;
9820 eval { $Ua = CPAN::LWP::UserAgent->new; };
9822 $CPAN::Frontend->mydie("CPAN::LWP::UserAgent->new dies with $@\n");
9824 $CPAN::Frontend->myprint("Fetching '$url'...");
9825 my $resp = $Ua->get($url);
9826 unless ($resp->is_success) {
9827 $CPAN::Frontend->mydie(sprintf "Could not download '%s': %s\n", $url, $resp->code);
9829 $CPAN::Frontend->myprint("DONE\n\n");
9830 my $yaml = $resp->content;
9831 # was fuer ein Umweg!
9832 my $fh = File::Temp->new(
9833 dir => File::Spec->tmpdir,
9834 template => 'cpan_reports_XXXX',
9838 my $tfilename = $fh->filename;
9840 close $fh or $CPAN::Frontend->mydie("Could not close '$tfilename': $!");
9841 my $unserialized = CPAN->_yaml_loadfile($tfilename)->[0];
9842 unlink $tfilename or $CPAN::Frontend->mydie("Could not unlink '$tfilename': $!");
9844 my $this_version_seen;
9845 for my $rep (@$unserialized) {
9846 my $rversion = $rep->{version};
9847 if ($rversion eq $version) {
9848 unless ($this_version_seen++) {
9849 $CPAN::Frontend->myprint ("$rep->{version}:\n");
9851 $CPAN::Frontend->myprint
9852 (sprintf("%1s%1s%-4s %s on %s %s (%s)\n",
9853 $rep->{archname} eq $Config::Config{archname}?"*":"",
9854 $rep->{action}eq"PASS"?"+":$rep->{action}eq"FAIL"?"-":"",
9857 ucfirst $rep->{osname},
9862 $other_versions{$rep->{version}}++;
9865 unless ($this_version_seen) {
9866 $CPAN::Frontend->myprint("No reports found for version '$version'
9867 Reports for other versions:\n");
9868 for my $v (sort keys %other_versions) {
9869 $CPAN::Frontend->myprint(" $v\: $other_versions{$v}\n");
9872 $url =~ s/\.yaml/.html/;
9873 $CPAN::Frontend->myprint("See $url for details\n");
9876 package CPAN::Bundle;
9881 $CPAN::Frontend->myprint($self->as_string);
9884 #-> CPAN::Bundle::undelay
9887 delete $self->{later};
9888 for my $c ( $self->contains ) {
9889 my $obj = CPAN::Shell->expandany($c) or next;
9894 # mark as dirty/clean
9895 #-> sub CPAN::Bundle::color_cmd_tmps ;
9896 sub color_cmd_tmps {
9898 my($depth) = shift || 0;
9899 my($color) = shift || 0;
9900 my($ancestors) = shift || [];
9901 # a module needs to recurse to its cpan_file, a distribution needs
9902 # to recurse into its prereq_pms, a bundle needs to recurse into its modules
9904 return if exists $self->{incommandcolor}
9906 && $self->{incommandcolor}==$color;
9907 if ($depth>=$CPAN::MAX_RECURSION) {
9908 die(CPAN::Exception::RecursiveDependency->new($ancestors));
9910 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
9912 for my $c ( $self->contains ) {
9913 my $obj = CPAN::Shell->expandany($c) or next;
9914 CPAN->debug("c[$c]obj[$obj]") if $CPAN::DEBUG;
9915 $obj->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
9917 # never reached code?
9919 #delete $self->{badtestcnt};
9921 $self->{incommandcolor} = $color;
9924 #-> sub CPAN::Bundle::as_string ;
9928 # following line must be "=", not "||=" because we have a moving target
9929 $self->{INST_VERSION} = $self->inst_version;
9930 return $self->SUPER::as_string;
9933 #-> sub CPAN::Bundle::contains ;
9936 my($inst_file) = $self->inst_file || "";
9937 my($id) = $self->id;
9938 $self->debug("inst_file[$inst_file]id[$id]") if $CPAN::DEBUG;
9939 if ($inst_file && CPAN::Version->vlt($self->inst_version,$self->cpan_version)) {
9942 unless ($inst_file) {
9943 # Try to get at it in the cpan directory
9944 $self->debug("no inst_file") if $CPAN::DEBUG;
9946 $CPAN::Frontend->mydie("I don't know a bundle with ID $id\n") unless
9947 $cpan_file = $self->cpan_file;
9948 if ($cpan_file eq "N/A") {
9949 $CPAN::Frontend->mydie("Bundle $id not found on disk and not on CPAN.
9950 Maybe stale symlink? Maybe removed during session? Giving up.\n");
9952 my $dist = $CPAN::META->instance('CPAN::Distribution',
9954 $self->debug("before get id[$dist->{ID}]") if $CPAN::DEBUG;
9956 $self->debug("after get id[$dist->{ID}]") if $CPAN::DEBUG;
9957 my($todir) = $CPAN::Config->{'cpan_home'};
9958 my(@me,$from,$to,$me);
9959 @me = split /::/, $self->id;
9961 $me = File::Spec->catfile(@me);
9962 $from = $self->find_bundle_file($dist->{build_dir},join('/',@me));
9963 $to = File::Spec->catfile($todir,$me);
9964 File::Path::mkpath(File::Basename::dirname($to));
9965 File::Copy::copy($from, $to)
9966 or Carp::confess("Couldn't copy $from to $to: $!");
9970 my $fh = FileHandle->new;
9972 open($fh,$inst_file) or die "Could not open '$inst_file': $!";
9974 $self->debug("inst_file[$inst_file]") if $CPAN::DEBUG;
9976 $in_cont = m/^=(?!head1\s+(?i-xsm:CONTENTS))/ ? 0 :
9977 m/^=head1\s+(?i-xsm:CONTENTS)/ ? 1 : $in_cont;
9978 next unless $in_cont;
9983 push @result, (split " ", $_, 2)[0];
9986 delete $self->{STATUS};
9987 $self->{CONTAINS} = \@result;
9988 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
9990 $CPAN::Frontend->mywarn(qq{
9991 The bundle file "$inst_file" may be a broken
9992 bundlefile. It seems not to contain any bundle definition.
9993 Please check the file and if it is bogus, please delete it.
9994 Sorry for the inconvenience.
10000 #-> sub CPAN::Bundle::find_bundle_file
10001 # $where is in local format, $what is in unix format
10002 sub find_bundle_file {
10003 my($self,$where,$what) = @_;
10004 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
10005 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
10006 ### my $bu = File::Spec->catfile($where,$what);
10007 ### return $bu if -f $bu;
10008 my $manifest = File::Spec->catfile($where,"MANIFEST");
10009 unless (-f $manifest) {
10010 require ExtUtils::Manifest;
10011 my $cwd = CPAN::anycwd();
10012 $self->safe_chdir($where);
10013 ExtUtils::Manifest::mkmanifest();
10014 $self->safe_chdir($cwd);
10016 my $fh = FileHandle->new($manifest)
10017 or Carp::croak("Couldn't open $manifest: $!");
10019 my $bundle_filename = $what;
10020 $bundle_filename =~ s|Bundle.*/||;
10021 my $bundle_unixpath;
10024 my($file) = /(\S+)/;
10025 if ($file =~ m|\Q$what\E$|) {
10026 $bundle_unixpath = $file;
10027 # return File::Spec->catfile($where,$bundle_unixpath); # bad
10030 # retry if she managed to have no Bundle directory
10031 $bundle_unixpath = $file if $file =~ m|\Q$bundle_filename\E$|;
10033 return File::Spec->catfile($where, split /\//, $bundle_unixpath)
10034 if $bundle_unixpath;
10035 Carp::croak("Couldn't find a Bundle file in $where");
10038 # needs to work quite differently from Module::inst_file because of
10039 # cpan_home/Bundle/ directory and the possibility that we have
10040 # shadowing effect. As it makes no sense to take the first in @INC for
10041 # Bundles, we parse them all for $VERSION and take the newest.
10043 #-> sub CPAN::Bundle::inst_file ;
10048 @me = split /::/, $self->id;
10050 my($incdir,$bestv);
10051 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
10052 my $parsefile = File::Spec->catfile($incdir, @me);
10053 CPAN->debug("parsefile[$parsefile]") if $CPAN::DEBUG;
10054 next unless -f $parsefile;
10055 my $have = eval { MM->parse_version($parsefile); };
10057 $CPAN::Frontend->mywarn("Error while parsing version number in file '$parsefile'\n");
10059 if (!$bestv || CPAN::Version->vgt($have,$bestv)) {
10060 $self->{INST_FILE} = $parsefile;
10061 $self->{INST_VERSION} = $bestv = $have;
10064 $self->{INST_FILE};
10067 #-> sub CPAN::Bundle::inst_version ;
10070 $self->inst_file; # finds INST_VERSION as side effect
10071 $self->{INST_VERSION};
10074 #-> sub CPAN::Bundle::rematein ;
10076 my($self,$meth) = @_;
10077 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
10078 my($id) = $self->id;
10079 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
10080 unless $self->inst_file || $self->cpan_file;
10082 for $s ($self->contains) {
10083 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
10084 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
10085 if ($type eq 'CPAN::Distribution') {
10086 $CPAN::Frontend->mywarn(qq{
10087 The Bundle }.$self->id.qq{ contains
10088 explicitly a file '$s'.
10089 Going to $meth that.
10091 $CPAN::Frontend->mysleep(5);
10093 # possibly noisy action:
10094 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
10095 my $obj = $CPAN::META->instance($type,$s);
10096 $obj->{reqtype} = $self->{reqtype};
10101 # If a bundle contains another that contains an xs_file we have here,
10102 # we just don't bother I suppose
10103 #-> sub CPAN::Bundle::xs_file
10108 #-> sub CPAN::Bundle::force ;
10109 sub fforce { shift->rematein('fforce',@_); }
10110 #-> sub CPAN::Bundle::force ;
10111 sub force { shift->rematein('force',@_); }
10112 #-> sub CPAN::Bundle::notest ;
10113 sub notest { shift->rematein('notest',@_); }
10114 #-> sub CPAN::Bundle::get ;
10115 sub get { shift->rematein('get',@_); }
10116 #-> sub CPAN::Bundle::make ;
10117 sub make { shift->rematein('make',@_); }
10118 #-> sub CPAN::Bundle::test ;
10121 # $self->{badtestcnt} ||= 0;
10122 $self->rematein('test',@_);
10124 #-> sub CPAN::Bundle::install ;
10127 $self->rematein('install',@_);
10129 #-> sub CPAN::Bundle::clean ;
10130 sub clean { shift->rematein('clean',@_); }
10132 #-> sub CPAN::Bundle::uptodate ;
10135 return 0 unless $self->SUPER::uptodate; # we mut have the current Bundle def
10137 foreach $c ($self->contains) {
10138 my $obj = CPAN::Shell->expandany($c);
10139 return 0 unless $obj->uptodate;
10144 #-> sub CPAN::Bundle::readme ;
10147 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
10148 No File found for bundle } . $self->id . qq{\n}), return;
10149 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
10150 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
10153 package CPAN::Module;
10157 #-> sub CPAN::Module::userid
10160 my $ro = $self->ro;
10162 return $ro->{userid} || $ro->{CPAN_USERID};
10164 #-> sub CPAN::Module::description
10167 my $ro = $self->ro or return "";
10171 #-> sub CPAN::Module::distribution
10174 CPAN::Shell->expand("Distribution",$self->cpan_file);
10177 #-> sub CPAN::Module::_is_representative_module
10178 sub _is_representative_module {
10180 return $self->{_is_representative_module} if defined $self->{_is_representative_module};
10181 my $pm = $self->cpan_file or return $self->{_is_representative_module} = 0;
10183 $pm =~ s{\.(?:tar\.(bz2|gz|Z)|t(?:gz|bz)|zip)$}{}i; # see base_id
10184 $pm =~ s|-\d+\.\d+.+$||;
10185 $pm =~ s|-[\d\.]+$||;
10187 $self->{_is_representative_module} = $pm eq $self->{ID} ? 1 : 0;
10188 # warn "DEBUG: $pm eq $self->{ID} => $self->{_is_representative_module}";
10189 $self->{_is_representative_module};
10192 #-> sub CPAN::Module::undelay
10195 delete $self->{later};
10196 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
10201 # mark as dirty/clean
10202 #-> sub CPAN::Module::color_cmd_tmps ;
10203 sub color_cmd_tmps {
10205 my($depth) = shift || 0;
10206 my($color) = shift || 0;
10207 my($ancestors) = shift || [];
10208 # a module needs to recurse to its cpan_file
10210 return if exists $self->{incommandcolor}
10212 && $self->{incommandcolor}==$color;
10213 return if $color==0 && !$self->{incommandcolor};
10215 if ( $self->uptodate ) {
10216 $self->{incommandcolor} = $color;
10218 } elsif (my $have_version = $self->available_version) {
10219 # maybe what we have is good enough
10221 my $who_asked_for_me = $ancestors->[-1];
10222 my $obj = CPAN::Shell->expandany($who_asked_for_me);
10224 } elsif ($obj->isa("CPAN::Bundle")) {
10225 # bundles cannot specify a minimum version
10227 } elsif ($obj->isa("CPAN::Distribution")) {
10228 if (my $prereq_pm = $obj->prereq_pm) {
10229 for my $k (keys %$prereq_pm) {
10230 if (my $want_version = $prereq_pm->{$k}{$self->id}) {
10231 if (CPAN::Version->vcmp($have_version,$want_version) >= 0) {
10232 $self->{incommandcolor} = $color;
10242 $self->{incommandcolor} = $color; # set me before recursion,
10243 # so we can break it
10245 if ($depth>=$CPAN::MAX_RECURSION) {
10246 die(CPAN::Exception::RecursiveDependency->new($ancestors));
10248 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
10250 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
10251 $dist->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
10255 # delete $self->{badtestcnt};
10257 $self->{incommandcolor} = $color;
10260 #-> sub CPAN::Module::as_glimpse ;
10264 my $class = ref($self);
10265 $class =~ s/^CPAN:://;
10267 my $color_off = "";
10269 $CPAN::Shell::COLOR_REGISTERED
10271 $CPAN::META->has_inst("Term::ANSIColor")
10275 $color_on = Term::ANSIColor::color("green");
10276 $color_off = Term::ANSIColor::color("reset");
10278 my $uptodateness = " ";
10279 unless ($class eq "Bundle") {
10280 my $u = $self->uptodate;
10281 $uptodateness = $u ? "=" : "<" if defined $u;
10284 my $d = $self->distribution;
10285 $d ? $d -> pretty_id : $self->cpan_userid;
10287 push @m, sprintf("%-7s %1s %s%-22s%s (%s)\n",
10298 #-> sub CPAN::Module::dslip_status
10302 # development status
10303 @{$stat->{D}}{qw,i c a b R M S,} = qw,idea
10304 pre-alpha alpha beta released
10307 @{$stat->{S}}{qw,m d u n a,} = qw,mailing-list
10308 developer comp.lang.perl.*
10311 @{$stat->{L}}{qw,p c + o h,} = qw,perl C C++ other hybrid,;
10313 @{$stat->{I}}{qw,f r O p h n,} = qw,functions
10315 object-oriented pragma
10318 @{$stat->{P}}{qw,p g l b a 2 o d r n,} = qw,Standard-Perl
10320 BSD Artistic Artistic_2
10322 distribution_allowed
10323 restricted_distribution
10325 for my $x (qw(d s l i p)) {
10326 $stat->{$x}{' '} = 'unknown';
10327 $stat->{$x}{'?'} = 'unknown';
10329 my $ro = $self->ro;
10330 return +{} unless $ro && $ro->{statd};
10337 DV => $stat->{D}{$ro->{statd}},
10338 SV => $stat->{S}{$ro->{stats}},
10339 LV => $stat->{L}{$ro->{statl}},
10340 IV => $stat->{I}{$ro->{stati}},
10341 PV => $stat->{P}{$ro->{statp}},
10345 #-> sub CPAN::Module::as_string ;
10349 CPAN->debug("$self entering as_string") if $CPAN::DEBUG;
10350 my $class = ref($self);
10351 $class =~ s/^CPAN:://;
10353 push @m, $class, " id = $self->{ID}\n";
10354 my $sprintf = " %-12s %s\n";
10355 push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
10356 if $self->description;
10357 my $sprintf2 = " %-12s %s (%s)\n";
10359 $userid = $self->userid;
10362 if ($author = CPAN::Shell->expand('Author',$userid)) {
10365 if ($m = $author->email) {
10372 $author->fullname . $email
10376 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
10377 if $self->cpan_version;
10378 if (my $cpan_file = $self->cpan_file) {
10379 push @m, sprintf($sprintf, 'CPAN_FILE', $cpan_file);
10380 if (my $dist = CPAN::Shell->expand("Distribution",$cpan_file)) {
10381 my $upload_date = $dist->upload_date;
10382 if ($upload_date) {
10383 push @m, sprintf($sprintf, 'UPLOAD_DATE', $upload_date);
10387 my $sprintf3 = " %-12s %1s%1s%1s%1s%1s (%s,%s,%s,%s,%s)\n";
10388 my $dslip = $self->dslip_status;
10392 @{$dslip}{qw(D S L I P DV SV LV IV PV)},
10394 my $local_file = $self->inst_file;
10395 unless ($self->{MANPAGE}) {
10398 $manpage = $self->manpage_headline($local_file);
10400 # If we have already untarred it, we should look there
10401 my $dist = $CPAN::META->instance('CPAN::Distribution',
10403 # warn "dist[$dist]";
10404 # mff=manifest file; mfh=manifest handle
10409 (-f ($mff = File::Spec->catfile($dist->{build_dir}, "MANIFEST")))
10411 $mfh = FileHandle->new($mff)
10413 CPAN->debug("mff[$mff]") if $CPAN::DEBUG;
10414 my $lfre = $self->id; # local file RE
10416 $lfre .= "\\.pm\$";
10417 my($lfl); # local file file
10419 my(@mflines) = <$mfh>;
10424 while (length($lfre)>5 and !$lfl) {
10425 ($lfl) = grep /$lfre/, @mflines;
10426 CPAN->debug("lfl[$lfl]lfre[$lfre]") if $CPAN::DEBUG;
10427 $lfre =~ s/.+?\.//;
10429 $lfl =~ s/\s.*//; # remove comments
10430 $lfl =~ s/\s+//g; # chomp would maybe be too system-specific
10431 my $lfl_abs = File::Spec->catfile($dist->{build_dir},$lfl);
10432 # warn "lfl_abs[$lfl_abs]";
10434 $manpage = $self->manpage_headline($lfl_abs);
10438 $self->{MANPAGE} = $manpage if $manpage;
10441 for $item (qw/MANPAGE/) {
10442 push @m, sprintf($sprintf, $item, $self->{$item})
10443 if exists $self->{$item};
10445 for $item (qw/CONTAINS/) {
10446 push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
10447 if exists $self->{$item} && @{$self->{$item}};
10449 push @m, sprintf($sprintf, 'INST_FILE',
10450 $local_file || "(not installed)");
10451 push @m, sprintf($sprintf, 'INST_VERSION',
10452 $self->inst_version) if $local_file;
10453 if (%{$CPAN::META->{is_tested}||{}}) { # XXX needs to be methodified somehow
10454 my $available_file = $self->available_file;
10455 if ($available_file && $available_file ne $local_file) {
10456 push @m, sprintf($sprintf, 'AVAILABLE_FILE', $available_file);
10457 push @m, sprintf($sprintf, 'AVAILABLE_VERSION', $self->available_version);
10463 #-> sub CPAN::Module::manpage_headline
10464 sub manpage_headline {
10465 my($self,$local_file) = @_;
10466 my(@local_file) = $local_file;
10467 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
10468 push @local_file, $local_file;
10470 for $locf (@local_file) {
10471 next unless -f $locf;
10472 my $fh = FileHandle->new($locf)
10473 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
10477 $inpod = m/^=(?!head1\s+NAME\s*$)/ ? 0 :
10478 m/^=head1\s+NAME\s*$/ ? 1 : $inpod;
10479 next unless $inpod;
10495 #-> sub CPAN::Module::cpan_file ;
10496 # Note: also inherited by CPAN::Bundle
10499 # CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
10500 unless ($self->ro) {
10501 CPAN::Index->reload;
10503 my $ro = $self->ro;
10504 if ($ro && defined $ro->{CPAN_FILE}) {
10505 return $ro->{CPAN_FILE};
10507 my $userid = $self->userid;
10509 if ($CPAN::META->exists("CPAN::Author",$userid)) {
10510 my $author = $CPAN::META->instance("CPAN::Author",
10512 my $fullname = $author->fullname;
10513 my $email = $author->email;
10514 unless (defined $fullname && defined $email) {
10515 return sprintf("Contact Author %s",
10519 return "Contact Author $fullname <$email>";
10521 return "Contact Author $userid (Email address not available)";
10529 #-> sub CPAN::Module::cpan_version ;
10533 my $ro = $self->ro;
10535 # Can happen with modules that are not on CPAN
10538 $ro->{CPAN_VERSION} = 'undef'
10539 unless defined $ro->{CPAN_VERSION};
10540 $ro->{CPAN_VERSION};
10543 #-> sub CPAN::Module::force ;
10546 $self->{force_update} = 1;
10549 #-> sub CPAN::Module::fforce ;
10552 $self->{force_update} = 2;
10555 #-> sub CPAN::Module::notest ;
10558 # $CPAN::Frontend->mywarn("XDEBUG: set notest for Module");
10562 #-> sub CPAN::Module::rematein ;
10564 my($self,$meth) = @_;
10565 $CPAN::Frontend->myprint(sprintf("Running %s for module '%s'\n",
10568 my $cpan_file = $self->cpan_file;
10569 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/) {
10570 $CPAN::Frontend->mywarn(sprintf qq{
10571 The module %s isn\'t available on CPAN.
10573 Either the module has not yet been uploaded to CPAN, or it is
10574 temporary unavailable. Please contact the author to find out
10575 more about the status. Try 'i %s'.
10582 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
10583 $pack->called_for($self->id);
10584 if (exists $self->{force_update}) {
10585 if ($self->{force_update} == 2) {
10586 $pack->fforce($meth);
10588 $pack->force($meth);
10591 $pack->notest($meth) if exists $self->{notest} && $self->{notest};
10593 $pack->{reqtype} ||= "";
10594 CPAN->debug("dist-reqtype[$pack->{reqtype}]".
10595 "self-reqtype[$self->{reqtype}]") if $CPAN::DEBUG;
10596 if ($pack->{reqtype}) {
10597 if ($pack->{reqtype} eq "b" && $self->{reqtype} =~ /^[rc]$/) {
10598 $pack->{reqtype} = $self->{reqtype};
10600 exists $pack->{install}
10603 UNIVERSAL::can($pack->{install},"failed") ?
10604 $pack->{install}->failed :
10605 $pack->{install} =~ /^NO/
10608 delete $pack->{install};
10609 $CPAN::Frontend->mywarn
10610 ("Promoting $pack->{ID} from 'build_requires' to 'requires'");
10614 $pack->{reqtype} = $self->{reqtype};
10617 my $success = eval {
10621 $pack->unforce if $pack->can("unforce") && exists $self->{force_update};
10622 $pack->unnotest if $pack->can("unnotest") && exists $self->{notest};
10623 delete $self->{force_update};
10624 delete $self->{notest};
10631 #-> sub CPAN::Module::perldoc ;
10632 sub perldoc { shift->rematein('perldoc') }
10633 #-> sub CPAN::Module::readme ;
10634 sub readme { shift->rematein('readme') }
10635 #-> sub CPAN::Module::look ;
10636 sub look { shift->rematein('look') }
10637 #-> sub CPAN::Module::cvs_import ;
10638 sub cvs_import { shift->rematein('cvs_import') }
10639 #-> sub CPAN::Module::get ;
10640 sub get { shift->rematein('get',@_) }
10641 #-> sub CPAN::Module::make ;
10642 sub make { shift->rematein('make') }
10643 #-> sub CPAN::Module::test ;
10646 # $self->{badtestcnt} ||= 0;
10647 $self->rematein('test',@_);
10650 #-> sub CPAN::Module::uptodate ;
10654 my $inst = $self->inst_version or return undef;
10655 my $cpan = $self->cpan_version;
10657 CPAN::Version->vgt($cpan,$inst) and return 0;
10658 CPAN->debug(join("",
10659 "returning uptodate. inst_file[",
10661 "cpan[$cpan] inst[$inst]")) if $CPAN::DEBUG;
10665 #-> sub CPAN::Module::install ;
10669 if ($self->uptodate
10671 not exists $self->{force_update}
10673 $CPAN::Frontend->myprint(sprintf("%s is up to date (%s).\n",
10675 $self->inst_version,
10680 my $ro = $self->ro;
10681 if ($ro && $ro->{stats} && $ro->{stats} eq "a") {
10682 $CPAN::Frontend->mywarn(qq{
10683 \n\n\n ***WARNING***
10684 The module $self->{ID} has no active maintainer.\n\n\n
10686 $CPAN::Frontend->mysleep(5);
10688 return $doit ? $self->rematein('install') : 1;
10690 #-> sub CPAN::Module::clean ;
10691 sub clean { shift->rematein('clean') }
10693 #-> sub CPAN::Module::inst_file ;
10696 $self->_file_in_path([@INC]);
10699 #-> sub CPAN::Module::available_file ;
10700 sub available_file {
10702 my $sep = $Config::Config{path_sep};
10703 my $perllib = $ENV{PERL5LIB};
10704 $perllib = $ENV{PERLLIB} unless defined $perllib;
10705 my @perllib = split(/$sep/,$perllib) if defined $perllib;
10707 if ($CPAN::Perl5lib_tempfile) {
10708 my $yaml = CPAN->_yaml_loadfile($CPAN::Perl5lib_tempfile);
10709 @cpan_perl5inc = @{$yaml->[0]{inc} || []};
10711 $self->_file_in_path([@cpan_perl5inc,@perllib,@INC]);
10714 #-> sub CPAN::Module::file_in_path ;
10715 sub _file_in_path {
10716 my($self,$path) = @_;
10717 my($dir,@packpath);
10718 @packpath = split /::/, $self->{ID};
10719 $packpath[-1] .= ".pm";
10720 if (@packpath == 1 && $packpath[0] eq "readline.pm") {
10721 unshift @packpath, "Term", "ReadLine"; # historical reasons
10723 foreach $dir (@$path) {
10724 my $pmfile = File::Spec->catfile($dir,@packpath);
10732 #-> sub CPAN::Module::xs_file ;
10735 my($dir,@packpath);
10736 @packpath = split /::/, $self->{ID};
10737 push @packpath, $packpath[-1];
10738 $packpath[-1] .= "." . $Config::Config{'dlext'};
10739 foreach $dir (@INC) {
10740 my $xsfile = File::Spec->catfile($dir,'auto',@packpath);
10748 #-> sub CPAN::Module::inst_version ;
10751 my $parsefile = $self->inst_file or return;
10752 my $have = $self->parse_version($parsefile);
10756 #-> sub CPAN::Module::inst_version ;
10757 sub available_version {
10759 my $parsefile = $self->available_file or return;
10760 my $have = $self->parse_version($parsefile);
10764 #-> sub CPAN::Module::parse_version ;
10765 sub parse_version {
10766 my($self,$parsefile) = @_;
10767 my $have = eval { MM->parse_version($parsefile); };
10769 $CPAN::Frontend->mywarn("Error while parsing version number in file '$parsefile'\n");
10771 my $leastsanity = eval { defined $have && length $have; };
10772 $have = "undef" unless $leastsanity;
10773 $have =~ s/^ //; # since the %vd hack these two lines here are needed
10774 $have =~ s/ $//; # trailing whitespace happens all the time
10776 $have = CPAN::Version->readable($have);
10778 $have =~ s/\s*//g; # stringify to float around floating point issues
10779 $have; # no stringify needed, \s* above matches always
10782 #-> sub CPAN::Module::reports
10785 $self->distribution->reports;
10798 CPAN - query, download and build perl modules from CPAN sites
10804 perl -MCPAN -e shell
10814 cpan> install Acme::Meta # in the shell
10816 CPAN::Shell->install("Acme::Meta"); # in perl
10820 cpan> install NWCLARK/Acme-Meta-0.02.tar.gz # in the shell
10823 install("NWCLARK/Acme-Meta-0.02.tar.gz"); # in perl
10827 $mo = CPAN::Shell->expandany($mod);
10828 $mo = CPAN::Shell->expand("Module",$mod); # same thing
10830 # distribution objects:
10832 $do = CPAN::Shell->expand("Module",$mod)->distribution;
10833 $do = CPAN::Shell->expandany($distro); # same thing
10834 $do = CPAN::Shell->expand("Distribution",
10835 $distro); # same thing
10839 The CPAN module automates or at least simplifies the make and install
10840 of perl modules and extensions. It includes some primitive searching
10841 capabilities and knows how to use Net::FTP or LWP or some external
10842 download clients to fetch the distributions from the net.
10844 These are fetched from one or more of the mirrored CPAN (Comprehensive
10845 Perl Archive Network) sites and unpacked in a dedicated directory.
10847 The CPAN module also supports the concept of named and versioned
10848 I<bundles> of modules. Bundles simplify the handling of sets of
10849 related modules. See Bundles below.
10851 The package contains a session manager and a cache manager. The
10852 session manager keeps track of what has been fetched, built and
10853 installed in the current session. The cache manager keeps track of the
10854 disk space occupied by the make processes and deletes excess space
10855 according to a simple FIFO mechanism.
10857 All methods provided are accessible in a programmer style and in an
10858 interactive shell style.
10860 =head2 CPAN::shell([$prompt, $command]) Starting Interactive Mode
10862 The interactive mode is entered by running
10864 perl -MCPAN -e shell
10870 which puts you into a readline interface. If C<Term::ReadKey> and
10871 either C<Term::ReadLine::Perl> or C<Term::ReadLine::Gnu> are installed
10872 it supports both history and command completion.
10874 Once you are on the command line, type C<h> to get a one page help
10875 screen and the rest should be self-explanatory.
10877 The function call C<shell> takes two optional arguments, one is the
10878 prompt, the second is the default initial command line (the latter
10879 only works if a real ReadLine interface module is installed).
10881 The most common uses of the interactive modes are
10885 =item Searching for authors, bundles, distribution files and modules
10887 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
10888 for each of the four categories and another, C<i> for any of the
10889 mentioned four. Each of the four entities is implemented as a class
10890 with slightly differing methods for displaying an object.
10892 Arguments you pass to these commands are either strings exactly matching
10893 the identification string of an object or regular expressions that are
10894 then matched case-insensitively against various attributes of the
10895 objects. The parser recognizes a regular expression only if you
10896 enclose it between two slashes.
10898 The principle is that the number of found objects influences how an
10899 item is displayed. If the search finds one item, the result is
10900 displayed with the rather verbose method C<as_string>, but if we find
10901 more than one, we display each object with the terse method
10906 cpan> m Acme::MetaSyntactic
10907 Module id = Acme::MetaSyntactic
10908 CPAN_USERID BOOK (Philippe Bruhat (BooK) <[...]>)
10910 CPAN_FILE B/BO/BOOK/Acme-MetaSyntactic-0.99.tar.gz
10911 UPLOAD_DATE 2006-11-06
10912 MANPAGE Acme::MetaSyntactic - Themed metasyntactic variables names
10913 INST_FILE /usr/local/lib/perl/5.10.0/Acme/MetaSyntactic.pm
10918 FULLNAME Philippe Bruhat (BooK)
10919 cpan> d BOOK/Acme-MetaSyntactic-0.99.tar.gz
10920 Distribution id = B/BO/BOOK/Acme-MetaSyntactic-0.99.tar.gz
10921 CPAN_USERID BOOK (Philippe Bruhat (BooK) <[...]>)
10922 CONTAINSMODS Acme::MetaSyntactic Acme::MetaSyntactic::Alias [...]
10923 UPLOAD_DATE 2006-11-06
10925 Module = Acme::MetaSyntactic::loremipsum (BOOK/Acme-MetaSyntactic-0.99.tar.gz)
10926 Module Text::Lorem (ADEOLA/Text-Lorem-0.3.tar.gz)
10927 Module Text::Lorem::More (RKRIMEN/Text-Lorem-More-0.12.tar.gz)
10928 Module Text::Lorem::More::Source (RKRIMEN/Text-Lorem-More-0.12.tar.gz)
10930 Distribution BEATNIK/Filter-NumberLines-0.02.tar.gz
10931 Module = DateTime::TimeZone::Europe::Berlin (DROLSKY/DateTime-TimeZone-0.7904.tar.gz)
10932 Module Filter::NumberLines (BEATNIK/Filter-NumberLines-0.02.tar.gz)
10935 The examples illustrate several aspects: the first three queries
10936 target modules, authors, or distros directly and yield exactly one
10937 result. The last two use regular expressions and yield several
10938 results. The last one targets all of bundles, modules, authors, and
10939 distros simultaneously. When more than one result is available, they
10940 are printed in one-line format.
10942 =item C<get>, C<make>, C<test>, C<install>, C<clean> modules or distributions
10944 These commands take any number of arguments and investigate what is
10945 necessary to perform the action. If the argument is a distribution
10946 file name (recognized by embedded slashes), it is processed. If it is
10947 a module, CPAN determines the distribution file in which this module
10948 is included and processes that, following any dependencies named in
10949 the module's META.yml or Makefile.PL (this behavior is controlled by
10950 the configuration parameter C<prerequisites_policy>.)
10952 C<get> downloads a distribution file and untars or unzips it, C<make>
10953 builds it, C<test> runs the test suite, and C<install> installs it.
10955 Any C<make> or C<test> are run unconditionally. An
10957 install <distribution_file>
10959 also is run unconditionally. But for
10963 CPAN checks if an install is actually needed for it and prints
10964 I<module up to date> in the case that the distribution file containing
10965 the module doesn't need to be updated.
10967 CPAN also keeps track of what it has done within the current session
10968 and doesn't try to build a package a second time regardless if it
10969 succeeded or not. It does not repeat a test run if the test
10970 has been run successfully before. Same for install runs.
10972 The C<force> pragma may precede another command (currently: C<get>,
10973 C<make>, C<test>, or C<install>) and executes the command from scratch
10974 and tries to continue in case of some errors. See the section below on
10975 the C<force> and the C<fforce> pragma.
10977 The C<notest> pragma may be used to skip the test part in the build
10982 cpan> notest install Tk
10984 A C<clean> command results in a
10988 being executed within the distribution file's working directory.
10990 =item C<readme>, C<perldoc>, C<look> module or distribution
10992 C<readme> displays the README file of the associated distribution.
10993 C<Look> gets and untars (if not yet done) the distribution file,
10994 changes to the appropriate directory and opens a subshell process in
10995 that directory. C<perldoc> displays the pod documentation of the
10996 module in html or plain text format.
11000 =item C<ls> globbing_expression
11002 The first form lists all distribution files in and below an author's
11003 CPAN directory as they are stored in the CHECKUMS files distributed on
11004 CPAN. The listing goes recursive into all subdirectories.
11006 The second form allows to limit or expand the output with shell
11007 globbing as in the following examples:
11013 The last example is very slow and outputs extra progress indicators
11014 that break the alignment of the result.
11016 Note that globbing only lists directories explicitly asked for, for
11017 example FOO/* will not list FOO/bar/Acme-Sthg-n.nn.tar.gz. This may be
11018 regarded as a bug and may be changed in future versions.
11022 The C<failed> command reports all distributions that failed on one of
11023 C<make>, C<test> or C<install> for some reason in the currently
11024 running shell session.
11026 =item Persistence between sessions
11028 If the C<YAML> or the C<YAML::Syck> module is installed a record of
11029 the internal state of all modules is written to disk after each step.
11030 The files contain a signature of the currently running perl version
11033 If the configurations variable C<build_dir_reuse> is set to a true
11034 value, then CPAN.pm reads the collected YAML files. If the stored
11035 signature matches the currently running perl the stored state is
11036 loaded into memory such that effectively persistence between sessions
11039 =item The C<force> and the C<fforce> pragma
11041 To speed things up in complex installation scenarios, CPAN.pm keeps
11042 track of what it has already done and refuses to do some things a
11043 second time. A C<get>, a C<make>, and an C<install> are not repeated.
11044 A C<test> is only repeated if the previous test was unsuccessful. The
11045 diagnostic message when CPAN.pm refuses to do something a second time
11046 is one of I<Has already been >C<unwrapped|made|tested successfully> or
11047 something similar. Another situation where CPAN refuses to act is an
11048 C<install> if the according C<test> was not successful.
11050 In all these cases, the user can override the goatish behaviour by
11051 prepending the command with the word force, for example:
11053 cpan> force get Foo
11054 cpan> force make AUTHOR/Bar-3.14.tar.gz
11055 cpan> force test Baz
11056 cpan> force install Acme::Meta
11058 Each I<forced> command is executed with the according part of its
11061 The C<fforce> pragma is a variant that emulates a C<force get> which
11062 erases the entire memory followed by the action specified, effectively
11063 restarting the whole get/make/test/install procedure from scratch.
11067 Interactive sessions maintain a lockfile, per default C<~/.cpan/.lock>.
11068 Batch jobs can run without a lockfile and do not disturb each other.
11070 The shell offers to run in I<degraded mode> when another process is
11071 holding the lockfile. This is an experimental feature that is not yet
11072 tested very well. This second shell then does not write the history
11073 file, does not use the metadata file and has a different prompt.
11077 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
11078 in the cpan-shell it is intended that you can press C<^C> anytime and
11079 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
11080 to clean up and leave the shell loop. You can emulate the effect of a
11081 SIGTERM by sending two consecutive SIGINTs, which usually means by
11082 pressing C<^C> twice.
11084 CPAN.pm ignores a SIGPIPE. If the user sets C<inactivity_timeout>, a
11085 SIGALRM is used during the run of the C<perl Makefile.PL> or C<perl
11086 Build.PL> subprocess.
11092 The commands that are available in the shell interface are methods in
11093 the package CPAN::Shell. If you enter the shell command, all your
11094 input is split by the Text::ParseWords::shellwords() routine which
11095 acts like most shells do. The first word is being interpreted as the
11096 method to be called and the rest of the words are treated as arguments
11097 to this method. Continuation lines are supported if a line ends with a
11102 C<autobundle> writes a bundle file into the
11103 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
11104 a list of all modules that are both available from CPAN and currently
11105 installed within @INC. The name of the bundle file is based on the
11106 current date and a counter.
11110 Note: this feature is still in alpha state and may change in future
11111 versions of CPAN.pm
11113 This commands provides a statistical overview over recent download
11114 activities. The data for this is collected in the YAML file
11115 C<FTPstats.yml> in your C<cpan_home> directory. If no YAML module is
11116 configured or YAML not installed, then no stats are provided.
11120 mkmyconfig() writes your own CPAN::MyConfig file into your ~/.cpan/
11121 directory so that you can save your own preferences instead of the
11124 =head2 recent ***EXPERIMENTAL COMMAND***
11126 The C<recent> command downloads a list of recent uploads to CPAN and
11127 displays them I<slowly>. While the command is running $SIG{INT} is
11128 defined to mean that the loop shall be left after having displayed the
11131 B<Note>: This command requires XML::LibXML installed.
11133 B<Note>: This whole command currently is just a hack and will
11134 probably change in future versions of CPAN.pm but the general
11135 approach will likely stay.
11137 B<Note>: See also L<smoke>
11141 recompile() is a very special command in that it takes no argument and
11142 runs the make/test/install cycle with brute force over all installed
11143 dynamically loadable extensions (aka XS modules) with 'force' in
11144 effect. The primary purpose of this command is to finish a network
11145 installation. Imagine, you have a common source tree for two different
11146 architectures. You decide to do a completely independent fresh
11147 installation. You start on one architecture with the help of a Bundle
11148 file produced earlier. CPAN installs the whole Bundle for you, but
11149 when you try to repeat the job on the second architecture, CPAN
11150 responds with a C<"Foo up to date"> message for all modules. So you
11151 invoke CPAN's recompile on the second architecture and you're done.
11153 Another popular use for C<recompile> is to act as a rescue in case your
11154 perl breaks binary compatibility. If one of the modules that CPAN uses
11155 is in turn depending on binary compatibility (so you cannot run CPAN
11156 commands), then you should try the CPAN::Nox module for recovery.
11158 =head2 report Bundle|Distribution|Module
11160 The C<report> command temporarily turns on the C<test_report> config
11161 variable, then runs the C<force test> command with the given
11162 arguments. The C<force> pragma is used to re-run the tests and repeat
11163 every step that might have failed before.
11165 =head2 smoke ***EXPERIMENTAL COMMAND***
11167 B<*** WARNING: this command downloads and executes software from CPAN to
11168 your computer of completely unknown status. You should never do
11169 this with your normal account and better have a dedicated well
11170 separated and secured machine to do this. ***>
11172 The C<smoke> command takes the list of recent uploads to CPAN as
11173 provided by the C<recent> command and tests them all. While the
11174 command is running $SIG{INT} is defined to mean that the current item
11177 B<Note>: This whole command currently is just a hack and will
11178 probably change in future versions of CPAN.pm but the general
11179 approach will likely stay.
11181 B<Note>: See also L<recent>
11183 =head2 upgrade [Module|/Regex/]...
11185 The C<upgrade> command first runs an C<r> command with the given
11186 arguments and then installs the newest versions of all modules that
11187 were listed by that.
11189 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
11191 Although it may be considered internal, the class hierarchy does matter
11192 for both users and programmer. CPAN.pm deals with above mentioned four
11193 classes, and all those classes share a set of methods. A classical
11194 single polymorphism is in effect. A metaclass object registers all
11195 objects of all kinds and indexes them with a string. The strings
11196 referencing objects have a separated namespace (well, not completely
11201 words containing a "/" (slash) Distribution
11202 words starting with Bundle:: Bundle
11203 everything else Module or Author
11205 Modules know their associated Distribution objects. They always refer
11206 to the most recent official release. Developers may mark their releases
11207 as unstable development versions (by inserting an underbar into the
11208 module version number which will also be reflected in the distribution
11209 name when you run 'make dist'), so the really hottest and newest
11210 distribution is not always the default. If a module Foo circulates
11211 on CPAN in both version 1.23 and 1.23_90, CPAN.pm offers a convenient
11212 way to install version 1.23 by saying
11216 This would install the complete distribution file (say
11217 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
11218 like to install version 1.23_90, you need to know where the
11219 distribution file resides on CPAN relative to the authors/id/
11220 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
11221 so you would have to say
11223 install BAR/Foo-1.23_90.tar.gz
11225 The first example will be driven by an object of the class
11226 CPAN::Module, the second by an object of class CPAN::Distribution.
11228 =head2 Integrating local directories
11230 Note: this feature is still in alpha state and may change in future
11231 versions of CPAN.pm
11233 Distribution objects are normally distributions from the CPAN, but
11234 there is a slightly degenerate case for Distribution objects, too, of
11235 projects held on the local disk. These distribution objects have the
11236 same name as the local directory and end with a dot. A dot by itself
11237 is also allowed for the current directory at the time CPAN.pm was
11238 used. All actions such as C<make>, C<test>, and C<install> are applied
11239 directly to that directory. This gives the command C<cpan .> an
11240 interesting touch: while the normal mantra of installing a CPAN module
11241 without CPAN.pm is one of
11243 perl Makefile.PL perl Build.PL
11244 ( go and get prerequisites )
11246 make test ./Build test
11247 make install ./Build install
11249 the command C<cpan .> does all of this at once. It figures out which
11250 of the two mantras is appropriate, fetches and installs all
11251 prerequisites, cares for them recursively and finally finishes the
11252 installation of the module in the current directory, be it a CPAN
11255 The typical usage case is for private modules or working copies of
11256 projects from remote repositories on the local disk.
11260 The usual shell redirection symbols C< | > and C<< > >> are recognized
11261 by the cpan shell when surrounded by whitespace. So piping into a
11262 pager and redirecting output into a file works quite similar to any
11265 =head1 CONFIGURATION
11267 When the CPAN module is used for the first time, a configuration
11268 dialog tries to determine a couple of site specific options. The
11269 result of the dialog is stored in a hash reference C< $CPAN::Config >
11270 in a file CPAN/Config.pm.
11272 The default values defined in the CPAN/Config.pm file can be
11273 overridden in a user specific file: CPAN/MyConfig.pm. Such a file is
11274 best placed in $HOME/.cpan/CPAN/MyConfig.pm, because $HOME/.cpan is
11275 added to the search path of the CPAN module before the use() or
11276 require() statements. The mkmyconfig command writes this file for you.
11278 The C<o conf> command has various bells and whistles:
11282 =item completion support
11284 If you have a ReadLine module installed, you can hit TAB at any point
11285 of the commandline and C<o conf> will offer you completion for the
11286 built-in subcommands and/or config variable names.
11288 =item displaying some help: o conf help
11290 Displays a short help
11292 =item displaying current values: o conf [KEY]
11294 Displays the current value(s) for this config variable. Without KEY
11295 displays all subcommands and config variables.
11301 If KEY starts and ends with a slash the string in between is
11302 interpreted as a regular expression and only keys matching this regex
11309 =item changing of scalar values: o conf KEY VALUE
11311 Sets the config variable KEY to VALUE. The empty string can be
11312 specified as usual in shells, with C<''> or C<"">
11316 o conf wget /usr/bin/wget
11318 =item changing of list values: o conf KEY SHIFT|UNSHIFT|PUSH|POP|SPLICE|LIST
11320 If a config variable name ends with C<list>, it is a list. C<o conf
11321 KEY shift> removes the first element of the list, C<o conf KEY pop>
11322 removes the last element of the list. C<o conf KEYS unshift LIST>
11323 prepends a list of values to the list, C<o conf KEYS push LIST>
11324 appends a list of valued to the list.
11326 Likewise, C<o conf KEY splice LIST> passes the LIST to the according
11329 Finally, any other list of arguments is taken as a new list value for
11330 the KEY variable discarding the previous value.
11334 o conf urllist unshift http://cpan.dev.local/CPAN
11335 o conf urllist splice 3 1
11336 o conf urllist http://cpan1.local http://cpan2.local ftp://ftp.perl.org
11338 =item reverting to saved: o conf defaults
11340 Reverts all config variables to the state in the saved config file.
11342 =item saving the config: o conf commit
11344 Saves all config variables to the current config file (CPAN/Config.pm
11345 or CPAN/MyConfig.pm that was loaded at start).
11349 The configuration dialog can be started any time later again by
11350 issuing the command C< o conf init > in the CPAN shell. A subset of
11351 the configuration dialog can be run by issuing C<o conf init WORD>
11352 where WORD is any valid config variable or a regular expression.
11354 =head2 Config Variables
11356 Currently the following keys in the hash reference $CPAN::Config are
11359 applypatch path to external prg
11360 auto_commit commit all changes to config variables to disk
11361 build_cache size of cache for directories to build modules
11362 build_dir locally accessible directory to build modules
11363 build_dir_reuse boolean if distros in build_dir are persistent
11364 build_requires_install_policy
11365 to install or not to install when a module is
11366 only needed for building. yes|no|ask/yes|ask/no
11367 bzip2 path to external prg
11368 cache_metadata use serializer to cache metadata
11369 check_sigs if signatures should be verified
11370 colorize_debug Term::ANSIColor attributes for debugging output
11371 colorize_output boolean if Term::ANSIColor should colorize output
11372 colorize_print Term::ANSIColor attributes for normal output
11373 colorize_warn Term::ANSIColor attributes for warnings
11374 commandnumber_in_prompt
11375 boolean if you want to see current command number
11376 commands_quote prefered character to use for quoting external
11377 commands when running them. Defaults to double
11378 quote on Windows, single tick everywhere else;
11379 can be set to space to disable quoting
11380 connect_to_internet_ok
11381 if we shall ask if opening a connection is ok before
11382 urllist is specified
11383 cpan_home local directory reserved for this package
11384 curl path to external prg
11385 dontload_hash DEPRECATED
11386 dontload_list arrayref: modules in the list will not be
11387 loaded by the CPAN::has_inst() routine
11388 ftp path to external prg
11389 ftp_passive if set, the envariable FTP_PASSIVE is set for downloads
11390 ftp_proxy proxy host for ftp requests
11391 ftpstats_period max number of days to keep download statistics
11392 ftpstats_size max number of items to keep in the download statistics
11394 gpg path to external prg
11395 gzip location of external program gzip
11396 halt_on_failure stop processing after the first failure of queued
11397 items or dependencies
11398 histfile file to maintain history between sessions
11399 histsize maximum number of lines to keep in histfile
11400 http_proxy proxy host for http requests
11401 inactivity_timeout breaks interactive Makefile.PLs or Build.PLs
11402 after this many seconds inactivity. Set to 0 to
11404 index_expire after this many days refetch index files
11405 inhibit_startup_message
11406 if true, does not print the startup message
11407 keep_source_where directory in which to keep the source (if we do)
11408 load_module_verbosity
11409 report loading of optional modules used by CPAN.pm
11410 lynx path to external prg
11411 make location of external make program
11412 make_arg arguments that should always be passed to 'make'
11413 make_install_make_command
11414 the make command for running 'make install', for
11415 example 'sudo make'
11416 make_install_arg same as make_arg for 'make install'
11417 makepl_arg arguments passed to 'perl Makefile.PL'
11418 mbuild_arg arguments passed to './Build'
11419 mbuild_install_arg arguments passed to './Build install'
11420 mbuild_install_build_command
11421 command to use instead of './Build' when we are
11422 in the install stage, for example 'sudo ./Build'
11423 mbuildpl_arg arguments passed to 'perl Build.PL'
11424 ncftp path to external prg
11425 ncftpget path to external prg
11426 no_proxy don't proxy to these hosts/domains (comma separated list)
11427 pager location of external program more (or any pager)
11428 password your password if you CPAN server wants one
11429 patch path to external prg
11430 perl5lib_verbosity verbosity level for PERL5LIB additions
11431 prefer_installer legal values are MB and EUMM: if a module comes
11432 with both a Makefile.PL and a Build.PL, use the
11433 former (EUMM) or the latter (MB); if the module
11434 comes with only one of the two, that one will be
11436 prerequisites_policy
11437 what to do if you are missing module prerequisites
11438 ('follow' automatically, 'ask' me, or 'ignore')
11439 prefs_dir local directory to store per-distro build options
11440 proxy_user username for accessing an authenticating proxy
11441 proxy_pass password for accessing an authenticating proxy
11442 randomize_urllist add some randomness to the sequence of the urllist
11443 scan_cache controls scanning of cache ('atstart' or 'never')
11444 shell your favorite shell
11445 show_unparsable_versions
11446 boolean if r command tells which modules are versionless
11447 show_upload_date boolean if commands should try to determine upload date
11448 show_zero_versions boolean if r command tells for which modules $version==0
11449 tar location of external program tar
11450 tar_verbosity verbosity level for the tar command
11451 term_is_latin deprecated: if true Unicode is translated to ISO-8859-1
11452 (and nonsense for characters outside latin range)
11453 term_ornaments boolean to turn ReadLine ornamenting on/off
11454 test_report email test reports (if CPAN::Reporter is installed)
11455 trust_test_report_history
11456 skip testing when previously tested ok (according to
11457 CPAN::Reporter history)
11458 unzip location of external program unzip
11459 urllist arrayref to nearby CPAN sites (or equivalent locations)
11460 use_sqlite use CPAN::SQLite for metadata storage (fast and lean)
11461 username your username if you CPAN server wants one
11462 wait_list arrayref to a wait server to try (See CPAN::WAIT)
11463 wget path to external prg
11464 yaml_load_code enable YAML code deserialisation via CPAN::DeferedCode
11465 yaml_module which module to use to read/write YAML files
11467 You can set and query each of these options interactively in the cpan
11468 shell with the C<o conf> or the C<o conf init> command as specified below.
11472 =item C<o conf E<lt>scalar optionE<gt>>
11474 prints the current value of the I<scalar option>
11476 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
11478 Sets the value of the I<scalar option> to I<value>
11480 =item C<o conf E<lt>list optionE<gt>>
11482 prints the current value of the I<list option> in MakeMaker's
11485 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
11487 shifts or pops the array in the I<list option> variable
11489 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
11491 works like the corresponding perl commands.
11493 =item interactive editing: o conf init [MATCH|LIST]
11495 Runs an interactive configuration dialog for matching variables.
11496 Without argument runs the dialog over all supported config variables.
11497 To specify a MATCH the argument must be enclosed by slashes.
11501 o conf init ftp_passive ftp_proxy
11502 o conf init /color/
11504 Note: this method of setting config variables often provides more
11505 explanation about the functioning of a variable than the manpage.
11509 =head2 CPAN::anycwd($path): Note on config variable getcwd
11511 CPAN.pm changes the current working directory often and needs to
11512 determine its own current working directory. Per default it uses
11513 Cwd::cwd but if this doesn't work on your system for some reason,
11514 alternatives can be configured according to the following table:
11532 Calls the external command cwd.
11536 =head2 Note on the format of the urllist parameter
11538 urllist parameters are URLs according to RFC 1738. We do a little
11539 guessing if your URL is not compliant, but if you have problems with
11540 C<file> URLs, please try the correct format. Either:
11542 file://localhost/whatever/ftp/pub/CPAN/
11546 file:///home/ftp/pub/CPAN/
11548 =head2 The urllist parameter has CD-ROM support
11550 The C<urllist> parameter of the configuration table contains a list of
11551 URLs that are to be used for downloading. If the list contains any
11552 C<file> URLs, CPAN always tries to get files from there first. This
11553 feature is disabled for index files. So the recommendation for the
11554 owner of a CD-ROM with CPAN contents is: include your local, possibly
11555 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
11557 o conf urllist push file://localhost/CDROM/CPAN
11559 CPAN.pm will then fetch the index files from one of the CPAN sites
11560 that come at the beginning of urllist. It will later check for each
11561 module if there is a local copy of the most recent version.
11563 Another peculiarity of urllist is that the site that we could
11564 successfully fetch the last file from automatically gets a preference
11565 token and is tried as the first site for the next request. So if you
11566 add a new site at runtime it may happen that the previously preferred
11567 site will be tried another time. This means that if you want to disallow
11568 a site for the next transfer, it must be explicitly removed from
11571 =head2 Maintaining the urllist parameter
11573 If you have YAML.pm (or some other YAML module configured in
11574 C<yaml_module>) installed, CPAN.pm collects a few statistical data
11575 about recent downloads. You can view the statistics with the C<hosts>
11576 command or inspect them directly by looking into the C<FTPstats.yml>
11577 file in your C<cpan_home> directory.
11579 To get some interesting statistics it is recommended to set the
11580 C<randomize_urllist> parameter that introduces some amount of
11581 randomness into the URL selection.
11583 =head2 The C<requires> and C<build_requires> dependency declarations
11585 Since CPAN.pm version 1.88_51 modules declared as C<build_requires> by
11586 a distribution are treated differently depending on the config
11587 variable C<build_requires_install_policy>. By setting
11588 C<build_requires_install_policy> to C<no> such a module is not being
11589 installed. It is only built and tested and then kept in the list of
11590 tested but uninstalled modules. As such it is available during the
11591 build of the dependent module by integrating the path to the
11592 C<blib/arch> and C<blib/lib> directories in the environment variable
11593 PERL5LIB. If C<build_requires_install_policy> is set ti C<yes>, then
11594 both modules declared as C<requires> and those declared as
11595 C<build_requires> are treated alike. By setting to C<ask/yes> or
11596 C<ask/no>, CPAN.pm asks the user and sets the default accordingly.
11598 =head2 Configuration for individual distributions (I<Distroprefs>)
11600 (B<Note:> This feature has been introduced in CPAN.pm 1.8854 and is
11601 still considered beta quality)
11603 Distributions on the CPAN usually behave according to what we call the
11604 CPAN mantra. Or since the event of Module::Build we should talk about
11607 perl Makefile.PL perl Build.PL
11609 make test ./Build test
11610 make install ./Build install
11612 But some modules cannot be built with this mantra. They try to get
11613 some extra data from the user via the environment, extra arguments or
11614 interactively thus disturbing the installation of large bundles like
11615 Phalanx100 or modules with many dependencies like Plagger.
11617 The distroprefs system of C<CPAN.pm> addresses this problem by
11618 allowing the user to specify extra informations and recipes in YAML
11625 pass additional arguments to one of the four commands,
11629 set environment variables
11633 instantiate an Expect object that reads from the console, waits for
11634 some regular expressions and enters some answers
11638 temporarily override assorted C<CPAN.pm> configuration variables
11642 specify dependencies that the original maintainer forgot to specify
11646 disable the installation of an object altogether
11650 See the YAML and Data::Dumper files that come with the C<CPAN.pm>
11651 distribution in the C<distroprefs/> directory for examples.
11655 The YAML files themselves must have the C<.yml> extension, all other
11656 files are ignored (for two exceptions see I<Fallback Data::Dumper and
11657 Storable> below). The containing directory can be specified in
11658 C<CPAN.pm> in the C<prefs_dir> config variable. Try C<o conf init
11659 prefs_dir> in the CPAN shell to set and activate the distroprefs
11662 Every YAML file may contain arbitrary documents according to the YAML
11663 specification and every single document is treated as an entity that
11664 can specify the treatment of a single distribution.
11666 The names of the files can be picked freely, C<CPAN.pm> always reads
11667 all files (in alphabetical order) and takes the key C<match> (see
11668 below in I<Language Specs>) as a hashref containing match criteria
11669 that determine if the current distribution matches the YAML document
11672 =head2 Fallback Data::Dumper and Storable
11674 If neither your configured C<yaml_module> nor YAML.pm is installed
11675 CPAN.pm falls back to using Data::Dumper and Storable and looks for
11676 files with the extensions C<.dd> or C<.st> in the C<prefs_dir>
11677 directory. These files are expected to contain one or more hashrefs.
11678 For Data::Dumper generated files, this is expected to be done with by
11679 defining C<$VAR1>, C<$VAR2>, etc. The YAML shell would produce these
11682 ysh < somefile.yml > somefile.dd
11684 For Storable files the rule is that they must be constructed such that
11685 C<Storable::retrieve(file)> returns an array reference and the array
11686 elements represent one distropref object each. The conversion from
11687 YAML would look like so:
11689 perl -MYAML=LoadFile -MStorable=nstore -e '
11690 @y=LoadFile(shift);
11691 nstore(\@y, shift)' somefile.yml somefile.st
11693 In bootstrapping situations it is usually sufficient to translate only
11694 a few YAML files to Data::Dumper for the crucial modules like
11695 C<YAML::Syck>, C<YAML.pm> and C<Expect.pm>. If you prefer Storable
11696 over Data::Dumper, remember to pull out a Storable version that writes
11697 an older format than all the other Storable versions that will need to
11702 The following example contains all supported keywords and structures
11703 with the exception of C<eexpect> which can be used instead of
11709 module: "Dancing::Queen"
11710 distribution: "^CHACHACHA/Dancing-"
11711 perl: "/usr/local/cariba-perl/bin/perl"
11713 archname: "freebsd"
11715 DANCING_FLOOR: "Shubiduh"
11721 - "--somearg=specialcase"
11726 - "Which is your favorite fruit"
11738 commendline: "echo SKIPPING make"
11751 WANT_TO_INSTALL: YES
11754 - "Do you really want to install"
11758 - "ABCDE/Fedcba-3.14-ABCDE-01.patch"
11761 configure_requires:
11764 Test::Exception: 0.25
11769 =head2 Language Specs
11771 Every YAML document represents a single hash reference. The valid keys
11772 in this hash are as follows:
11776 =item comment [scalar]
11780 =item cpanconfig [hash]
11782 Temporarily override assorted C<CPAN.pm> configuration variables.
11784 Supported are: C<build_requires_install_policy>, C<check_sigs>,
11785 C<make>, C<make_install_make_command>, C<prefer_installer>,
11786 C<test_report>. Please report as a bug when you need another one
11789 =item depends [hash] *** EXPERIMENTAL FEATURE ***
11791 All three types, namely C<configure_requires>, C<build_requires>, and
11792 C<requires> are supported in the way specified in the META.yml
11793 specification. The current implementation I<merges> the specified
11794 dependencies with those declared by the package maintainer. In a
11795 future implementation this may be changed to override the original
11798 =item disabled [boolean]
11800 Specifies that this distribution shall not be processed at all.
11802 =item features [array] *** EXPERIMENTAL FEATURE ***
11804 Experimental implementation to deal with optional_features from
11805 META.yml. Still needs coordination with installer software and
11806 currently only works for META.yml declaring C<dynamic_config=0>. Use
11809 =item goto [string]
11811 The canonical name of a delegate distribution that shall be installed
11812 instead. Useful when a new version, although it tests OK itself,
11813 breaks something else or a developer release or a fork is already
11814 uploaded that is better than the last released version.
11816 =item install [hash]
11818 Processing instructions for the C<make install> or C<./Build install>
11819 phase of the CPAN mantra. See below under I<Processing Instructions>.
11823 Processing instructions for the C<make> or C<./Build> phase of the
11824 CPAN mantra. See below under I<Processing Instructions>.
11828 A hashref with one or more of the keys C<distribution>, C<modules>,
11829 C<perl>, C<perlconfig>, and C<env> that specify if a document is
11830 targeted at a specific CPAN distribution or installation.
11832 The corresponding values are interpreted as regular expressions. The
11833 C<distribution> related one will be matched against the canonical
11834 distribution name, e.g. "AUTHOR/Foo-Bar-3.14.tar.gz".
11836 The C<module> related one will be matched against I<all> modules
11837 contained in the distribution until one module matches.
11839 The C<perl> related one will be matched against C<$^X> (but with the
11842 The value associated with C<perlconfig> is itself a hashref that is
11843 matched against corresponding values in the C<%Config::Config> hash
11844 living in the C<Config.pm> module.
11846 The value associated with C<env> is itself a hashref that is
11847 matched against corresponding values in the C<%ENV> hash.
11849 If more than one restriction of C<module>, C<distribution>, etc. is
11850 specified, the results of the separately computed match values must
11851 all match. If this is the case then the hashref represented by the
11852 YAML document is returned as the preference structure for the current
11855 =item patches [array]
11857 An array of patches on CPAN or on the local disk to be applied in
11858 order via the external patch program. If the value for the C<-p>
11859 parameter is C<0> or C<1> is determined by reading the patch
11862 Note: if the C<applypatch> program is installed and C<CPAN::Config>
11863 knows about it B<and> a patch is written by the C<makepatch> program,
11864 then C<CPAN.pm> lets C<applypatch> apply the patch. Both C<makepatch>
11865 and C<applypatch> are available from CPAN in the C<JV/makepatch-*>
11870 Processing instructions for the C<perl Makefile.PL> or C<perl
11871 Build.PL> phase of the CPAN mantra. See below under I<Processing
11876 Processing instructions for the C<make test> or C<./Build test> phase
11877 of the CPAN mantra. See below under I<Processing Instructions>.
11881 =head2 Processing Instructions
11887 Arguments to be added to the command line
11891 A full commandline that will be executed as it stands by a system
11892 call. During the execution the environment variable PERL will is set
11893 to $^X (but with an absolute path). If C<commandline> is specified,
11894 the content of C<args> is not used.
11896 =item eexpect [hash]
11898 Extended C<expect>. This is a hash reference with four allowed keys,
11899 C<mode>, C<timeout>, C<reuse>, and C<talk>.
11901 C<mode> may have the values C<deterministic> for the case where all
11902 questions come in the order written down and C<anyorder> for the case
11903 where the questions may come in any order. The default mode is
11906 C<timeout> denotes a timeout in seconds. Floating point timeouts are
11907 OK. In the case of a C<mode=deterministic> the timeout denotes the
11908 timeout per question, in the case of C<mode=anyorder> it denotes the
11909 timeout per byte received from the stream or questions.
11911 C<talk> is a reference to an array that contains alternating questions
11912 and answers. Questions are regular expressions and answers are literal
11913 strings. The Expect module will then watch the stream coming from the
11914 execution of the external program (C<perl Makefile.PL>, C<perl
11915 Build.PL>, C<make>, etc.).
11917 In the case of C<mode=deterministic> the CPAN.pm will inject the
11918 according answer as soon as the stream matches the regular expression.
11920 In the case of C<mode=anyorder> CPAN.pm will answer a question as soon
11921 as the timeout is reached for the next byte in the input stream. In
11922 this mode you can use the C<reuse> parameter to decide what shall
11923 happen with a question-answer pair after it has been used. In the
11924 default case (reuse=0) it is removed from the array, so it cannot be
11925 used again accidentally. In this case, if you want to answer the
11926 question C<Do you really want to do that> several times, then it must
11927 be included in the array at least as often as you want this answer to
11928 be given. Setting the parameter C<reuse> to 1 makes this repetition
11933 Environment variables to be set during the command
11935 =item expect [array]
11937 C<< expect: <array> >> is a short notation for
11940 mode: deterministic
11946 =head2 Schema verification with C<Kwalify>
11948 If you have the C<Kwalify> module installed (which is part of the
11949 Bundle::CPANxxl), then all your distroprefs files are checked for
11950 syntactical correctness.
11952 =head2 Example Distroprefs Files
11954 C<CPAN.pm> comes with a collection of example YAML files. Note that these
11955 are really just examples and should not be used without care because
11956 they cannot fit everybody's purpose. After all the authors of the
11957 packages that ask questions had a need to ask, so you should watch
11958 their questions and adjust the examples to your environment and your
11959 needs. You have beend warned:-)
11961 =head1 PROGRAMMER'S INTERFACE
11963 If you do not enter the shell, the available shell commands are both
11964 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
11965 functions in the calling package (C<install(...)>). Before calling low-level
11966 commands it makes sense to initialize components of CPAN you need, e.g.:
11968 CPAN::HandleConfig->load;
11969 CPAN::Shell::setup_output;
11970 CPAN::Index->reload;
11972 High-level commands do such initializations automatically.
11974 There's currently only one class that has a stable interface -
11975 CPAN::Shell. All commands that are available in the CPAN shell are
11976 methods of the class CPAN::Shell. Each of the commands that produce
11977 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
11978 the IDs of all modules within the list.
11982 =item expand($type,@things)
11984 The IDs of all objects available within a program are strings that can
11985 be expanded to the corresponding real objects with the
11986 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
11987 list of CPAN::Module objects according to the C<@things> arguments
11988 given. In scalar context it only returns the first element of the
11991 =item expandany(@things)
11993 Like expand, but returns objects of the appropriate type, i.e.
11994 CPAN::Bundle objects for bundles, CPAN::Module objects for modules and
11995 CPAN::Distribution objects for distributions. Note: it does not expand
11996 to CPAN::Author objects.
11998 =item Programming Examples
12000 This enables the programmer to do operations that combine
12001 functionalities that are available in the shell.
12003 # install everything that is outdated on my disk:
12004 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
12006 # install my favorite programs if necessary:
12007 for $mod (qw(Net::FTP Digest::SHA Data::Dumper)) {
12008 CPAN::Shell->install($mod);
12011 # list all modules on my disk that have no VERSION number
12012 for $mod (CPAN::Shell->expand("Module","/./")) {
12013 next unless $mod->inst_file;
12014 # MakeMaker convention for undefined $VERSION:
12015 next unless $mod->inst_version eq "undef";
12016 print "No VERSION in ", $mod->id, "\n";
12019 # find out which distribution on CPAN contains a module:
12020 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
12022 Or if you want to write a cronjob to watch The CPAN, you could list
12023 all modules that need updating. First a quick and dirty way:
12025 perl -e 'use CPAN; CPAN::Shell->r;'
12027 If you don't want to get any output in the case that all modules are
12028 up to date, you can parse the output of above command for the regular
12029 expression //modules are up to date// and decide to mail the output
12030 only if it doesn't match. Ick?
12032 If you prefer to do it more in a programmer style in one single
12033 process, maybe something like this suits you better:
12035 # list all modules on my disk that have newer versions on CPAN
12036 for $mod (CPAN::Shell->expand("Module","/./")) {
12037 next unless $mod->inst_file;
12038 next if $mod->uptodate;
12039 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
12040 $mod->id, $mod->inst_version, $mod->cpan_version;
12043 If that gives you too much output every day, you maybe only want to
12044 watch for three modules. You can write
12046 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")) {
12048 as the first line instead. Or you can combine some of the above
12051 # watch only for a new mod_perl module
12052 $mod = CPAN::Shell->expand("Module","mod_perl");
12053 exit if $mod->uptodate;
12054 # new mod_perl arrived, let me know all update recommendations
12059 =head2 Methods in the other Classes
12063 =item CPAN::Author::as_glimpse()
12065 Returns a one-line description of the author
12067 =item CPAN::Author::as_string()
12069 Returns a multi-line description of the author
12071 =item CPAN::Author::email()
12073 Returns the author's email address
12075 =item CPAN::Author::fullname()
12077 Returns the author's name
12079 =item CPAN::Author::name()
12081 An alias for fullname
12083 =item CPAN::Bundle::as_glimpse()
12085 Returns a one-line description of the bundle
12087 =item CPAN::Bundle::as_string()
12089 Returns a multi-line description of the bundle
12091 =item CPAN::Bundle::clean()
12093 Recursively runs the C<clean> method on all items contained in the bundle.
12095 =item CPAN::Bundle::contains()
12097 Returns a list of objects' IDs contained in a bundle. The associated
12098 objects may be bundles, modules or distributions.
12100 =item CPAN::Bundle::force($method,@args)
12102 Forces CPAN to perform a task that it normally would have refused to
12103 do. Force takes as arguments a method name to be called and any number
12104 of additional arguments that should be passed to the called method.
12105 The internals of the object get the needed changes so that CPAN.pm
12106 does not refuse to take the action. The C<force> is passed recursively
12107 to all contained objects. See also the section above on the C<force>
12108 and the C<fforce> pragma.
12110 =item CPAN::Bundle::get()
12112 Recursively runs the C<get> method on all items contained in the bundle
12114 =item CPAN::Bundle::inst_file()
12116 Returns the highest installed version of the bundle in either @INC or
12117 C<$CPAN::Config->{cpan_home}>. Note that this is different from
12118 CPAN::Module::inst_file.
12120 =item CPAN::Bundle::inst_version()
12122 Like CPAN::Bundle::inst_file, but returns the $VERSION
12124 =item CPAN::Bundle::uptodate()
12126 Returns 1 if the bundle itself and all its members are uptodate.
12128 =item CPAN::Bundle::install()
12130 Recursively runs the C<install> method on all items contained in the bundle
12132 =item CPAN::Bundle::make()
12134 Recursively runs the C<make> method on all items contained in the bundle
12136 =item CPAN::Bundle::readme()
12138 Recursively runs the C<readme> method on all items contained in the bundle
12140 =item CPAN::Bundle::test()
12142 Recursively runs the C<test> method on all items contained in the bundle
12144 =item CPAN::Distribution::as_glimpse()
12146 Returns a one-line description of the distribution
12148 =item CPAN::Distribution::as_string()
12150 Returns a multi-line description of the distribution
12152 =item CPAN::Distribution::author
12154 Returns the CPAN::Author object of the maintainer who uploaded this
12157 =item CPAN::Distribution::pretty_id()
12159 Returns a string of the form "AUTHORID/TARBALL", where AUTHORID is the
12160 author's PAUSE ID and TARBALL is the distribution filename.
12162 =item CPAN::Distribution::base_id()
12164 Returns the distribution filename without any archive suffix. E.g
12167 =item CPAN::Distribution::clean()
12169 Changes to the directory where the distribution has been unpacked and
12170 runs C<make clean> there.
12172 =item CPAN::Distribution::containsmods()
12174 Returns a list of IDs of modules contained in a distribution file.
12175 Only works for distributions listed in the 02packages.details.txt.gz
12176 file. This typically means that only the most recent version of a
12177 distribution is covered.
12179 =item CPAN::Distribution::cvs_import()
12181 Changes to the directory where the distribution has been unpacked and
12182 runs something like
12184 cvs -d $cvs_root import -m $cvs_log $cvs_dir $userid v$version
12188 =item CPAN::Distribution::dir()
12190 Returns the directory into which this distribution has been unpacked.
12192 =item CPAN::Distribution::force($method,@args)
12194 Forces CPAN to perform a task that it normally would have refused to
12195 do. Force takes as arguments a method name to be called and any number
12196 of additional arguments that should be passed to the called method.
12197 The internals of the object get the needed changes so that CPAN.pm
12198 does not refuse to take the action. See also the section above on the
12199 C<force> and the C<fforce> pragma.
12201 =item CPAN::Distribution::get()
12203 Downloads the distribution from CPAN and unpacks it. Does nothing if
12204 the distribution has already been downloaded and unpacked within the
12207 =item CPAN::Distribution::install()
12209 Changes to the directory where the distribution has been unpacked and
12210 runs the external command C<make install> there. If C<make> has not
12211 yet been run, it will be run first. A C<make test> will be issued in
12212 any case and if this fails, the install will be canceled. The
12213 cancellation can be avoided by letting C<force> run the C<install> for
12216 This install method has only the power to install the distribution if
12217 there are no dependencies in the way. To install an object and all of
12218 its dependencies, use CPAN::Shell->install.
12220 Note that install() gives no meaningful return value. See uptodate().
12222 =item CPAN::Distribution::install_tested()
12224 Install all the distributions that have been tested sucessfully but
12225 not yet installed. See also C<is_tested>.
12227 =item CPAN::Distribution::isa_perl()
12229 Returns 1 if this distribution file seems to be a perl distribution.
12230 Normally this is derived from the file name only, but the index from
12231 CPAN can contain a hint to achieve a return value of true for other
12234 =item CPAN::Distribution::look()
12236 Changes to the directory where the distribution has been unpacked and
12237 opens a subshell there. Exiting the subshell returns.
12239 =item CPAN::Distribution::make()
12241 First runs the C<get> method to make sure the distribution is
12242 downloaded and unpacked. Changes to the directory where the
12243 distribution has been unpacked and runs the external commands C<perl
12244 Makefile.PL> or C<perl Build.PL> and C<make> there.
12246 =item CPAN::Distribution::perldoc()
12248 Downloads the pod documentation of the file associated with a
12249 distribution (in html format) and runs it through the external
12250 command lynx specified in C<$CPAN::Config->{lynx}>. If lynx
12251 isn't available, it converts it to plain text with external
12252 command html2text and runs it through the pager specified
12253 in C<$CPAN::Config->{pager}>
12255 =item CPAN::Distribution::prefs()
12257 Returns the hash reference from the first matching YAML file that the
12258 user has deposited in the C<prefs_dir/> directory. The first
12259 succeeding match wins. The files in the C<prefs_dir/> are processed
12260 alphabetically and the canonical distroname (e.g.
12261 AUTHOR/Foo-Bar-3.14.tar.gz) is matched against the regular expressions
12262 stored in the $root->{match}{distribution} attribute value.
12263 Additionally all module names contained in a distribution are matched
12264 agains the regular expressions in the $root->{match}{module} attribute
12265 value. The two match values are ANDed together. Each of the two
12266 attributes are optional.
12268 =item CPAN::Distribution::prereq_pm()
12270 Returns the hash reference that has been announced by a distribution
12271 as the the C<requires> and C<build_requires> elements. These can be
12272 declared either by the C<META.yml> (if authoritative) or can be
12273 deposited after the run of C<Build.PL> in the file C<./_build/prereqs>
12274 or after the run of C<Makfile.PL> written as the C<PREREQ_PM> hash in
12275 a comment in the produced C<Makefile>. I<Note>: this method only works
12276 after an attempt has been made to C<make> the distribution. Returns
12279 =item CPAN::Distribution::readme()
12281 Downloads the README file associated with a distribution and runs it
12282 through the pager specified in C<$CPAN::Config->{pager}>.
12284 =item CPAN::Distribution::reports()
12286 Downloads report data for this distribution from www.cpantesters.org
12287 and displays a subset of them.
12289 =item CPAN::Distribution::read_yaml()
12291 Returns the content of the META.yml of this distro as a hashref. Note:
12292 works only after an attempt has been made to C<make> the distribution.
12293 Returns undef otherwise. Also returns undef if the content of META.yml
12294 is not authoritative. (The rules about what exactly makes the content
12295 authoritative are still in flux.)
12297 =item CPAN::Distribution::test()
12299 Changes to the directory where the distribution has been unpacked and
12300 runs C<make test> there.
12302 =item CPAN::Distribution::uptodate()
12304 Returns 1 if all the modules contained in the distribution are
12305 uptodate. Relies on containsmods.
12307 =item CPAN::Index::force_reload()
12309 Forces a reload of all indices.
12311 =item CPAN::Index::reload()
12313 Reloads all indices if they have not been read for more than
12314 C<$CPAN::Config->{index_expire}> days.
12316 =item CPAN::InfoObj::dump()
12318 CPAN::Author, CPAN::Bundle, CPAN::Module, and CPAN::Distribution
12319 inherit this method. It prints the data structure associated with an
12320 object. Useful for debugging. Note: the data structure is considered
12321 internal and thus subject to change without notice.
12323 =item CPAN::Module::as_glimpse()
12325 Returns a one-line description of the module in four columns: The
12326 first column contains the word C<Module>, the second column consists
12327 of one character: an equals sign if this module is already installed
12328 and uptodate, a less-than sign if this module is installed but can be
12329 upgraded, and a space if the module is not installed. The third column
12330 is the name of the module and the fourth column gives maintainer or
12331 distribution information.
12333 =item CPAN::Module::as_string()
12335 Returns a multi-line description of the module
12337 =item CPAN::Module::clean()
12339 Runs a clean on the distribution associated with this module.
12341 =item CPAN::Module::cpan_file()
12343 Returns the filename on CPAN that is associated with the module.
12345 =item CPAN::Module::cpan_version()
12347 Returns the latest version of this module available on CPAN.
12349 =item CPAN::Module::cvs_import()
12351 Runs a cvs_import on the distribution associated with this module.
12353 =item CPAN::Module::description()
12355 Returns a 44 character description of this module. Only available for
12356 modules listed in The Module List (CPAN/modules/00modlist.long.html
12357 or 00modlist.long.txt.gz)
12359 =item CPAN::Module::distribution()
12361 Returns the CPAN::Distribution object that contains the current
12362 version of this module.
12364 =item CPAN::Module::dslip_status()
12366 Returns a hash reference. The keys of the hash are the letters C<D>,
12367 C<S>, C<L>, C<I>, and <P>, for development status, support level,
12368 language, interface and public licence respectively. The data for the
12369 DSLIP status are collected by pause.perl.org when authors register
12370 their namespaces. The values of the 5 hash elements are one-character
12371 words whose meaning is described in the table below. There are also 5
12372 hash elements C<DV>, C<SV>, C<LV>, C<IV>, and <PV> that carry a more
12373 verbose value of the 5 status variables.
12375 Where the 'DSLIP' characters have the following meanings:
12377 D - Development Stage (Note: *NO IMPLIED TIMESCALES*):
12378 i - Idea, listed to gain consensus or as a placeholder
12379 c - under construction but pre-alpha (not yet released)
12380 a/b - Alpha/Beta testing
12382 M - Mature (no rigorous definition)
12383 S - Standard, supplied with Perl 5
12388 u - Usenet newsgroup comp.lang.perl.modules
12389 n - None known, try comp.lang.perl.modules
12390 a - abandoned; volunteers welcome to take over maintainance
12393 p - Perl-only, no compiler needed, should be platform independent
12394 c - C and perl, a C compiler will be needed
12395 h - Hybrid, written in perl with optional C code, no compiler needed
12396 + - C++ and perl, a C++ compiler will be needed
12397 o - perl and another language other than C or C++
12399 I - Interface Style
12400 f - plain Functions, no references used
12401 h - hybrid, object and function interfaces available
12402 n - no interface at all (huh?)
12403 r - some use of unblessed References or ties
12404 O - Object oriented using blessed references and/or inheritance
12407 p - Standard-Perl: user may choose between GPL and Artistic
12408 g - GPL: GNU General Public License
12409 l - LGPL: "GNU Lesser General Public License" (previously known as
12410 "GNU Library General Public License")
12411 b - BSD: The BSD License
12412 a - Artistic license alone
12413 2 - Artistic license 2.0 or later
12414 o - open source: appoved by www.opensource.org
12415 d - allows distribution without restrictions
12416 r - restricted distribtion
12417 n - no license at all
12419 =item CPAN::Module::force($method,@args)
12421 Forces CPAN to perform a task that it normally would have refused to
12422 do. Force takes as arguments a method name to be called and any number
12423 of additional arguments that should be passed to the called method.
12424 The internals of the object get the needed changes so that CPAN.pm
12425 does not refuse to take the action. See also the section above on the
12426 C<force> and the C<fforce> pragma.
12428 =item CPAN::Module::get()
12430 Runs a get on the distribution associated with this module.
12432 =item CPAN::Module::inst_file()
12434 Returns the filename of the module found in @INC. The first file found
12435 is reported just like perl itself stops searching @INC when it finds a
12438 =item CPAN::Module::available_file()
12440 Returns the filename of the module found in PERL5LIB or @INC. The
12441 first file found is reported. The advantage of this method over
12442 C<inst_file> is that modules that have been tested but not yet
12443 installed are included because PERL5LIB keeps track of tested modules.
12445 =item CPAN::Module::inst_version()
12447 Returns the version number of the installed module in readable format.
12449 =item CPAN::Module::available_version()
12451 Returns the version number of the available module in readable format.
12453 =item CPAN::Module::install()
12455 Runs an C<install> on the distribution associated with this module.
12457 =item CPAN::Module::look()
12459 Changes to the directory where the distribution associated with this
12460 module has been unpacked and opens a subshell there. Exiting the
12463 =item CPAN::Module::make()
12465 Runs a C<make> on the distribution associated with this module.
12467 =item CPAN::Module::manpage_headline()
12469 If module is installed, peeks into the module's manpage, reads the
12470 headline and returns it. Moreover, if the module has been downloaded
12471 within this session, does the equivalent on the downloaded module even
12472 if it is not installed.
12474 =item CPAN::Module::perldoc()
12476 Runs a C<perldoc> on this module.
12478 =item CPAN::Module::readme()
12480 Runs a C<readme> on the distribution associated with this module.
12482 =item CPAN::Module::reports()
12484 Calls the reports() method on the associated distribution object.
12486 =item CPAN::Module::test()
12488 Runs a C<test> on the distribution associated with this module.
12490 =item CPAN::Module::uptodate()
12492 Returns 1 if the module is installed and up-to-date.
12494 =item CPAN::Module::userid()
12496 Returns the author's ID of the module.
12500 =head2 Cache Manager
12502 Currently the cache manager only keeps track of the build directory
12503 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
12504 deletes complete directories below C<build_dir> as soon as the size of
12505 all directories there gets bigger than $CPAN::Config->{build_cache}
12506 (in MB). The contents of this cache may be used for later
12507 re-installations that you intend to do manually, but will never be
12508 trusted by CPAN itself. This is due to the fact that the user might
12509 use these directories for building modules on different architectures.
12511 There is another directory ($CPAN::Config->{keep_source_where}) where
12512 the original distribution files are kept. This directory is not
12513 covered by the cache manager and must be controlled by the user. If
12514 you choose to have the same directory as build_dir and as
12515 keep_source_where directory, then your sources will be deleted with
12516 the same fifo mechanism.
12520 A bundle is just a perl module in the namespace Bundle:: that does not
12521 define any functions or methods. It usually only contains documentation.
12523 It starts like a perl module with a package declaration and a $VERSION
12524 variable. After that the pod section looks like any other pod with the
12525 only difference being that I<one special pod section> exists starting with
12530 In this pod section each line obeys the format
12532 Module_Name [Version_String] [- optional text]
12534 The only required part is the first field, the name of a module
12535 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
12536 of the line is optional. The comment part is delimited by a dash just
12537 as in the man page header.
12539 The distribution of a bundle should follow the same convention as
12540 other distributions.
12542 Bundles are treated specially in the CPAN package. If you say 'install
12543 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
12544 the modules in the CONTENTS section of the pod. You can install your
12545 own Bundles locally by placing a conformant Bundle file somewhere into
12546 your @INC path. The autobundle() command which is available in the
12547 shell interface does that for you by including all currently installed
12548 modules in a snapshot bundle file.
12550 =head1 PREREQUISITES
12552 If you have a local mirror of CPAN and can access all files with
12553 "file:" URLs, then you only need a perl better than perl5.003 to run
12554 this module. Otherwise Net::FTP is strongly recommended. LWP may be
12555 required for non-UNIX systems or if your nearest CPAN site is
12556 associated with a URL that is not C<ftp:>.
12558 If you have neither Net::FTP nor LWP, there is a fallback mechanism
12559 implemented for an external ftp command or for an external lynx
12564 =head2 Finding packages and VERSION
12566 This module presumes that all packages on CPAN
12572 declare their $VERSION variable in an easy to parse manner. This
12573 prerequisite can hardly be relaxed because it consumes far too much
12574 memory to load all packages into the running program just to determine
12575 the $VERSION variable. Currently all programs that are dealing with
12576 version use something like this
12578 perl -MExtUtils::MakeMaker -le \
12579 'print MM->parse_version(shift)' filename
12581 If you are author of a package and wonder if your $VERSION can be
12582 parsed, please try the above method.
12586 come as compressed or gzipped tarfiles or as zip files and contain a
12587 C<Makefile.PL> or C<Build.PL> (well, we try to handle a bit more, but
12588 without much enthusiasm).
12594 The debugging of this module is a bit complex, because we have
12595 interferences of the software producing the indices on CPAN, of the
12596 mirroring process on CPAN, of packaging, of configuration, of
12597 synchronicity, and of bugs within CPAN.pm.
12599 For debugging the code of CPAN.pm itself in interactive mode some more
12600 or less useful debugging aid can be turned on for most packages within
12601 CPAN.pm with one of
12605 =item o debug package...
12607 sets debug mode for packages.
12609 =item o debug -package...
12611 unsets debug mode for packages.
12615 turns debugging on for all packages.
12617 =item o debug number
12621 which sets the debugging packages directly. Note that C<o debug 0>
12622 turns debugging off.
12624 What seems quite a successful strategy is the combination of C<reload
12625 cpan> and the debugging switches. Add a new debug statement while
12626 running in the shell and then issue a C<reload cpan> and see the new
12627 debugging messages immediately without losing the current context.
12629 C<o debug> without an argument lists the valid package names and the
12630 current set of packages in debugging mode. C<o debug> has built-in
12631 completion support.
12633 For debugging of CPAN data there is the C<dump> command which takes
12634 the same arguments as make/test/install and outputs each object's
12635 Data::Dumper dump. If an argument looks like a perl variable and
12636 contains one of C<$>, C<@> or C<%>, it is eval()ed and fed to
12637 Data::Dumper directly.
12639 =head2 Floppy, Zip, Offline Mode
12641 CPAN.pm works nicely without network too. If you maintain machines
12642 that are not networked at all, you should consider working with file:
12643 URLs. Of course, you have to collect your modules somewhere first. So
12644 you might use CPAN.pm to put together all you need on a networked
12645 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
12646 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
12647 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
12648 with this floppy. See also below the paragraph about CD-ROM support.
12650 =head2 Basic Utilities for Programmers
12654 =item has_inst($module)
12656 Returns true if the module is installed. Used to load all modules into
12657 the running CPAN.pm which are considered optional. The config variable
12658 C<dontload_list> can be used to intercept the C<has_inst()> call such
12659 that an optional module is not loaded despite being available. For
12660 example the following command will prevent that C<YAML.pm> is being
12663 cpan> o conf dontload_list push YAML
12665 See the source for details.
12667 =item has_usable($module)
12669 Returns true if the module is installed and is in a usable state. Only
12670 useful for a handful of modules that are used internally. See the
12671 source for details.
12673 =item instance($module)
12675 The constructor for all the singletons used to represent modules,
12676 distributions, authors and bundles. If the object already exists, this
12677 method returns the object, otherwise it calls the constructor.
12683 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
12684 install foreign, unmasked, unsigned code on your machine. We compare
12685 to a checksum that comes from the net just as the distribution file
12686 itself. But we try to make it easy to add security on demand:
12688 =head2 Cryptographically signed modules
12690 Since release 1.77 CPAN.pm has been able to verify cryptographically
12691 signed module distributions using Module::Signature. The CPAN modules
12692 can be signed by their authors, thus giving more security. The simple
12693 unsigned MD5 checksums that were used before by CPAN protect mainly
12694 against accidental file corruption.
12696 You will need to have Module::Signature installed, which in turn
12697 requires that you have at least one of Crypt::OpenPGP module or the
12698 command-line F<gpg> tool installed.
12700 You will also need to be able to connect over the Internet to the public
12701 keyservers, like pgp.mit.edu, and their port 11731 (the HKP protocol).
12703 The configuration parameter check_sigs is there to turn signature
12704 checking on or off.
12708 Most functions in package CPAN are exported per default. The reason
12709 for this is that the primary use is intended for the cpan shell or for
12714 When the CPAN shell enters a subshell via the look command, it sets
12715 the environment CPAN_SHELL_LEVEL to 1 or increments it if it is
12718 When CPAN runs, it sets the environment variable PERL5_CPAN_IS_RUNNING
12719 to the ID of the running process. It also sets
12720 PERL5_CPANPLUS_IS_RUNNING to prevent runaway processes which could
12721 happen with older versions of Module::Install.
12723 When running C<perl Makefile.PL>, the environment variable
12724 C<PERL5_CPAN_IS_EXECUTING> is set to the full path of the
12725 C<Makefile.PL> that is being executed. This prevents runaway processes
12726 with newer versions of Module::Install.
12728 When the config variable ftp_passive is set, all downloads will be run
12729 with the environment variable FTP_PASSIVE set to this value. This is
12730 in general a good idea as it influences both Net::FTP and LWP based
12731 connections. The same effect can be achieved by starting the cpan
12732 shell with this environment variable set. For Net::FTP alone, one can
12733 also always set passive mode by running libnetcfg.
12735 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
12737 Populating a freshly installed perl with my favorite modules is pretty
12738 easy if you maintain a private bundle definition file. To get a useful
12739 blueprint of a bundle definition file, the command autobundle can be used
12740 on the CPAN shell command line. This command writes a bundle definition
12741 file for all modules that are installed for the currently running perl
12742 interpreter. It's recommended to run this command only once and from then
12743 on maintain the file manually under a private name, say
12744 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
12746 cpan> install Bundle::my_bundle
12748 then answer a few questions and then go out for a coffee.
12750 Maintaining a bundle definition file means keeping track of two
12751 things: dependencies and interactivity. CPAN.pm sometimes fails on
12752 calculating dependencies because not all modules define all MakeMaker
12753 attributes correctly, so a bundle definition file should specify
12754 prerequisites as early as possible. On the other hand, it's a bit
12755 annoying that many distributions need some interactive configuring. So
12756 what I try to accomplish in my private bundle file is to have the
12757 packages that need to be configured early in the file and the gentle
12758 ones later, so I can go out after a few minutes and leave CPAN.pm
12761 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
12763 Thanks to Graham Barr for contributing the following paragraphs about
12764 the interaction between perl, and various firewall configurations. For
12765 further information on firewalls, it is recommended to consult the
12766 documentation that comes with the ncftp program. If you are unable to
12767 go through the firewall with a simple Perl setup, it is very likely
12768 that you can configure ncftp so that it works for your firewall.
12770 =head2 Three basic types of firewalls
12772 Firewalls can be categorized into three basic types.
12776 =item http firewall
12778 This is where the firewall machine runs a web server and to access the
12779 outside world you must do it via the web server. If you set environment
12780 variables like http_proxy or ftp_proxy to a values beginning with http://
12781 or in your web browser you have to set proxy information then you know
12782 you are running an http firewall.
12784 To access servers outside these types of firewalls with perl (even for
12785 ftp) you will need to use LWP.
12789 This where the firewall machine runs an ftp server. This kind of
12790 firewall will only let you access ftp servers outside the firewall.
12791 This is usually done by connecting to the firewall with ftp, then
12792 entering a username like "user@outside.host.com"
12794 To access servers outside these type of firewalls with perl you
12795 will need to use Net::FTP.
12797 =item One way visibility
12799 I say one way visibility as these firewalls try to make themselves look
12800 invisible to the users inside the firewall. An FTP data connection is
12801 normally created by sending the remote server your IP address and then
12802 listening for the connection. But the remote server will not be able to
12803 connect to you because of the firewall. So for these types of firewall
12804 FTP connections need to be done in a passive mode.
12806 There are two that I can think off.
12812 If you are using a SOCKS firewall you will need to compile perl and link
12813 it with the SOCKS library, this is what is normally called a 'socksified'
12814 perl. With this executable you will be able to connect to servers outside
12815 the firewall as if it is not there.
12817 =item IP Masquerade
12819 This is the firewall implemented in the Linux kernel, it allows you to
12820 hide a complete network behind one IP address. With this firewall no
12821 special compiling is needed as you can access hosts directly.
12823 For accessing ftp servers behind such firewalls you usually need to
12824 set the environment variable C<FTP_PASSIVE> or the config variable
12825 ftp_passive to a true value.
12831 =head2 Configuring lynx or ncftp for going through a firewall
12833 If you can go through your firewall with e.g. lynx, presumably with a
12836 /usr/local/bin/lynx -pscott:tiger
12838 then you would configure CPAN.pm with the command
12840 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
12842 That's all. Similarly for ncftp or ftp, you would configure something
12845 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
12847 Your mileage may vary...
12855 I installed a new version of module X but CPAN keeps saying,
12856 I have the old version installed
12858 Most probably you B<do> have the old version installed. This can
12859 happen if a module installs itself into a different directory in the
12860 @INC path than it was previously installed. This is not really a
12861 CPAN.pm problem, you would have the same problem when installing the
12862 module manually. The easiest way to prevent this behaviour is to add
12863 the argument C<UNINST=1> to the C<make install> call, and that is why
12864 many people add this argument permanently by configuring
12866 o conf make_install_arg UNINST=1
12870 So why is UNINST=1 not the default?
12872 Because there are people who have their precise expectations about who
12873 may install where in the @INC path and who uses which @INC array. In
12874 fine tuned environments C<UNINST=1> can cause damage.
12878 I want to clean up my mess, and install a new perl along with
12879 all modules I have. How do I go about it?
12881 Run the autobundle command for your old perl and optionally rename the
12882 resulting bundle file (e.g. Bundle/mybundle.pm), install the new perl
12883 with the Configure option prefix, e.g.
12885 ./Configure -Dprefix=/usr/local/perl-5.6.78.9
12887 Install the bundle file you produced in the first step with something like
12889 cpan> install Bundle::mybundle
12895 When I install bundles or multiple modules with one command
12896 there is too much output to keep track of.
12898 You may want to configure something like
12900 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
12901 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
12903 so that STDOUT is captured in a file for later inspection.
12908 I am not root, how can I install a module in a personal directory?
12910 First of all, you will want to use your own configuration, not the one
12911 that your root user installed. If you do not have permission to write
12912 in the cpan directory that root has configured, you will be asked if
12913 you want to create your own config. Answering "yes" will bring you into
12914 CPAN's configuration stage, using the system config for all defaults except
12915 things that have to do with CPAN's work directory, saving your choices to
12916 your MyConfig.pm file.
12918 You can also manually initiate this process with the following command:
12920 % perl -MCPAN -e 'mkmyconfig'
12926 from the CPAN shell.
12928 You will most probably also want to configure something like this:
12930 o conf makepl_arg "LIB=~/myperl/lib \
12931 INSTALLMAN1DIR=~/myperl/man/man1 \
12932 INSTALLMAN3DIR=~/myperl/man/man3 \
12933 INSTALLSCRIPT=~/myperl/bin \
12934 INSTALLBIN=~/myperl/bin"
12936 and then (oh joy) the equivalent command for Module::Build. That would
12939 o conf mbuildpl_arg "--lib=~/myperl/lib \
12940 --installman1dir=~/myperl/man/man1 \
12941 --installman3dir=~/myperl/man/man3 \
12942 --installscript=~/myperl/bin \
12943 --installbin=~/myperl/bin"
12945 You can make this setting permanent like all C<o conf> settings with
12946 C<o conf commit> or by setting C<auto_commit> beforehand.
12948 You will have to add ~/myperl/man to the MANPATH environment variable
12949 and also tell your perl programs to look into ~/myperl/lib, e.g. by
12952 use lib "$ENV{HOME}/myperl/lib";
12954 or setting the PERL5LIB environment variable.
12956 While we're speaking about $ENV{HOME}, it might be worth mentioning,
12957 that for Windows we use the File::HomeDir module that provides an
12958 equivalent to the concept of the home directory on Unix.
12960 Another thing you should bear in mind is that the UNINST parameter can
12961 be dangerous when you are installing into a private area because you
12962 might accidentally remove modules that other people depend on that are
12963 not using the private area.
12967 How to get a package, unwrap it, and make a change before building it?
12969 Have a look at the C<look> (!) command.
12973 I installed a Bundle and had a couple of fails. When I
12974 retried, everything resolved nicely. Can this be fixed to work
12977 The reason for this is that CPAN does not know the dependencies of all
12978 modules when it starts out. To decide about the additional items to
12979 install, it just uses data found in the META.yml file or the generated
12980 Makefile. An undetected missing piece breaks the process. But it may
12981 well be that your Bundle installs some prerequisite later than some
12982 depending item and thus your second try is able to resolve everything.
12983 Please note, CPAN.pm does not know the dependency tree in advance and
12984 cannot sort the queue of things to install in a topologically correct
12985 order. It resolves perfectly well IF all modules declare the
12986 prerequisites correctly with the PREREQ_PM attribute to MakeMaker or
12987 the C<requires> stanza of Module::Build. For bundles which fail and
12988 you need to install often, it is recommended to sort the Bundle
12989 definition file manually.
12993 In our intranet we have many modules for internal use. How
12994 can I integrate these modules with CPAN.pm but without uploading
12995 the modules to CPAN?
12997 Have a look at the CPAN::Site module.
13001 When I run CPAN's shell, I get an error message about things in my
13002 /etc/inputrc (or ~/.inputrc) file.
13004 These are readline issues and can only be fixed by studying readline
13005 configuration on your architecture and adjusting the referenced file
13006 accordingly. Please make a backup of the /etc/inputrc or ~/.inputrc
13007 and edit them. Quite often harmless changes like uppercasing or
13008 lowercasing some arguments solves the problem.
13012 Some authors have strange characters in their names.
13014 Internally CPAN.pm uses the UTF-8 charset. If your terminal is
13015 expecting ISO-8859-1 charset, a converter can be activated by setting
13016 term_is_latin to a true value in your config file. One way of doing so
13019 cpan> o conf term_is_latin 1
13021 If other charset support is needed, please file a bugreport against
13022 CPAN.pm at rt.cpan.org and describe your needs. Maybe we can extend
13023 the support or maybe UTF-8 terminals become widely available.
13025 Note: this config variable is deprecated and will be removed in a
13026 future version of CPAN.pm. It will be replaced with the conventions
13027 around the family of $LANG and $LC_* environment variables.
13031 When an install fails for some reason and then I correct the error
13032 condition and retry, CPAN.pm refuses to install the module, saying
13033 C<Already tried without success>.
13035 Use the force pragma like so
13037 force install Foo::Bar
13043 and then 'make install' directly in the subshell.
13047 How do I install a "DEVELOPER RELEASE" of a module?
13049 By default, CPAN will install the latest non-developer release of a
13050 module. If you want to install a dev release, you have to specify the
13051 partial path starting with the author id to the tarball you wish to
13054 cpan> install KWILLIAMS/Module-Build-0.27_07.tar.gz
13056 Note that you can use the C<ls> command to get this path listed.
13060 How do I install a module and all its dependencies from the commandline,
13061 without being prompted for anything, despite my CPAN configuration
13064 CPAN uses ExtUtils::MakeMaker's prompt() function to ask its questions, so
13065 if you set the PERL_MM_USE_DEFAULT environment variable, you shouldn't be
13066 asked any questions at all (assuming the modules you are installing are
13067 nice about obeying that variable as well):
13069 % PERL_MM_USE_DEFAULT=1 perl -MCPAN -e 'install My::Module'
13073 How do I create a Module::Build based Build.PL derived from an
13074 ExtUtils::MakeMaker focused Makefile.PL?
13076 http://search.cpan.org/search?query=Module::Build::Convert
13078 http://www.refcnt.org/papers/module-build-convert
13082 I'm frequently irritated with the CPAN shell's inability to help me
13083 select a good mirror.
13085 The urllist config parameter is yours. You can add and remove sites at
13086 will. You should find out which sites have the best uptodateness,
13087 bandwidth, reliability, etc. and are topologically close to you. Some
13088 people prefer fast downloads, others uptodateness, others reliability.
13089 You decide which to try in which order.
13091 Henk P. Penning maintains a site that collects data about CPAN sites:
13093 http://www.cs.uu.nl/people/henkp/mirmon/cpan.html
13095 Also, feel free to play with experimental features. Run
13097 o conf init randomize_urllist ftpstats_period ftpstats_size
13099 and choose your favorite parameters. After a few downloads running the
13100 C<hosts> command will probably assist you in choosing the best mirror
13105 Why do I get asked the same questions every time I start the shell?
13107 You can make your configuration changes permanent by calling the
13108 command C<o conf commit>. Alternatively set the C<auto_commit>
13109 variable to true by running C<o conf init auto_commit> and answering
13110 the following question with yes.
13114 Older versions of CPAN.pm had the original root directory of all
13115 tarballs in the build directory. Now there are always random
13116 characters appended to these directory names. Why was this done?
13118 The random characters are provided by File::Temp and ensure that each
13119 module's individual build directory is unique. This makes running
13120 CPAN.pm in concurrent processes simultaneously safe.
13124 Speaking of the build directory. Do I have to clean it up myself?
13126 You have the choice to set the config variable C<scan_cache> to
13127 C<never>. Then you must clean it up yourself. The other possible
13128 value, C<atstart> only cleans up the build directory when you start
13129 the CPAN shell. If you never start up the CPAN shell, you probably
13130 also have to clean up the build directory yourself.
13134 =head1 COMPATIBILITY
13136 =head2 OLD PERL VERSIONS
13138 CPAN.pm is regularly tested to run under 5.004, 5.005, and assorted
13139 newer versions. It is getting more and more difficult to get the
13140 minimal prerequisites working on older perls. It is close to
13141 impossible to get the whole Bundle::CPAN working there. If you're in
13142 the position to have only these old versions, be advised that CPAN is
13143 designed to work fine without the Bundle::CPAN installed.
13145 To get things going, note that GBARR/Scalar-List-Utils-1.18.tar.gz is
13146 compatible with ancient perls and that File::Temp is listed as a
13147 prerequisite but CPAN has reasonable workarounds if it is missing.
13151 This module and its competitor, the CPANPLUS module, are both much
13152 cooler than the other. CPAN.pm is older. CPANPLUS was designed to be
13153 more modular but it was never tried to make it compatible with CPAN.pm.
13155 =head1 SECURITY ADVICE
13157 This software enables you to upgrade software on your computer and so
13158 is inherently dangerous because the newly installed software may
13159 contain bugs and may alter the way your computer works or even make it
13160 unusable. Please consider backing up your data before every upgrade.
13164 Please report bugs via L<http://rt.cpan.org/>
13166 Before submitting a bug, please make sure that the traditional method
13167 of building a Perl module package from a shell by following the
13168 installation instructions of that package still works in your
13173 Andreas Koenig C<< <andk@cpan.org> >>
13177 This program is free software; you can redistribute it and/or
13178 modify it under the same terms as Perl itself.
13180 See L<http://www.perl.com/perl/misc/Artistic.html>
13182 =head1 TRANSLATIONS
13184 Kawai,Takanori provides a Japanese translation of this manpage at
13185 L<http://homepage3.nifty.com/hippo2000/perltips/CPAN.htm>
13189 L<cpan>, L<CPAN::Nox>, L<CPAN::Version>