diff options
author | Siep Kroonenberg <siepo@cybercomm.nl> | 2011-02-17 12:20:49 +0000 |
---|---|---|
committer | Siep Kroonenberg <siepo@cybercomm.nl> | 2011-02-17 12:20:49 +0000 |
commit | 316ee97c621496b0fe3267f57cce81bee44ca1e6 (patch) | |
tree | cb2cab1192b4f58a7971af19b213e980bceda4b4 /Master/tlpkg/tlperl/lib/CPAN.pm | |
parent | cd0f87b5d39480d85ad9bd4ee37f520f75bed560 (diff) |
Moving old tlperl prior to committing new one
git-svn-id: svn://tug.org/texlive/trunk@21422 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlperl/lib/CPAN.pm')
-rwxr-xr-x | Master/tlpkg/tlperl/lib/CPAN.pm | 3771 |
1 files changed, 0 insertions, 3771 deletions
diff --git a/Master/tlpkg/tlperl/lib/CPAN.pm b/Master/tlpkg/tlperl/lib/CPAN.pm deleted file mode 100755 index cb0b8909fa5..00000000000 --- a/Master/tlpkg/tlperl/lib/CPAN.pm +++ /dev/null @@ -1,3771 +0,0 @@ -# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*- -# vim: ts=4 sts=4 sw=4: -use strict; -package CPAN; -$CPAN::VERSION = '1.94_54'; -$CPAN::VERSION =~ s/_//; - -# we need to run chdir all over and we would get at wrong libraries -# there -use File::Spec (); -BEGIN { - if (File::Spec->can("rel2abs")) { - for my $inc (@INC) { - $inc = File::Spec->rel2abs($inc) unless ref $inc; - } - } -} -use CPAN::Author; -use CPAN::HandleConfig; -use CPAN::Version; -use CPAN::Bundle; -use CPAN::CacheMgr; -use CPAN::Complete; -use CPAN::Debug; -use CPAN::Distribution; -use CPAN::Distrostatus; -use CPAN::FTP; -use CPAN::Index 1.93; # https://rt.cpan.org/Ticket/Display.html?id=43349 -use CPAN::InfoObj; -use CPAN::Module; -use CPAN::Prompt; -use CPAN::URL; -use CPAN::Queue; -use CPAN::Tarzip; -use CPAN::DeferredCode; -use CPAN::Shell; -use CPAN::LWP::UserAgent; -use CPAN::Exception::RecursiveDependency; -use CPAN::Exception::yaml_not_installed; - -use Carp (); -use Config (); -use Cwd qw(chdir); -use DirHandle (); -use Exporter (); -use ExtUtils::MakeMaker qw(prompt); # for some unknown reason, - # 5.005_04 does not work without - # this -use File::Basename (); -use File::Copy (); -use File::Find; -use File::Path (); -use FileHandle (); -use Fcntl qw(:flock); -use Safe (); -use Sys::Hostname qw(hostname); -use Text::ParseWords (); -use Text::Wrap (); - -# protect against "called too early" -sub find_perl (); -sub anycwd (); -sub _uniq; - -no lib "."; - -require Mac::BuildTools if $^O eq 'MacOS'; -if ($ENV{PERL5_CPAN_IS_RUNNING} && $$ != $ENV{PERL5_CPAN_IS_RUNNING}) { - $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION} ||= $ENV{PERL5_CPAN_IS_RUNNING}; - my @rec = _uniq split(/,/, $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION}), $$; - $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION} = join ",", @rec; - # warn "# Note: Recursive call of CPAN.pm detected\n"; - my $w = sprintf "# Note: CPAN.pm is running in process %d now", pop @rec; - my %sleep = ( - 5 => 30, - 6 => 60, - 7 => 120, - ); - my $sleep = @rec > 7 ? 300 : ($sleep{scalar @rec}||0); - my $verbose = @rec >= 4; - while (@rec) { - $w .= sprintf " which has been called by process %d", pop @rec; - } - if ($sleep) { - $w .= ".\n\n# Sleeping $sleep seconds to protect other processes\n"; - } - if ($verbose) { - warn $w; - } - local $| = 1; - while ($sleep > 0) { - printf "\r#%5d", --$sleep; - sleep 1; - } - print "\n"; -} -$ENV{PERL5_CPAN_IS_RUNNING}=$$; -$ENV{PERL5_CPANPLUS_IS_RUNNING}=$$; # https://rt.cpan.org/Ticket/Display.html?id=23735 - -END { $CPAN::End++; &cleanup; } - -$CPAN::Signal ||= 0; -$CPAN::Frontend ||= "CPAN::Shell"; -unless (@CPAN::Defaultsites) { - @CPAN::Defaultsites = map { - CPAN::URL->new(TEXT => $_, FROM => "DEF") - } - "http://www.perl.org/CPAN/", - "ftp://ftp.perl.org/pub/CPAN/"; -} -# $CPAN::iCwd (i for initial) -$CPAN::iCwd ||= CPAN::anycwd(); -$CPAN::Perl ||= CPAN::find_perl(); -$CPAN::Defaultdocs ||= "http://search.cpan.org/perldoc?"; -$CPAN::Defaultrecent ||= "http://search.cpan.org/uploads.rdf"; -$CPAN::Defaultrecent ||= "http://cpan.uwinnipeg.ca/htdocs/cpan.xml"; - -# our globals are getting a mess -use vars qw( - $AUTOLOAD - $Be_Silent - $CONFIG_DIRTY - $Defaultdocs - $Echo_readline - $Frontend - $GOTOSHELL - $HAS_USABLE - $Have_warned - $MAX_RECURSION - $META - $RUN_DEGRADED - $Signal - $SQLite - $Suppress_readline - $VERSION - $autoload_recursion - $term - @Defaultsites - @EXPORT - ); - -$MAX_RECURSION = 32; - -@CPAN::ISA = qw(CPAN::Debug Exporter); - -# note that these functions live in CPAN::Shell and get executed via -# AUTOLOAD when called directly -@EXPORT = qw( - autobundle - bundle - clean - cvs_import - expand - force - fforce - get - install - install_tested - is_tested - make - mkmyconfig - notest - perldoc - readme - recent - recompile - report - shell - smoke - test - upgrade - ); - -sub soft_chdir_with_alternatives ($); - -{ - $autoload_recursion ||= 0; - - #-> sub CPAN::AUTOLOAD ; - sub AUTOLOAD { ## no critic - $autoload_recursion++; - my($l) = $AUTOLOAD; - $l =~ s/.*:://; - if ($CPAN::Signal) { - warn "Refusing to autoload '$l' while signal pending"; - $autoload_recursion--; - return; - } - if ($autoload_recursion > 1) { - my $fullcommand = join " ", map { "'$_'" } $l, @_; - warn "Refusing to autoload $fullcommand in recursion\n"; - $autoload_recursion--; - return; - } - my(%export); - @export{@EXPORT} = ''; - CPAN::HandleConfig->load unless $CPAN::Config_loaded++; - if (exists $export{$l}) { - CPAN::Shell->$l(@_); - } else { - die(qq{Unknown CPAN command "$AUTOLOAD". }. - qq{Type ? for help.\n}); - } - $autoload_recursion--; - } -} - -{ - my $x = *SAVEOUT; # avoid warning - open($x,">&STDOUT") or die "dup failed"; - my $redir = 0; - sub _redirect(@) { - #die if $redir; - local $_; - push(@_,undef); - while(defined($_=shift)) { - if (s/^\s*>//){ - my ($m) = s/^>// ? ">" : ""; - s/\s+//; - $_=shift unless length; - die "no dest" unless defined; - open(STDOUT,">$m$_") or die "open:$_:$!\n"; - $redir=1; - } elsif ( s/^\s*\|\s*// ) { - my $pipe="| $_"; - while(defined($_[0])){ - $pipe .= ' ' . shift; - } - open(STDOUT,$pipe) or die "open:$pipe:$!\n"; - $redir=1; - } else { - push(@_,$_); - } - } - return @_; - } - sub _unredirect { - return unless $redir; - $redir = 0; - ## redirect: unredirect and propagate errors. explicit close to wait for pipe. - close(STDOUT); - open(STDOUT,">&SAVEOUT"); - die "$@" if "$@"; - ## redirect: done - } -} - -sub _uniq { - my(@list) = @_; - my %seen; - return grep { !$seen{$_}++ } @list; -} - -#-> sub CPAN::shell ; -sub shell { - my($self) = @_; - $Suppress_readline = ! -t STDIN unless defined $Suppress_readline; - CPAN::HandleConfig->load unless $CPAN::Config_loaded++; - - my $oprompt = shift || CPAN::Prompt->new; - my $prompt = $oprompt; - my $commandline = shift || ""; - $CPAN::CurrentCommandId ||= 1; - - local($^W) = 1; - unless ($Suppress_readline) { - require Term::ReadLine; - if (! $term - or - $term->ReadLine eq "Term::ReadLine::Stub" - ) { - $term = Term::ReadLine->new('CPAN Monitor'); - } - if ($term->ReadLine eq "Term::ReadLine::Gnu") { - my $attribs = $term->Attribs; - $attribs->{attempted_completion_function} = sub { - &CPAN::Complete::gnu_cpl; - } - } else { - $readline::rl_completion_function = - $readline::rl_completion_function = 'CPAN::Complete::cpl'; - } - if (my $histfile = $CPAN::Config->{'histfile'}) {{ - unless ($term->can("AddHistory")) { - $CPAN::Frontend->mywarn("Terminal does not support AddHistory.\n"); - last; - } - $META->readhist($term,$histfile); - }} - for ($CPAN::Config->{term_ornaments}) { # alias - local $Term::ReadLine::termcap_nowarn = 1; - $term->ornaments($_) if defined; - } - # $term->OUT is autoflushed anyway - my $odef = select STDERR; - $| = 1; - select STDOUT; - $| = 1; - select $odef; - } - - $META->checklock(); - my @cwd = grep { defined $_ and length $_ } - CPAN::anycwd(), - File::Spec->can("tmpdir") ? File::Spec->tmpdir() : (), - File::Spec->rootdir(); - my $try_detect_readline; - $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term; - unless ($CPAN::Config->{inhibit_startup_message}) { - my $rl_avail = $Suppress_readline ? "suppressed" : - ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" : - "available (maybe install Bundle::CPAN or Bundle::CPANxxl?)"; - $CPAN::Frontend->myprint( - sprintf qq{ -cpan shell -- CPAN exploration and modules installation (v%s) -Enter 'h' for help. - -}, - $CPAN::VERSION, - $rl_avail - ) - } - my($continuation) = ""; - my $last_term_ornaments; - SHELLCOMMAND: while () { - if ($Suppress_readline) { - if ($Echo_readline) { - $|=1; - } - print $prompt; - last SHELLCOMMAND unless defined ($_ = <> ); - if ($Echo_readline) { - # backdoor: I could not find a way to record sessions - print $_; - } - chomp; - } else { - last SHELLCOMMAND unless - defined ($_ = $term->readline($prompt, $commandline)); - } - $_ = "$continuation$_" if $continuation; - s/^\s+//; - next SHELLCOMMAND if /^$/; - s/^\s*\?\s*/help /; - if (/^(?:q(?:uit)?|bye|exit)\s*$/i) { - last SHELLCOMMAND; - } elsif (s/\\$//s) { - chomp; - $continuation = $_; - $prompt = " > "; - } elsif (/^\!/) { - s/^\!//; - my($eval) = $_; - package - CPAN::Eval; # hide from the indexer - use strict; - use vars qw($import_done); - CPAN->import(':DEFAULT') unless $import_done++; - CPAN->debug("eval[$eval]") if $CPAN::DEBUG; - eval($eval); - warn $@ if $@; - $continuation = ""; - $prompt = $oprompt; - } elsif (/./) { - my(@line); - eval { @line = Text::ParseWords::shellwords($_) }; - warn($@), next SHELLCOMMAND if $@; - warn("Text::Parsewords could not parse the line [$_]"), - next SHELLCOMMAND unless @line; - $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG; - my $command = shift @line; - eval { - local (*STDOUT)=*STDOUT; - @line = _redirect(@line); - CPAN::Shell->$command(@line) - }; - my $command_error = $@; - _unredirect; - my $reported_error; - if ($command_error) { - my $err = $command_error; - if (ref $err and $err->isa('CPAN::Exception::blocked_urllist')) { - $CPAN::Frontend->mywarn("Client not fully configured, please proceed with configuring.$err"); - $reported_error = ref $err; - } else { - # I'd prefer never to arrive here and make all errors exception objects - if ($err =~ /\S/) { - require Carp; - require Dumpvalue; - my $dv = Dumpvalue->new(tick => '"'); - Carp::cluck(sprintf "Catching error: %s", $dv->stringify($err)); - } - } - } - if ($command =~ /^( - # classic commands - make - |test - |install - |clean - - # pragmas for classic commands - |ff?orce - |notest - - # compounds - |report - |smoke - |upgrade - )$/x) { - # only commands that tell us something about failed distros - # eval necessary for people without an urllist - eval {CPAN::Shell->failed($CPAN::CurrentCommandId,1);}; - if (my $err = $@) { - unless (ref $err and $reported_error eq ref $err) { - die $@; - } - } - } - soft_chdir_with_alternatives(\@cwd); - $CPAN::Frontend->myprint("\n"); - $continuation = ""; - $CPAN::CurrentCommandId++; - $prompt = $oprompt; - } - } continue { - $commandline = ""; # I do want to be able to pass a default to - # shell, but on the second command I see no - # use in that - $Signal=0; - CPAN::Queue->nullify_queue; - if ($try_detect_readline) { - if ($CPAN::META->has_inst("Term::ReadLine::Gnu") - || - $CPAN::META->has_inst("Term::ReadLine::Perl") - ) { - delete $INC{"Term/ReadLine.pm"}; - my $redef = 0; - local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef); - require Term::ReadLine; - $CPAN::Frontend->myprint("\n$redef subroutines in ". - "Term::ReadLine redefined\n"); - $GOTOSHELL = 1; - } - } - if ($term and $term->can("ornaments")) { - for ($CPAN::Config->{term_ornaments}) { # alias - if (defined $_) { - if (not defined $last_term_ornaments - or $_ != $last_term_ornaments - ) { - local $Term::ReadLine::termcap_nowarn = 1; - $term->ornaments($_); - $last_term_ornaments = $_; - } - } else { - undef $last_term_ornaments; - } - } - } - for my $class (qw(Module Distribution)) { - # again unsafe meta access? - for my $dm (keys %{$CPAN::META->{readwrite}{"CPAN::$class"}}) { - next unless $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor}; - CPAN->debug("BUG: $class '$dm' was in command state, resetting"); - delete $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor}; - } - } - if ($GOTOSHELL) { - $GOTOSHELL = 0; # not too often - $META->savehist if $CPAN::term && $CPAN::term->can("GetHistory"); - @_ = ($oprompt,""); - goto &shell; - } - } - soft_chdir_with_alternatives(\@cwd); -} - -#-> CPAN::soft_chdir_with_alternatives ; -sub soft_chdir_with_alternatives ($) { - my($cwd) = @_; - unless (@$cwd) { - my $root = File::Spec->rootdir(); - $CPAN::Frontend->mywarn(qq{Warning: no good directory to chdir to! -Trying '$root' as temporary haven. -}); - push @$cwd, $root; - } - while () { - if (chdir $cwd->[0]) { - return; - } else { - if (@$cwd>1) { - $CPAN::Frontend->mywarn(qq{Could not chdir to "$cwd->[0]": $! -Trying to chdir to "$cwd->[1]" instead. -}); - shift @$cwd; - } else { - $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd->[0]": $!}); - } - } - } -} - -sub _flock { - my($fh,$mode) = @_; - if ( $Config::Config{d_flock} || $Config::Config{d_fcntl_can_lock} ) { - return flock $fh, $mode; - } elsif (!$Have_warned->{"d_flock"}++) { - $CPAN::Frontend->mywarn("Your OS does not seem to support locking; continuing and ignoring all locking issues\n"); - $CPAN::Frontend->mysleep(5); - return 1; - } else { - return 1; - } -} - -sub _yaml_module () { - my $yaml_module = $CPAN::Config->{yaml_module} || "YAML"; - if ( - $yaml_module ne "YAML" - && - !$CPAN::META->has_inst($yaml_module) - ) { - # $CPAN::Frontend->mywarn("'$yaml_module' not installed, falling back to 'YAML'\n"); - $yaml_module = "YAML"; - } - if ($yaml_module eq "YAML" - && - $CPAN::META->has_inst($yaml_module) - && - $YAML::VERSION < 0.60 - && - !$Have_warned->{"YAML"}++ - ) { - $CPAN::Frontend->mywarn("Warning: YAML version '$YAML::VERSION' is too low, please upgrade!\n". - "I'll continue but problems are *very* likely to happen.\n" - ); - $CPAN::Frontend->mysleep(5); - } - return $yaml_module; -} - -# CPAN::_yaml_loadfile -sub _yaml_loadfile { - my($self,$local_file) = @_; - return +[] unless -s $local_file; - my $yaml_module = _yaml_module; - if ($CPAN::META->has_inst($yaml_module)) { - # temporarly enable yaml code deserialisation - no strict 'refs'; - # 5.6.2 could not do the local() with the reference - # so we do it manually instead - my $old_loadcode = ${"$yaml_module\::LoadCode"}; - ${ "$yaml_module\::LoadCode" } = $CPAN::Config->{yaml_load_code} || 0; - - my ($code, @yaml); - if ($code = UNIVERSAL::can($yaml_module, "LoadFile")) { - eval { @yaml = $code->($local_file); }; - if ($@) { - # this shall not be done by the frontend - die CPAN::Exception::yaml_process_error->new($yaml_module,$local_file,"parse",$@); - } - } elsif ($code = UNIVERSAL::can($yaml_module, "Load")) { - local *FH; - open FH, $local_file or die "Could not open '$local_file': $!"; - local $/; - my $ystream = <FH>; - eval { @yaml = $code->($ystream); }; - if ($@) { - # this shall not be done by the frontend - die CPAN::Exception::yaml_process_error->new($yaml_module,$local_file,"parse",$@); - } - } - ${"$yaml_module\::LoadCode"} = $old_loadcode; - return \@yaml; - } else { - # this shall not be done by the frontend - die CPAN::Exception::yaml_not_installed->new($yaml_module, $local_file, "parse"); - } - return +[]; -} - -# CPAN::_yaml_dumpfile -sub _yaml_dumpfile { - my($self,$local_file,@what) = @_; - my $yaml_module = _yaml_module; - if ($CPAN::META->has_inst($yaml_module)) { - my $code; - if (UNIVERSAL::isa($local_file, "FileHandle")) { - $code = UNIVERSAL::can($yaml_module, "Dump"); - eval { print $local_file $code->(@what) }; - } elsif ($code = UNIVERSAL::can($yaml_module, "DumpFile")) { - eval { $code->($local_file,@what); }; - } elsif ($code = UNIVERSAL::can($yaml_module, "Dump")) { - local *FH; - open FH, ">$local_file" or die "Could not open '$local_file': $!"; - print FH $code->(@what); - } - if ($@) { - die CPAN::Exception::yaml_process_error->new($yaml_module,$local_file,"dump",$@); - } - } else { - if (UNIVERSAL::isa($local_file, "FileHandle")) { - # I think this case does not justify a warning at all - } else { - die CPAN::Exception::yaml_not_installed->new($yaml_module, $local_file, "dump"); - } - } -} - -sub _init_sqlite () { - unless ($CPAN::META->has_inst("CPAN::SQLite")) { - $CPAN::Frontend->mywarn(qq{CPAN::SQLite not installed, trying to work without\n}) - unless $Have_warned->{"CPAN::SQLite"}++; - return; - } - require CPAN::SQLite::META; # not needed since CVS version of 2006-12-17 - $CPAN::SQLite ||= CPAN::SQLite::META->new($CPAN::META); -} - -{ - my $negative_cache = {}; - sub _sqlite_running { - if ($negative_cache->{time} && time < $negative_cache->{time} + 60) { - # need to cache the result, otherwise too slow - return $negative_cache->{fact}; - } else { - $negative_cache = {}; # reset - } - my $ret = $CPAN::Config->{use_sqlite} && ($CPAN::SQLite || _init_sqlite()); - return $ret if $ret; # fast anyway - $negative_cache->{time} = time; - return $negative_cache->{fact} = $ret; - } -} - -$META ||= CPAN->new; # In case we re-eval ourselves we need the || - -# from here on only subs. -################################################################################ - -sub _perl_fingerprint { - my($self,$other_fingerprint) = @_; - my $dll = eval {OS2::DLLname()}; - my $mtime_dll = 0; - if (defined $dll) { - $mtime_dll = (-f $dll ? (stat(_))[9] : '-1'); - } - my $mtime_perl = (-f CPAN::find_perl ? (stat(_))[9] : '-1'); - my $this_fingerprint = { - '$^X' => CPAN::find_perl, - sitearchexp => $Config::Config{sitearchexp}, - 'mtime_$^X' => $mtime_perl, - 'mtime_dll' => $mtime_dll, - }; - if ($other_fingerprint) { - if (exists $other_fingerprint->{'stat($^X)'}) { # repair fp from rev. 1.88_57 - $other_fingerprint->{'mtime_$^X'} = $other_fingerprint->{'stat($^X)'}[9]; - } - # mandatory keys since 1.88_57 - for my $key (qw($^X sitearchexp mtime_dll mtime_$^X)) { - return unless $other_fingerprint->{$key} eq $this_fingerprint->{$key}; - } - return 1; - } else { - return $this_fingerprint; - } -} - -sub suggest_myconfig () { - SUGGEST_MYCONFIG: if(!$INC{'CPAN/MyConfig.pm'}) { - $CPAN::Frontend->myprint("You don't seem to have a user ". - "configuration (MyConfig.pm) yet.\n"); - my $new = CPAN::Shell::colorable_makemaker_prompt("Do you want to create a ". - "user configuration now? (Y/n)", - "yes"); - if($new =~ m{^y}i) { - CPAN::Shell->mkmyconfig(); - return &checklock; - } else { - $CPAN::Frontend->mydie("OK, giving up."); - } - } -} - -#-> sub CPAN::all_objects ; -sub all_objects { - my($mgr,$class) = @_; - CPAN::HandleConfig->load unless $CPAN::Config_loaded++; - CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG; - CPAN::Index->reload; - values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok -} - -# Called by shell, not in batch mode. In batch mode I see no risk in -# having many processes updating something as installations are -# continually checked at runtime. In shell mode I suspect it is -# unintentional to open more than one shell at a time - -#-> sub CPAN::checklock ; -sub checklock { - my($self) = @_; - my $lockfile = File::Spec->catfile($CPAN::Config->{cpan_home},".lock"); - if (-f $lockfile && -M _ > 0) { - my $fh = FileHandle->new($lockfile) or - $CPAN::Frontend->mydie("Could not open lockfile '$lockfile': $!"); - my $otherpid = <$fh>; - my $otherhost = <$fh>; - $fh->close; - if (defined $otherpid && $otherpid) { - chomp $otherpid; - } - if (defined $otherhost && $otherhost) { - chomp $otherhost; - } - my $thishost = hostname(); - if (defined $otherhost && defined $thishost && - $otherhost ne '' && $thishost ne '' && - $otherhost ne $thishost) { - $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile '$lockfile'\n". - "reports other host $otherhost and other ". - "process $otherpid.\n". - "Cannot proceed.\n")); - } elsif ($RUN_DEGRADED) { - $CPAN::Frontend->mywarn("Running in downgraded mode (experimental)\n"); - } elsif (defined $otherpid && $otherpid) { - return if $$ == $otherpid; # should never happen - $CPAN::Frontend->mywarn( - qq{ -There seems to be running another CPAN process (pid $otherpid). Contacting... -}); - if (kill 0, $otherpid or $!{EPERM}) { - $CPAN::Frontend->mywarn(qq{Other job is running.\n}); - my($ans) = - CPAN::Shell::colorable_makemaker_prompt - (qq{Shall I try to run in downgraded }. - qq{mode? (Y/n)},"y"); - if ($ans =~ /^y/i) { - $CPAN::Frontend->mywarn("Running in downgraded mode (experimental). -Please report if something unexpected happens\n"); - $RUN_DEGRADED = 1; - for ($CPAN::Config) { - # XXX - # $_->{build_dir_reuse} = 0; # 2006-11-17 akoenig Why was that? - $_->{commandnumber_in_prompt} = 0; # visibility - $_->{histfile} = ""; # who should win otherwise? - $_->{cache_metadata} = 0; # better would be a lock? - $_->{use_sqlite} = 0; # better would be a write lock! - $_->{auto_commit} = 0; # we are violent, do not persist - $_->{test_report} = 0; # Oliver Paukstadt had sent wrong reports in degraded mode - } - } else { - $CPAN::Frontend->mydie(" -You may want to kill the other job and delete the lockfile. On UNIX try: - kill $otherpid - rm $lockfile -"); - } - } elsif (-w $lockfile) { - my($ans) = - CPAN::Shell::colorable_makemaker_prompt - (qq{Other job not responding. Shall I overwrite }. - qq{the lockfile '$lockfile'? (Y/n)},"y"); - $CPAN::Frontend->myexit("Ok, bye\n") - unless $ans =~ /^y/i; - } else { - Carp::croak( - qq{Lockfile '$lockfile' not writable by you. }. - qq{Cannot proceed.\n}. - qq{ On UNIX try:\n}. - qq{ rm '$lockfile'\n}. - qq{ and then rerun us.\n} - ); - } - } else { - $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Found invalid lockfile ". - "'$lockfile', please remove. Cannot proceed.\n")); - } - } - my $dotcpan = $CPAN::Config->{cpan_home}; - eval { File::Path::mkpath($dotcpan);}; - if ($@) { - # A special case at least for Jarkko. - my $firsterror = $@; - my $seconderror; - my $symlinkcpan; - if (-l $dotcpan) { - $symlinkcpan = readlink $dotcpan; - die "readlink $dotcpan failed: $!" unless defined $symlinkcpan; - eval { File::Path::mkpath($symlinkcpan); }; - if ($@) { - $seconderror = $@; - } else { - $CPAN::Frontend->mywarn(qq{ -Working directory $symlinkcpan created. -}); - } - } - unless (-d $dotcpan) { - my $mess = qq{ -Your configuration suggests "$dotcpan" as your -CPAN.pm working directory. I could not create this directory due -to this error: $firsterror\n}; - $mess .= qq{ -As "$dotcpan" is a symlink to "$symlinkcpan", -I tried to create that, but I failed with this error: $seconderror -} if $seconderror; - $mess .= qq{ -Please make sure the directory exists and is writable. -}; - $CPAN::Frontend->mywarn($mess); - return suggest_myconfig; - } - } # $@ after eval mkpath $dotcpan - if (0) { # to test what happens when a race condition occurs - for (reverse 1..10) { - print $_, "\n"; - sleep 1; - } - } - # locking - if (!$RUN_DEGRADED && !$self->{LOCKFH}) { - my $fh; - unless ($fh = FileHandle->new("+>>$lockfile")) { - if ($! =~ /Permission/) { - $CPAN::Frontend->mywarn(qq{ - -Your configuration suggests that CPAN.pm should use a working -directory of - $CPAN::Config->{cpan_home} -Unfortunately we could not create the lock file - $lockfile -due to permission problems. - -Please make sure that the configuration variable - \$CPAN::Config->{cpan_home} -points to a directory where you can write a .lock file. You can set -this variable in either a CPAN/MyConfig.pm or a CPAN/Config.pm in your -\@INC path; -}); - return suggest_myconfig; - } - } - my $sleep = 1; - while (!CPAN::_flock($fh, LOCK_EX|LOCK_NB)) { - if ($sleep>10) { - $CPAN::Frontend->mydie("Giving up\n"); - } - $CPAN::Frontend->mysleep($sleep++); - $CPAN::Frontend->mywarn("Could not lock lockfile with flock: $!; retrying\n"); - } - - seek $fh, 0, 0; - truncate $fh, 0; - $fh->autoflush(1); - $fh->print($$, "\n"); - $fh->print(hostname(), "\n"); - $self->{LOCK} = $lockfile; - $self->{LOCKFH} = $fh; - } - $SIG{TERM} = sub { - my $sig = shift; - &cleanup; - $CPAN::Frontend->mydie("Got SIG$sig, leaving"); - }; - $SIG{INT} = sub { - # no blocks!!! - my $sig = shift; - &cleanup if $Signal; - die "Got yet another signal" if $Signal > 1; - $CPAN::Frontend->mydie("Got another SIG$sig") if $Signal; - $CPAN::Frontend->mywarn("Caught SIG$sig, trying to continue\n"); - $Signal++; - }; - -# From: Larry Wall <larry@wall.org> -# Subject: Re: deprecating SIGDIE -# To: perl5-porters@perl.org -# Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT) -# -# The original intent of __DIE__ was only to allow you to substitute one -# kind of death for another on an application-wide basis without respect -# to whether you were in an eval or not. As a global backstop, it should -# not be used any more lightly (or any more heavily :-) than class -# UNIVERSAL. Any attempt to build a general exception model on it should -# be politely squashed. Any bug that causes every eval {} to have to be -# modified should be not so politely squashed. -# -# Those are my current opinions. It is also my optinion that polite -# arguments degenerate to personal arguments far too frequently, and that -# when they do, it's because both people wanted it to, or at least didn't -# sufficiently want it not to. -# -# Larry - - # global backstop to cleanup if we should really die - $SIG{__DIE__} = \&cleanup; - $self->debug("Signal handler set.") if $CPAN::DEBUG; -} - -#-> sub CPAN::DESTROY ; -sub DESTROY { - &cleanup; # need an eval? -} - -#-> sub CPAN::anycwd ; -sub anycwd () { - my $getcwd; - $getcwd = $CPAN::Config->{'getcwd'} || 'cwd'; - CPAN->$getcwd(); -} - -#-> sub CPAN::cwd ; -sub cwd {Cwd::cwd();} - -#-> sub CPAN::getcwd ; -sub getcwd {Cwd::getcwd();} - -#-> sub CPAN::fastcwd ; -sub fastcwd {Cwd::fastcwd();} - -#-> sub CPAN::backtickcwd ; -sub backtickcwd {my $cwd = `cwd`; chomp $cwd; $cwd} - -#-> sub CPAN::find_perl ; -sub find_perl () { - my($perl) = File::Spec->file_name_is_absolute($^X) ? $^X : ""; - unless ($perl) { - my $candidate = File::Spec->catfile($CPAN::iCwd,$^X); - $^X = $perl = $candidate if MM->maybe_command($candidate); - } - unless ($perl) { - my ($component,$perl_name); - DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") { - PATH_COMPONENT: foreach $component (File::Spec->path(), - $Config::Config{'binexp'}) { - next unless defined($component) && $component; - my($abs) = File::Spec->catfile($component,$perl_name); - if (MM->maybe_command($abs)) { - $^X = $perl = $abs; - last DIST_PERLNAME; - } - } - } - } - return $perl; -} - - -#-> sub CPAN::exists ; -sub exists { - my($mgr,$class,$id) = @_; - CPAN::HandleConfig->load unless $CPAN::Config_loaded++; - CPAN::Index->reload; - ### Carp::croak "exists called without class argument" unless $class; - $id ||= ""; - $id =~ s/:+/::/g if $class eq "CPAN::Module"; - my $exists; - if (CPAN::_sqlite_running) { - $exists = (exists $META->{readonly}{$class}{$id} or - $CPAN::SQLite->set($class, $id)); - } else { - $exists = exists $META->{readonly}{$class}{$id}; - } - $exists ||= exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok -} - -#-> sub CPAN::delete ; -sub delete { - my($mgr,$class,$id) = @_; - delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok - delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok -} - -#-> sub CPAN::has_usable -# has_inst is sometimes too optimistic, we should replace it with this -# has_usable whenever a case is given -sub has_usable { - my($self,$mod,$message) = @_; - return 1 if $HAS_USABLE->{$mod}; - my $has_inst = $self->has_inst($mod,$message); - return unless $has_inst; - my $usable; - $usable = { - - # - # these subroutines die if they believe the installed version is unusable; - # - - LWP => [ # we frequently had "Can't locate object - # method "new" via package "LWP::UserAgent" at - # (eval 69) line 2006 - sub {require LWP}, - sub {require LWP::UserAgent}, - sub {require HTTP::Request}, - sub {require URI::URL; - unless (CPAN::Version->vge(URI::URL::->VERSION,0.08)) { - for ("Will not use URI::URL, need 0.08\n") { - $CPAN::Frontend->mywarn($_); - die $_; - } - } - }, - ], - 'Net::FTP' => [ - sub {require Net::FTP}, - sub {require Net::Config}, - ], - 'File::HomeDir' => [ - sub {require File::HomeDir; - unless (CPAN::Version->vge(File::HomeDir::->VERSION, 0.52)) { - for ("Will not use File::HomeDir, need 0.52\n") { - $CPAN::Frontend->mywarn($_); - die $_; - } - } - }, - ], - 'Archive::Tar' => [ - sub {require Archive::Tar; - my $demand = "1.50"; - unless (CPAN::Version->vge(Archive::Tar::->VERSION, $demand)) { - my $atv = Archive::Tar->VERSION; - for ("You have Archive::Tar $atv, but $demand or later is recommended. Please upgrade.\n") { - $CPAN::Frontend->mywarn($_); - # don't die, because we may need - # Archive::Tar to upgrade - } - - } - }, - ], - 'File::Temp' => [ - # XXX we should probably delete from - # %INC too so we can load after we - # installed a new enough version -- - # I'm not sure. - sub {require File::Temp; - unless (CPAN::Version->vge(File::Temp::->VERSION,0.16)) { - for ("Will not use File::Temp, need 0.16\n") { - $CPAN::Frontend->mywarn($_); - die $_; - } - } - }, - ] - }; - if ($usable->{$mod}) { - for my $c (0..$#{$usable->{$mod}}) { - my $code = $usable->{$mod}[$c]; - my $ret = eval { &$code() }; - $ret = "" unless defined $ret; - if ($@) { - # warn "DEBUG: c[$c]\$\@[$@]ret[$ret]"; - return; - } - } - } - return $HAS_USABLE->{$mod} = 1; -} - -#-> sub CPAN::has_inst -sub has_inst { - my($self,$mod,$message) = @_; - Carp::croak("CPAN->has_inst() called without an argument") - unless defined $mod; - my %dont = map { $_ => 1 } keys %{$CPAN::META->{dontload_hash}||{}}, - keys %{$CPAN::Config->{dontload_hash}||{}}, - @{$CPAN::Config->{dontload_list}||[]}; - if (defined $message && $message eq "no" # afair only used by Nox - || - $dont{$mod} - ) { - $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok - return 0; - } - my $file = $mod; - my $obj; - $file =~ s|::|/|g; - $file .= ".pm"; - if ($INC{$file}) { - # checking %INC is wrong, because $INC{LWP} may be true - # although $INC{"URI/URL.pm"} may have failed. But as - # I really want to say "bla loaded OK", I have to somehow - # cache results. - ### warn "$file in %INC"; #debug - return 1; - } elsif (eval { require $file }) { - # eval is good: if we haven't yet read the database it's - # perfect and if we have installed the module in the meantime, - # it tries again. The second require is only a NOOP returning - # 1 if we had success, otherwise it's retrying - - my $mtime = (stat $INC{$file})[9]; - # privileged files loaded by has_inst; Note: we use $mtime - # as a proxy for a checksum. - $CPAN::Shell::reload->{$file} = $mtime; - my $v = eval "\$$mod\::VERSION"; - $v = $v ? " (v$v)" : ""; - CPAN::Shell->optprint("load_module","CPAN: $mod loaded ok$v\n"); - if ($mod eq "CPAN::WAIT") { - push @CPAN::Shell::ISA, 'CPAN::WAIT'; - } - return 1; - } elsif ($mod eq "Net::FTP") { - $CPAN::Frontend->mywarn(qq{ - Please, install Net::FTP as soon as possible. CPAN.pm installs it for you - if you just type - install Bundle::libnet - -}) unless $Have_warned->{"Net::FTP"}++; - $CPAN::Frontend->mysleep(3); - } elsif ($mod eq "Digest::SHA") { - if ($Have_warned->{"Digest::SHA"}++) { - $CPAN::Frontend->mywarn(qq{CPAN: checksum security checks disabled }. - qq{because Digest::SHA not installed.\n}); - } else { - $CPAN::Frontend->mywarn(qq{ - CPAN: checksum security checks disabled because Digest::SHA not installed. - Please consider installing the Digest::SHA module. - -}); - $CPAN::Frontend->mysleep(2); - } - } elsif ($mod eq "Module::Signature") { - # NOT prefs_lookup, we are not a distro - my $check_sigs = $CPAN::Config->{check_sigs}; - if (not $check_sigs) { - # they do not want us:-( - } elsif (not $Have_warned->{"Module::Signature"}++) { - # No point in complaining unless the user can - # reasonably install and use it. - if (eval { require Crypt::OpenPGP; 1 } || - ( - defined $CPAN::Config->{'gpg'} - && - $CPAN::Config->{'gpg'} =~ /\S/ - ) - ) { - $CPAN::Frontend->mywarn(qq{ - CPAN: Module::Signature security checks disabled because Module::Signature - not installed. Please consider installing the Module::Signature module. - You may also need to be able to connect over the Internet to the public - keyservers like pgp.mit.edu (port 11371). - -}); - $CPAN::Frontend->mysleep(2); - } - } - } else { - delete $INC{$file}; # if it inc'd LWP but failed during, say, URI - } - return 0; -} - -#-> sub CPAN::instance ; -sub instance { - my($mgr,$class,$id) = @_; - CPAN::Index->reload; - $id ||= ""; - # unsafe meta access, ok? - return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id}; - $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id); -} - -#-> sub CPAN::new ; -sub new { - bless {}, shift; -} - -#-> sub CPAN::cleanup ; -sub cleanup { - # warn "cleanup called with arg[@_] End[$CPAN::End] Signal[$Signal]"; - local $SIG{__DIE__} = ''; - my($message) = @_; - my $i = 0; - my $ineval = 0; - my($subroutine); - while ((undef,undef,undef,$subroutine) = caller(++$i)) { - $ineval = 1, last if - $subroutine eq '(eval)'; - } - return if $ineval && !$CPAN::End; - return unless defined $META->{LOCK}; - return unless -f $META->{LOCK}; - $META->savehist; - close $META->{LOCKFH}; - unlink $META->{LOCK}; - # require Carp; - # Carp::cluck("DEBUGGING"); - if ( $CPAN::CONFIG_DIRTY ) { - $CPAN::Frontend->mywarn("Warning: Configuration not saved.\n"); - } - $CPAN::Frontend->myprint("Lockfile removed.\n"); -} - -#-> sub CPAN::readhist -sub readhist { - my($self,$term,$histfile) = @_; - my $histsize = $CPAN::Config->{'histsize'} || 100; - $term->Attribs->{'MaxHistorySize'} = $histsize if (defined($term->Attribs->{'MaxHistorySize'})); - my($fh) = FileHandle->new; - open $fh, "<$histfile" or return; - local $/ = "\n"; - while (<$fh>) { - chomp; - $term->AddHistory($_); - } - close $fh; -} - -#-> sub CPAN::savehist -sub savehist { - my($self) = @_; - my($histfile,$histsize); - unless ($histfile = $CPAN::Config->{'histfile'}) { - $CPAN::Frontend->mywarn("No history written (no histfile specified).\n"); - return; - } - $histsize = $CPAN::Config->{'histsize'} || 100; - if ($CPAN::term) { - unless ($CPAN::term->can("GetHistory")) { - $CPAN::Frontend->mywarn("Terminal does not support GetHistory.\n"); - return; - } - } else { - return; - } - my @h = $CPAN::term->GetHistory; - splice @h, 0, @h-$histsize if @h>$histsize; - my($fh) = FileHandle->new; - open $fh, ">$histfile" or $CPAN::Frontend->mydie("Couldn't open >$histfile: $!"); - local $\ = local $, = "\n"; - print $fh @h; - close $fh; -} - -#-> sub CPAN::is_tested -sub is_tested { - my($self,$what,$when) = @_; - unless ($what) { - Carp::cluck("DEBUG: empty what"); - return; - } - $self->{is_tested}{$what} = $when; -} - -#-> sub CPAN::reset_tested -# forget all distributions tested -- resets what gets included in PERL5LIB -sub reset_tested { - my ($self) = @_; - $self->{is_tested} = {}; -} - -#-> sub CPAN::is_installed -# unsets the is_tested flag: as soon as the thing is installed, it is -# not needed in set_perl5lib anymore -sub is_installed { - my($self,$what) = @_; - delete $self->{is_tested}{$what}; -} - -sub _list_sorted_descending_is_tested { - my($self) = @_; - sort - { ($self->{is_tested}{$b}||0) <=> ($self->{is_tested}{$a}||0) } - keys %{$self->{is_tested}} -} - -#-> sub CPAN::set_perl5lib -# Notes on max environment variable length: -# - Win32 : XP or later, 8191; Win2000 or NT4, 2047 -{ -my $fh; -sub set_perl5lib { - my($self,$for) = @_; - unless ($for) { - (undef,undef,undef,$for) = caller(1); - $for =~ s/.*://; - } - $self->{is_tested} ||= {}; - return unless %{$self->{is_tested}}; - my $env = $ENV{PERL5LIB}; - $env = $ENV{PERLLIB} unless defined $env; - my @env; - push @env, split /\Q$Config::Config{path_sep}\E/, $env if defined $env and length $env; - #my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}}; - #$CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n"); - - my @dirs = map {("$_/blib/arch", "$_/blib/lib")} $self->_list_sorted_descending_is_tested; - return if !@dirs; - - if (@dirs < 12) { - $CPAN::Frontend->optprint('perl5lib', "Prepending @dirs to PERL5LIB for '$for'\n"); - $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env; - } elsif (@dirs < 24 ) { - my @d = map {my $cp = $_; - $cp =~ s/^\Q$CPAN::Config->{build_dir}\E/%BUILDDIR%/; - $cp - } @dirs; - $CPAN::Frontend->optprint('perl5lib', "Prepending @d to PERL5LIB; ". - "%BUILDDIR%=$CPAN::Config->{build_dir} ". - "for '$for'\n" - ); - $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env; - } else { - my $cnt = keys %{$self->{is_tested}}; - $CPAN::Frontend->optprint('perl5lib', "Prepending blib/arch and blib/lib of ". - "$cnt build dirs to PERL5LIB; ". - "for '$for'\n" - ); - $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env; - } -}} - - -1; - - -__END__ - -=head1 NAME - -CPAN - query, download and build perl modules from CPAN sites - -=head1 SYNOPSIS - -Interactive mode: - - perl -MCPAN -e shell - ---or-- - - cpan - -Basic commands: - - # Modules: - - cpan> install Acme::Meta # in the shell - - CPAN::Shell->install("Acme::Meta"); # in perl - - # Distributions: - - cpan> install NWCLARK/Acme-Meta-0.02.tar.gz # in the shell - - CPAN::Shell-> - install("NWCLARK/Acme-Meta-0.02.tar.gz"); # in perl - - # module objects: - - $mo = CPAN::Shell->expandany($mod); - $mo = CPAN::Shell->expand("Module",$mod); # same thing - - # distribution objects: - - $do = CPAN::Shell->expand("Module",$mod)->distribution; - $do = CPAN::Shell->expandany($distro); # same thing - $do = CPAN::Shell->expand("Distribution", - $distro); # same thing - -=head1 DESCRIPTION - -The CPAN module automates or at least simplifies the make and install -of perl modules and extensions. It includes some primitive searching -capabilities and knows how to use Net::FTP, LWP, and certain external -download clients to fetch distributions from the net. - -These are fetched from one or more mirrored CPAN (Comprehensive -Perl Archive Network) sites and unpacked in a dedicated directory. - -The CPAN module also supports named and versioned -I<bundles> of modules. Bundles simplify handling of sets of -related modules. See Bundles below. - -The package contains a session manager and a cache manager. The -session manager keeps track of what has been fetched, built, and -installed in the current session. The cache manager keeps track of the -disk space occupied by the make processes and deletes excess space -using a simple FIFO mechanism. - -All methods provided are accessible in a programmer style and in an -interactive shell style. - -=head2 CPAN::shell([$prompt, $command]) Starting Interactive Mode - -Enter interactive mode by running - - perl -MCPAN -e shell - -or - - cpan - -which puts you into a readline interface. If C<Term::ReadKey> and -either of C<Term::ReadLine::Perl> or C<Term::ReadLine::Gnu> are installed, -history and command completion are supported. - -Once at the command line, type C<h> for one-page help -screen; the rest should be self-explanatory. - -The function call C<shell> takes two optional arguments: one the -prompt, the second the default initial command line (the latter -only works if a real ReadLine interface module is installed). - -The most common uses of the interactive modes are - -=over 2 - -=item Searching for authors, bundles, distribution files and modules - -There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m> -for each of the four categories and another, C<i> for any of the -mentioned four. Each of the four entities is implemented as a class -with slightly differing methods for displaying an object. - -Arguments to these commands are either strings exactly matching -the identification string of an object, or regular expressions -matched case-insensitively against various attributes of the -objects. The parser only recognizes a regular expression when you -enclose it with slashes. - -The principle is that the number of objects found influences how an -item is displayed. If the search finds one item, the result is -displayed with the rather verbose method C<as_string>, but if -more than one is found, each object is displayed with the terse method -C<as_glimpse>. - -Examples: - - cpan> m Acme::MetaSyntactic - Module id = Acme::MetaSyntactic - CPAN_USERID BOOK (Philippe Bruhat (BooK) <[...]>) - CPAN_VERSION 0.99 - CPAN_FILE B/BO/BOOK/Acme-MetaSyntactic-0.99.tar.gz - UPLOAD_DATE 2006-11-06 - MANPAGE Acme::MetaSyntactic - Themed metasyntactic variables names - INST_FILE /usr/local/lib/perl/5.10.0/Acme/MetaSyntactic.pm - INST_VERSION 0.99 - cpan> a BOOK - Author id = BOOK - EMAIL [...] - FULLNAME Philippe Bruhat (BooK) - cpan> d BOOK/Acme-MetaSyntactic-0.99.tar.gz - Distribution id = B/BO/BOOK/Acme-MetaSyntactic-0.99.tar.gz - CPAN_USERID BOOK (Philippe Bruhat (BooK) <[...]>) - CONTAINSMODS Acme::MetaSyntactic Acme::MetaSyntactic::Alias [...] - UPLOAD_DATE 2006-11-06 - cpan> m /lorem/ - Module = Acme::MetaSyntactic::loremipsum (BOOK/Acme-MetaSyntactic-0.99.tar.gz) - Module Text::Lorem (ADEOLA/Text-Lorem-0.3.tar.gz) - Module Text::Lorem::More (RKRIMEN/Text-Lorem-More-0.12.tar.gz) - Module Text::Lorem::More::Source (RKRIMEN/Text-Lorem-More-0.12.tar.gz) - cpan> i /berlin/ - Distribution BEATNIK/Filter-NumberLines-0.02.tar.gz - Module = DateTime::TimeZone::Europe::Berlin (DROLSKY/DateTime-TimeZone-0.7904.tar.gz) - Module Filter::NumberLines (BEATNIK/Filter-NumberLines-0.02.tar.gz) - Author [...] - -The examples illustrate several aspects: the first three queries -target modules, authors, or distros directly and yield exactly one -result. The last two use regular expressions and yield several -results. The last one targets all of bundles, modules, authors, and -distros simultaneously. When more than one result is available, they -are printed in one-line format. - -=item C<get>, C<make>, C<test>, C<install>, C<clean> modules or distributions - -These commands take any number of arguments and investigate what is -necessary to perform the action. Argument processing is as follows: - - known module name in format Foo/Bar.pm module - other embedded slash distribution - - with trailing slash dot directory - enclosing slashes regexp - known module name in format Foo::Bar module - -If the argument is a distribution file name (recognized by embedded -slashes), it is processed. If it is a module, CPAN determines the -distribution file in which this module is included and processes that, -following any dependencies named in the module's META.yml or -Makefile.PL (this behavior is controlled by the configuration -parameter C<prerequisites_policy>). If an argument is enclosed in -slashes it is treated as a regular expression: it is expanded and if -the result is a single object (distribution, bundle or module), this -object is processed. - -Example: - - install Dummy::Perl # installs the module - install AUXXX/Dummy-Perl-3.14.tar.gz # installs that distribution - install /Dummy-Perl-3.14/ # same if the regexp is unambiguous - -C<get> downloads a distribution file and untars or unzips it, C<make> -builds it, C<test> runs the test suite, and C<install> installs it. - -Any C<make> or C<test> is run unconditionally. An - - install <distribution_file> - -is also run unconditionally. But for - - install <module> - -CPAN checks whether an install is needed and prints -I<module up to date> if the distribution file containing -the module doesn't need updating. - -CPAN also keeps track of what it has done within the current session -and doesn't try to build a package a second time regardless of whether it -succeeded or not. It does not repeat a test run if the test -has been run successfully before. Same for install runs. - -The C<force> pragma may precede another command (currently: C<get>, -C<make>, C<test>, or C<install>) to execute the command from scratch -and attempt to continue past certain errors. See the section below on -the C<force> and the C<fforce> pragma. - -The C<notest> pragma skips the test part in the build -process. - -Example: - - cpan> notest install Tk - -A C<clean> command results in a - - make clean - -being executed within the distribution file's working directory. - -=item C<readme>, C<perldoc>, C<look> module or distribution - -C<readme> displays the README file of the associated distribution. -C<Look> gets and untars (if not yet done) the distribution file, -changes to the appropriate directory and opens a subshell process in -that directory. C<perldoc> displays the module's pod documentation -in html or plain text format. - -=item C<ls> author - -=item C<ls> globbing_expression - -The first form lists all distribution files in and below an author's -CPAN directory as stored in the CHECKUMS files distributed on -CPAN. The listing recurses into subdirectories. - -The second form limits or expands the output with shell -globbing as in the following examples: - - ls JV/make* - ls GSAR/*make* - ls */*make* - -The last example is very slow and outputs extra progress indicators -that break the alignment of the result. - -Note that globbing only lists directories explicitly asked for, for -example FOO/* will not list FOO/bar/Acme-Sthg-n.nn.tar.gz. This may be -regarded as a bug that may be changed in some future version. - -=item C<failed> - -The C<failed> command reports all distributions that failed on one of -C<make>, C<test> or C<install> for some reason in the currently -running shell session. - -=item Persistence between sessions - -If the C<YAML> or the C<YAML::Syck> module is installed a record of -the internal state of all modules is written to disk after each step. -The files contain a signature of the currently running perl version -for later perusal. - -If the configurations variable C<build_dir_reuse> is set to a true -value, then CPAN.pm reads the collected YAML files. If the stored -signature matches the currently running perl, the stored state is -loaded into memory such that persistence between sessions -is effectively established. - -=item The C<force> and the C<fforce> pragma - -To speed things up in complex installation scenarios, CPAN.pm keeps -track of what it has already done and refuses to do some things a -second time. A C<get>, a C<make>, and an C<install> are not repeated. -A C<test> is repeated only if the previous test was unsuccessful. The -diagnostic message when CPAN.pm refuses to do something a second time -is one of I<Has already been >C<unwrapped|made|tested successfully> or -something similar. Another situation where CPAN refuses to act is an -C<install> if the corresponding C<test> was not successful. - -In all these cases, the user can override this stubborn behaviour by -prepending the command with the word force, for example: - - cpan> force get Foo - cpan> force make AUTHOR/Bar-3.14.tar.gz - cpan> force test Baz - cpan> force install Acme::Meta - -Each I<forced> command is executed with the corresponding part of its -memory erased. - -The C<fforce> pragma is a variant that emulates a C<force get> which -erases the entire memory followed by the action specified, effectively -restarting the whole get/make/test/install procedure from scratch. - -=item Lockfile - -Interactive sessions maintain a lockfile, by default C<~/.cpan/.lock>. -Batch jobs can run without a lockfile and not disturb each other. - -The shell offers to run in I<downgraded mode> when another process is -holding the lockfile. This is an experimental feature that is not yet -tested very well. This second shell then does not write the history -file, does not use the metadata file, and has a different prompt. - -=item Signals - -CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are -in the cpan-shell, it is intended that you can press C<^C> anytime and -return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell -to clean up and leave the shell loop. You can emulate the effect of a -SIGTERM by sending two consecutive SIGINTs, which usually means by -pressing C<^C> twice. - -CPAN.pm ignores SIGPIPE. If the user sets C<inactivity_timeout>, a -SIGALRM is used during the run of the C<perl Makefile.PL> or C<perl -Build.PL> subprocess. A SIGALRM is also used during module version -parsing, and is controlled by C<version_timeout>. - -=back - -=head2 CPAN::Shell - -The commands available in the shell interface are methods in -the package CPAN::Shell. If you enter the shell command, your -input is split by the Text::ParseWords::shellwords() routine, which -acts like most shells do. The first word is interpreted as the -method to be invoked, and the rest of the words are treated as the method's arguments. -Continuation lines are supported by ending a line with a -literal backslash. - -=head2 autobundle - -C<autobundle> writes a bundle file into the -C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains -a list of all modules that are both available from CPAN and currently -installed within @INC. The name of the bundle file is based on the -current date and a counter. - -=head2 hosts - -Note: this feature is still in alpha state and may change in future -versions of CPAN.pm - -This commands provides a statistical overview over recent download -activities. The data for this is collected in the YAML file -C<FTPstats.yml> in your C<cpan_home> directory. If no YAML module is -configured or YAML not installed, no stats are provided. - -=head2 mkmyconfig - -mkmyconfig() writes your own CPAN::MyConfig file into your C<~/.cpan/> -directory so that you can save your own preferences instead of the -system-wide ones. - -=head2 recent ***EXPERIMENTAL COMMAND*** - -The C<recent> command downloads a list of recent uploads to CPAN and -displays them I<slowly>. While the command is running, a $SIG{INT} -exits the loop after displaying the current item. - -B<Note>: This command requires XML::LibXML installed. - -B<Note>: This whole command currently is just a hack and will -probably change in future versions of CPAN.pm, but the general -approach will likely remain. - -B<Note>: See also L<smoke> - -=head2 recompile - -recompile() is a special command that takes no argument and -runs the make/test/install cycle with brute force over all installed -dynamically loadable extensions (aka XS modules) with 'force' in -effect. The primary purpose of this command is to finish a network -installation. Imagine you have a common source tree for two different -architectures. You decide to do a completely independent fresh -installation. You start on one architecture with the help of a Bundle -file produced earlier. CPAN installs the whole Bundle for you, but -when you try to repeat the job on the second architecture, CPAN -responds with a C<"Foo up to date"> message for all modules. So you -invoke CPAN's recompile on the second architecture and you're done. - -Another popular use for C<recompile> is to act as a rescue in case your -perl breaks binary compatibility. If one of the modules that CPAN uses -is in turn depending on binary compatibility (so you cannot run CPAN -commands), then you should try the CPAN::Nox module for recovery. - -=head2 report Bundle|Distribution|Module - -The C<report> command temporarily turns on the C<test_report> config -variable, then runs the C<force test> command with the given -arguments. The C<force> pragma reruns the tests and repeats -every step that might have failed before. - -=head2 smoke ***EXPERIMENTAL COMMAND*** - -B<*** WARNING: this command downloads and executes software from CPAN to -your computer of completely unknown status. You should never do -this with your normal account and better have a dedicated well -separated and secured machine to do this. ***> - -The C<smoke> command takes the list of recent uploads to CPAN as -provided by the C<recent> command and tests them all. While the -command is running $SIG{INT} is defined to mean that the current item -shall be skipped. - -B<Note>: This whole command currently is just a hack and will -probably change in future versions of CPAN.pm, but the general -approach will likely remain. - -B<Note>: See also L<recent> - -=head2 upgrade [Module|/Regex/]... - -The C<upgrade> command first runs an C<r> command with the given -arguments and then installs the newest versions of all modules that -were listed by that. - -=head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution - -Although it may be considered internal, the class hierarchy does matter -for both users and programmer. CPAN.pm deals with the four -classes mentioned above, and those classes all share a set of methods. Classical -single polymorphism is in effect. A metaclass object registers all -objects of all kinds and indexes them with a string. The strings -referencing objects have a separated namespace (well, not completely -separated): - - Namespace Class - - words containing a "/" (slash) Distribution - words starting with Bundle:: Bundle - everything else Module or Author - -Modules know their associated Distribution objects. They always refer -to the most recent official release. Developers may mark their releases -as unstable development versions (by inserting an underbar into the -module version number which will also be reflected in the distribution -name when you run 'make dist'), so the really hottest and newest -distribution is not always the default. If a module Foo circulates -on CPAN in both version 1.23 and 1.23_90, CPAN.pm offers a convenient -way to install version 1.23 by saying - - install Foo - -This would install the complete distribution file (say -BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would -like to install version 1.23_90, you need to know where the -distribution file resides on CPAN relative to the authors/id/ -directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz; -so you would have to say - - install BAR/Foo-1.23_90.tar.gz - -The first example will be driven by an object of the class -CPAN::Module, the second by an object of class CPAN::Distribution. - -=head2 Integrating local directories - -Note: this feature is still in alpha state and may change in future -versions of CPAN.pm - -Distribution objects are normally distributions from the CPAN, but -there is a slightly degenerate case for Distribution objects, too, of -projects held on the local disk. These distribution objects have the -same name as the local directory and end with a dot. A dot by itself -is also allowed for the current directory at the time CPAN.pm was -used. All actions such as C<make>, C<test>, and C<install> are applied -directly to that directory. This gives the command C<cpan .> an -interesting touch: while the normal mantra of installing a CPAN module -without CPAN.pm is one of - - perl Makefile.PL perl Build.PL - ( go and get prerequisites ) - make ./Build - make test ./Build test - make install ./Build install - -the command C<cpan .> does all of this at once. It figures out which -of the two mantras is appropriate, fetches and installs all -prerequisites, takes care of them recursively, and finally finishes the -installation of the module in the current directory, be it a CPAN -module or not. - -The typical usage case is for private modules or working copies of -projects from remote repositories on the local disk. - -=head2 Redirection - -The usual shell redirection symbols C< | > and C<< > >> are recognized -by the cpan shell B<only when surrounded by whitespace>. So piping to -pager or redirecting output into a file works somewhat as in a normal -shell, with the stipulation that you must type extra spaces. - -=head1 CONFIGURATION - -When the CPAN module is used for the first time, a configuration -dialogue tries to determine a couple of site specific options. The -result of the dialog is stored in a hash reference C< $CPAN::Config > -in a file CPAN/Config.pm. - -Default values defined in the CPAN/Config.pm file can be -overridden in a user specific file: CPAN/MyConfig.pm. Such a file is -best placed in C<$HOME/.cpan/CPAN/MyConfig.pm>, because C<$HOME/.cpan> is -added to the search path of the CPAN module before the use() or -require() statements. The mkmyconfig command writes this file for you. - -The C<o conf> command has various bells and whistles: - -=over - -=item completion support - -If you have a ReadLine module installed, you can hit TAB at any point -of the commandline and C<o conf> will offer you completion for the -built-in subcommands and/or config variable names. - -=item displaying some help: o conf help - -Displays a short help - -=item displaying current values: o conf [KEY] - -Displays the current value(s) for this config variable. Without KEY, -displays all subcommands and config variables. - -Example: - - o conf shell - -If KEY starts and ends with a slash, the string in between is -treated as a regular expression and only keys matching this regex -are displayed - -Example: - - o conf /color/ - -=item changing of scalar values: o conf KEY VALUE - -Sets the config variable KEY to VALUE. The empty string can be -specified as usual in shells, with C<''> or C<""> - -Example: - - o conf wget /usr/bin/wget - -=item changing of list values: o conf KEY SHIFT|UNSHIFT|PUSH|POP|SPLICE|LIST - -If a config variable name ends with C<list>, it is a list. C<o conf -KEY shift> removes the first element of the list, C<o conf KEY pop> -removes the last element of the list. C<o conf KEYS unshift LIST> -prepends a list of values to the list, C<o conf KEYS push LIST> -appends a list of valued to the list. - -Likewise, C<o conf KEY splice LIST> passes the LIST to the corresponding -splice command. - -Finally, any other list of arguments is taken as a new list value for -the KEY variable discarding the previous value. - -Examples: - - o conf urllist unshift http://cpan.dev.local/CPAN - o conf urllist splice 3 1 - o conf urllist http://cpan1.local http://cpan2.local ftp://ftp.perl.org - -=item reverting to saved: o conf defaults - -Reverts all config variables to the state in the saved config file. - -=item saving the config: o conf commit - -Saves all config variables to the current config file (CPAN/Config.pm -or CPAN/MyConfig.pm that was loaded at start). - -=back - -The configuration dialog can be started any time later again by -issuing the command C< o conf init > in the CPAN shell. A subset of -the configuration dialog can be run by issuing C<o conf init WORD> -where WORD is any valid config variable or a regular expression. - -=head2 Config Variables - -The following keys in the hash reference $CPAN::Config are -currently defined: - - applypatch path to external prg - auto_commit commit all changes to config variables to disk - build_cache size of cache for directories to build modules - build_dir locally accessible directory to build modules - build_dir_reuse boolean if distros in build_dir are persistent - build_requires_install_policy - to install or not to install when a module is - only needed for building. yes|no|ask/yes|ask/no - bzip2 path to external prg - cache_metadata use serializer to cache metadata - check_sigs if signatures should be verified - colorize_debug Term::ANSIColor attributes for debugging output - colorize_output boolean if Term::ANSIColor should colorize output - colorize_print Term::ANSIColor attributes for normal output - colorize_warn Term::ANSIColor attributes for warnings - commandnumber_in_prompt - boolean if you want to see current command number - commands_quote preferred character to use for quoting external - commands when running them. Defaults to double - quote on Windows, single tick everywhere else; - can be set to space to disable quoting - connect_to_internet_ok - whether to ask if opening a connection is ok before - urllist is specified - cpan_home local directory reserved for this package - curl path to external prg - dontload_hash DEPRECATED - dontload_list arrayref: modules in the list will not be - loaded by the CPAN::has_inst() routine - ftp path to external prg - ftp_passive if set, the envariable FTP_PASSIVE is set for downloads - ftp_proxy proxy host for ftp requests - ftpstats_period max number of days to keep download statistics - ftpstats_size max number of items to keep in the download statistics - getcwd see below - gpg path to external prg - gzip location of external program gzip - halt_on_failure stop processing after the first failure of queued - items or dependencies - histfile file to maintain history between sessions - histsize maximum number of lines to keep in histfile - http_proxy proxy host for http requests - inactivity_timeout breaks interactive Makefile.PLs or Build.PLs - after this many seconds inactivity. Set to 0 to - disable timeouts. - index_expire refetch index files after this many days - inhibit_startup_message - if true, suppress the startup message - keep_source_where directory in which to keep the source (if we do) - load_module_verbosity - report loading of optional modules used by CPAN.pm - lynx path to external prg - make location of external make program - make_arg arguments that should always be passed to 'make' - make_install_make_command - the make command for running 'make install', for - example 'sudo make' - make_install_arg same as make_arg for 'make install' - makepl_arg arguments passed to 'perl Makefile.PL' - mbuild_arg arguments passed to './Build' - mbuild_install_arg arguments passed to './Build install' - mbuild_install_build_command - command to use instead of './Build' when we are - in the install stage, for example 'sudo ./Build' - mbuildpl_arg arguments passed to 'perl Build.PL' - ncftp path to external prg - ncftpget path to external prg - no_proxy don't proxy to these hosts/domains (comma separated list) - pager location of external program more (or any pager) - password your password if you CPAN server wants one - patch path to external prg - patches_dir local directory containing patch files - perl5lib_verbosity verbosity level for PERL5LIB additions - prefer_installer legal values are MB and EUMM: if a module comes - with both a Makefile.PL and a Build.PL, use the - former (EUMM) or the latter (MB); if the module - comes with only one of the two, that one will be - used no matter the setting - prerequisites_policy - what to do if you are missing module prerequisites - ('follow' automatically, 'ask' me, or 'ignore') - prefs_dir local directory to store per-distro build options - proxy_user username for accessing an authenticating proxy - proxy_pass password for accessing an authenticating proxy - randomize_urllist add some randomness to the sequence of the urllist - scan_cache controls scanning of cache ('atstart' or 'never') - shell your favorite shell - show_unparsable_versions - boolean if r command tells which modules are versionless - show_upload_date boolean if commands should try to determine upload date - show_zero_versions boolean if r command tells for which modules $version==0 - tar location of external program tar - tar_verbosity verbosity level for the tar command - term_is_latin deprecated: if true Unicode is translated to ISO-8859-1 - (and nonsense for characters outside latin range) - term_ornaments boolean to turn ReadLine ornamenting on/off - test_report email test reports (if CPAN::Reporter is installed) - trust_test_report_history - skip testing when previously tested ok (according to - CPAN::Reporter history) - unzip location of external program unzip - urllist arrayref to nearby CPAN sites (or equivalent locations) - use_sqlite use CPAN::SQLite for metadata storage (fast and lean) - username your username if you CPAN server wants one - version_timeout stops version parsing after this many seconds. - Default is 15 secs. Set to 0 to disable. - wait_list arrayref to a wait server to try (See CPAN::WAIT) - wget path to external prg - yaml_load_code enable YAML code deserialisation via CPAN::DeferredCode - yaml_module which module to use to read/write YAML files - -You can set and query each of these options interactively in the cpan -shell with the C<o conf> or the C<o conf init> command as specified below. - -=over 2 - -=item C<o conf E<lt>scalar optionE<gt>> - -prints the current value of the I<scalar option> - -=item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>> - -Sets the value of the I<scalar option> to I<value> - -=item C<o conf E<lt>list optionE<gt>> - -prints the current value of the I<list option> in MakeMaker's -neatvalue format. - -=item C<o conf E<lt>list optionE<gt> [shift|pop]> - -shifts or pops the array in the I<list option> variable - -=item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>> - -works like the corresponding perl commands. - -=item interactive editing: o conf init [MATCH|LIST] - -Runs an interactive configuration dialog for matching variables. -Without argument runs the dialog over all supported config variables. -To specify a MATCH the argument must be enclosed by slashes. - -Examples: - - o conf init ftp_passive ftp_proxy - o conf init /color/ - -Note: this method of setting config variables often provides more -explanation about the functioning of a variable than the manpage. - -=back - -=head2 CPAN::anycwd($path): Note on config variable getcwd - -CPAN.pm changes the current working directory often and needs to -determine its own current working directory. By default it uses -Cwd::cwd, but if for some reason this doesn't work on your system, -configure alternatives according to the following table: - -=over 4 - -=item cwd - -Calls Cwd::cwd - -=item getcwd - -Calls Cwd::getcwd - -=item fastcwd - -Calls Cwd::fastcwd - -=item backtickcwd - -Calls the external command cwd. - -=back - -=head2 Note on the format of the urllist parameter - -urllist parameters are URLs according to RFC 1738. We do a little -guessing if your URL is not compliant, but if you have problems with -C<file> URLs, please try the correct format. Either: - - file://localhost/whatever/ftp/pub/CPAN/ - -or - - file:///home/ftp/pub/CPAN/ - -=head2 The urllist parameter has CD-ROM support - -The C<urllist> parameter of the configuration table contains a list of -URLs used for downloading. If the list contains any -C<file> URLs, CPAN always tries there first. This -feature is disabled for index files. So the recommendation for the -owner of a CD-ROM with CPAN contents is: include your local, possibly -outdated CD-ROM as a C<file> URL at the end of urllist, e.g. - - o conf urllist push file://localhost/CDROM/CPAN - -CPAN.pm will then fetch the index files from one of the CPAN sites -that come at the beginning of urllist. It will later check for each -module to see whether there is a local copy of the most recent version. - -Another peculiarity of urllist is that the site that we could -successfully fetch the last file from automatically gets a preference -token and is tried as the first site for the next request. So if you -add a new site at runtime it may happen that the previously preferred -site will be tried another time. This means that if you want to disallow -a site for the next transfer, it must be explicitly removed from -urllist. - -=head2 Maintaining the urllist parameter - -If you have YAML.pm (or some other YAML module configured in -C<yaml_module>) installed, CPAN.pm collects a few statistical data -about recent downloads. You can view the statistics with the C<hosts> -command or inspect them directly by looking into the C<FTPstats.yml> -file in your C<cpan_home> directory. - -To get some interesting statistics, it is recommended that -C<randomize_urllist> be set; this introduces some amount of -randomness into the URL selection. - -=head2 The C<requires> and C<build_requires> dependency declarations - -Since CPAN.pm version 1.88_51 modules declared as C<build_requires> by -a distribution are treated differently depending on the config -variable C<build_requires_install_policy>. By setting -C<build_requires_install_policy> to C<no>, such a module is not -installed. It is only built and tested, and then kept in the list of -tested but uninstalled modules. As such, it is available during the -build of the dependent module by integrating the path to the -C<blib/arch> and C<blib/lib> directories in the environment variable -PERL5LIB. If C<build_requires_install_policy> is set ti C<yes>, then -both modules declared as C<requires> and those declared as -C<build_requires> are treated alike. By setting to C<ask/yes> or -C<ask/no>, CPAN.pm asks the user and sets the default accordingly. - -=head2 Configuration for individual distributions (I<Distroprefs>) - -(B<Note:> This feature has been introduced in CPAN.pm 1.8854 and is -still considered beta quality) - -Distributions on CPAN usually behave according to what we call the -CPAN mantra. Or since the advent of Module::Build we should talk about -two mantras: - - perl Makefile.PL perl Build.PL - make ./Build - make test ./Build test - make install ./Build install - -But some modules cannot be built with this mantra. They try to get -some extra data from the user via the environment, extra arguments, or -interactively--thus disturbing the installation of large bundles like -Phalanx100 or modules with many dependencies like Plagger. - -The distroprefs system of C<CPAN.pm> addresses this problem by -allowing the user to specify extra informations and recipes in YAML -files to either - -=over - -=item - -pass additional arguments to one of the four commands, - -=item - -set environment variables - -=item - -instantiate an Expect object that reads from the console, waits for -some regular expressions and enters some answers - -=item - -temporarily override assorted C<CPAN.pm> configuration variables - -=item - -specify dependencies the original maintainer forgot - -=item - -disable the installation of an object altogether - -=back - -See the YAML and Data::Dumper files that come with the C<CPAN.pm> -distribution in the C<distroprefs/> directory for examples. - -=head2 Filenames - -The YAML files themselves must have the C<.yml> extension; all other -files are ignored (for two exceptions see I<Fallback Data::Dumper and -Storable> below). The containing directory can be specified in -C<CPAN.pm> in the C<prefs_dir> config variable. Try C<o conf init -prefs_dir> in the CPAN shell to set and activate the distroprefs -system. - -Every YAML file may contain arbitrary documents according to the YAML -specification, and every document is treated as an entity that -can specify the treatment of a single distribution. - -Filenames can be picked arbitrarily; C<CPAN.pm> always reads -all files (in alphabetical order) and takes the key C<match> (see -below in I<Language Specs>) as a hashref containing match criteria -that determine if the current distribution matches the YAML document -or not. - -=head2 Fallback Data::Dumper and Storable - -If neither your configured C<yaml_module> nor YAML.pm is installed, -CPAN.pm falls back to using Data::Dumper and Storable and looks for -files with the extensions C<.dd> or C<.st> in the C<prefs_dir> -directory. These files are expected to contain one or more hashrefs. -For Data::Dumper generated files, this is expected to be done with by -defining C<$VAR1>, C<$VAR2>, etc. The YAML shell would produce these -with the command - - ysh < somefile.yml > somefile.dd - -For Storable files the rule is that they must be constructed such that -C<Storable::retrieve(file)> returns an array reference and the array -elements represent one distropref object each. The conversion from -YAML would look like so: - - perl -MYAML=LoadFile -MStorable=nstore -e ' - @y=LoadFile(shift); - nstore(\@y, shift)' somefile.yml somefile.st - -In bootstrapping situations it is usually sufficient to translate only -a few YAML files to Data::Dumper for crucial modules like -C<YAML::Syck>, C<YAML.pm> and C<Expect.pm>. If you prefer Storable -over Data::Dumper, remember to pull out a Storable version that writes -an older format than all the other Storable versions that will need to -read them. - -=head2 Blueprint - -The following example contains all supported keywords and structures -with the exception of C<eexpect> which can be used instead of -C<expect>. - - --- - comment: "Demo" - match: - module: "Dancing::Queen" - distribution: "^CHACHACHA/Dancing-" - not_distribution: "\.zip$" - perl: "/usr/local/cariba-perl/bin/perl" - perlconfig: - archname: "freebsd" - not_cc: "gcc" - env: - DANCING_FLOOR: "Shubiduh" - disabled: 1 - cpanconfig: - make: gmake - pl: - args: - - "--somearg=specialcase" - - env: {} - - expect: - - "Which is your favorite fruit" - - "apple\n" - - make: - args: - - all - - extra-all - - env: {} - - expect: [] - - commandline: "echo SKIPPING make" - - test: - args: [] - - env: {} - - expect: [] - - install: - args: [] - - env: - WANT_TO_INSTALL: YES - - expect: - - "Do you really want to install" - - "y\n" - - patches: - - "ABCDE/Fedcba-3.14-ABCDE-01.patch" - - depends: - configure_requires: - LWP: 5.8 - build_requires: - Test::Exception: 0.25 - requires: - Spiffy: 0.30 - - -=head2 Language Specs - -Every YAML document represents a single hash reference. The valid keys -in this hash are as follows: - -=over - -=item comment [scalar] - -A comment - -=item cpanconfig [hash] - -Temporarily override assorted C<CPAN.pm> configuration variables. - -Supported are: C<build_requires_install_policy>, C<check_sigs>, -C<make>, C<make_install_make_command>, C<prefer_installer>, -C<test_report>. Please report as a bug when you need another one -supported. - -=item depends [hash] *** EXPERIMENTAL FEATURE *** - -All three types, namely C<configure_requires>, C<build_requires>, and -C<requires> are supported in the way specified in the META.yml -specification. The current implementation I<merges> the specified -dependencies with those declared by the package maintainer. In a -future implementation this may be changed to override the original -declaration. - -=item disabled [boolean] - -Specifies that this distribution shall not be processed at all. - -=item features [array] *** EXPERIMENTAL FEATURE *** - -Experimental implementation to deal with optional_features from -META.yml. Still needs coordination with installer software and -currently works only for META.yml declaring C<dynamic_config=0>. Use -with caution. - -=item goto [string] - -The canonical name of a delegate distribution to install -instead. Useful when a new version, although it tests OK itself, -breaks something else or a developer release or a fork is already -uploaded that is better than the last released version. - -=item install [hash] - -Processing instructions for the C<make install> or C<./Build install> -phase of the CPAN mantra. See below under I<Processing Instructions>. - -=item make [hash] - -Processing instructions for the C<make> or C<./Build> phase of the -CPAN mantra. See below under I<Processing Instructions>. - -=item match [hash] - -A hashref with one or more of the keys C<distribution>, C<modules>, -C<perl>, C<perlconfig>, and C<env> that specify whether a document is -targeted at a specific CPAN distribution or installation. -Keys prefixed with C<not_> negates the corresponding match. - -The corresponding values are interpreted as regular expressions. The -C<distribution> related one will be matched against the canonical -distribution name, e.g. "AUTHOR/Foo-Bar-3.14.tar.gz". - -The C<module> related one will be matched against I<all> modules -contained in the distribution until one module matches. - -The C<perl> related one will be matched against C<$^X> (but with the -absolute path). - -The value associated with C<perlconfig> is itself a hashref that is -matched against corresponding values in the C<%Config::Config> hash -living in the C<Config.pm> module. -Keys prefixed with C<not_> negates the corresponding match. - -The value associated with C<env> is itself a hashref that is -matched against corresponding values in the C<%ENV> hash. -Keys prefixed with C<not_> negates the corresponding match. - -If more than one restriction of C<module>, C<distribution>, etc. is -specified, the results of the separately computed match values must -all match. If so, the hashref represented by the -YAML document is returned as the preference structure for the current -distribution. - -=item patches [array] - -An array of patches on CPAN or on the local disk to be applied in -order via an external patch program. If the value for the C<-p> -parameter is C<0> or C<1> is determined by reading the patch -beforehand. The path to each patch is either an absolute path on the -local filesystem or relative to a patch directory specified in the -C<patches_dir> configuration variable or in the format of a canonical -distroname. For examples please consult the distroprefs/ directory in -the CPAN.pm distribution (these examples are not installed by -default). - -Note: if the C<applypatch> program is installed and C<CPAN::Config> -knows about it B<and> a patch is written by the C<makepatch> program, -then C<CPAN.pm> lets C<applypatch> apply the patch. Both C<makepatch> -and C<applypatch> are available from CPAN in the C<JV/makepatch-*> -distribution. - -=item pl [hash] - -Processing instructions for the C<perl Makefile.PL> or C<perl -Build.PL> phase of the CPAN mantra. See below under I<Processing -Instructions>. - -=item test [hash] - -Processing instructions for the C<make test> or C<./Build test> phase -of the CPAN mantra. See below under I<Processing Instructions>. - -=back - -=head2 Processing Instructions - -=over - -=item args [array] - -Arguments to be added to the command line - -=item commandline - -A full commandline to run via C<system()>. -During execution, the environment variable PERL is set -to $^X (but with an absolute path). If C<commandline> is specified, -C<args> is not used. - -=item eexpect [hash] - -Extended C<expect>. This is a hash reference with four allowed keys, -C<mode>, C<timeout>, C<reuse>, and C<talk>. - -You must install the C<Expect> module to use C<eexpect>. CPAN.pm -does not install it for you. - -C<mode> may have the values C<deterministic> for the case where all -questions come in the order written down and C<anyorder> for the case -where the questions may come in any order. The default mode is -C<deterministic>. - -C<timeout> denotes a timeout in seconds. Floating-point timeouts are -OK. With C<mode=deterministic>, the timeout denotes the -timeout per question; with C<mode=anyorder> it denotes the -timeout per byte received from the stream or questions. - -C<talk> is a reference to an array that contains alternating questions -and answers. Questions are regular expressions and answers are literal -strings. The Expect module watches the stream from the -execution of the external program (C<perl Makefile.PL>, C<perl -Build.PL>, C<make>, etc.). - -For C<mode=deterministic>, the CPAN.pm injects the -corresponding answer as soon as the stream matches the regular expression. - -For C<mode=anyorder> CPAN.pm answers a question as soon -as the timeout is reached for the next byte in the input stream. In -this mode you can use the C<reuse> parameter to decide what will -happen with a question-answer pair after it has been used. In the -default case (reuse=0) it is removed from the array, avoiding being -used again accidentally. If you want to answer the -question C<Do you really want to do that> several times, then it must -be included in the array at least as often as you want this answer to -be given. Setting the parameter C<reuse> to 1 makes this repetition -unnecessary. - -=item env [hash] - -Environment variables to be set during the command - -=item expect [array] - -You must install the C<Expect> module to use C<expect>. CPAN.pm -does not install it for you. - -C<< expect: <array> >> is a short notation for this C<eexpect>: - - eexpect: - mode: deterministic - timeout: 15 - talk: <array> - -=back - -=head2 Schema verification with C<Kwalify> - -If you have the C<Kwalify> module installed (which is part of the -Bundle::CPANxxl), then all your distroprefs files are checked for -syntactic correctness. - -=head2 Example Distroprefs Files - -C<CPAN.pm> comes with a collection of example YAML files. Note that these -are really just examples and should not be used without care because -they cannot fit everybody's purpose. After all, the authors of the -packages that ask questions had a need to ask, so you should watch -their questions and adjust the examples to your environment and your -needs. You have been warned:-) - -=head1 PROGRAMMER'S INTERFACE - -If you do not enter the shell, shell commands are -available both as methods (C<CPAN::Shell-E<gt>install(...)>) and as -functions in the calling package (C<install(...)>). Before calling low-level -commands, it makes sense to initialize components of CPAN you need, e.g.: - - CPAN::HandleConfig->load; - CPAN::Shell::setup_output; - CPAN::Index->reload; - -High-level commands do such initializations automatically. - -There's currently only one class that has a stable interface - -CPAN::Shell. All commands that are available in the CPAN shell are -methods of the class CPAN::Shell. Each of the commands that produce -listings of modules (C<r>, C<autobundle>, C<u>) also return a list of -the IDs of all modules within the list. - -=over 2 - -=item expand($type,@things) - -The IDs of all objects available within a program are strings that can -be expanded to the corresponding real objects with the -C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a -list of CPAN::Module objects according to the C<@things> arguments -given. In scalar context, it returns only the first element of the -list. - -=item expandany(@things) - -Like expand, but returns objects of the appropriate type, i.e. -CPAN::Bundle objects for bundles, CPAN::Module objects for modules, and -CPAN::Distribution objects for distributions. Note: it does not expand -to CPAN::Author objects. - -=item Programming Examples - -This enables the programmer to do operations that combine -functionalities that are available in the shell. - - # install everything that is outdated on my disk: - perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)' - - # install my favorite programs if necessary: - for $mod (qw(Net::FTP Digest::SHA Data::Dumper)) { - CPAN::Shell->install($mod); - } - - # list all modules on my disk that have no VERSION number - for $mod (CPAN::Shell->expand("Module","/./")) { - next unless $mod->inst_file; - # MakeMaker convention for undefined $VERSION: - next unless $mod->inst_version eq "undef"; - print "No VERSION in ", $mod->id, "\n"; - } - - # find out which distribution on CPAN contains a module: - print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file - -Or if you want to schedule a I<cron> job to watch CPAN, you could list -all modules that need updating. First a quick and dirty way: - - perl -e 'use CPAN; CPAN::Shell->r;' - -If you don't want any output should all modules be -up to date, parse the output of above command for the regular -expression C</modules are up to date/> and decide to mail the output -only if it doesn't match. - -If you prefer to do it more in a programmerish style in one single -process, something like this may better suit you: - - # list all modules on my disk that have newer versions on CPAN - for $mod (CPAN::Shell->expand("Module","/./")) { - next unless $mod->inst_file; - next if $mod->uptodate; - printf "Module %s is installed as %s, could be updated to %s from CPAN\n", - $mod->id, $mod->inst_version, $mod->cpan_version; - } - -If that gives too much output every day, you may want to -watch only for three modules. You can write - - for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")) { - -as the first line instead. Or you can combine some of the above -tricks: - - # watch only for a new mod_perl module - $mod = CPAN::Shell->expand("Module","mod_perl"); - exit if $mod->uptodate; - # new mod_perl arrived, let me know all update recommendations - CPAN::Shell->r; - -=back - -=head2 Methods in the other Classes - -=over 4 - -=item CPAN::Author::as_glimpse() - -Returns a one-line description of the author - -=item CPAN::Author::as_string() - -Returns a multi-line description of the author - -=item CPAN::Author::email() - -Returns the author's email address - -=item CPAN::Author::fullname() - -Returns the author's name - -=item CPAN::Author::name() - -An alias for fullname - -=item CPAN::Bundle::as_glimpse() - -Returns a one-line description of the bundle - -=item CPAN::Bundle::as_string() - -Returns a multi-line description of the bundle - -=item CPAN::Bundle::clean() - -Recursively runs the C<clean> method on all items contained in the bundle. - -=item CPAN::Bundle::contains() - -Returns a list of objects' IDs contained in a bundle. The associated -objects may be bundles, modules or distributions. - -=item CPAN::Bundle::force($method,@args) - -Forces CPAN to perform a task that it normally would have refused to -do. Force takes as arguments a method name to be called and any number -of additional arguments that should be passed to the called method. -The internals of the object get the needed changes so that CPAN.pm -does not refuse to take the action. The C<force> is passed recursively -to all contained objects. See also the section above on the C<force> -and the C<fforce> pragma. - -=item CPAN::Bundle::get() - -Recursively runs the C<get> method on all items contained in the bundle - -=item CPAN::Bundle::inst_file() - -Returns the highest installed version of the bundle in either @INC or -C<< $CPAN::Config->{cpan_home} >>. Note that this is different from -CPAN::Module::inst_file. - -=item CPAN::Bundle::inst_version() - -Like CPAN::Bundle::inst_file, but returns the $VERSION - -=item CPAN::Bundle::uptodate() - -Returns 1 if the bundle itself and all its members are uptodate. - -=item CPAN::Bundle::install() - -Recursively runs the C<install> method on all items contained in the bundle - -=item CPAN::Bundle::make() - -Recursively runs the C<make> method on all items contained in the bundle - -=item CPAN::Bundle::readme() - -Recursively runs the C<readme> method on all items contained in the bundle - -=item CPAN::Bundle::test() - -Recursively runs the C<test> method on all items contained in the bundle - -=item CPAN::Distribution::as_glimpse() - -Returns a one-line description of the distribution - -=item CPAN::Distribution::as_string() - -Returns a multi-line description of the distribution - -=item CPAN::Distribution::author - -Returns the CPAN::Author object of the maintainer who uploaded this -distribution - -=item CPAN::Distribution::pretty_id() - -Returns a string of the form "AUTHORID/TARBALL", where AUTHORID is the -author's PAUSE ID and TARBALL is the distribution filename. - -=item CPAN::Distribution::base_id() - -Returns the distribution filename without any archive suffix. E.g -"Foo-Bar-0.01" - -=item CPAN::Distribution::clean() - -Changes to the directory where the distribution has been unpacked and -runs C<make clean> there. - -=item CPAN::Distribution::containsmods() - -Returns a list of IDs of modules contained in a distribution file. -Works only for distributions listed in the 02packages.details.txt.gz -file. This typically means that just most recent version of a -distribution is covered. - -=item CPAN::Distribution::cvs_import() - -Changes to the directory where the distribution has been unpacked and -runs something like - - cvs -d $cvs_root import -m $cvs_log $cvs_dir $userid v$version - -there. - -=item CPAN::Distribution::dir() - -Returns the directory into which this distribution has been unpacked. - -=item CPAN::Distribution::force($method,@args) - -Forces CPAN to perform a task that it normally would have refused to -do. Force takes as arguments a method name to be called and any number -of additional arguments that should be passed to the called method. -The internals of the object get the needed changes so that CPAN.pm -does not refuse to take the action. See also the section above on the -C<force> and the C<fforce> pragma. - -=item CPAN::Distribution::get() - -Downloads the distribution from CPAN and unpacks it. Does nothing if -the distribution has already been downloaded and unpacked within the -current session. - -=item CPAN::Distribution::install() - -Changes to the directory where the distribution has been unpacked and -runs the external command C<make install> there. If C<make> has not -yet been run, it will be run first. A C<make test> is issued in -any case and if this fails, the install is cancelled. The -cancellation can be avoided by letting C<force> run the C<install> for -you. - -This install method only has the power to install the distribution if -there are no dependencies in the way. To install an object along with all -its dependencies, use CPAN::Shell->install. - -Note that install() gives no meaningful return value. See uptodate(). - -=item CPAN::Distribution::install_tested() - -Install all distributions that have tested sucessfully but -not yet installed. See also C<is_tested>. - -=item CPAN::Distribution::isa_perl() - -Returns 1 if this distribution file seems to be a perl distribution. -Normally this is derived from the file name only, but the index from -CPAN can contain a hint to achieve a return value of true for other -filenames too. - -=item CPAN::Distribution::look() - -Changes to the directory where the distribution has been unpacked and -opens a subshell there. Exiting the subshell returns. - -=item CPAN::Distribution::make() - -First runs the C<get> method to make sure the distribution is -downloaded and unpacked. Changes to the directory where the -distribution has been unpacked and runs the external commands C<perl -Makefile.PL> or C<perl Build.PL> and C<make> there. - -=item CPAN::Distribution::perldoc() - -Downloads the pod documentation of the file associated with a -distribution (in HTML format) and runs it through the external -command I<lynx> specified in C<< $CPAN::Config->{lynx} >>. If I<lynx> -isn't available, it converts it to plain text with the external -command I<html2text> and runs it through the pager specified -in C<< $CPAN::Config->{pager} >>. - -=item CPAN::Distribution::prefs() - -Returns the hash reference from the first matching YAML file that the -user has deposited in the C<prefs_dir/> directory. The first -succeeding match wins. The files in the C<prefs_dir/> are processed -alphabetically, and the canonical distroname (e.g. -AUTHOR/Foo-Bar-3.14.tar.gz) is matched against the regular expressions -stored in the $root->{match}{distribution} attribute value. -Additionally all module names contained in a distribution are matched -against the regular expressions in the $root->{match}{module} attribute -value. The two match values are ANDed together. Each of the two -attributes are optional. - -=item CPAN::Distribution::prereq_pm() - -Returns the hash reference that has been announced by a distribution -as the C<requires> and C<build_requires> elements. These can be -declared either by the C<META.yml> (if authoritative) or can be -deposited after the run of C<Build.PL> in the file C<./_build/prereqs> -or after the run of C<Makfile.PL> written as the C<PREREQ_PM> hash in -a comment in the produced C<Makefile>. I<Note>: this method only works -after an attempt has been made to C<make> the distribution. Returns -undef otherwise. - -=item CPAN::Distribution::readme() - -Downloads the README file associated with a distribution and runs it -through the pager specified in C<< $CPAN::Config->{pager} >>. - -=item CPAN::Distribution::reports() - -Downloads report data for this distribution from www.cpantesters.org -and displays a subset of them. - -=item CPAN::Distribution::read_yaml() - -Returns the content of the META.yml of this distro as a hashref. Note: -works only after an attempt has been made to C<make> the distribution. -Returns undef otherwise. Also returns undef if the content of META.yml -is not authoritative. (The rules about what exactly makes the content -authoritative are still in flux.) - -=item CPAN::Distribution::test() - -Changes to the directory where the distribution has been unpacked and -runs C<make test> there. - -=item CPAN::Distribution::uptodate() - -Returns 1 if all the modules contained in the distribution are -uptodate. Relies on containsmods. - -=item CPAN::Index::force_reload() - -Forces a reload of all indices. - -=item CPAN::Index::reload() - -Reloads all indices if they have not been read for more than -C<< $CPAN::Config->{index_expire} >> days. - -=item CPAN::InfoObj::dump() - -CPAN::Author, CPAN::Bundle, CPAN::Module, and CPAN::Distribution -inherit this method. It prints the data structure associated with an -object. Useful for debugging. Note: the data structure is considered -internal and thus subject to change without notice. - -=item CPAN::Module::as_glimpse() - -Returns a one-line description of the module in four columns: The -first column contains the word C<Module>, the second column consists -of one character: an equals sign if this module is already installed -and uptodate, a less-than sign if this module is installed but can be -upgraded, and a space if the module is not installed. The third column -is the name of the module and the fourth column gives maintainer or -distribution information. - -=item CPAN::Module::as_string() - -Returns a multi-line description of the module - -=item CPAN::Module::clean() - -Runs a clean on the distribution associated with this module. - -=item CPAN::Module::cpan_file() - -Returns the filename on CPAN that is associated with the module. - -=item CPAN::Module::cpan_version() - -Returns the latest version of this module available on CPAN. - -=item CPAN::Module::cvs_import() - -Runs a cvs_import on the distribution associated with this module. - -=item CPAN::Module::description() - -Returns a 44 character description of this module. Only available for -modules listed in The Module List (CPAN/modules/00modlist.long.html -or 00modlist.long.txt.gz) - -=item CPAN::Module::distribution() - -Returns the CPAN::Distribution object that contains the current -version of this module. - -=item CPAN::Module::dslip_status() - -Returns a hash reference. The keys of the hash are the letters C<D>, -C<S>, C<L>, C<I>, and <P>, for development status, support level, -language, interface and public licence respectively. The data for the -DSLIP status are collected by pause.perl.org when authors register -their namespaces. The values of the 5 hash elements are one-character -words whose meaning is described in the table below. There are also 5 -hash elements C<DV>, C<SV>, C<LV>, C<IV>, and <PV> that carry a more -verbose value of the 5 status variables. - -Where the 'DSLIP' characters have the following meanings: - - D - Development Stage (Note: *NO IMPLIED TIMESCALES*): - i - Idea, listed to gain consensus or as a placeholder - c - under construction but pre-alpha (not yet released) - a/b - Alpha/Beta testing - R - Released - M - Mature (no rigorous definition) - S - Standard, supplied with Perl 5 - - S - Support Level: - m - Mailing-list - d - Developer - u - Usenet newsgroup comp.lang.perl.modules - n - None known, try comp.lang.perl.modules - a - abandoned; volunteers welcome to take over maintainance - - L - Language Used: - p - Perl-only, no compiler needed, should be platform independent - c - C and perl, a C compiler will be needed - h - Hybrid, written in perl with optional C code, no compiler needed - + - C++ and perl, a C++ compiler will be needed - o - perl and another language other than C or C++ - - I - Interface Style - f - plain Functions, no references used - h - hybrid, object and function interfaces available - n - no interface at all (huh?) - r - some use of unblessed References or ties - O - Object oriented using blessed references and/or inheritance - - P - Public License - p - Standard-Perl: user may choose between GPL and Artistic - g - GPL: GNU General Public License - l - LGPL: "GNU Lesser General Public License" (previously known as - "GNU Library General Public License") - b - BSD: The BSD License - a - Artistic license alone - 2 - Artistic license 2.0 or later - o - open source: appoved by www.opensource.org - d - allows distribution without restrictions - r - restricted distribtion - n - no license at all - -=item CPAN::Module::force($method,@args) - -Forces CPAN to perform a task it would normally refuse to -do. Force takes as arguments a method name to be invoked and any number -of additional arguments to pass that method. -The internals of the object get the needed changes so that CPAN.pm -does not refuse to take the action. See also the section above on the -C<force> and the C<fforce> pragma. - -=item CPAN::Module::get() - -Runs a get on the distribution associated with this module. - -=item CPAN::Module::inst_file() - -Returns the filename of the module found in @INC. The first file found -is reported, just as perl itself stops searching @INC once it finds a -module. - -=item CPAN::Module::available_file() - -Returns the filename of the module found in PERL5LIB or @INC. The -first file found is reported. The advantage of this method over -C<inst_file> is that modules that have been tested but not yet -installed are included because PERL5LIB keeps track of tested modules. - -=item CPAN::Module::inst_version() - -Returns the version number of the installed module in readable format. - -=item CPAN::Module::available_version() - -Returns the version number of the available module in readable format. - -=item CPAN::Module::install() - -Runs an C<install> on the distribution associated with this module. - -=item CPAN::Module::look() - -Changes to the directory where the distribution associated with this -module has been unpacked and opens a subshell there. Exiting the -subshell returns. - -=item CPAN::Module::make() - -Runs a C<make> on the distribution associated with this module. - -=item CPAN::Module::manpage_headline() - -If module is installed, peeks into the module's manpage, reads the -headline, and returns it. Moreover, if the module has been downloaded -within this session, does the equivalent on the downloaded module even -if it hasn't been installed yet. - -=item CPAN::Module::perldoc() - -Runs a C<perldoc> on this module. - -=item CPAN::Module::readme() - -Runs a C<readme> on the distribution associated with this module. - -=item CPAN::Module::reports() - -Calls the reports() method on the associated distribution object. - -=item CPAN::Module::test() - -Runs a C<test> on the distribution associated with this module. - -=item CPAN::Module::uptodate() - -Returns 1 if the module is installed and up-to-date. - -=item CPAN::Module::userid() - -Returns the author's ID of the module. - -=back - -=head2 Cache Manager - -Currently the cache manager only keeps track of the build directory -($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that -deletes complete directories below C<build_dir> as soon as the size of -all directories there gets bigger than $CPAN::Config->{build_cache} -(in MB). The contents of this cache may be used for later -re-installations that you intend to do manually, but will never be -trusted by CPAN itself. This is due to the fact that the user might -use these directories for building modules on different architectures. - -There is another directory ($CPAN::Config->{keep_source_where}) where -the original distribution files are kept. This directory is not -covered by the cache manager and must be controlled by the user. If -you choose to have the same directory as build_dir and as -keep_source_where directory, then your sources will be deleted with -the same fifo mechanism. - -=head2 Bundles - -A bundle is just a perl module in the namespace Bundle:: that does not -define any functions or methods. It usually only contains documentation. - -It starts like a perl module with a package declaration and a $VERSION -variable. After that the pod section looks like any other pod with the -only difference being that I<one special pod section> exists starting with -(verbatim): - - =head1 CONTENTS - -In this pod section each line obeys the format - - Module_Name [Version_String] [- optional text] - -The only required part is the first field, the name of a module -(e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest -of the line is optional. The comment part is delimited by a dash just -as in the man page header. - -The distribution of a bundle should follow the same convention as -other distributions. - -Bundles are treated specially in the CPAN package. If you say 'install -Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all -the modules in the CONTENTS section of the pod. You can install your -own Bundles locally by placing a conformant Bundle file somewhere into -your @INC path. The autobundle() command which is available in the -shell interface does that for you by including all currently installed -modules in a snapshot bundle file. - -=head1 PREREQUISITES - -The CPAN program is trying to depend on as little as possible so the -user can use it in hostile enviroment. It works better the more goodies -the environment provides. For example if you try in the CPAN shell - - install Bundle::CPAN - -or - - install Bundle::CPANxxl - -you will find the shell more convenient than the bare shell before. - -If you have a local mirror of CPAN and can access all files with -"file:" URLs, then you only need a perl later than perl5.003 to run -this module. Otherwise Net::FTP is strongly recommended. LWP may be -required for non-UNIX systems, or if your nearest CPAN site is -associated with a URL that is not C<ftp:>. - -If you have neither Net::FTP nor LWP, there is a fallback mechanism -implemented for an external ftp command or for an external lynx -command. - -=head1 UTILITIES - -=head2 Finding packages and VERSION - -This module presumes that all packages on CPAN - -=over 2 - -=item * - -declare their $VERSION variable in an easy to parse manner. This -prerequisite can hardly be relaxed because it consumes far too much -memory to load all packages into the running program just to determine -the $VERSION variable. Currently all programs that are dealing with -version use something like this - - perl -MExtUtils::MakeMaker -le \ - 'print MM->parse_version(shift)' filename - -If you are author of a package and wonder if your $VERSION can be -parsed, please try the above method. - -=item * - -come as compressed or gzipped tarfiles or as zip files and contain a -C<Makefile.PL> or C<Build.PL> (well, we try to handle a bit more, but -with little enthusiasm). - -=back - -=head2 Debugging - -Debugging this module is more than a bit complex due to interference from -the software producing the indices on CPAN, the mirroring process on CPAN, -packaging, configuration, synchronicity, and even (gasp!) due to bugs -within the CPAN.pm module itself. - -For debugging the code of CPAN.pm itself in interactive mode, some -debugging aid can be turned on for most packages within -CPAN.pm with one of - -=over 2 - -=item o debug package... - -sets debug mode for packages. - -=item o debug -package... - -unsets debug mode for packages. - -=item o debug all - -turns debugging on for all packages. - -=item o debug number - -=back - -which sets the debugging packages directly. Note that C<o debug 0> -turns debugging off. - -What seems a successful strategy is the combination of C<reload -cpan> and the debugging switches. Add a new debug statement while -running in the shell and then issue a C<reload cpan> and see the new -debugging messages immediately without losing the current context. - -C<o debug> without an argument lists the valid package names and the -current set of packages in debugging mode. C<o debug> has built-in -completion support. - -For debugging of CPAN data there is the C<dump> command which takes -the same arguments as make/test/install and outputs each object's -Data::Dumper dump. If an argument looks like a perl variable and -contains one of C<$>, C<@> or C<%>, it is eval()ed and fed to -Data::Dumper directly. - -=head2 Floppy, Zip, Offline Mode - -CPAN.pm works nicely without network access, too. If you maintain machines -that are not networked at all, you should consider working with C<file:> -URLs. You'll have to collect your modules somewhere first. So -you might use CPAN.pm to put together all you need on a networked -machine. Then copy the $CPAN::Config->{keep_source_where} (but not -$CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind -of a personal CPAN. CPAN.pm on the non-networked machines works nicely -with this floppy. See also below the paragraph about CD-ROM support. - -=head2 Basic Utilities for Programmers - -=over 2 - -=item has_inst($module) - -Returns true if the module is installed. Used to load all modules into -the running CPAN.pm that are considered optional. The config variable -C<dontload_list> intercepts the C<has_inst()> call such -that an optional module is not loaded despite being available. For -example, the following command will prevent C<YAML.pm> from being -loaded: - - cpan> o conf dontload_list push YAML - -See the source for details. - -=item has_usable($module) - -Returns true if the module is installed and in a usable state. Only -useful for a handful of modules that are used internally. See the -source for details. - -=item instance($module) - -The constructor for all the singletons used to represent modules, -distributions, authors, and bundles. If the object already exists, this -method returns the object; otherwise, it calls the constructor. - -=back - -=head1 SECURITY - -There's no strong security layer in CPAN.pm. CPAN.pm helps you to -install foreign, unmasked, unsigned code on your machine. We compare -to a checksum that comes from the net just as the distribution file -itself. But we try to make it easy to add security on demand: - -=head2 Cryptographically signed modules - -Since release 1.77, CPAN.pm has been able to verify cryptographically -signed module distributions using Module::Signature. The CPAN modules -can be signed by their authors, thus giving more security. The simple -unsigned MD5 checksums that were used before by CPAN protect mainly -against accidental file corruption. - -You will need to have Module::Signature installed, which in turn -requires that you have at least one of Crypt::OpenPGP module or the -command-line F<gpg> tool installed. - -You will also need to be able to connect over the Internet to the public -keyservers, like pgp.mit.edu, and their port 11731 (the HKP protocol). - -The configuration parameter check_sigs is there to turn signature -checking on or off. - -=head1 EXPORT - -Most functions in package CPAN are exported by default. The reason -for this is that the primary use is intended for the cpan shell or for -one-liners. - -=head1 ENVIRONMENT - -When the CPAN shell enters a subshell via the look command, it sets -the environment CPAN_SHELL_LEVEL to 1, or increments that variable if it is -already set. - -When CPAN runs, it sets the environment variable PERL5_CPAN_IS_RUNNING -to the ID of the running process. It also sets -PERL5_CPANPLUS_IS_RUNNING to prevent runaway processes which could -happen with older versions of Module::Install. - -When running C<perl Makefile.PL>, the environment variable -C<PERL5_CPAN_IS_EXECUTING> is set to the full path of the -C<Makefile.PL> that is being executed. This prevents runaway processes -with newer versions of Module::Install. - -When the config variable ftp_passive is set, all downloads will be run -with the environment variable FTP_PASSIVE set to this value. This is -in general a good idea as it influences both Net::FTP and LWP based -connections. The same effect can be achieved by starting the cpan -shell with this environment variable set. For Net::FTP alone, one can -also always set passive mode by running libnetcfg. - -=head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES - -Populating a freshly installed perl with one's favorite modules is pretty -easy if you maintain a private bundle definition file. To get a useful -blueprint of a bundle definition file, the command autobundle can be used -on the CPAN shell command line. This command writes a bundle definition -file for all modules installed for the current perl -interpreter. It's recommended to run this command once only, and from then -on maintain the file manually under a private name, say -Bundle/my_bundle.pm. With a clever bundle file you can then simply say - - cpan> install Bundle::my_bundle - -then answer a few questions and go out for coffee (possibly -even in a different city). - -Maintaining a bundle definition file means keeping track of two -things: dependencies and interactivity. CPAN.pm sometimes fails on -calculating dependencies because not all modules define all MakeMaker -attributes correctly, so a bundle definition file should specify -prerequisites as early as possible. On the other hand, it's -annoying that so many distributions need some interactive configuring. So -what you can try to accomplish in your private bundle file is to have the -packages that need to be configured early in the file and the gentle -ones later, so you can go out for cofeee after a few minutes and leave CPAN.pm -to churn away untended. - -=head1 WORKING WITH CPAN.pm BEHIND FIREWALLS - -Thanks to Graham Barr for contributing the following paragraphs about -the interaction between perl, and various firewall configurations. For -further information on firewalls, it is recommended to consult the -documentation that comes with the I<ncftp> program. If you are unable to -go through the firewall with a simple Perl setup, it is likely -that you can configure I<ncftp> so that it works through your firewall. - -=head2 Three basic types of firewalls - -Firewalls can be categorized into three basic types. - -=over 4 - -=item http firewall - -This is when the firewall machine runs a web server, and to access the -outside world, you must do so via that web server. If you set environment -variables like http_proxy or ftp_proxy to values beginning with http://, -or in your web browser you've proxy information set, then you know -you are running behind an http firewall. - -To access servers outside these types of firewalls with perl (even for -ftp), you need LWP. - -=item ftp firewall - -This where the firewall machine runs an ftp server. This kind of -firewall will only let you access ftp servers outside the firewall. -This is usually done by connecting to the firewall with ftp, then -entering a username like "user@outside.host.com". - -To access servers outside these type of firewalls with perl, you -need Net::FTP. - -=item One-way visibility - -One-way visibility means these firewalls try to make themselves -invisible to users inside the firewall. An FTP data connection is -normally created by sending your IP address to the remote server and then -listening for the return connection. But the remote server will not be able to -connect to you because of the firewall. For these types of firewall, -FTP connections need to be done in a passive mode. - -There are two that I can think off. - -=over 4 - -=item SOCKS - -If you are using a SOCKS firewall, you will need to compile perl and link -it with the SOCKS library. This is what is normally called a 'socksified' -perl. With this executable you will be able to connect to servers outside -the firewall as if it were not there. - -=item IP Masquerade - -This is when the firewall implemented in the kernel (via NAT, or networking -address translation), it allows you to hide a complete network behind one -IP address. With this firewall no special compiling is needed as you can -access hosts directly. - -For accessing ftp servers behind such firewalls you usually need to -set the environment variable C<FTP_PASSIVE> or the config variable -ftp_passive to a true value. - -=back - -=back - -=head2 Configuring lynx or ncftp for going through a firewall - -If you can go through your firewall with e.g. lynx, presumably with a -command such as - - /usr/local/bin/lynx -pscott:tiger - -then you would configure CPAN.pm with the command - - o conf lynx "/usr/local/bin/lynx -pscott:tiger" - -That's all. Similarly for ncftp or ftp, you would configure something -like - - o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg" - -Your mileage may vary... - -=head1 FAQ - -=over 4 - -=item 1) - -I installed a new version of module X but CPAN keeps saying, -I have the old version installed - -Probably you B<do> have the old version installed. This can -happen if a module installs itself into a different directory in the -@INC path than it was previously installed. This is not really a -CPAN.pm problem, you would have the same problem when installing the -module manually. The easiest way to prevent this behaviour is to add -the argument C<UNINST=1> to the C<make install> call, and that is why -many people add this argument permanently by configuring - - o conf make_install_arg UNINST=1 - -=item 2) - -So why is UNINST=1 not the default? - -Because there are people who have their precise expectations about who -may install where in the @INC path and who uses which @INC array. In -fine tuned environments C<UNINST=1> can cause damage. - -=item 3) - -I want to clean up my mess, and install a new perl along with -all modules I have. How do I go about it? - -Run the autobundle command for your old perl and optionally rename the -resulting bundle file (e.g. Bundle/mybundle.pm), install the new perl -with the Configure option prefix, e.g. - - ./Configure -Dprefix=/usr/local/perl-5.6.78.9 - -Install the bundle file you produced in the first step with something like - - cpan> install Bundle::mybundle - -and you're done. - -=item 4) - -When I install bundles or multiple modules with one command -there is too much output to keep track of. - -You may want to configure something like - - o conf make_arg "| tee -ai /root/.cpan/logs/make.out" - o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out" - -so that STDOUT is captured in a file for later inspection. - - -=item 5) - -I am not root, how can I install a module in a personal directory? - -First of all, you will want to use your own configuration, not the one -that your root user installed. If you do not have permission to write -in the cpan directory that root has configured, you will be asked if -you want to create your own config. Answering "yes" will bring you into -CPAN's configuration stage, using the system config for all defaults except -things that have to do with CPAN's work directory, saving your choices to -your MyConfig.pm file. - -You can also manually initiate this process with the following command: - - % perl -MCPAN -e 'mkmyconfig' - -or by running - - mkmyconfig - -from the CPAN shell. - -You will most probably also want to configure something like this: - - o conf makepl_arg "LIB=~/myperl/lib \ - INSTALLMAN1DIR=~/myperl/man/man1 \ - INSTALLMAN3DIR=~/myperl/man/man3 \ - INSTALLSCRIPT=~/myperl/bin \ - INSTALLBIN=~/myperl/bin" - -and then the equivalent command for Module::Build, which is - - o conf mbuildpl_arg "--lib=~/myperl/lib \ - --installman1dir=~/myperl/man/man1 \ - --installman3dir=~/myperl/man/man3 \ - --installscript=~/myperl/bin \ - --installbin=~/myperl/bin" - -You can make this setting permanent like all C<o conf> settings with -C<o conf commit> or by setting C<auto_commit> beforehand. - -You will have to add ~/myperl/man to the MANPATH environment variable -and also tell your perl programs to look into ~/myperl/lib, e.g. by -including - - use lib "$ENV{HOME}/myperl/lib"; - -or setting the PERL5LIB environment variable. - -While we're speaking about $ENV{HOME}, it might be worth mentioning, -that for Windows we use the File::HomeDir module that provides an -equivalent to the concept of the home directory on Unix. - -Another thing you should bear in mind is that the UNINST parameter can -be dangerous when you are installing into a private area because you -might accidentally remove modules that other people depend on that are -not using the private area. - -=item 6) - -How to get a package, unwrap it, and make a change before building it? - -Have a look at the C<look> (!) command. - -=item 7) - -I installed a Bundle and had a couple of fails. When I -retried, everything resolved nicely. Can this be fixed to work -on first try? - -The reason for this is that CPAN does not know the dependencies of all -modules when it starts out. To decide about the additional items to -install, it just uses data found in the META.yml file or the generated -Makefile. An undetected missing piece breaks the process. But it may -well be that your Bundle installs some prerequisite later than some -depending item and thus your second try is able to resolve everything. -Please note, CPAN.pm does not know the dependency tree in advance and -cannot sort the queue of things to install in a topologically correct -order. It resolves perfectly well B<if> all modules declare the -prerequisites correctly with the PREREQ_PM attribute to MakeMaker or -the C<requires> stanza of Module::Build. For bundles which fail and -you need to install often, it is recommended to sort the Bundle -definition file manually. - -=item 8) - -In our intranet, we have many modules for internal use. How -can I integrate these modules with CPAN.pm but without uploading -the modules to CPAN? - -Have a look at the CPAN::Site module. - -=item 9) - -When I run CPAN's shell, I get an error message about things in my -C</etc/inputrc> (or C<~/.inputrc>) file. - -These are readline issues and can only be fixed by studying readline -configuration on your architecture and adjusting the referenced file -accordingly. Please make a backup of the C</etc/inputrc> or C<~/.inputrc> -and edit them. Quite often harmless changes like uppercasing or -lowercasing some arguments solves the problem. - -=item 10) - -Some authors have strange characters in their names. - -Internally CPAN.pm uses the UTF-8 charset. If your terminal is -expecting ISO-8859-1 charset, a converter can be activated by setting -term_is_latin to a true value in your config file. One way of doing so -would be - - cpan> o conf term_is_latin 1 - -If other charset support is needed, please file a bugreport against -CPAN.pm at rt.cpan.org and describe your needs. Maybe we can extend -the support or maybe UTF-8 terminals become widely available. - -Note: this config variable is deprecated and will be removed in a -future version of CPAN.pm. It will be replaced with the conventions -around the family of $LANG and $LC_* environment variables. - -=item 11) - -When an install fails for some reason and then I correct the error -condition and retry, CPAN.pm refuses to install the module, saying -C<Already tried without success>. - -Use the force pragma like so - - force install Foo::Bar - -Or you can use - - look Foo::Bar - -and then C<make install> directly in the subshell. - -=item 12) - -How do I install a "DEVELOPER RELEASE" of a module? - -By default, CPAN will install the latest non-developer release of a -module. If you want to install a dev release, you have to specify the -partial path starting with the author id to the tarball you wish to -install, like so: - - cpan> install KWILLIAMS/Module-Build-0.27_07.tar.gz - -Note that you can use the C<ls> command to get this path listed. - -=item 13) - -How do I install a module and all its dependencies from the commandline, -without being prompted for anything, despite my CPAN configuration -(or lack thereof)? - -CPAN uses ExtUtils::MakeMaker's prompt() function to ask its questions, so -if you set the PERL_MM_USE_DEFAULT environment variable, you shouldn't be -asked any questions at all (assuming the modules you are installing are -nice about obeying that variable as well): - - % PERL_MM_USE_DEFAULT=1 perl -MCPAN -e 'install My::Module' - -=item 14) - -How do I create a Module::Build based Build.PL derived from an -ExtUtils::MakeMaker focused Makefile.PL? - -http://search.cpan.org/dist/Module-Build-Convert/ - -=item 15) - -I'm frequently irritated with the CPAN shell's inability to help me -select a good mirror. - -The urllist config parameter is yours. You can add and remove sites at -will. You should find out which sites have the best uptodateness, -bandwidth, reliability, etc. and are topologically close to you. Some -people prefer fast downloads, others uptodateness, others reliability. -You decide which to try in which order. - -Henk P. Penning maintains a site that collects data about CPAN sites: - - http://www.cs.uu.nl/people/henkp/mirmon/cpan.html - -Also, feel free to play with experimental features. Run - - o conf init randomize_urllist ftpstats_period ftpstats_size - -and choose your favorite parameters. After a few downloads running the -C<hosts> command will probably assist you in choosing the best mirror -sites. - -=item 16) - -Why do I get asked the same questions every time I start the shell? - -You can make your configuration changes permanent by calling the -command C<o conf commit>. Alternatively set the C<auto_commit> -variable to true by running C<o conf init auto_commit> and answering -the following question with yes. - -=item 17) - -Older versions of CPAN.pm had the original root directory of all -tarballs in the build directory. Now there are always random -characters appended to these directory names. Why was this done? - -The random characters are provided by File::Temp and ensure that each -module's individual build directory is unique. This makes running -CPAN.pm in concurrent processes simultaneously safe. - -=item 18) - -Speaking of the build directory. Do I have to clean it up myself? - -You have the choice to set the config variable C<scan_cache> to -C<never>. Then you must clean it up yourself. The other possible -value, C<atstart> only cleans up the build directory when you start -the CPAN shell. If you never start up the CPAN shell, you probably -also have to clean up the build directory yourself. - -=back - -=head1 COMPATIBILITY - -=head2 OLD PERL VERSIONS - -CPAN.pm is regularly tested to run under 5.004, 5.005, and assorted -newer versions. It is getting more and more difficult to get the -minimal prerequisites working on older perls. It is close to -impossible to get the whole Bundle::CPAN working there. If you're in -the position to have only these old versions, be advised that CPAN is -designed to work fine without the Bundle::CPAN installed. - -To get things going, note that GBARR/Scalar-List-Utils-1.18.tar.gz is -compatible with ancient perls and that File::Temp is listed as a -prerequisite but CPAN has reasonable workarounds if it is missing. - -=head2 CPANPLUS - -This module and its competitor, the CPANPLUS module, are both much -cooler than the other. CPAN.pm is older. CPANPLUS was designed to be -more modular, but it was never intended to be compatible with CPAN.pm. - -=head1 SECURITY ADVICE - -This software enables you to upgrade software on your computer and so -is inherently dangerous because the newly installed software may -contain bugs and may alter the way your computer works or even make it -unusable. Please consider backing up your data before every upgrade. - -=head1 BUGS - -Please report bugs via L<http://rt.cpan.org/> - -Before submitting a bug, please make sure that the traditional method -of building a Perl module package from a shell by following the -installation instructions of that package still works in your -environment. - -=head1 AUTHOR - -Andreas Koenig C<< <andk@cpan.org> >> - -=head1 LICENSE - -This program is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -See L<http://www.perl.com/perl/misc/Artistic.html> - -=head1 TRANSLATIONS - -Kawai,Takanori provides a Japanese translation of a very old version -of this manpage at -L<http://homepage3.nifty.com/hippo2000/perltips/CPAN.htm> - -=head1 SEE ALSO - -Many people enter the CPAN shell by running the L<cpan> utility -program which is installed in the same directory as perl itself. So if -you have this directory in your PATH variable (or some equivalent in -your operating system) then typing C<cpan> in a console window will -work for you as well. Above that the utility provides several -commandline shortcuts. - -=cut |