summaryrefslogtreecommitdiff
path: root/lib/CPAN.pm
diff options
context:
space:
mode:
authorSteve Peters <steve@fisharerojo.org>2007-02-13 15:23:00 +0000
committerSteve Peters <steve@fisharerojo.org>2007-02-13 15:23:00 +0000
commitf20de9f042d39c1d62d00a7c9da4cca3665ec21d (patch)
treec1624df621c2b99a60394f580f6953438e28ef25 /lib/CPAN.pm
parentdbeafbd11804a1f3337ac72205001f934fa9e9af (diff)
downloadperl-f20de9f042d39c1d62d00a7c9da4cca3665ec21d.tar.gz
Upgrade to CPAN-1.88_72
p4raw-id: //depot/perl@30256
Diffstat (limited to 'lib/CPAN.pm')
-rw-r--r--lib/CPAN.pm1420
1 files changed, 954 insertions, 466 deletions
diff --git a/lib/CPAN.pm b/lib/CPAN.pm
index 434fc16a7d..2221a5fce8 100644
--- a/lib/CPAN.pm
+++ b/lib/CPAN.pm
@@ -1,7 +1,7 @@
# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
use strict;
package CPAN;
-$CPAN::VERSION = '1.88_69';
+$CPAN::VERSION = '1.88_73';
$CPAN::VERSION = eval $CPAN::VERSION;
use CPAN::HandleConfig;
@@ -64,13 +64,13 @@ use vars qw(
$AUTOLOAD
$Be_Silent
$CONFIG_DIRTY
- $DEBUG
$Defaultdocs
$Defaultrecent
$Frontend
$GOTOSHELL
$HAS_USABLE
$Have_warned
+ $MAX_RECURSION
$META
$RUN_DEGRADED
$Signal
@@ -83,6 +83,8 @@ use vars qw(
@EXPORT
);
+$MAX_RECURSION = 32;
+
@CPAN::ISA = qw(CPAN::Debug Exporter);
# note that these functions live in CPAN::Shell and get executed via
@@ -98,6 +100,7 @@ use vars qw(
get
install
install_tested
+ is_tested
make
mkmyconfig
notest
@@ -179,14 +182,7 @@ sub shell {
$CPAN::Frontend->mywarn("Terminal does not support AddHistory.\n");
last;
}
- my($fh) = FileHandle->new;
- open $fh, "<$histfile" or last;
- local $/ = "\n";
- while (<$fh>) {
- chomp;
- $term->AddHistory($_);
- }
- close $fh;
+ $META->readhist($term,$histfile);
}}
for ($CPAN::Config->{term_ornaments}) { # alias
local $Term::ReadLine::termcap_nowarn = 1;
@@ -374,14 +370,28 @@ sub _yaml_loadfile {
return +[] unless -s $local_file;
my $yaml_module = _yaml_module;
if ($CPAN::META->has_inst($yaml_module)) {
- my $code = UNIVERSAL::can($yaml_module, "LoadFile");
- my @yaml;
- 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",$@);
+ my $code;
+ if ($code = UNIVERSAL::can($yaml_module, "LoadFile")) {
+ my @yaml;
+ 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",$@);
+ }
+ return \@yaml;
+ } elsif ($code = UNIVERSAL::can($yaml_module, "Load")) {
+ local *FH;
+ open FH, $local_file or die "Could not open '$local_file': $!";
+ local $/;
+ my $ystream = <FH>;
+ my @yaml;
+ 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",$@);
+ }
+ return \@yaml;
}
- return \@yaml;
} else {
# this shall not be done by the frontend
die CPAN::Exception::yaml_not_installed->new($yaml_module, $local_file, "parse");
@@ -394,12 +404,16 @@ 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")) {
- my $code = UNIVERSAL::can($yaml_module, "Dump");
+ $code = UNIVERSAL::can($yaml_module, "Dump");
eval { print $local_file $code->(@what) };
- } else {
- my $code = UNIVERSAL::can($yaml_module, "DumpFile");
+ } 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",$@);
@@ -466,11 +480,13 @@ use strict;
clean
cvs_import
dump
+ failed
force
fforce
hosts
install
install_tested
+ is_tested
look
ls
make
@@ -520,6 +536,10 @@ package CPAN::Exception::RecursiveDependency;
use strict;
use overload '""' => "as_string";
+# a module sees its distribution (no version)
+# a distribution sees its prereqs (which are module names) (usually with versions)
+# a bundle sees its module names and/or its distributions (no version)
+
sub new {
my($class) = shift;
my($deps) = shift;
@@ -709,10 +729,11 @@ sub _perl_fingerprint {
if (defined $dll) {
$mtime_dll = (-f $dll ? (stat(_))[9] : '-1');
}
+ my $mtime_perl = (-f $^X ? (stat(_))[9] : '-1');
my $this_fingerprint = {
'$^X' => $^X,
sitearchexp => $Config::Config{sitearchexp},
- 'mtime_$^X' => (stat $^X)[9],
+ 'mtime_$^X' => $mtime_perl,
'mtime_dll' => $mtime_dll,
};
if ($other_fingerprint) {
@@ -1064,6 +1085,16 @@ sub has_usable {
}
},
],
+ 'Archive::Tar' => [
+ sub {require Archive::Tar;
+ unless (Archive::Tar::->VERSION >= 1.00) {
+ for ("Will not use Archive::Tar, need 1.00\n") {
+ $CPAN::Frontend->mywarn($_);
+ die $_;
+ }
+ }
+ },
+ ],
};
if ($usable->{$mod}) {
for my $c (0..$#{$usable->{$mod}}) {
@@ -1128,7 +1159,7 @@ sub has_inst {
$CPAN::Frontend->mysleep(3);
} elsif ($mod eq "Digest::SHA"){
if ($Have_warned->{"Digest::SHA"}++) {
- $CPAN::Frontend->myprint(qq{CPAN: checksum security checks disabled}.
+ $CPAN::Frontend->myprint(qq{CPAN: checksum security checks disabled }.
qq{because Digest::SHA not installed.\n});
} else {
$CPAN::Frontend->mywarn(qq{
@@ -1210,6 +1241,19 @@ sub cleanup {
$CPAN::Frontend->myprint("Lockfile removed.\n");
}
+#-> sub CPAN::readhist
+sub readhist {
+ my($self,$term,$histfile) = @_;
+ my($fh) = FileHandle->new;
+ open $fh, "<$histfile" or last;
+ local $/ = "\n";
+ while (<$fh>) {
+ chomp;
+ $term->AddHistory($_);
+ }
+ close $fh;
+}
+
#-> sub CPAN::savehist
sub savehist {
my($self) = @_;
@@ -1327,8 +1371,11 @@ sub tidyup {
my($toremove) = shift @{$self->{FIFO}};
unless ($toremove =~ /\.yml$/) {
$CPAN::Frontend->myprint(sprintf(
- "DEL: $toremove (%.1f>%.1f MB)\n",
- $self->{DU}, $self->{'MAX'})
+ "DEL(%.1f>%.1fMB): %s \n",
+ $self->{DU},
+ $self->{MAX},
+ $toremove,
+ )
);
}
return if $CPAN::Signal;
@@ -1436,7 +1483,22 @@ sub _clean_cache {
$self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
if $CPAN::DEBUG;
File::Path::rmtree($dir);
- unlink "$dir.yml"; # may fail
+ my $id_deleted = 0;
+ if ($dir !~ /\.yml$/ && -f "$dir.yml") {
+ my $yaml_module = CPAN::_yaml_module;
+ if ($CPAN::META->has_inst($yaml_module)) {
+ my($peek_yaml) = CPAN->_yaml_loadfile("$dir.yml");
+ if (my $id = $peek_yaml->[0]{distribution}{ID}) {
+ $CPAN::META->delete("CPAN::Distribution", $id);
+ # $CPAN::Frontend->mywarn (" +++\n");
+ $id_deleted++;
+ }
+ }
+ unlink "$dir.yml"; # may fail
+ unless ($id_deleted) {
+ CPAN->debug("no distro found associated with '$dir'");
+ }
+ }
$self->{DU} -= $self->{SIZE}{$dir};
delete $self->{SIZE}{$dir};
}
@@ -1470,6 +1532,7 @@ sub scan_cache {
return if $self->{SCAN} eq 'never';
$CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
unless $self->{SCAN} eq 'atstart';
+ return unless $CPAN::META->{LOCK};
$CPAN::Frontend->myprint(
sprintf("Scanning cache %s for sizes\n",
$self->{ID}));
@@ -1724,7 +1787,7 @@ sub o {
CPAN::HandleConfig->prettyprint($k);
}
$CPAN::Frontend->myprint("\n");
- } else {
+ } else {
if (CPAN::HandleConfig->edit(@o_what)) {
} else {
$CPAN::Frontend->myprint(qq{Type 'o conf' to view all configuration }.
@@ -1841,7 +1904,7 @@ sub hosts {
$S{end} ||= $last->{end};
my $dltime = $last->{end} - $start;
my $dlsize = $last->{filesize} || 0;
- my $url = $last->{thesiteurl}->text;
+ my $url = ref $last->{thesiteurl} ? $last->{thesiteurl}->text : $last->{thesiteurl};
my $s = $S{ok}{$url} ||= {};
$s->{n}++;
$s->{dlsize} ||= 0;
@@ -1904,6 +1967,7 @@ sub reload {
"CPAN/Kwalify.pm",
"CPAN/Queue.pm",
"CPAN/Reporter.pm",
+ "CPAN/SQLite.pm",
"CPAN/Tarzip.pm",
"CPAN/Version.pm",
);
@@ -2127,7 +2191,7 @@ sub report {
# re-run (as documented)
}
-# experimental (compare with _is_tested)
+# compare with is_tested
#-> sub CPAN::Shell::install_tested
sub install_tested {
my($self,@some) = @_;
@@ -2141,8 +2205,8 @@ sub install_tested {
$CPAN::Frontend->mywarn("No YAML file for $b available, skipping\n");
next;
}
- my $yaml_content = CPAN::_yaml_loadfile($yaml);
- my $id = $yaml_content->[0]{ID};
+ my $yaml_content = CPAN->_yaml_loadfile($yaml);
+ my $id = $yaml_content->[0]{distribution}{ID};
unless ($id){
$CPAN::Frontend->mywarn("No ID found in '$yaml', skipping\n");
next;
@@ -2442,11 +2506,11 @@ sub status {
}
}
-# experimental (must run after failed or similar [I think])
-# intended as a preparation ot install_tested
+# compare with install_tested
#-> sub CPAN::Shell::is_tested
-sub _is_tested {
+sub is_tested {
my($self) = @_;
+ CPAN::Index->reload;
for my $b (reverse $CPAN::META->_list_sorted_descending_is_tested) {
my $time;
if ($CPAN::META->{is_tested}{$b}) {
@@ -2727,7 +2791,7 @@ sub print_ornamented {
my $color_on = eval { Term::ANSIColor::color($ornament) } || "";
if ($@) {
print "Term::ANSIColor rejects color[$ornament]: $@\n
-Please choose a different color (Hint: try 'o conf init color.*')\n";
+Please choose a different color (Hint: try 'o conf init /color/')\n";
}
print $color_on,
$swhat,
@@ -2819,6 +2883,7 @@ sub unrecoverable_error {
#-> sub CPAN::Shell::mysleep ;
sub mysleep {
my($self, $sleep) = @_;
+ use Time::HiRes qw(sleep);
sleep $sleep;
}
@@ -2861,6 +2926,8 @@ sub rematein {
# enter the queue but not its copy. How do they get a sensible
# test_count?
+ my $needs_recursion_protection = "make|test|install";
+
# construct the queue
my($s,@s,@qcopy);
STHING: foreach $s (@some) {
@@ -2887,7 +2954,10 @@ sub rematein {
}
if (0) {
} elsif (ref $obj) {
- $obj->color_cmd_tmps(0,1);
+ if ($meth =~ /^($needs_recursion_protection)$/) {
+ # silly for look or dump
+ $obj->color_cmd_tmps(0,1);
+ }
CPAN::Queue->new(qmod => $obj->id, reqtype => "c");
push @qcopy, $obj;
} elsif ($CPAN::META->exists('CPAN::Author',uc($s))) {
@@ -2927,6 +2997,15 @@ to find objects with matching identifiers.
my $s = $q->as_string;
my $reqtype = $q->reqtype || "";
$obj = CPAN::Shell->expandany($s);
+ unless ($obj) {
+ # don't know how this can happen, maybe we should panic,
+ # but maybe we get a solution from the first user who hits
+ # this unfortunate exception?
+ $CPAN::Frontend->mywarn("Warning: Could not expand string '$s' ".
+ "to an object. Skipping.");
+ $CPAN::Frontend->mysleep(5);
+ next;
+ }
$obj->{reqtype} ||= "";
{
# force debugging because CPAN::SQLite somehow delivers us
@@ -3002,8 +3081,10 @@ to find objects with matching identifiers.
}
CPAN::Queue->delete_first($s);
}
- for my $obj (@qcopy) {
- $obj->color_cmd_tmps(0,0);
+ if ($meth =~ /^($needs_recursion_protection)$/) {
+ for my $obj (@qcopy) {
+ $obj->color_cmd_tmps(0,0);
+ }
}
}
@@ -3233,6 +3314,7 @@ sub _new_stats {
sub _add_to_statistics {
my($self,$stats) = @_;
my $yaml_module = CPAN::_yaml_module;
+ $self->debug("yaml_module[$yaml_module]") if $CPAN::DEBUG;
if ($CPAN::META->has_inst($yaml_module)) {
$stats->{thesiteurl} = $ThesiteURL;
if (CPAN->has_inst("Time::HiRes")) {
@@ -3254,7 +3336,7 @@ sub _add_to_statistics {
# arbitrary hardcoded constants until somebody demands to have
# them settable
while (
- @{$fullstats->{history}} > 9999
+ @{$fullstats->{history}} > 999
|| $time - $fullstats->{history}[0]{start} > 30*86400 # one month
) {
shift @{$fullstats->{history}}
@@ -3563,7 +3645,9 @@ sub localize {
if ($ret) {
$stats->{filesize} = -s $ret;
}
+ $self->debug("before _add_to_statistics") if $CPAN::DEBUG;
$self->_add_to_statistics($stats);
+ $self->debug("after _add_to_statistics") if $CPAN::DEBUG;
if ($ret) {
unlink "$aslocal.bak$$";
return $ret;
@@ -4202,7 +4286,7 @@ sub cpl {
$pos ||= 0;
CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
$line =~ s/^\s*//;
- if ($line =~ s/^(force\s*)//) {
+ if ($line =~ s/^((?:notest|f?force)\s*)//) {
$pos -= length($1);
}
my @return;
@@ -5372,7 +5456,11 @@ sub pretty_id {
substr($id,5);
}
-# mark as dirty/clean
+# mark as dirty/clean for the sake of recursion detection. $color=1
+# means "in use", $color=0 means "not in use anymore". $color=2 means
+# we have determined prereqs now and thus insist on passing this
+# through (at least) once again.
+
#-> sub CPAN::Distribution::color_cmd_tmps ;
sub color_cmd_tmps {
my($self) = shift;
@@ -5382,8 +5470,9 @@ sub color_cmd_tmps {
# a distribution needs to recurse into its prereq_pms
return if exists $self->{incommandcolor}
+ && $color==1
&& $self->{incommandcolor}==$color;
- if ($depth>=100){
+ if ($depth>=$CPAN::MAX_RECURSION){
$CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
}
# warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
@@ -5407,7 +5496,7 @@ sub color_cmd_tmps {
# as we are at the end of a command, we'll give up this
# reminder of a broken test. Other commands may test this guy
# again. Maybe 'badtestcnt' should be renamed to
- # 'makte_test_failed_within_command'?
+ # 'make_test_failed_within_command'?
delete $self->{badtestcnt};
}
$self->{incommandcolor} = $color;
@@ -5745,8 +5834,10 @@ EOF
my $prefer_installer = "eumm"; # eumm|mb
if (-f File::Spec->catfile($packagedir,"Build.PL")) {
if ($mpl_exists) { # they *can* choose
- $prefer_installer = CPAN::HandleConfig->prefs_lookup($self,
- q{prefer_installer});
+ if ($CPAN::META->has_inst("Module::Build")) {
+ $prefer_installer = CPAN::HandleConfig->prefs_lookup($self,
+ q{prefer_installer});
+ }
} else {
$prefer_installer = "mb";
}
@@ -7190,6 +7281,13 @@ sub _find_prefs {
# CPAN::Distribution::prefs
sub prefs {
my($self) = @_;
+ if (exists $self->{negative_prefs_cache}
+ &&
+ $self->{negative_prefs_cache} != $CPAN::CurrentCommandId
+ ) {
+ delete $self->{negative_prefs_cache};
+ delete $self->{prefs};
+ }
if (exists $self->{prefs}) {
return $self->{prefs}; # XXX comment out during debugging
}
@@ -7219,7 +7317,8 @@ $filler2 $bs $filler2
return $self->{prefs};
}
}
- return +{};
+ $self->{negative_prefs_cache} = $CPAN::CurrentCommandId;
+ return $self->{prefs} = +{};
}
# CPAN::Distribution::make_x_arg
@@ -7280,6 +7379,7 @@ sub follow_prereqs {
c => "commandline",
);
my($filler1,$filler2,$filler3,$filler4);
+ # $DB::single=1;
my $unsat = "Unsatisfied dependencies detected during";
my $w = length($unsat) > length($pretty_id) ? length($unsat) : length($pretty_id);
{
@@ -7319,7 +7419,7 @@ of modules we are processing right now?", "yes");
# warn "calling color_cmd_tmps(0,1)";
my $any = CPAN::Shell->expandany($p);
if ($any) {
- $any->color_cmd_tmps(0,1);
+ $any->color_cmd_tmps(0,2);
} else {
$CPAN::Frontend->mywarn("Warning (maybe a bug): Cannot expand prereq '$p'\n");
$CPAN::Frontend->mysleep(2);
@@ -7341,19 +7441,21 @@ sub unsat_prereq {
my $prereq_pm = $self->prereq_pm or return;
my(@need);
my %merged = (%{$prereq_pm->{requires}||{}},%{$prereq_pm->{build_requires}||{}});
+ my @merged = %merged;
+ CPAN->debug("all merged_prereqs[@merged]") if $CPAN::DEBUG;
NEED: while (my($need_module, $need_version) = each %merged) {
- my($available_version,$available_file);
+ my($available_version,$available_file,$nmo);
if ($need_module eq "perl") {
$available_version = $];
$available_file = $^X;
} else {
- my $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
+ $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
next if $nmo->uptodate;
$available_file = $nmo->available_file;
# if they have not specified a version, we accept any installed one
if (not defined $need_version or
- $need_version eq "0" or
+ $need_version == 0 or
$need_version eq "undef") {
next if defined $available_file;
}
@@ -7410,13 +7512,71 @@ sub unsat_prereq {
}
if ($self->{sponsored_mods}{$need_module}++){
# We have already sponsored it and for some reason it's still
- # not available. So we do nothing. Or what should we do?
+ # not available. So we do ... what??
+
# if we push it again, we have a potential infinite loop
- next;
+
+ # The following "next" was a very problematic construct.
+ # It helped a lot but broke some day and must be replaced.
+
+ # We must be able to deal with modules that come again and
+ # again as a prereq and have themselves prereqs and the
+ # queue becomes long but finally we would find the correct
+ # order. The RecursiveDependency check should trigger a
+ # die when it's becoming too weird. Unfortunately removing
+ # this next breaks many other things.
+
+ # The bug that brought this up is described in Todo under
+ # "5.8.9 cannot install Compress::Zlib"
+
+ # next; # this is the next that must go away
+
+ # The following "next NEED" are fine and the error message
+ # explains well what is going on. For example when the DBI
+ # fails and consequently DBD::SQLite fails and now we are
+ # processing CPAN::SQLite. Then we must have a "next" for
+ # DBD::SQLite. How can we get it and how can we identify
+ # all other cases we must identify?
+
+ my $do = $nmo->distribution;
+ next NEED unless $do; # not on CPAN
+ NOSAYER: for my $nosayer (
+ "unwrapped",
+ "writemakefile",
+ "signature_verify",
+ "make",
+ "make_test",
+ "install",
+ "make_clean",
+ ) {
+ if (
+ $do->{$nosayer}
+ &&(UNIVERSAL::can($do->{$nosayer},"failed") ?
+ $do->{$nosayer}->failed :
+ $do->{$nosayer} =~ /^NO/)
+ ) {
+ if ($nosayer eq "make_test"
+ &&
+ $do->{make_test}{COMMANDID} != $CPAN::CurrentCommandId
+ ) {
+ next NOSAYER;
+ }
+ $CPAN::Frontend->mywarn("Warning: Prerequisite ".
+ "'$need_module => $need_version' ".
+ "for '$self->{ID}' failed when ".
+ "processing '$do->{ID}' with ".
+ "'$nosayer => $do->{$nosayer}'. Continuing, ".
+ "but chances to succeed are limited.\n"
+ );
+ next NEED;
+ }
+ }
}
my $needed_as = exists $prereq_pm->{requires}{$need_module} ? "r" : "b";
push @need, [$need_module,$needed_as];
}
+ my @unfolded = map { "[".join(",",@$_)."]" } @need;
+ CPAN->debug("returning from unsat_prereq[@unfolded]") if $CPAN::DEBUG;
@need;
}
@@ -7437,6 +7597,7 @@ sub read_yaml {
# cannot read YAML's own
# META.yml
}
+ # not "authoritative"
if (not exists $self->{yaml_content}{dynamic_config}
or $self->{yaml_content}{dynamic_config}
) {
@@ -7451,7 +7612,7 @@ sub read_yaml {
sub prereq_pm {
my($self) = @_;
$self->{prereq_pm_detected} ||= 0;
- CPAN->debug("prereq_pm_detected[$self->{prereq_pm_detected}]") if $CPAN::DEBUG;
+ CPAN->debug("ID[$self->{ID}]prereq_pm_detected[$self->{prereq_pm_detected}]") if $CPAN::DEBUG;
return $self->{prereq_pm} if $self->{prereq_pm_detected};
return unless $self->{writemakefile} # no need to have succeeded
# but we must have run it
@@ -7516,13 +7677,17 @@ sub prereq_pm {
# Regexp modified by A.Speer to remember actual version of file
# PREREQ_PM hash key wants, then add to
- while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
+ while ( $p =~ m/(?:\s)([\w\:]+)=>(q\[.*?\]|undef),?/g ){
# In case a prereq is mentioned twice, complain.
if ( defined $req->{$1} ) {
warn "Warning: PREREQ_PM mentions $1 more than once, ".
"last mention wins";
}
- $req->{$1} = $2;
+ my($m,$n) = ($1,$2);
+ if ($n =~ /^q\[(.*?)\]$/) {
+ $n = $1;
+ }
+ $req->{$m} = $n;
}
last;
}
@@ -7597,11 +7762,17 @@ sub test {
local $ENV{MAKEFLAGS}; # protect us from outer make calls
$CPAN::Frontend->myprint("Running $make test\n");
- if (my @prereq = $self->unsat_prereq){
- unless ($prereq[0][0] eq "perl") {
- return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
- }
- }
+
+# if (my @prereq = $self->unsat_prereq){
+# if ( $CPAN::DEBUG ) {
+# require Data::Dumper;
+# CPAN->debug(sprintf "unsat_prereq[%s]", Data::Dumper::Dumper(\@prereq));
+# }
+# unless ($prereq[0][0] eq "perl") {
+# return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
+# }
+# }
+
EXCUSE: {
my @e;
unless (exists $self->{make} or exists $self->{later}) {
@@ -7617,8 +7788,11 @@ sub test {
) and push @e, "Can't test without successful make";
$self->{badtestcnt} ||= 0;
- $self->{badtestcnt} > 0 and
+ if ($self->{badtestcnt} > 0) {
+ require Data::Dumper;
+ CPAN->debug(sprintf "NOREPEAT[%s]", Data::Dumper::Dumper($self)) if $CPAN::DEBUG;
push @e, "Won't repeat unsuccessful test during this command";
+ }
exists $self->{later} and length($self->{later}) and
push @e, $self->{later};
@@ -7672,6 +7846,11 @@ sub test {
} else {
$system = join " ", $self->_make_command(), "test";
}
+ my $make_test_arg = $self->make_x_arg("test");
+ $system = sprintf("%s%s",
+ $system,
+ $make_test_arg ? " $make_test_arg" : "",
+ );
my($tests_ok);
my %env;
while (my($k,$v) = each %ENV) {
@@ -7750,7 +7929,7 @@ sub test {
# local $CPAN::DEBUG = 16; # Distribution
for my $m (keys %{$self->{sponsored_mods}}) {
- my $m_obj = CPAN::Shell->expand("Module",$m);
+ my $m_obj = CPAN::Shell->expand("Module",$m) or next;
# XXX we need available_version which reflects
# $ENV{PERL5LIB} so that already tested but not yet
# installed modules are counted.
@@ -7917,7 +8096,10 @@ sub install {
if (my $goto = $self->prefs->{goto}) {
return $self->goto($goto);
}
- $self->test;
+ $DB::single=1;
+ unless ($self->{badtestcnt}) {
+ $self->test;
+ }
if ($CPAN::Signal){
delete $self->{force_update};
return;
@@ -8333,8 +8515,9 @@ sub color_cmd_tmps {
# to recurse into its prereq_pms, a bundle needs to recurse into its modules
return if exists $self->{incommandcolor}
+ && $color==1
&& $self->{incommandcolor}==$color;
- if ($depth>=100){
+ if ($depth>=$CPAN::MAX_RECURSION){
$CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
}
# warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
@@ -8522,62 +8705,6 @@ Going to $meth that.
my $obj = $CPAN::META->instance($type,$s);
$obj->{reqtype} = $self->{reqtype};
$obj->$meth();
- if ($obj->isa('CPAN::Bundle')
- &&
- exists $obj->{install_failed}
- &&
- ref($obj->{install_failed}) eq "HASH"
- ) {
- for (keys %{$obj->{install_failed}}) {
- $self->{install_failed}{$_} = undef; # propagate faiure up
- # to me in a
- # recursive call
- $fail{$s} = 1; # the bundle itself may have succeeded but
- # not all children
- }
- } else {
- my $success;
- $success = $obj->can("uptodate") ? $obj->uptodate : 0;
- $success ||= $obj->{install} && $obj->{install} eq "YES";
- if ($success) {
- delete $self->{install_failed}{$s};
- } else {
- $fail{$s} = 1;
- }
- }
- }
-
- # recap with less noise
- if ( $meth eq "install" ) {
- if (%fail) {
- require Text::Wrap;
- my $raw = sprintf(qq{Bundle summary:
-The following items in bundle %s had installation problems:},
- $self->id
- );
- $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
- $CPAN::Frontend->myprint("\n");
- my $paragraph = "";
- my %reported;
- for $s ($self->contains) {
- if ($fail{$s}){
- $paragraph .= "$s ";
- $self->{install_failed}{$s} = undef;
- $reported{$s} = undef;
- }
- }
- my $report_propagated;
- for $s (sort keys %{$self->{install_failed}}) {
- next if exists $reported{$s};
- $paragraph .= "and the following items had problems
-during recursive bundle calls: " unless $report_propagated++;
- $paragraph .= "$s ";
- }
- $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
- $CPAN::Frontend->myprint("\n");
- } else {
- $self->{install} = 'YES';
- }
}
}
@@ -8675,9 +8802,41 @@ sub color_cmd_tmps {
# a module needs to recurse to its cpan_file
return if exists $self->{incommandcolor}
+ && $color==1
&& $self->{incommandcolor}==$color;
- return if $depth>=1 && $self->uptodate;
- if ($depth>=100){
+ return if $color==0 && !$self->{incommandcolor};
+ if ($color>=1) {
+ if ( $self->uptodate ) {
+ $self->{incommandcolor} = $color;
+ return;
+ } elsif (my $have_version = $self->available_version) {
+ # maybe what we have is good enough
+ if (@$ancestors) {
+ my $who_asked_for_me = $ancestors->[-1];
+ my $obj = CPAN::Shell->expandany($who_asked_for_me);
+ if (0) {
+ } elsif ($obj->isa("CPAN::Bundle")) {
+ # bundles cannot specify a minimum version
+ return;
+ } elsif ($obj->isa("CPAN::Distribution")) {
+ if (my $prereq_pm = $obj->prereq_pm) {
+ for my $k (keys %$prereq_pm) {
+ if (my $want_version = $prereq_pm->{$k}{$self->id}) {
+ if (CPAN::Version->vcmp($have_version,$want_version) >= 0) {
+ $self->{incommandcolor} = $color;
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ $self->{incommandcolor} = $color; # set me before recursion,
+ # so we can break it
+ }
+ if ($depth>=$CPAN::MAX_RECURSION){
$CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
}
# warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
@@ -8735,17 +8894,22 @@ sub as_glimpse {
sub dslip_status {
my($self) = @_;
my($stat);
+ # development status
@{$stat->{D}}{qw,i c a b R M S,} = qw,idea
pre-alpha alpha beta released
mature standard,;
+ # support level
@{$stat->{S}}{qw,m d u n a,} = qw,mailing-list
developer comp.lang.perl.*
none abandoned,;
+ # language
@{$stat->{L}}{qw,p c + o h,} = qw,perl C C++ other hybrid,;
+ # interface
@{$stat->{I}}{qw,f r O p h n,} = qw,functions
references+ties
object-oriented pragma
hybrid none,;
+ # public licence
@{$stat->{P}}{qw,p g l b a o d r n,} = qw,Standard-Perl
GPL LGPL
BSD Artistic
@@ -9213,11 +9377,13 @@ CPAN - query, download and build perl modules from CPAN sites
Interactive mode:
- perl -MCPAN -e shell;
+ perl -MCPAN -e shell
+
+--or--
-Batch mode:
+ cpan
- use CPAN;
+Basic commands:
# Modules:
@@ -9246,14 +9412,13 @@ Batch mode:
=head1 DESCRIPTION
-The CPAN module is designed to automate the make and install of perl
-modules and extensions. It includes some primitive searching
-capabilities and knows how to use Net::FTP or LWP (or some external
-download clients) to fetch the raw data from the net.
+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 or LWP or some external
+download clients to fetch the distributions from the net.
-Distributions are fetched from one or more of the mirrored CPAN
-(Comprehensive Perl Archive Network) sites and unpacked in a dedicated
-directory.
+These are fetched from one or more of the mirrored CPAN (Comprehensive
+Perl Archive Network) sites and unpacked in a dedicated directory.
The CPAN module also supports the concept of named and versioned
I<bundles> of modules. Bundles simplify the handling of sets of
@@ -9274,11 +9439,15 @@ The interactive mode is entered by running
perl -MCPAN -e shell
-which puts you into a readline interface. If Term::ReadKey and either
-Term::ReadLine::Perl or Term::ReadLine::Gnu are installed it supports
-both history and command completion.
+or
+
+ cpan
+
+which puts you into a readline interface. If C<Term::ReadKey> and
+either C<Term::ReadLine::Perl> or C<Term::ReadLine::Gnu> are installed
+it supports both history and command completion.
-Once you are on the command line, type 'h' to get a one page help
+Once you are on the command line, type C<h> to get a one page help
screen and the rest should be self-explanatory.
The function call C<shell> takes two optional arguments, one is the
@@ -9308,7 +9477,7 @@ displayed with the rather verbose method C<as_string>, but if we find
more than one, we display each object with the terse method
C<as_glimpse>.
-=item get, make, test, install, clean modules or distributions
+=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. If the argument is a distribution
@@ -9341,7 +9510,7 @@ 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>) and executes the command from scratch
and tries to continue in case of some errors. See the section below on
-The C<force> and the C<fforce> pragma.
+the C<force> and the C<fforce> pragma.
The C<notest> pragma may be used to skip the test part in the build
process.
@@ -9356,7 +9525,7 @@ A C<clean> command results in a
being executed within the distribution file's working directory.
-=item readme, perldoc, look module or distribution
+=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,
@@ -9364,9 +9533,9 @@ changes to the appropriate directory and opens a subshell process in
that directory. C<perldoc> displays the pod documentation of the
module in html or plain text format.
-=item ls author
+=item C<ls> author
-=item ls globbing_expression
+=item C<ls> globbing_expression
The first form lists all distribution files in and below an author's
CPAN directory as they are stored in the CHECKUMS files distributed on
@@ -9386,7 +9555,7 @@ 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 and may be changed in future versions.
-=item failed
+=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
@@ -9585,6 +9754,631 @@ module or not.
The typical usage case is for private modules or working copies of
projects from remote repositories on the local disk.
+=head1 CONFIGURATION
+
+When the CPAN module is used for the first time, a configuration
+dialog 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.
+
+The 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 $HOME/.cpan/CPAN/MyConfig.pm, because $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
+
+=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 according
+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
+
+Currently the following keys in the hash reference $CPAN::Config are
+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
+ commands_quote prefered 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
+ 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
+ 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
+ getcwd see below
+ gpg path to external prg
+ gzip location of external program gzip
+ 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
+ never break.
+ index_expire after this many days refetch index files
+ inhibit_startup_message
+ if true, does not print the startup message
+ keep_source_where directory in which to keep the source (if we do)
+ 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
+ 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 in any case
+ 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_upload_date boolean if commands should try to determine upload date
+ tar location of external program tar
+ term_is_latin if true internal UTF-8 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)
+ 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
+ wait_list arrayref to a wait server to try (See CPAN::WAIT)
+ wget path to external prg
+ 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. Per default it uses
+Cwd::cwd but if this doesn't work on your system for some reason,
+alternatives can be configured 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 that are to be used for downloading. If the list contains any
+C<file> URLs, CPAN always tries to get files from 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 if 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 to set the
+C<randomize_urllist> parameter that 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 being
+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 the CPAN usually behave according to what we call the
+CPAN mantra. Or since the event 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
+
+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 single document is treated as an entity that
+can specify the treatment of a single distribution.
+
+The names of the files can be picked freely, 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 the 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-"
+ perl: "/usr/local/cariba-perl/bin/perl"
+ 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: []
+
+ commendline: "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"
+
+
+=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 disabled [boolean]
+
+Specifies that this distribution shall not be processed at all.
+
+=item goto [string]
+
+The canonical name of a delegate distribution that shall be installed
+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<Processiong Instructions>.
+
+=item make [hash]
+
+Processing instructions for the C<make> or C<./Build> phase of the
+CPAN mantra. See below under I<Processiong Instructions>.
+
+=item match [hash]
+
+A hashref with one or more of the keys C<distribution>, C<modules>, or
+C<perl> that specify if a document is targeted at a specific CPAN
+distribution.
+
+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>.
+
+If more than one restriction of C<module>, C<distribution>, and
+C<perl> is specified, the results of the separately computed match
+values must all match. If this is the case then 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 the external patch program. If the value for the C<-p>
+parameter is C<0> or C<1> is determined by reading the patch
+beforehand.
+
+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<Processiong
+Instructions>.
+
+=item test [hash]
+
+Processing instructions for the C<make test> or C<./Build test> phase
+of the CPAN mantra. See below under I<Processiong Instructions>.
+
+=back
+
+=head2 Processing Instructions
+
+=over
+
+=item args [array]
+
+Arguments to be added to the command line
+
+=item commandline
+
+A full commandline that will be executed as it stands by a system
+call. During the execution the environment variable PERL will is set
+to $^X. If C<commandline> is specified, the content of C<args> is not
+used.
+
+=item eexpect [hash]
+
+Extended C<expect>. This is a hash reference with three allowed keys,
+C<mode>, C<timeout>, and C<talk>.
+
+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. In the case of a C<mode=deterministic> the timeout denotes the
+timeout per question, in the case of 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 will then watch the stream coming from the
+execution of the external program (C<perl Makefile.PL>, C<perl
+Build.PL>, C<make>, etc.).
+
+In the case of C<mode=deterministic> the CPAN.pm will inject the
+according answer as soon as the stream matches the regular expression.
+In the case of C<mode=anyorder> the CPAN.pm will answer a question as
+soon as the timeout is reached for the next byte in the input stream.
+In the latter case it removes the according question/answer pair from
+the array, so 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.
+
+=item env [hash]
+
+Environment variables to be set during the command
+
+=item expect [array]
+
+C<< expect: <array> >> is a short notation for
+
+ 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
+syntactical 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 beend warned:-)
+
=head1 PROGRAMMER'S INTERFACE
If you do not enter the shell, the available shell commands are both
@@ -9836,6 +10630,11 @@ its dependencies, use CPAN::Shell->install.
Note that install() gives no meaningful return value. See uptodate().
+=item CPAN::Distribution::install_tested()
+
+Install all the distributions that have been 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.
@@ -9843,6 +10642,11 @@ 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::is_tested()
+
+List all the distributions that have been tested sucessfully but not
+yet installed. See also C<install_tested>.
+
=item CPAN::Distribution::look()
Changes to the directory where the distribution has been unpacked and
@@ -9880,10 +10684,13 @@ attributes are optional.
=item CPAN::Distribution::prereq_pm()
Returns the hash reference that has been announced by a distribution
-as the merge of the C<requires> element and the C<build_requires>
-element of the META.yml or the C<PREREQ_PM> hash in the
-C<Makefile.PL>. Note: works only after an attempt has been made to
-C<make> the distribution. Returns undef otherwise.
+as the 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()
@@ -9895,7 +10702,8 @@ through the pager specified in C<$CPAN::Config->{pager}>.
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 dynamic.
+is not authoritative. (The rules about what exactly makes the content
+authoritative are still in flux.)
=item CPAN::Distribution::test()
@@ -10276,326 +11084,6 @@ method returns the object, otherwise it calls the constructor.
=back
-=head1 CONFIGURATION
-
-When the CPAN module is used for the first time, a configuration
-dialog 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.
-
-The 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 $HOME/.cpan/CPAN/MyConfig.pm, because $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
-
-=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 according
-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 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/
-
-=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
-
-Currently the following keys in the hash reference $CPAN::Config are
-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
- commands_quote prefered 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
- 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
- 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
- getcwd see below
- gpg path to external prg
- gzip location of external program gzip
- 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
- never break.
- index_expire after this many days refetch index files
- inhibit_startup_message
- if true, does not print the startup message
- keep_source_where directory in which to keep the source (if we do)
- 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
- 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 in any case
- 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_upload_date boolean if commands should try to determine upload date
- tar location of external program tar
- term_is_latin if true internal UTF-8 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)
- 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
- wait_list arrayref to a wait server to try (See CPAN::WAIT)
- wget path to external prg
- 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 command set defined within the C<o conf> command:
-
-=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.
-
-=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. Per default it uses
-Cwd::cwd but if this doesn't work on your system for some reason,
-alternatives can be configured according to the following table:
-
-=over 2
-
-=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 urllist parameter has CD-ROM support
-
-The C<urllist> parameter of the configuration table contains a list of
-URLs that are to be used for downloading. If the list contains any
-C<file> URLs, CPAN always tries to get files from 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 if 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 to set the
-C<randomize_urllist> parameter that introduces some amount of
-randomness into the URL selection.
-
-=head2 prefs_dir for avoiding interactive questions (ALPHA)
-
-(B<Note:> This feature has been introduced in CPAN.pm 1.8854 and is
-still considered experimental and may still be changed)
-
-The files in the directory specified in C<prefs_dir> are YAML files
-that specify how CPAN.pm shall treat distributions that deviate from
-the normal non-interactive model of building and installing CPAN
-modules.
-
-Some modules try to get some data from the user interactively thus
-disturbing the installation of large bundles like Phalanx100 or
-modules like Plagger.
-
-CPAN.pm can use YAML files to either pass additional arguments to one
-of the four commands, set environment variables or instantiate an
-Expect object that reads from the console and enters answers on your
-behalf (latter option requires Expect.pm installed). A further option
-is to apply patches from the local disk or from CPAN.
-
-CPAN.pm comes with a couple of such YAML files. The structure is
-currently not documented because in flux. Please see the distroprefs
-directory of the CPAN distribution for examples and follow the
-C<00.README> file in there.
-
-Please note that setting the environment variable PERL_MM_USE_DEFAULT
-to a true value can also get you a long way if you want to always pick
-the default answers. But this only works if the author of a package
-used the prompt function provided by ExtUtils::MakeMaker and if the
-defaults are OK for you.
-
=head1 SECURITY
There's no strong security layer in CPAN.pm. CPAN.pm helps you to