Upgrade to CPAN-1.9102
[p5sagit/p5-mst-13.2.git] / lib / CPAN.pm
index d7e96f4..5062175 100644 (file)
@@ -1,7 +1,7 @@
 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
 use strict;
 package CPAN;
-$CPAN::VERSION = '1.90';
+$CPAN::VERSION = '1.9102';
 $CPAN::VERSION = eval $CPAN::VERSION if $CPAN::VERSION =~ /_/;
 
 use CPAN::HandleConfig;
@@ -520,6 +520,7 @@ use strict;
                                     recompile
                                     reload
                                     report
+                                    reports
                                     scripts
                                     test
                                     upgrade
@@ -1455,17 +1456,16 @@ sub tidyup {
   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;
@@ -1499,12 +1499,12 @@ sub entries {
        }
     }
     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;
@@ -1526,8 +1526,11 @@ sub disk_usage {
         $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') {
@@ -1552,10 +1555,11 @@ sub disk_usage {
            }
          },
          $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};
@@ -1638,15 +1642,20 @@ sub scan_cache {
                             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;
@@ -2829,6 +2838,7 @@ sub format_result {
         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,
@@ -2931,9 +2941,9 @@ sub mywarn {
 #-> 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?
@@ -2984,8 +2994,11 @@ sub unrecoverable_error {
 #-> 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 ;
@@ -3077,7 +3090,7 @@ sub rematein {
             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(
@@ -3231,6 +3244,7 @@ sub recent {
                         notest
                         perldoc
                         readme
+                        reports
                         test
                        )) {
         *$command = sub { shift->rematein($command, @_); };
@@ -3664,20 +3678,6 @@ sub localize {
                     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};
             }
@@ -4637,7 +4637,10 @@ sub reanimate_build_dir {
             # $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}
                     ||
@@ -5467,6 +5470,12 @@ sub dir_listing {
     @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;
 
@@ -5477,14 +5486,20 @@ sub cpan_comment {
     $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;
@@ -5717,6 +5732,7 @@ sub get {
 
   EXCUSE: {
        my @e;
+        my $goodbye_message;
         $self->debug("checking disabled id[$self->{ID}]") if $CPAN::DEBUG;
         if ($self->prefs->{disabled}) {
             my $why = sprintf(
@@ -5725,11 +5741,14 @@ sub get {
                               $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} && -d $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"
@@ -5747,15 +5766,35 @@ sub get {
                                           )
                 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(
@@ -5779,22 +5818,27 @@ sub get {
 
     $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);
@@ -5812,7 +5856,6 @@ and fix the problem, then retry.
 EOF
     }
     if ($CPAN::Signal){
-        $self->safe_chdir($sub_wd);
         return;
     }
     $self->safe_chdir("tmp-$$");
@@ -5820,6 +5863,7 @@ EOF
     #
     # Unpack the goods
     #
+    my $local_file = $self->{localfile};
     my $ct = eval{CPAN::Tarzip->new($local_file)};
     unless ($ct) {
         $self->{unwrapped} = CPAN::Distrostatus->new("NO");
@@ -5926,11 +5970,6 @@ EOF
             }
         }
     }
-    if ($CPAN::Signal){
-        $self->safe_chdir($sub_wd);
-        return;
-    }
-
     $self->{build_dir} = $packagedir;
     $self->safe_chdir($builddir);
     File::Path::rmtree("tmp-$$");
@@ -5938,9 +5977,13 @@ EOF
     $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) {
@@ -5981,7 +6024,6 @@ EOF
        ) {
         $self->store_persistent_state;
     }
-
     return $self;
 }
 
@@ -6028,81 +6070,99 @@ sub try_download {
                                $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 {
-                    my $fail = "Could not find patch '$patch'";
+                    $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 $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 {
@@ -6169,7 +6229,7 @@ We\'ll try to build it with that Makefile then.
             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";
@@ -6925,7 +6985,9 @@ is part of the perl-%s distribution. To install that, you need to run
         }
 
        if (defined $self->{make}) {
-            if ($self->{make}->failed) {
+            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 {
@@ -7072,7 +7134,7 @@ is part of the perl-%s distribution. To install that, you need to run
                     ->new("NO '$system' returned status $ret");
                 $CPAN::Frontend->mywarn("Warning: No success on command[$system]\n");
                 $self->store_persistent_state;
-                return;
+                return $self->goodbye("$system -- NOT OK\n");
             }
        }
        if (-f "Makefile" || -f "Build") {
@@ -7094,7 +7156,7 @@ is part of the perl-%s distribution. To install that, you need to run
             $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 {
             my $follow = eval { $self->follow_prereqs(@prereq); };
             if (0) {
@@ -7103,7 +7165,7 @@ is part of the perl-%s distribution. To install that, you need to run
                 return 1;
             } elsif ($@ && ref $@ && $@->isa("CPAN::Exception::RecursiveDependency")) {
                 $CPAN::Frontend->mywarn($@);
-                return;
+                return $self->goodbye("[depend] -- NOT OK\n");
             }
         }
     }
@@ -7119,7 +7181,7 @@ is part of the perl-%s distribution. To install that, you need to run
             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};
@@ -7170,7 +7232,15 @@ is part of the perl-%s distribution. To install that, you need to run
     $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;
@@ -8073,11 +8143,7 @@ sub test {
     }
     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");
@@ -8147,7 +8213,7 @@ sub test {
                 $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");
             }
         }
 
@@ -8277,7 +8343,7 @@ sub goto {
     # 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);
 }
 
@@ -8557,6 +8623,7 @@ Could not fork '$html_converter $saved_file': $!});
             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,
@@ -8616,6 +8683,7 @@ sub _getsave_url {
     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,
@@ -8681,6 +8749,91 @@ sub _build_command {
     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;
 
@@ -8959,26 +9112,27 @@ package CPAN::Module;
 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};
@@ -9243,6 +9397,7 @@ sub as_string {
     join "", @m, "\n";
 }
 
+#-> sub CPAN::Module::manpage_headline
 sub manpage_headline {
   my($self,$local_file) = @_;
   my(@local_file) = $local_file;
@@ -9558,6 +9713,12 @@ sub parse_version {
     $have; # no stringify needed, \s* above matches always
 }
 
+#-> sub CPAN::Module::reports
+sub reports {
+    my($self) = @_;
+    $self->distribution->reports;
+}
+
 package CPAN;
 use strict;
 
@@ -10906,6 +11067,11 @@ undef otherwise.
 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:
@@ -11098,6 +11264,10 @@ Runs a C<perldoc> on this module.
 
 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.