Update CPAN.pm to 1.93_03
[p5sagit/p5-mst-13.2.git] / lib / CPAN / HandleConfig.pm
index 4f4b5a3..ce68f90 100644 (file)
@@ -1,8 +1,8 @@
 package CPAN::HandleConfig;
 use strict;
-use vars qw(%can %keys $VERSION);
+use vars qw(%can %keys $loading $VERSION);
 
-$VERSION = sprintf "%.6f", substr(q$Rev: 1264 $,4)/1000000 + 5.4;
+$VERSION = "5.5";
 
 %can = (
         commit   => "Commit changes to disk",
@@ -14,8 +14,17 @@ $VERSION = sprintf "%.6f", substr(q$Rev: 1264 $,4)/1000000 + 5.4;
 # Q: where is the "How do I add a new config option" HOWTO?
 # A1: svn diff -r 757:758 # where dagolden added test_report
 # A2: svn diff -r 985:986 # where andk added yaml_module
+# A3: 1. add new config option to %keys below
+#     2. add a Pod description in CPAN::FirstTime; it should include a
+#        prompt line; see others for examples
+#     3. add a "matcher" section in CPAN::FirstTime::init that includes
+#        a prompt function; see others for examples
+#     4. add config option to documentation section in CPAN.pm
+
 %keys = map { $_ => undef }
     (
+     "applypatch",
+     "auto_commit",
      "build_cache",
      "build_dir",
      "build_dir_reuse",
@@ -23,11 +32,13 @@ $VERSION = sprintf "%.6f", substr(q$Rev: 1264 $,4)/1000000 + 5.4;
      "bzip2",
      "cache_metadata",
      "check_sigs",
+     "colorize_debug",
      "colorize_output",
      "colorize_print",
      "colorize_warn",
      "commandnumber_in_prompt",
      "commands_quote",
+     "connect_to_internet_ok",
      "cpan_home",
      "curl",
      "dontload_hash", # deprecated after 1.83_68 (rev. 581)
@@ -35,9 +46,12 @@ $VERSION = sprintf "%.6f", substr(q$Rev: 1264 $,4)/1000000 + 5.4;
      "ftp",
      "ftp_passive",
      "ftp_proxy",
+     "ftpstats_size",
+     "ftpstats_period",
      "getcwd",
      "gpg",
      "gzip",
+     "halt_on_failure",
      "histfile",
      "histsize",
      "http_proxy",
@@ -45,6 +59,7 @@ $VERSION = sprintf "%.6f", substr(q$Rev: 1264 $,4)/1000000 + 5.4;
      "index_expire",
      "inhibit_startup_message",
      "keep_source_where",
+     "load_module_verbosity",
      "lynx",
      "make",
      "make_arg",
@@ -61,51 +76,44 @@ $VERSION = sprintf "%.6f", substr(q$Rev: 1264 $,4)/1000000 + 5.4;
      "pager",
      "password",
      "patch",
+     "perl5lib_verbosity",
      "prefer_installer",
-     "prerequisites_policy",
      "prefs_dir",
+     "prerequisites_policy",
      "proxy_pass",
      "proxy_user",
      "randomize_urllist",
      "scan_cache",
      "shell",
+     "show_unparsable_versions",
      "show_upload_date",
+     "show_zero_versions",
      "tar",
+     "tar_verbosity",
      "term_is_latin",
      "term_ornaments",
      "test_report",
+     "trust_test_report_history",
      "unzip",
      "urllist",
+     "use_sqlite",
      "username",
      "wait_list",
      "wget",
+     "yaml_load_code",
      "yaml_module",
     );
 
 my %prefssupport = map { $_ => 1 }
     (
      "build_requires_install_policy",
+     "check_sigs",
      "make",
      "make_install_make_command",
      "prefer_installer",
      "test_report",
     );
 
-if ($^O eq "MSWin32") {
-    for my $k (qw(
-                  mbuild_install_build_command
-                  make_install_make_command
-                 )) {
-        delete $keys{$k};
-        if (exists $CPAN::Config->{$k}) {
-            for ("deleting previously set config variable '$k' => '$CPAN::Config->{$k}'") {
-                $CPAN::Frontend ? $CPAN::Frontend->mywarn($_) : warn $_;
-            }
-            delete $CPAN::Config->{$k};
-        }
-    }
-}
-
 # returns true on successful action
 sub edit {
     my($self,@args) = @_;
@@ -113,106 +121,133 @@ sub edit {
     CPAN->debug("self[$self]args[".join(" | ",@args)."]");
     my($o,$str,$func,$args,$key_exists);
     $o = shift @args;
-    $DB::single = 1;
     if($can{$o}) {
-       $self->$o(args => \@args); # o conf init => sub init => sub load
-       return 1;
+        $self->$o(args => \@args); # o conf init => sub init => sub load
+        return 1;
     } else {
         CPAN->debug("o[$o]") if $CPAN::DEBUG;
         unless (exists $keys{$o}) {
             $CPAN::Frontend->mywarn("Warning: unknown configuration variable '$o'\n");
         }
+        my $changed;
+
+
         # one day I used randomize_urllist for a boolean, so we must
         # list them explicitly --ak
-       if ($o =~ /^(wait_list|urllist|dontload_list)$/) {
-           $func = shift @args;
-           $func ||= "";
+        if (0) {
+        } elsif ($o =~ /^(wait_list|urllist|dontload_list)$/) {
+
+            #
+            # ARRAYS
+            #
+
+            $func = shift @args;
+            $func ||= "";
             CPAN->debug("func[$func]args[@args]") if $CPAN::DEBUG;
-            my $changed;
-           # Let's avoid eval, it's easier to comprehend without.
-           if ($func eq "push") {
-               push @{$CPAN::Config->{$o}}, @args;
+            # Let's avoid eval, it's easier to comprehend without.
+            if ($func eq "push") {
+                push @{$CPAN::Config->{$o}}, @args;
                 $changed = 1;
-           } elsif ($func eq "pop") {
-               pop @{$CPAN::Config->{$o}};
+            } elsif ($func eq "pop") {
+                pop @{$CPAN::Config->{$o}};
                 $changed = 1;
-           } elsif ($func eq "shift") {
-               shift @{$CPAN::Config->{$o}};
+            } elsif ($func eq "shift") {
+                shift @{$CPAN::Config->{$o}};
                 $changed = 1;
-           } elsif ($func eq "unshift") {
-               unshift @{$CPAN::Config->{$o}}, @args;
+            } elsif ($func eq "unshift") {
+                unshift @{$CPAN::Config->{$o}}, @args;
                 $changed = 1;
-           } elsif ($func eq "splice") {
+            } elsif ($func eq "splice") {
                 my $offset = shift @args || 0;
                 my $length = shift @args || 0;
-               splice @{$CPAN::Config->{$o}}, $offset, $length, @args; # may warn
+                splice @{$CPAN::Config->{$o}}, $offset, $length, @args; # may warn
                 $changed = 1;
-           } elsif ($func) {
-               $CPAN::Config->{$o} = [$func, @args];
+            } elsif ($func) {
+                $CPAN::Config->{$o} = [$func, @args];
                 $changed = 1;
-           } else {
+            } else {
                 $self->prettyprint($o);
-           }
+            }
             if ($changed) {
-                $CPAN::CONFIG_DIRTY = 1;
                 if ($o eq "urllist") {
                     # reset the cached values
                     undef $CPAN::FTP::Thesite;
                     undef $CPAN::FTP::Themethod;
+                    $CPAN::Index::LAST_TIME = 0;
                 } elsif ($o eq "dontload_list") {
                     # empty it, it will be built up again
                     $CPAN::META->{dontload_hash} = {};
                 }
             }
-            return $changed;
         } elsif ($o =~ /_hash$/) {
-            if (@args==1 && $args[0] eq ""){
+
+            #
+            # HASHES
+            #
+
+            if (@args==1 && $args[0] eq "") {
                 @args = ();
             } elsif (@args % 2) {
                 push @args, "";
             }
             $CPAN::Config->{$o} = { @args };
-            $CPAN::CONFIG_DIRTY = 1;
+            $changed = 1;
         } else {
-            if (defined $args[0]){
+
+            #
+            # SCALARS
+            #
+
+            if (defined $args[0]) {
                 $CPAN::CONFIG_DIRTY = 1;
                 $CPAN::Config->{$o} = $args[0];
+                $changed = 1;
             }
-           $self->prettyprint($o)
+            $self->prettyprint($o)
                 if exists $keys{$o} or defined $CPAN::Config->{$o};
-            return 1;
-       }
+        }
+        if ($changed) {
+            if ($CPAN::Config->{auto_commit}) {
+                $self->commit;
+            } else {
+                $CPAN::CONFIG_DIRTY = 1;
+                $CPAN::Frontend->myprint("Please use 'o conf commit' to ".
+                                         "make the config permanent!\n\n");
+            }
+        }
     }
 }
 
 sub prettyprint {
-  my($self,$k) = @_;
-  my $v = $CPAN::Config->{$k};
-  if (ref $v) {
-    my(@report);
-    if (ref $v eq "ARRAY") {
-      @report = map {"\t$_ \[$v->[$_]]\n"} 0..$#$v;
+    my($self,$k) = @_;
+    my $v = $CPAN::Config->{$k};
+    if (ref $v) {
+        my(@report);
+        if (ref $v eq "ARRAY") {
+            @report = map {"\t$_ \[$v->[$_]]\n"} 0..$#$v;
+        } else {
+            @report = map
+                {
+                    sprintf "\t%-18s => %s\n",
+                               "[$_]",
+                                        defined $v->{$_} ? "[$v->{$_}]" : "undef"
+                } keys %$v;
+        }
+        $CPAN::Frontend->myprint(
+                                 join(
+                                      "",
+                                      sprintf(
+                                              "    %-18s\n",
+                                              $k
+                                             ),
+                                      @report
+                                     )
+                                );
+    } elsif (defined $v) {
+        $CPAN::Frontend->myprint(sprintf "    %-18s [%s]\n", $k, $v);
     } else {
-      @report = map { sprintf("\t%-18s => %s\n",
-                              map { "[$_]" } $_,
-                              defined $v->{$_} ? $v->{$_} : "UNDEFINED"
-                             )} keys %$v;
+        $CPAN::Frontend->myprint(sprintf "    %-18s undef\n", $k);
     }
-    $CPAN::Frontend->myprint(
-                             join(
-                                  "",
-                                  sprintf(
-                                          "    %-18s\n",
-                                          $k
-                                         ),
-                                  @report
-                                 )
-                            );
-  } elsif (defined $v) {
-    $CPAN::Frontend->myprint(sprintf "    %-18s [%s]\n", $k, $v);
-  } else {
-    $CPAN::Frontend->myprint(sprintf "    %-18s [%s]\n", $k, "UNDEFINED");
-  }
 }
 
 sub commit {
@@ -233,10 +268,10 @@ sub commit {
         $configpm = $args[0];
       }
     }
-    unless (defined $configpm){
-       $configpm ||= $INC{"CPAN/MyConfig.pm"};
-       $configpm ||= $INC{"CPAN/Config.pm"};
-       $configpm || Carp::confess(q{
+    unless (defined $configpm) {
+        $configpm ||= $INC{"CPAN/MyConfig.pm"};
+        $configpm ||= $INC{"CPAN/Config.pm"};
+        $configpm || Carp::confess(q{
 CPAN::Config::commit called without an argument.
 Please specify a filename where to save the configuration or try
 "o conf init" to have an interactive course through configing.
@@ -244,19 +279,20 @@ Please specify a filename where to save the configuration or try
     }
     my($mode);
     if (-f $configpm) {
-       $mode = (stat $configpm)[2];
-       if ($mode && ! -w _) {
-           Carp::confess("$configpm is not writable");
-       }
+        $mode = (stat $configpm)[2];
+        if ($mode && ! -w _) {
+            Carp::confess("$configpm is not writable");
+        }
     }
 
     my $msg;
+    my $home = home();
     $msg = <<EOF unless $configpm =~ /MyConfig/;
 
 # This is CPAN.pm's systemwide configuration file. This file provides
 # defaults for users, and the values can be changed in a per-user
 # configuration file. The user-config file is being looked for as
-# ~/.cpan/CPAN/MyConfig.pm.
+# $home/.cpan/CPAN/MyConfig.pm.
 
 EOF
     $msg ||= "\n";
@@ -267,15 +303,15 @@ EOF
     $fh->print(qq[$msg\$CPAN::Config = \{\n]);
     foreach (sort keys %$CPAN::Config) {
         unless (exists $keys{$_}) {
-            $CPAN::Frontend->mywarn("Dropping unknown config variable '$_'\n");
-            delete $CPAN::Config->{$_};
+            # do not drop them: forward compatibility!
+            $CPAN::Frontend->mywarn("Unknown config variable '$_'\n");
             next;
         }
-       $fh->print(
-                  "  '$_' => ",
-                  $self->neatvalue($CPAN::Config->{$_}),
-                  ",\n"
-                 );
+        $fh->print(
+            "  '$_' => ",
+            $self->neatvalue($CPAN::Config->{$_}),
+            ",\n"
+        );
     }
 
     $fh->print("};\n1;\n__END__\n");
@@ -296,7 +332,7 @@ sub neatvalue {
     my($self, $v) = @_;
     return "undef" unless defined $v;
     my($t) = ref $v;
-    unless ($t){
+    unless ($t) {
         $v =~ s/\\/\\\\/g;
         return "q[$v]";
     }
@@ -312,7 +348,7 @@ sub neatvalue {
     }
     return "$v" unless $t eq 'HASH';
     my(@m, $key, $val);
-    while (($key,$val) = each %$v){
+    while (($key,$val) = each %$v) {
         last unless defined $key; # cautious programming in case (undef,undef) is true
         push(@m,"q[$key]=>".$self->neatvalue($val)) ;
     }
@@ -332,7 +368,7 @@ sub defaults {
     for my $config (qw(CPAN/MyConfig.pm CPAN/Config.pm)) {
         if ($INC{$config}) {
             CPAN->debug("INC{'$config'}[$INC{$config}]") if $CPAN::DEBUG;
-            CPAN::Shell->reload_this($config,{force => 1});
+            CPAN::Shell->_reload_this($config,{reloforce => 1});
             $CPAN::Frontend->myprint("'$INC{$config}' reread\n");
             last;
         }
@@ -377,7 +413,7 @@ else: quote it with the correct quote type for the box we're on
     my ($quotes,$use_quote)
         = $^O eq 'MSWin32'
             ? ('"', '"')
-                : (q<"'>, "'")
+                : (q{"'}, "'")
                     ;
 
     sub safe_quote {
@@ -397,12 +433,8 @@ else: quote it with the correct quote type for the box we're on
 
 sub init {
     my($self,@args) = @_;
-    undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
-                                                      # have the least
-                                                      # important
-                                                      # variable
-                                                      # undefined
-    $self->load(@args);
+    CPAN->debug("self[$self]args[".join(",",@args)."]");
+    $self->load(doit => 1, @args);
     1;
 }
 
@@ -410,7 +442,7 @@ sub init {
 # maintainability.  RMB
 #
 sub _configpmtest {
-    my($configpmdir, $configpmtest) = @_; 
+    my($configpmdir, $configpmtest) = @_;
     if (-w $configpmtest) {
         return $configpmtest;
     } elsif (-w $configpmdir) {
@@ -419,20 +451,20 @@ sub _configpmtest {
         unlink $configpm_bak if -f $configpm_bak;
         if( -f $configpmtest ) {
             if( rename $configpmtest, $configpm_bak ) {
-                               $CPAN::Frontend->mywarn(<<END);
+                $CPAN::Frontend->mywarn(<<END);
 Old configuration file $configpmtest
     moved to $configpm_bak
 END
-           }
-       }
-       my $fh = FileHandle->new;
-       if ($fh->open(">$configpmtest")) {
-           $fh->print("1;\n");
-           return $configpmtest;
-       } else {
-           # Should never happen
-           Carp::confess("Cannot open >$configpmtest");
-       }
+            }
+        }
+        my $fh = FileHandle->new;
+        if ($fh->open(">$configpmtest")) {
+            $fh->print("1;\n");
+            return $configpmtest;
+        } else {
+            # Should never happen
+            Carp::confess("Cannot open >$configpmtest");
+        }
     } else { return }
 }
 
@@ -457,49 +489,69 @@ sub require_myconfig_or_config () {
 
 sub home () {
     my $home;
+    # Suppress load messages until we load the config and know whether
+    # load messages are desired.  Otherwise, it's unexpected and odd 
+    # why one load message pops up even when verbosity is turned off.
+    # This means File::HomeDir load messages are never seen, but I
+    # think that's probably OK -- DAGOLDEN
+    
+    # 5.6.2 seemed to segfault localizing a value in a hashref 
+    # so do it manually instead
+    my $old_v = $CPAN::Config->{load_module_verbosity};
+    $CPAN::Config->{load_module_verbosity} = q[none];
     if ($CPAN::META->has_usable("File::HomeDir")) {
-        $home = File::HomeDir->my_data;
-    } else {
+        $home = File::HomeDir->can('my_dot_config')
+            ? File::HomeDir->my_dot_config
+                : File::HomeDir->my_data;
+        unless (defined $home) {
+            $home = File::HomeDir->my_home
+        }
+    }
+    unless (defined $home) {
         $home = $ENV{HOME};
     }
+    $CPAN::Config->{load_module_verbosity} = $old_v;
     $home;
 }
 
 sub load {
     my($self, %args) = @_;
-       $CPAN::Be_Silent++ if $args{be_silent};
+    $CPAN::Be_Silent++ if $args{be_silent};
+    my $doit;
+    $doit = delete $args{doit};
 
-    my(@miss);
     use Carp;
     require_myconfig_or_config;
-    return unless @miss = $self->missing_config_data;
+    my @miss = $self->missing_config_data;
+    return unless $doit || @miss;
+    return if $loading;
+    $loading++;
 
     require CPAN::FirstTime;
-    my($configpm,$fh,$redo,$theycalled);
+    my($configpm,$fh,$redo);
     $redo ||= "";
-    $theycalled++ if @miss==1 && $miss[0] eq 'inhibit_startup_message';
     if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
-       $configpm = $INC{"CPAN/Config.pm"};
-       $redo++;
+        $configpm = $INC{"CPAN/Config.pm"};
+        $redo++;
     } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
-       $configpm = $INC{"CPAN/MyConfig.pm"};
-       $redo++;
+        $configpm = $INC{"CPAN/MyConfig.pm"};
+        $redo++;
     } else {
-       my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
-       my($configpmdir) = File::Spec->catdir($path_to_cpan,"CPAN");
-       my($configpmtest) = File::Spec->catfile($configpmdir,"Config.pm");
+        my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
+        my($configpmdir) = File::Spec->catdir($path_to_cpan,"CPAN");
+        my($configpmtest) = File::Spec->catfile($configpmdir,"Config.pm");
         my $inc_key;
-       if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
-           $configpm = _configpmtest($configpmdir,$configpmtest);
+        if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
+            $configpm = _configpmtest($configpmdir,$configpmtest);
             $inc_key = "CPAN/Config.pm";
-       }
-       unless ($configpm) {
-           $configpmdir = File::Spec->catdir(home,".cpan","CPAN");
-           File::Path::mkpath($configpmdir);
-           $configpmtest = File::Spec->catfile($configpmdir,"MyConfig.pm");
-           $configpm = _configpmtest($configpmdir,$configpmtest);
+        }
+        unless ($configpm) {
+            $configpmdir = File::Spec->catdir(home,".cpan","CPAN");
+            File::Path::mkpath($configpmdir);
+            $configpmtest = File::Spec->catfile($configpmdir,"MyConfig.pm");
+            $configpm = _configpmtest($configpmdir,$configpmtest);
             $inc_key = "CPAN/MyConfig.pm";
-       }
+        }
         if ($configpm) {
           $INC{$inc_key} = $configpm;
         } else {
@@ -510,27 +562,25 @@ sub load {
 
     }
     local($") = ", ";
-    if ($redo && ! $theycalled){
+    if ($redo && !$doit) {
         $CPAN::Frontend->myprint(<<END);
 Sorry, we have to rerun the configuration dialog for CPAN.pm due to
-the following indispensable but missing parameters:
+some missing parameters...
 
-@miss
 END
         $args{args} = \@miss;
     }
-    if (0) {
-        # where do we need this?
-        $CPAN::Frontend->myprint(qq{
-$configpm initialized.
-});
-    }
     CPAN::FirstTime::init($configpm, %args);
+    $loading--;
+    return;
 }
 
+
+# returns mandatory but missing entries in the Config
 sub missing_config_data {
     my(@miss);
     for (
+         "auto_commit",
          "build_cache",
          "build_dir",
          "cache_metadata",
@@ -539,7 +589,7 @@ sub missing_config_data {
          #"gzip",
          "http_proxy",
          "index_expire",
-         "inhibit_startup_message",
+         #"inhibit_startup_message",
          "keep_source_where",
          #"make",
          "make_arg",
@@ -547,7 +597,7 @@ sub missing_config_data {
          "makepl_arg",
          "mbuild_arg",
          "mbuild_install_arg",
-         "mbuild_install_build_command",
+         ($^O eq "MSWin32" ? "" : "mbuild_install_build_command"),
          "mbuildpl_arg",
          "no_proxy",
          #"pager",
@@ -558,7 +608,7 @@ sub missing_config_data {
          "urllist",
         ) {
         next unless exists $keys{$_};
-       push @miss, $_ unless defined $CPAN::Config->{$_};
+        push @miss, $_ unless defined $CPAN::Config->{$_};
     }
     return @miss;
 }
@@ -588,17 +638,17 @@ sub cpl {
     CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
     my(@words) = split " ", substr($line,0,$pos+1);
     if (
-       defined($words[2])
-       and
+        defined($words[2])
+        and
         $words[2] =~ /list$/
         and
-       (
-        @words == 3
-        ||
-        @words == 4 && length($word)
-       )
+        (
+        @words == 3
+        ||
+        @words == 4 && length($word)
+        )
        ) {
-       return grep /^\Q$word\E/, qw(splice shift unshift pop push);
+        return grep /^\Q$word\E/, qw(splice shift unshift pop push);
     } elsif (defined($words[2])
              and
              $words[2] eq "init"
@@ -608,9 +658,9 @@ sub cpl {
              ||
              @words >= 4 && length($word)
             )) {
-       return sort grep /^\Q$word\E/, keys %keys;
+        return sort grep /^\Q$word\E/, keys %keys;
     } elsif (@words >= 4) {
-       return ();
+        return ();
     }
     my %seen;
     my(@o_conf) =  sort grep { !$seen{$_}++ }
@@ -622,10 +672,17 @@ sub cpl {
 
 sub prefs_lookup {
     my($self,$distro,$what) = @_;
+
     if ($prefssupport{$what}) {
-        return $distro->prefs->{cpanconfig}{$what} || $CPAN::Config->{$what};
+        return $CPAN::Config->{$what} unless
+            $distro
+                and $distro->prefs
+                    and $distro->prefs->{cpanconfig}
+                        and defined $distro->prefs->{cpanconfig}{$what};
+        return $distro->prefs->{cpanconfig}{$what};
     } else {
-        warn "Warning: $what no yet officially supported for distroprefs, doing a normal lookup";
+        $CPAN::Frontend->mywarn("Warning: $what not yet officially ".
+                                "supported for distroprefs, doing a normal lookup");
         return $CPAN::Config->{$what};
     }
 }
@@ -644,10 +701,11 @@ sub prefs_lookup {
 
     use strict;
     use vars qw($AUTOLOAD $VERSION);
-    $VERSION = sprintf "%.2f", substr(q$Rev: 1264 $,4)/100;
+    $VERSION = "5.5";
 
     # formerly CPAN::HandleConfig was known as CPAN::Config
     sub AUTOLOAD {
+        my $class = shift; # e.g. in dh-make-perl: CPAN::Config
         my($l) = $AUTOLOAD;
         $CPAN::Frontend->mywarn("Dispatching deprecated method '$l' to CPAN::HandleConfig\n");
         $l =~ s/.*:://;