# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
use strict;
package CPAN;
-$CPAN::VERSION = '1.88_76';
-$CPAN::VERSION = eval $CPAN::VERSION;
+$CPAN::VERSION = '1.9102';
+$CPAN::VERSION = eval $CPAN::VERSION if $CPAN::VERSION =~ /_/;
use CPAN::HandleConfig;
use CPAN::Version;
BEGIN {
if (File::Spec->can("rel2abs")) {
for my $inc (@INC) {
- $inc = File::Spec->rel2abs($inc);
+ $inc = File::Spec->rel2abs($inc) unless ref $inc;
}
}
}
require Mac::BuildTools if $^O eq 'MacOS';
$ENV{PERL5_CPAN_IS_RUNNING}=1;
+$ENV{PERL5_CPANPLUS_IS_RUNNING}=1; # https://rt.cpan.org/Ticket/Display.html?id=23735
END { $CPAN::End++; &cleanup; }
$CONFIG_DIRTY
$Defaultdocs
$Defaultrecent
+ $Echo_readline
$Frontend
$GOTOSHELL
$HAS_USABLE
$try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
my $rl_avail = $Suppress_readline ? "suppressed" :
($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
- "available (try 'install Bundle::CPAN')";
+ "available (maybe install Bundle::CPAN or Bundle::CPANxxl?)";
unless ($CPAN::Config->{'inhibit_startup_message'}){
$CPAN::Frontend->myprint(
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
# $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;
}
recompile
reload
report
+ reports
scripts
test
upgrade
sub new {
my($class) = shift;
my($deps) = shift;
- my @deps;
- my %seen;
- for my $dep (@$deps) {
- push @deps, $dep;
- last if $seen{$dep}++;
+ my (@deps,%seen,$loop_starts_with);
+ DCHAIN: for my $dep (@$deps) {
+ push @deps, {name => $dep, display_as => $dep};
+ if ($seen{$dep}++){
+ $loop_starts_with = $dep;
+ last DCHAIN;
+ }
+ }
+ my $in_loop = 0;
+ for my $i (0..$#deps) {
+ my $x = $deps[$i]{name};
+ $in_loop ||= $x eq $loop_starts_with;
+ my $xo = CPAN::Shell->expandany($x) or next;
+ if ($xo->isa("CPAN::Module")) {
+ my $have = $xo->inst_version || "N/A";
+ my($want,$d,$want_type);
+ if ($i>0 and $d = $deps[$i-1]{name}) {
+ my $do = CPAN::Shell->expandany($d);
+ $want = $do->{prereq_pm}{requires}{$x};
+ if (defined $want) {
+ $want_type = "requires: ";
+ } else {
+ $want = $do->{prereq_pm}{build_requires}{$x};
+ if (defined $want) {
+ $want_type = "build_requires: ";
+ } else {
+ $want_type = "unknown status";
+ $want = "???";
+ }
+ }
+ } else {
+ $want = $xo->cpan_version;
+ $want_type = "want: ";
+ }
+ $deps[$i]{have} = $have;
+ $deps[$i]{want_type} = $want_type;
+ $deps[$i]{want} = $want;
+ $deps[$i]{display_as} = "$x (have: $have; $want_type$want)";
+ } elsif ($xo->isa("CPAN::Distribution")) {
+ $deps[$i]{display_as} = $xo->pretty_id;
+ if ($in_loop) {
+ $xo->{make} = CPAN::Distrostatus->new("NO cannot resolve circular dependency");
+ } else {
+ $xo->{make} = CPAN::Distrostatus->new("NO one dependency ($loop_starts_with) is a circular dependency");
+ }
+ $xo->store_persistent_state; # otherwise I will not reach
+ # all involved parties for
+ # the next session
+ }
}
bless { deps => \@deps }, $class;
}
sub as_string {
my($self) = shift;
- "\nRecursive dependency detected:\n " .
- join("\n => ", @{$self->{deps}}) .
- ".\nCannot continue.\n";
+ my $ret = "\nRecursive dependency detected:\n ";
+ $ret .= join("\n => ", map {$_->{display_as}} @{$self->{deps}});
+ $ret .= ".\nCannot resolve.\n";
+ $ret;
}
package CPAN::Exception::yaml_not_installed;
use overload '""' => "as_string";
sub new {
- my($class,$module,$file,$during,$error) = shift;
+ my($class,$module,$file,$during,$error) = @_;
bless { module => $module,
file => $file,
during => $during,
sub as_string {
my($self) = shift;
- "Alert: While trying to $self->{during} YAML file\n".
- " $self->{file}\n".
- "with '$self->{module}' the following error was encountered:\n".
- " $self->{error}\n";
+ if ($self->{during}) {
+ if ($self->{file}) {
+ if ($self->{module}) {
+ if ($self->{error}) {
+ return "Alert: While trying to '$self->{during}' YAML file\n".
+ " '$self->{file}'\n".
+ "with '$self->{module}' the following error was encountered:\n".
+ " $self->{error}\n";
+ } else {
+ return "Alert: While trying to '$self->{during}' YAML file\n".
+ " '$self->{file}'\n".
+ "with '$self->{module}' some unknown error was encountered\n";
+ }
+ } else {
+ return "Alert: While trying to '$self->{during}' YAML file\n".
+ " '$self->{file}'\n".
+ "some unknown error was encountered\n";
+ }
+ } else {
+ return "Alert: While trying to '$self->{during}' some YAML file\n".
+ "some unknown error was encountered\n";
+ }
+ } else {
+ return "Alert: unknown error encountered\n";
+ }
}
package CPAN::Prompt; use overload '""' => "as_string";
my($self) = @_;
return unless $CPAN::META->{LOCK};
return unless -d $self->{ID};
- while ($self->{DU} > $self->{'MAX'} ) {
- my($toremove) = shift @{$self->{FIFO}};
- unless ($toremove =~ /\.yml$/) {
- $CPAN::Frontend->myprint(sprintf(
- "DEL(%.1f>%.1fMB): %s \n",
- $self->{DU},
- $self->{MAX},
- $toremove,
- )
- );
- }
+ my @toremove = grep { $self->{SIZE}{$_}==0 } @{$self->{FIFO}};
+ for my $current (0..$#toremove) {
+ my $toremove = $toremove[$current];
+ $CPAN::Frontend->myprint(sprintf(
+ "DEL(%d/%d): %s \n",
+ $current+1,
+ scalar @toremove,
+ $toremove,
+ )
+ );
return if $CPAN::Signal;
$self->_clean_cache($toremove);
return if $CPAN::Signal;
}
}
chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
- sort { -M $b <=> -M $a} @entries;
+ sort { -M $a <=> -M $b} @entries;
}
#-> sub CPAN::CacheMgr::disk_usage ;
sub disk_usage {
- my($self,$dir) = @_;
+ my($self,$dir,$fast) = @_;
return if exists $self->{SIZE}{$dir};
return if $CPAN::Signal;
my($Du) = 0;
if (-e $dir) {
- unless (-x $dir) {
- unless (chmod 0755, $dir) {
- $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
- "permission to change the permission; cannot ".
- "estimate disk usage of '$dir'\n");
- $CPAN::Frontend->mysleep(5);
- return;
+ if (-d $dir) {
+ unless (-x $dir) {
+ unless (chmod 0755, $dir) {
+ $CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
+ "permission to change the permission; cannot ".
+ "estimate disk usage of '$dir'\n");
+ $CPAN::Frontend->mysleep(5);
+ return;
+ }
}
+ } elsif (-f $dir) {
+ # nothing to say, no matter what the permissions
}
} else {
- $CPAN::Frontend->mywarn("Directory '$dir' has gone. Cannot continue.\n");
+ $CPAN::Frontend->mywarn("File or directory '$dir' has gone, ignoring\n");
return;
}
- find(
- sub {
+ if ($fast) {
+ $Du = 0; # placeholder
+ } else {
+ find(
+ sub {
$File::Find::prune++ if $CPAN::Signal;
return if -l $_;
if ($^O eq 'MacOS') {
}
},
$dir
- );
+ );
+ }
return if $CPAN::Signal;
$self->{SIZE}{$dir} = $Du/1024/1024;
- push @{$self->{FIFO}}, $dir;
+ unshift @{$self->{FIFO}}, $dir;
$self->debug("measured $dir is $Du") if $CPAN::DEBUG;
$self->{DU} += $Du/1024/1024;
$self->{DU};
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}) {
+ my($peek_yaml) = eval { CPAN->_yaml_loadfile("$dir.yml"); };
+ if ($@) {
+ $CPAN::Frontend->mywarn("(parse error on '$dir.yml' removing anyway)");
+ unlink "$dir.yml" or
+ $CPAN::Frontend->mywarn("(Could not unlink '$dir.yml': $!)");
+ return;
+ } elsif (my $id = $peek_yaml->[0]{distribution}{ID}) {
$CPAN::META->delete("CPAN::Distribution", $id);
+
+ # XXX we should restore the state NOW, otherise this
+ # distro does not exist until we read an index. BUG ALERT(?)
+
# $CPAN::Frontend->mywarn (" +++\n");
$id_deleted++;
}
sprintf("Scanning cache %s for sizes\n",
$self->{ID}));
my $e;
- my @entries = grep { !/^\.\.?$/ } $self->entries($self->{ID});
+ my @entries = $self->entries($self->{ID});
my $i = 0;
my $painted = 0;
for $e (@entries) {
- # next if $e eq ".." || $e eq ".";
- $self->disk_usage($e);
+ my $symbol = ".";
+ if ($self->{DU} > $self->{MAX}) {
+ $symbol = "-";
+ $self->disk_usage($e,1);
+ } else {
+ $self->disk_usage($e);
+ }
$i++;
while (($painted/76) < ($i/@entries)) {
- $CPAN::Frontend->myprint(".");
+ $CPAN::Frontend->myprint($symbol);
$painted++;
}
return if $CPAN::Signal;
if ($CPAN::META->has_inst("File::Temp")) {
$installation_report_fh
= File::Temp->new(
+ dir => File::Spec->tmpdir,
template => 'cpan_install_XXXX',
suffix => '.txt',
unlink => 0,
#-> sub CPAN::Shell::mydie ;
sub mydie {
my($self,$what) = @_;
- $self->print_ornamented($what, $CPAN::Config->{colorize_warn}||'bold red on_white');
+ $self->mywarn($what);
- # If it is the shell, we want that the following die to be silent,
+ # If it is the shell, we want the following die to be silent,
# but if it is not the shell, we would need a 'die $what'. We need
# to take care that only shell commands use mydie. Is this
# possible?
#-> sub CPAN::Shell::mysleep ;
sub mysleep {
my($self, $sleep) = @_;
- use Time::HiRes qw(sleep);
- sleep $sleep;
+ if (CPAN->has_inst("Time::HiRes")) {
+ Time::HiRes::sleep($sleep);
+ } else {
+ sleep($sleep < 1 ? 1 : int($sleep + 0.5));
+ }
}
#-> sub CPAN::Shell::setup_output ;
if (0) {
} elsif (ref $obj) {
if ($meth =~ /^($needs_recursion_protection)$/) {
- # silly for look or dump
- $obj->color_cmd_tmps(0,1);
+ # it would be silly to check for recursion for look or dump
+ # (we are in CPAN::Shell::rematein)
+ CPAN->debug("Going to test against recursion") if $CPAN::DEBUG;
+ eval { $obj->color_cmd_tmps(0,1); };
+ if ($@){
+ if (ref $@
+ and $@->isa("CPAN::Exception::RecursiveDependency")) {
+ $CPAN::Frontend->mywarn($@);
+ } else {
+ if (0) {
+ require Carp;
+ Carp::confess(sprintf "DEBUG: \$\@[%s]ref[%s]", $@, ref $@);
+ }
+ die;
+ }
+ }
}
CPAN::Queue->new(qmod => $obj->id, reqtype => "c");
push @qcopy, $obj;
} elsif ($CPAN::META->exists('CPAN::Author',uc($s))) {
$obj = $CPAN::META->instance('CPAN::Author',uc($s));
- if ($meth =~ /^(dump|ls)$/) {
+ if ($meth =~ /^(dump|ls|reports)$/) {
$obj->$meth();
} else {
$CPAN::Frontend->mywarn(
# 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.");
+ "to an object. Skipping.\n");
$CPAN::Frontend->mysleep(5);
+ CPAN::Queue->delete_first($s);
next;
}
$obj->{reqtype} ||= "";
require overload;
$serialized = overload::StrVal($obj);
}
+ CPAN->debug("Going to panic. meth[$meth]s[$s]") if $CPAN::DEBUG;
$CPAN::Frontend->mydie("Panic: obj[$serialized] cannot meth[$meth]");
} elsif ($obj->$meth()){
CPAN::Queue->delete($s);
+ CPAN->debug("From queue deleted. meth[$meth]s[$s]") if $CPAN::DEBUG;
} else {
- CPAN->debug("failed");
+ CPAN->debug("Failed. pragma[@pragma]meth[$meth]") if $CPAN::DEBUG;
}
$obj->undelay;
notest
perldoc
readme
+ reports
test
)) {
*$command = sub { shift->rematein($command, @_); };
# need no eval because if this fails, it is serious
my $sfile = File::Spec->catfile($CPAN::Config->{cpan_home},"FTPstats.yml");
CPAN->_yaml_dumpfile("$sfile.$$",$fullstats);
- if ( $sdebug||$CPAN::DEBUG ) {
+ if ( $sdebug ) {
local $CPAN::DEBUG = 512; # FTP
push @debug, time;
CPAN->debug(sprintf("DEBUG history: before_read[%d]before[%d]at[%d]".
if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
$Ua->proxy('http', $var)
if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
-
-
-# >>>>> On Wed, 13 Dec 2000 09:21:34 -0500, "Robison, Jonathon (J.M.)" <jrobiso2@visteon.com> said:
-#
-# > I note that although CPAN.pm can use proxies, it doesn't seem equipped to
-# > use ones that require basic autorization.
-#
-# > Example of when I use it manually in my own stuff:
-#
-# > $ua->proxy(['http','ftp'], http://my.proxy.server:83');
-# > $req->proxy_authorization_basic("username","password");
-# > $res = $ua->request($req);
-#
-
$Ua->no_proxy($var)
if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
}
sort { $b->[1] <=> $a->[1] }
map { [ $_, -M File::Spec->catfile($d,$_) ] }
grep {/\.yml$/} readdir $dh;
- DISTRO: for $dirent (@candidates) {
+ DISTRO: for $i (0..$#candidates) {
+ my $dirent = $candidates[$i];
my $y = eval {CPAN->_yaml_loadfile(File::Spec->catfile($d,$dirent))};
- die $@ if $@;
+ if ($@) {
+ warn "Error while parsing file '$dirent'; error: '$@'";
+ next DISTRO;
+ }
my $c = $y->[0];
if ($c && CPAN->_perl_fingerprint($c->{perl})) {
my $key = $c->{distribution}{ID};
my $do
= $CPAN::META->{readwrite}{'CPAN::Distribution'}{$key}
= $c->{distribution};
- delete $do->{badtestcnt};
+ for my $skipper (qw(badtestcnt notest force_update)) {
+ delete $do->{$skipper};
+ }
# $DB::single = 1;
if ($do->{make_test}
&& $do->{build_dir}
- && !$do->{make_test}->failed
+ && !(UNIVERSAL::can($do->{make_test},"failed") ?
+ $do->{make_test}->failed :
+ $do->{make_test} =~ /^YES/
+ )
&& (
!$do->{install}
||
}
}
$CPAN::Frontend->myprint(sprintf(
- "DONE\nFound %s old builds, restored the state of %s\n",
+ "DONE\nFound %s old build%s, restored the state of %s\n",
@candidates ? sprintf("%d",scalar @candidates) : "no",
+ @candidates==1 ? "" : "s",
$restored || "none",
));
}
@result;
}
+#-> sub CPAN::Author::reports
+sub reports {
+ $CPAN::Frontend->mywarn("reports on authors not implemented.
+Please file a bugreport if you need this.\n");
+}
+
package CPAN::Distribution;
use strict;
$ro->{CPAN_COMMENT}
}
-# CPAN::Distribution::undelay
+#-> CPAN::Distribution::undelay
sub undelay {
my $self = shift;
delete $self->{later};
}
+#-> CPAN::Distribution::is_dot_dist
+sub is_dot_dist {
+ my($self) = @_;
+ return substr($self->id,-1,1) eq ".";
+}
+
# add the A/AN/ stuff
-# CPAN::Distribution::normalize
+#-> CPAN::Distribution::normalize
sub normalize {
my($self,$s) = @_;
$s = $self->id unless defined $s;
&& $color==1
&& $self->{incommandcolor}==$color;
if ($depth>=$CPAN::MAX_RECURSION){
- $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
+ die(CPAN::Exception::RecursiveDependency->new($ancestors));
}
# warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
my $prereq_pm = $self->prereq_pm;
EXCUSE: {
my @e;
+ my $goodbye_message;
$self->debug("checking disabled id[$self->{ID}]") if $CPAN::DEBUG;
if ($self->prefs->{disabled}) {
my $why = sprintf(
$self->{prefs_file_doc},
);
push @e, $why;
- $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $why");
+ $self->{unwrapped} = CPAN::Distrostatus->new("NO $why");
+ $goodbye_message = "[disabled] -- NA $why";
# note: not intended to be persistent but at least visible
# during this session
} else {
- if (exists $self->{build_dir}) {
+ if (exists $self->{build_dir} && -d $self->{build_dir}
+ && ($self->{modulebuild}||$self->{writemakefile})
+ ) {
# this deserves print, not warn:
$CPAN::Frontend->myprint(" Has already been unwrapped into directory ".
"$self->{build_dir}\n"
);
- return;
+ return 1;
}
# although we talk about 'force' we shall not test on
)
and push @e, "Unwrapping had some problem, won't try again without force";
}
-
- $CPAN::Frontend->mywarn(join "", map {"$_\n"} @e) and return if @e;
+ if (@e) {
+ $CPAN::Frontend->mywarn(join "", map {"$_\n"} @e);
+ if ($goodbye_message) {
+ $self->goodbye($goodbye_message);
+ }
+ return;
+ }
}
my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
- #
- # Get the file on local disk
- #
+ $self->get_file_onto_local_disk;
+ return if $CPAN::Signal;
+ $self->check_integrity;
+ return if $CPAN::Signal;
+ my($packagedir,$local_file) = $self->run_preps_on_packagedir;
+ $packagedir ||= $self->{build_dir};
+
+ if ($CPAN::Signal){
+ $self->safe_chdir($sub_wd);
+ return;
+ }
+ return $self->run_MM_or_MB($local_file,$packagedir);
+}
+#-> CPAN::Distribution::get_file_onto_local_disk
+sub get_file_onto_local_disk {
+ my($self) = @_;
+
+ return if $self->is_dot_dist;
my($local_file);
my($local_wanted) =
File::Spec->catfile(
$self->debug("local_wanted[$local_wanted]local_file[$local_file]") if $CPAN::DEBUG;
$self->{localfile} = $local_file;
- return if $CPAN::Signal;
+}
- #
- # Check integrity
- #
+
+#-> CPAN::Distribution::check_integrity
+sub check_integrity {
+ my($self) = @_;
+
+ return if $self->is_dot_dist;
if ($CPAN::META->has_inst("Digest::SHA")) {
$self->debug("Digest::SHA is installed, verifying");
$self->verifyCHECKSUM;
} else {
$self->debug("Digest::SHA is NOT installed");
}
- return if $CPAN::Signal;
+}
+
+#-> CPAN::Distribution::run_preps_on_packagedir
+sub run_preps_on_packagedir {
+ my($self) = @_;
+ return if $self->is_dot_dist;
- #
- # Create a clean room and go there
- #
$CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
$self->safe_chdir($builddir);
EOF
}
if ($CPAN::Signal){
- $self->safe_chdir($sub_wd);
return;
}
$self->safe_chdir("tmp-$$");
#
# Unpack the goods
#
+ my $local_file = $self->{localfile};
my $ct = eval{CPAN::Tarzip->new($local_file)};
unless ($ct) {
$self->{unwrapped} = CPAN::Distrostatus->new("NO");
} else {
$self->{was_uncompressed}++ unless $ct->gtest();
$local_file = $self->handle_singlefile($local_file);
-# } else {
-# $self->{archived} = "NO";
-# $self->safe_chdir($sub_wd);
-# return;
}
# we are still in the tmp directory!
}
}
}
- if ($CPAN::Signal){
- $self->safe_chdir($sub_wd);
- return;
- }
-
$self->{build_dir} = $packagedir;
$self->safe_chdir($builddir);
File::Path::rmtree("tmp-$$");
$self->safe_chdir($packagedir);
$self->_signature_business();
$self->safe_chdir($builddir);
- return if $CPAN::Signal;
+ return($packagedir,$local_file);
+}
+#-> sub CPAN::Distribution::run_MM_or_MB
+sub run_MM_or_MB {
+ my($self,$local_file,$packagedir) = @_;
my($mpl) = File::Spec->catfile($packagedir,"Makefile.PL");
my($mpl_exists) = -f $mpl;
unless ($mpl_exists) {
return unless $self->patch;
if (lc($prefer_installer) eq "mb") {
$self->{modulebuild} = 1;
+ } elsif ($self->{archived} eq "patch") {
+ # not an edge case, nothing to install for sure
+ my $why = "A patch file cannot be installed";
+ $CPAN::Frontend->mywarn("Refusing to handle this file: $why\n");
+ $self->{writemakefile} = CPAN::Distrostatus->new("NO $why");
} elsif (! $mpl_exists) {
$self->_edge_cases($mpl,$packagedir,$local_file);
}
) {
$self->store_persistent_state;
}
-
return $self;
}
$local_wanted);
}
-#-> CPAN::Distribution::patch
-sub patch {
- my($self) = @_;
- $self->debug("checking patches id[$self->{ID}]") if $CPAN::DEBUG;
- my $patches = $self->prefs->{patches};
- $patches ||= "";
- $self->debug("patches[$patches]") if $CPAN::DEBUG;
- if ($patches) {
- return unless @$patches;
- $self->safe_chdir($self->{build_dir});
- CPAN->debug("patches[$patches]") if $CPAN::DEBUG;
- my $patchbin = $CPAN::Config->{patch};
- unless ($patchbin && length $patchbin) {
- $CPAN::Frontend->mydie("No external patch command configured\n\n".
- "Please run 'o conf init /patch/'\n\n");
- }
- unless (MM->maybe_command($patchbin)) {
- $CPAN::Frontend->mydie("No external patch command available\n\n".
- "Please run 'o conf init /patch/'\n\n");
- }
- $patchbin = CPAN::HandleConfig->safe_quote($patchbin);
- local $ENV{PATCH_GET} = 0; # shall replace -g0 which is not
- # supported everywhere (and then,
- # not ever necessary there)
- my $stdpatchargs = "-N --fuzz=3";
- my $countedpatches = @$patches == 1 ? "1 patch" : (scalar @$patches . " patches");
- $CPAN::Frontend->myprint("Going to apply $countedpatches:\n");
- for my $patch (@$patches) {
- unless (-f $patch) {
- if (my $trydl = $self->try_download($patch)) {
- $patch = $trydl;
+{
+ my $stdpatchargs = "";
+ #-> CPAN::Distribution::patch
+ sub patch {
+ my($self) = @_;
+ $self->debug("checking patches id[$self->{ID}]") if $CPAN::DEBUG;
+ my $patches = $self->prefs->{patches};
+ $patches ||= "";
+ $self->debug("patches[$patches]") if $CPAN::DEBUG;
+ if ($patches) {
+ return unless @$patches;
+ $self->safe_chdir($self->{build_dir});
+ CPAN->debug("patches[$patches]") if $CPAN::DEBUG;
+ my $patchbin = $CPAN::Config->{patch};
+ unless ($patchbin && length $patchbin) {
+ $CPAN::Frontend->mydie("No external patch command configured\n\n".
+ "Please run 'o conf init /patch/'\n\n");
+ }
+ unless (MM->maybe_command($patchbin)) {
+ $CPAN::Frontend->mydie("No external patch command available\n\n".
+ "Please run 'o conf init /patch/'\n\n");
+ }
+ $patchbin = CPAN::HandleConfig->safe_quote($patchbin);
+ local $ENV{PATCH_GET} = 0; # formerly known as -g0
+ unless ($stdpatchargs) {
+ my $system = "$patchbin --version |";
+ local *FH;
+ open FH, $system or die "Could not fork '$system': $!";
+ local $/ = "\n";
+ my $pversion;
+ PARSEVERSION: while (<FH>) {
+ if (/^patch\s+([\d\.]+)/) {
+ $pversion = $1;
+ last PARSEVERSION;
+ }
+ }
+ if ($pversion) {
+ $stdpatchargs = "-N --fuzz=3";
+ } else {
+ $stdpatchargs = "-N";
+ }
+ }
+ my $countedpatches = @$patches == 1 ? "1 patch" : (scalar @$patches . " patches");
+ $CPAN::Frontend->myprint("Going to apply $countedpatches:\n");
+ for my $patch (@$patches) {
+ unless (-f $patch) {
+ if (my $trydl = $self->try_download($patch)) {
+ $patch = $trydl;
+ } else {
+ my $fail = "Could not find patch '$patch'";
+ $CPAN::Frontend->mywarn("$fail; cannot continue\n");
+ $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
+ delete $self->{build_dir};
+ return;
+ }
+ }
+ $CPAN::Frontend->myprint(" $patch\n");
+ my $readfh = CPAN::Tarzip->TIEHANDLE($patch);
+
+ my $pcommand;
+ my $ppp = $self->_patch_p_parameter($readfh);
+ if ($ppp eq "applypatch") {
+ $pcommand = "$CPAN::Config->{applypatch} -verbose";
} else {
- my $fail = "Could not find patch '$patch'";
+ my $thispatchargs = join " ", $stdpatchargs, $ppp;
+ $pcommand = "$patchbin $thispatchargs";
+ }
+
+ $readfh = CPAN::Tarzip->TIEHANDLE($patch); # open again
+ my $writefh = FileHandle->new;
+ $CPAN::Frontend->myprint(" $pcommand\n");
+ unless (open $writefh, "|$pcommand") {
+ my $fail = "Could not fork '$pcommand'";
+ $CPAN::Frontend->mywarn("$fail; cannot continue\n");
+ $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
+ delete $self->{build_dir};
+ return;
+ }
+ while (my $x = $readfh->READLINE) {
+ print $writefh $x;
+ }
+ unless (close $writefh) {
+ my $fail = "Could not apply patch '$patch'";
$CPAN::Frontend->mywarn("$fail; cannot continue\n");
$self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
delete $self->{build_dir};
return;
}
}
- $CPAN::Frontend->myprint(" $patch\n");
- my $readfh = CPAN::Tarzip->TIEHANDLE($patch);
-
- my $pcommand;
- my $ppp = $self->_patch_p_parameter($readfh);
- if ($ppp eq "applypatch") {
- $pcommand = "$CPAN::Config->{applypatch} -verbose";
- } else {
- my $thispatchargs = join " ", $stdpatchargs, $ppp;
- $pcommand = "$patchbin $thispatchargs";
- }
-
- $readfh = CPAN::Tarzip->TIEHANDLE($patch); # open again
- my $writefh = FileHandle->new;
- $CPAN::Frontend->myprint(" $pcommand\n");
- unless (open $writefh, "|$pcommand") {
- my $fail = "Could not fork '$pcommand'";
- $CPAN::Frontend->mywarn("$fail; cannot continue\n");
- $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
- delete $self->{build_dir};
- return;
- }
- while (my $x = $readfh->READLINE) {
- print $writefh $x;
- }
- unless (close $writefh) {
- my $fail = "Could not apply patch '$patch'";
- $CPAN::Frontend->mywarn("$fail; cannot continue\n");
- $self->{unwrapped} = CPAN::Distrostatus->new("NO -- $fail");
- delete $self->{build_dir};
- return;
- }
+ $self->{patched}++;
}
- $self->{patched}++;
+ return 1;
}
- return 1;
}
sub _patch_p_parameter {
my $fh = FileHandle->new;
my $script_file = File::Spec->catfile($packagedir,$local_file);
$fh->open($script_file)
- or Carp::croak("Could not open $script_file: $!");
+ or Carp::croak("Could not open script '$script_file': $!");
local $/ = "\n";
# name parsen und prereq
my($state) = "poddir";
);
my $wrap =
- sprintf(qq{I'd recommend removing %s. Its signature
-is invalid. Maybe you have configured your 'urllist' with
-a bad URL. Please check this array with 'o conf urllist', and
-retry. For more information, try opening a subshell with
+ sprintf(qq{I'd recommend removing %s. Some error occured }.
+ qq{while checking its signature, so it could }.
+ qq{be invalid. Maybe you have configured }.
+ qq{your 'urllist' with a bad URL. Please check this }.
+ qq{array with 'o conf urllist' and retry. Or }.
+ qq{examine the distribution in a subshell. Try
look %s
-and there run
+and run
cpansign -v
},
$self->{localfile},
if ( $local_file =~ /\.pm(\.(gz|Z))?(?!\n)\Z/ ){
$self->{archived} = "pm";
+ } elsif ( $local_file =~ /\.patch(\.(gz|bz2))?(?!\n)\Z/ ) {
+ $self->{archived} = "patch";
} else {
$self->{archived} = "maybe_pl";
}
$self->{unwrapped} = CPAN::Distrostatus->new("NO -- uncompressing failed");
}
} else {
- File::Copy::cp($local_file,".");
- $self->{unwrapped} = CPAN::Distrostatus->new("NO -- copying failed");
+ if (File::Copy::cp($local_file,".")) {
+ $self->{unwrapped} = CPAN::Distrostatus->new("YES");
+ } else {
+ $self->{unwrapped} = CPAN::Distrostatus->new("NO -- copying failed");
+ }
}
return $to;
}
#-> sub CPAN::Distribution::notest ;
sub notest {
my($self, $method) = @_;
- # warn "XDEBUG: set notest for $self $method";
+ # $CPAN::Frontend->mywarn("XDEBUG: set notest for $self $method");
$self->{"notest"}++; # name should probably have been force_install
}
sub unnotest {
my($self) = @_;
# warn "XDEBUG: deleting notest";
- delete $self->{'notest'};
+ delete $self->{notest};
}
#-> sub CPAN::Distribution::unforce ;
push @e, $err;
}
- defined $self->{make} and push @e,
- "Has already been made";
+ if (defined $self->{make}) {
+ if (UNIVERSAL::can($self->{make},"failed") ?
+ $self->{make}->failed :
+ $self->{make} =~ /^NO/) {
+ if ($self->{force_update}) {
+ # Trying an already failed 'make' (unless somebody else blocks)
+ } else {
+ # introduced for turning recursion detection into a distrostatus
+ my $error = length $self->{make}>3
+ ? substr($self->{make},3) : "Unknown error";
+ $CPAN::Frontend->mywarn("Could not make: $error\n");
+ $self->store_persistent_state;
+ return;
+ }
+ } else {
+ push @e, "Has already been made";
+ }
+ }
- if (exists $self->{later} and length($self->{later})) {
+ if ($self->{later}) { # see also undelay
if ($self->unsat_prereq) {
push @e, $self->{later};
-# RT ticket 18438 raises doubts if the deletion of {later} is valid.
-# YAML-0.53 triggered the later hodge-podge here, but my margin notes
-# are not sufficient to be sure if we really must/may do the delete
-# here. SO I accept the suggested patch for now. If we trigger a bug
-# again, I must go into deep contemplation about the {later} flag.
-
-# } else {
-# delete $self->{later};
}
}
->new("NO '$system' returned status $ret");
$CPAN::Frontend->mywarn("Warning: No success on command[$system]\n");
$self->store_persistent_state;
- $self->store_persistent_state;
- return;
+ return $self->goodbye("$system -- NOT OK\n");
}
}
if (-f "Makefile" || -f "Build") {
$CPAN::Frontend->mywarn("$id $need; you have only $]; giving up\n");
$self->{make} = CPAN::Distrostatus->new("NO $need");
$self->store_persistent_state;
- return;
+ return $self->goodbye("[prereq] -- NOT OK\n");
} else {
- return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
+ my $follow = eval { $self->follow_prereqs(@prereq); };
+ if (0) {
+ } elsif ($follow){
+ # signal success to the queuerunner
+ return 1;
+ } elsif ($@ && ref $@ && $@->isa("CPAN::Exception::RecursiveDependency")) {
+ $CPAN::Frontend->mywarn($@);
+ return $self->goodbye("[depend] -- NOT OK\n");
+ }
}
}
if ($CPAN::Signal){
unless (-f "Build") {
my $cwd = CPAN::anycwd();
$CPAN::Frontend->mywarn("Alert: no Build file available for 'make $self->{id}'".
- " in cwd[$cwd]. Danger, Will Robinson!");
+ " in cwd[$cwd]. Danger, Will Robinson!\n");
$CPAN::Frontend->mysleep(5);
}
$system = join " ", $self->_build_command(), $CPAN::Config->{mbuild_arg};
$self->store_persistent_state;
}
-# CPAN::Distribution::_run_via_expect
+# CPAN::Distribution::goodbye ;
+sub goodbye {
+ my($self,$goodbye) = @_;
+ my $id = $self->pretty_id;
+ $CPAN::Frontend->mywarn(" $id\n $goodbye");
+ return;
+}
+
+# CPAN::Distribution::_run_via_expect ;
sub _run_via_expect {
my($self,$system,$expect_model) = @_;
CPAN->debug("system[$system]expect_model[$expect_model]") if $CPAN::DEBUG;
my $ok = 1;
# do not take the order of C<keys %$match> because
# "module" is by far the slowest
- for my $sub_attribute (qw(distribution perl module)) {
+ my $saw_valid_subkeys = 0;
+ for my $sub_attribute (qw(distribution perl perlconfig module)) {
next unless exists $match->{$sub_attribute};
+ $saw_valid_subkeys++;
my $qr = eval "qr{$distropref->{match}{$sub_attribute}}";
if ($sub_attribute eq "module") {
my $okm = 0;
} elsif ($sub_attribute eq "perl") {
my $okp = $^X =~ /$qr/;
$ok &&= $okp;
+ } elsif ($sub_attribute eq "perlconfig") {
+ for my $perlconfigkey (keys %{$match->{perlconfig}}) {
+ my $perlconfigval = $match->{perlconfig}->{$perlconfigkey};
+ # XXX should probably warn if Config does not exist
+ my $okpc = $Config::Config{$perlconfigkey} =~ /$perlconfigval/;
+ $ok &&= $okpc;
+ last if $ok == 0;
+ }
} else {
$CPAN::Frontend->mydie("Nonconforming .$thisexte file '$abs': ".
"unknown sub_attribut '$sub_attribute'. ".
}
last if $ok == 0; # short circuit
}
+ unless ($saw_valid_subkeys) {
+ $CPAN::Frontend->mydie("Nonconforming .$thisexte file '$abs': ".
+ "missing match/* subattribute. ".
+ "Please ".
+ "remove, cannot continue.");
+ }
#CPAN->debug(sprintf "ok[%d]", $ok) if $CPAN::DEBUG;
if ($ok) {
return {
$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 == 0 or
- $need_version eq "undef") {
- next if defined $available_file;
+ if (defined $available_file
+ and ( # a few quick shortcurcuits
+ not defined $need_version
+ or $need_version eq '0' # "==" would trigger warning when not numeric
+ or $need_version eq "undef"
+ )) {
+ next NEED;
}
$available_version = $nmo->available_version;
# if we push it again, we have a potential infinite loop
# The following "next" was a very problematic construct.
- # It helped a lot but broke some day and must be replaced.
+ # It helped a lot but broke some day and had to be
+ # replaced.
# We must be able to deal with modules that come again and
# again as a prereq and have themselves prereqs and the
# 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
+ # next; # this is the next that had to go away
# The following "next NEED" are fine and the error message
# explains well what is going on. For example when the DBI
"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;
+ if ($do->{$nosayer}) {
+ if (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;
+ } else { # the other guy succeeded
+ if ($nosayer eq "install") {
+ # we had this with
+ # DMAKI/DateTime-Calendar-Chinese-0.05.tar.gz
+ # 2007-03
+ $CPAN::Frontend->mywarn("Warning: Prerequisite ".
+ "'$need_module => $need_version' ".
+ "for '$self->{ID}' already installed ".
+ "but installation looks suspicious. ".
+ "Skipping another installation attempt, ".
+ "to prevent looping endlessly.\n"
+ );
+ next NEED;
+ }
}
- $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;
}
}
}
EXCUSE: {
my @e;
- unless (exists $self->{make} or exists $self->{later}) {
+ if ($self->{make} or $self->{later}) {
+ # go ahead
+ } else {
push @e,
"Make had some problems, won't test";
}
$self->{make}->failed :
$self->{make} =~ /^NO/
) and push @e, "Can't test without successful make";
-
$self->{badtestcnt} ||= 0;
if ($self->{badtestcnt} > 0) {
require Data::Dumper;
push @e, "Won't repeat unsuccessful test during this command";
}
- exists $self->{later} and length($self->{later}) and
- push @e, $self->{later};
+ push @e, $self->{later} if $self->{later};
if (exists $self->{build_dir}) {
- if ($CPAN::META->{is_tested}{$self->{build_dir}}
- &&
- exists $self->{make_test}
- &&
- !(
- UNIVERSAL::can($self->{make_test},"failed") ?
- $self->{make_test}->failed :
- $self->{make_test} =~ /^NO/
- )
- ) {
- push @e, "Has already been tested successfully";
+ if (exists $self->{make_test}) {
+ if (
+ UNIVERSAL::can($self->{make_test},"failed") ?
+ $self->{make_test}->failed :
+ $self->{make_test} =~ /^NO/
+ ) {
+ if (
+ UNIVERSAL::can($self->{make_test},"commandid")
+ &&
+ $self->{make_test}->commandid == $CPAN::CurrentCommandId
+ ) {
+ push @e, "Has already been tested within this command";
+ }
+ } else {
+ push @e, "Has already been tested successfully";
+ }
}
} elsif (!@e) {
push @e, "Has no own directory";
}
my $ready_to_report = $want_report;
if ($ready_to_report
- && (
- substr($self->id,-1,1) eq "."
- ||
- $self->author->id eq "LOCAL"
- )
+ && $self->is_dot_dist
) {
$CPAN::Frontend->mywarn("Reporting via CPAN::Reporter is disabled ".
"for local directories\n");
$CPAN::Frontend->mywarn("Tests succeeded but $but\n");
$self->{make_test} = CPAN::Distrostatus->new("NO $but");
$self->store_persistent_state;
- return;
+ return $self->goodbye("[dependencies] -- NA");
}
}
$CPAN::Frontend->mywarn("Distribution has no own directory, nothing to do.\n");
return 1;
}
+ if (exists $self->{writemakefile}
+ and $self->{writemakefile}->failed
+ ) {
+ $CPAN::Frontend->mywarn("No Makefile, don't know how to 'make clean'\n");
+ return 1;
+ }
EXCUSE: {
my @e;
exists $self->{make_clean} and $self->{make_clean} eq "YES" and
# and run where we left off
my($method) = (caller(1))[3];
- CPAN->instance("CPAN::Distribution",$goto)->$method;
+ CPAN->instance("CPAN::Distribution",$goto)->$method();
CPAN::Queue->delete_first($goto);
}
if (my $goto = $self->prefs->{goto}) {
return $self->goto($goto);
}
- $DB::single=1;
+ # $DB::single=1;
unless ($self->{badtestcnt}) {
$self->test;
}
$CPAN::Frontend->myprint("Running $make install\n");
EXCUSE: {
my @e;
- unless (exists $self->{make} or exists $self->{later}) {
+ if ($self->{make} or $self->{later}) {
+ # go ahead
+ } else {
push @e,
"Make had some problems, won't install";
}
$self->{install}->text eq "YES" :
$self->{install} =~ /^YES/
) {
- push @e, "Already done";
+ $CPAN::Frontend->myprint(" Already done\n");
+ $CPAN::META->is_installed($self->{build_dir});
+ return 1;
} else {
# comment in Todo on 2006-02-11; maybe retry?
push @e, "Already tried without success";
}
}
- exists $self->{later} and length($self->{later}) and
- push @e, $self->{later};
+ push @e, $self->{later} if $self->{later};
$CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
unless (chdir $self->{build_dir}) {
my($fh,$filename);
if ($CPAN::META->has_inst("File::Temp")) {
$fh = File::Temp->new(
+ dir => File::Spec->tmpdir,
template => 'cpan_htmlconvert_XXXX',
suffix => '.txt',
unlink => 0,
my($fh,$filename);
if ($CPAN::META->has_inst("File::Temp")) {
$fh = File::Temp->new(
+ dir => File::Spec->tmpdir,
template => "cpan_getsave_url_XXXX",
suffix => ".html",
unlink => 0,
return "./Build";
}
+#-> sub CPAN::Distribution::reports
+sub reports {
+ my($self) = @_;
+ my $pathname = $self->id;
+ $CPAN::Frontend->myprint("Distribution: $pathname\n");
+
+ unless ($CPAN::META->has_inst("CPAN::DistnameInfo")) {
+ $CPAN::Frontend->mydie("CPAN::DistnameInfo not installed; cannot continue");
+ }
+ unless ($CPAN::META->has_usable("LWP")) {
+ $CPAN::Frontend->mydie("LWP not installed; cannot continue");
+ }
+ unless ($CPAN::META->has_inst("File::Temp")) {
+ $CPAN::Frontend->mydie("File::Temp not installed; cannot continue");
+ }
+
+ my $d = CPAN::DistnameInfo->new($pathname);
+
+ my $dist = $d->dist; # "CPAN-DistnameInfo"
+ my $version = $d->version; # "0.02"
+ my $maturity = $d->maturity; # "released"
+ my $filename = $d->filename; # "CPAN-DistnameInfo-0.02.tar.gz"
+ my $cpanid = $d->cpanid; # "GBARR"
+ my $distvname = $d->distvname; # "CPAN-DistnameInfo-0.02"
+
+ my $url = sprintf "http://cpantesters.perl.org/show/%s.yaml", $dist;
+
+ CPAN::LWP::UserAgent->config;
+ my $Ua;
+ eval { $Ua = CPAN::LWP::UserAgent->new; };
+ if ($@) {
+ $CPAN::Frontend->mydie("CPAN::LWP::UserAgent->new dies with $@\n");
+ }
+ $CPAN::Frontend->myprint("Fetching '$url'...");
+ my $resp = $Ua->get($url);
+ unless ($resp->is_success) {
+ $CPAN::Frontend->mydie(sprintf "Could not download '%s': %s\n", $url, $resp->code);
+ }
+ $CPAN::Frontend->myprint("DONE\n\n");
+ my $yaml = $resp->content;
+ # was fuer ein Umweg!
+ my $fh = File::Temp->new(
+ dir => File::Spec->tmpdir,
+ template => 'cpan_reports_XXXX',
+ suffix => '.yaml',
+ unlink => 0,
+ );
+ my $tfilename = $fh->filename;
+ print $fh $yaml;
+ close $fh or $CPAN::Frontend->mydie("Could not close '$tfilename': $!");
+ my $unserialized = CPAN->_yaml_loadfile($tfilename)->[0];
+ unlink $tfilename or $CPAN::Frontend->mydie("Could not unlink '$tfilename': $!");
+ my %other_versions;
+ my $this_version_seen;
+ for my $rep (@$unserialized) {
+ my $rversion = $rep->{version};
+ if ($rversion eq $version){
+ unless ($this_version_seen++) {
+ $CPAN::Frontend->myprint ("$rep->{version}:\n");
+ }
+ $CPAN::Frontend->myprint
+ (sprintf("%1s%1s%-4s %s on %s %s (%s)\n",
+ $rep->{archname} eq $Config::Config{archname}?"*":"",
+ $rep->{action}eq"PASS"?"+":$rep->{action}eq"FAIL"?"-":"",
+ $rep->{action},
+ $rep->{perl},
+ ucfirst $rep->{osname},
+ $rep->{osvers},
+ $rep->{archname},
+ ));
+ } else {
+ $other_versions{$rep->{version}}++;
+ }
+ }
+ unless ($this_version_seen) {
+ $CPAN::Frontend->myprint("No reports found for version '$version'
+Reports for other versions:\n");
+ for my $v (sort keys %other_versions) {
+ $CPAN::Frontend->myprint(" $v\: $other_versions{$v}\n");
+ }
+ }
+ $url =~ s/\.yaml/.html/;
+ $CPAN::Frontend->myprint("See $url for details\n");
+}
+
package CPAN::Bundle;
use strict;
$CPAN::Frontend->myprint($self->as_string);
}
+#-> CPAN::Bundle::undelay
sub undelay {
my $self = shift;
delete $self->{later};
&& $color==1
&& $self->{incommandcolor}==$color;
if ($depth>=$CPAN::MAX_RECURSION){
- $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
+ die(CPAN::Exception::RecursiveDependency->new($ancestors));
}
# warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
use strict;
# Accessors
-# sub CPAN::Module::userid
+#-> sub CPAN::Module::userid
sub userid {
my $self = shift;
my $ro = $self->ro;
return unless $ro;
return $ro->{userid} || $ro->{CPAN_USERID};
}
-# sub CPAN::Module::description
+#-> sub CPAN::Module::description
sub description {
my $self = shift;
my $ro = $self->ro or return "";
$ro->{description}
}
+#-> sub CPAN::Module::distribution
sub distribution {
my($self) = @_;
CPAN::Shell->expand("Distribution",$self->cpan_file);
}
-# sub CPAN::Module::undelay
+#-> sub CPAN::Module::undelay
sub undelay {
my $self = shift;
delete $self->{later};
# so we can break it
}
if ($depth>=$CPAN::MAX_RECURSION){
- $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
+ die(CPAN::Exception::RecursiveDependency->new($ancestors));
}
# warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
join "", @m, "\n";
}
+#-> sub CPAN::Module::manpage_headline
sub manpage_headline {
my($self,$local_file) = @_;
my(@local_file) = $local_file;
$self->{force_update} = 2;
}
+#-> sub CPAN::Module::notest ;
sub notest {
my($self) = @_;
- # warn "XDEBUG: set notest for Module";
- $self->{'notest'}++;
+ # $CPAN::Frontend->mywarn("XDEBUG: set notest for Module");
+ $self->{notest}++;
}
#-> sub CPAN::Module::rematein ;
$pack->force($meth);
}
}
- $pack->notest($meth) if exists $self->{'notest'};
+ $pack->notest($meth) if exists $self->{notest} && $self->{notest};
$pack->{reqtype} ||= "";
CPAN->debug("dist-reqtype[$pack->{reqtype}]".
$pack->{reqtype} = $self->{reqtype};
}
- eval {
+ my $success = eval {
$pack->$meth();
};
my $err = $@;
$pack->unforce if $pack->can("unforce") && exists $self->{force_update};
- $pack->unnotest if $pack->can("unnotest") && exists $self->{'notest'};
+ $pack->unnotest if $pack->can("unnotest") && exists $self->{notest};
delete $self->{force_update};
- delete $self->{'notest'};
+ delete $self->{notest};
if ($err) {
die $err;
}
+ return $success;
}
#-> sub CPAN::Module::perldoc ;
$have; # no stringify needed, \s* above matches always
}
+#-> sub CPAN::Module::reports
+sub reports {
+ my($self) = @_;
+ $self->distribution->reports;
+}
+
package CPAN;
use strict;
module: "Dancing::Queen"
distribution: "^CHACHACHA/Dancing-"
perl: "/usr/local/cariba-perl/bin/perl"
+ perlconfig:
+ archname: "freebsd"
disabled: 1
cpanconfig:
make: gmake
=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.
+A hashref with one or more of the keys C<distribution>, C<modules>,
+C<perl>, and C<perlconfig> that specify if a document is targeted at a
+specific CPAN distribution or installation.
The corresponding values are interpreted as regular expressions. The
C<distribution> related one will be matched against the canonical
The C<perl> related one will be matched against C<$^X>.
+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.
+
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
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 cpantesters.perl.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:
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.
http://search.cpan.org/search?query=Module::Build::Convert
-http://accognoscere.org/papers/perl-module-build-convert/module-build-convert.html
+http://www.refcnt.org/papers/module-build-convert
=item 15)