Upgrade to CPAN-1.9101
[p5sagit/p5-mst-13.2.git] / lib / CPAN / FirstTime.pm
1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
2 package CPAN::Mirrored::By;
3 use strict;
4
5 sub new {
6     my($self,@arg) = @_;
7     bless [@arg], $self;
8 }
9 sub continent { shift->[0] }
10 sub country { shift->[1] }
11 sub url { shift->[2] }
12
13 package CPAN::FirstTime;
14 use strict;
15
16 use ExtUtils::MakeMaker ();
17 use FileHandle ();
18 use File::Basename ();
19 use File::Path ();
20 use File::Spec ();
21 use vars qw($VERSION $urllist);
22 $VERSION = sprintf "%.6f", substr(q$Rev: 1669 $,4)/1000000 + 5.4;
23
24 =head1 NAME
25
26 CPAN::FirstTime - Utility for CPAN::Config file Initialization
27
28 =head1 SYNOPSIS
29
30 CPAN::FirstTime::init()
31
32 =head1 DESCRIPTION
33
34 The init routine asks a few questions and writes a CPAN/Config.pm or
35 CPAN/MyConfig.pm file (depending on what it is currently using).
36
37 =head1 LICENSE
38
39 This program is free software; you can redistribute it and/or
40 modify it under the same terms as Perl itself.
41
42 =cut
43
44 use vars qw( %prompts );
45
46 sub init {
47     my($configpm, %args) = @_;
48     use Config;
49     # extra args after 'o conf init'
50     my $matcher = $args{args} && @{$args{args}} ? $args{args}[0] : '';
51     if ($matcher =~ /^\/(.*)\/$/) {
52         # case /regex/ => take the first, ignore the rest
53         $matcher = $1;
54         shift @{$args{args}};
55         if (@{$args{args}}) {
56             local $" = " ";
57             $CPAN::Frontend->mywarn("Ignoring excessive arguments '@{$args{args}}'");
58             $CPAN::Frontend->mysleep(2);
59         }
60     } elsif (0 == length $matcher) {
61     } elsif (0 && $matcher eq "~") { # extremely buggy, but a nice idea
62         my @unconfigured = grep { not exists $CPAN::Config->{$_}
63                                       or not defined $CPAN::Config->{$_}
64                                           or not length $CPAN::Config->{$_}
65                                   } keys %$CPAN::Config;
66         $matcher = "\\b(".join("|", @unconfigured).")\\b";
67         $CPAN::Frontend->mywarn("matcher[$matcher]");
68     } else {
69         # case WORD... => all arguments must be valid
70         for my $arg (@{$args{args}}) {
71             unless (exists $CPAN::HandleConfig::keys{$arg}) {
72                 $CPAN::Frontend->mywarn("'$arg' is not a valid configuration variable\n");
73                 return;
74             }
75         }
76         $matcher = "\\b(".join("|",@{$args{args}}).")\\b";
77     }
78     CPAN->debug("matcher[$matcher]") if $CPAN::DEBUG;
79
80     unless ($CPAN::VERSION) {
81         require CPAN::Nox;
82     }
83     require CPAN::HandleConfig;
84     CPAN::HandleConfig::require_myconfig_or_config();
85     $CPAN::Config ||= {};
86     local($/) = "\n";
87     local($\) = "";
88     local($|) = 1;
89
90     my($ans,$default);
91
92     #
93     #= Files, directories
94     #
95
96     unless ($matcher) {
97         $CPAN::Frontend->myprint($prompts{manual_config});
98     }
99
100     my $manual_conf;
101
102     local *_real_prompt;
103     if ( $args{autoconfig} ) {
104         $manual_conf = "no";
105     } elsif ($matcher) {
106         $manual_conf = "yes";
107     } else {
108         my $_conf = prompt("Would you like me to configure as much as possible ".
109                            "automatically?", "yes");
110         $manual_conf = ($_conf and $_conf =~ /^y/i) ? "no" : "yes";
111     }
112     CPAN->debug("manual_conf[$manual_conf]") if $CPAN::DEBUG;
113     my $fastread;
114     {
115       if ($manual_conf =~ /^y/i) {
116         $fastread = 0;
117       } else {
118         $fastread = 1;
119         $CPAN::Config->{urllist} ||= [];
120
121         local $^W = 0;
122         # prototype should match that of &MakeMaker::prompt
123         my $current_second = time;
124         my $current_second_count = 0;
125         my $i_am_mad = 0;
126         *_real_prompt = sub {
127           my($q,$a) = @_;
128           my($ret) = defined $a ? $a : "";
129           $CPAN::Frontend->myprint(sprintf qq{%s [%s]\n\n}, $q, $ret);
130           eval { require Time::HiRes };
131           unless ($@) {
132               if (time == $current_second) {
133                   $current_second_count++;
134                   if ($current_second_count > 20) {
135                       # I don't like more than 20 prompts per second
136                       $i_am_mad++;
137                   }
138               } else {
139                   $current_second = time;
140                   $current_second_count = 0;
141                   $i_am_mad-- if $i_am_mad>0;
142               }
143               if ($i_am_mad>0){
144                   #require Carp;
145                   #Carp::cluck("SLEEEEEEEEPIIIIIIIIIIINGGGGGGGGGGG");
146                   Time::HiRes::sleep(0.1);
147               }
148           }
149           $ret;
150         };
151       }
152     }
153
154     if (!$matcher or q{
155                        build_dir
156                        build_dir_reuse
157                        cpan_home
158                        keep_source_where
159                        prefs_dir
160                       } =~ /$matcher/){
161         $CPAN::Frontend->myprint($prompts{config_intro});
162
163         if (!$matcher or 'cpan_home' =~ /$matcher/) {
164             my $cpan_home = $CPAN::Config->{cpan_home}
165                 || File::Spec->catdir($ENV{HOME}, ".cpan");
166
167             if (-d $cpan_home) {
168                 $CPAN::Frontend->myprint(qq{
169
170 I see you already have a  directory
171     $cpan_home
172 Shall we use it as the general CPAN build and cache directory?
173
174 });
175             } else {
176                 # no cpan-home, must prompt and get one
177                 $CPAN::Frontend->myprint($prompts{cpan_home_where});
178             }
179
180             $default = $cpan_home;
181             my $loop = 0;
182             my $last_ans;
183           PROMPT: while ($ans = prompt("CPAN build and cache directory?",$default)) {
184                 if (File::Spec->file_name_is_absolute($ans)) {
185                     my @cpan_home = split /[\/\\]/, $ans;
186                   DIR: for my $dir (@cpan_home) {
187                         if ($dir =~ /^~/ and (!$last_ans or $ans ne $last_ans)) {
188                             $CPAN::Frontend
189                                 ->mywarn("Warning: a tilde in the path will be ".
190                                          "taken as a literal tilde. Please ".
191                                          "confirm again if you want to keep it\n");
192                             $last_ans = $default = $ans;
193                             next PROMPT;
194                         }
195                     }
196                 } else {
197                     require Cwd;
198                     my $cwd = Cwd::cwd();
199                     my $absans = File::Spec->catdir($cwd,$ans);
200                     $CPAN::Frontend->mywarn("The path '$ans' is not an ".
201                                             "absolute path. Please specify ".
202                                             "an absolute path\n");
203                     $default = $absans;
204                     next;
205                 }
206                 eval { File::Path::mkpath($ans); }; # dies if it can't
207                 if ($@) {
208                     $CPAN::Frontend->mywarn("Couldn't create directory $ans.\n".
209                                             "Please retry.\n");
210                     next;
211                 }
212                 if (-d $ans && -w _) {
213                     last;
214                 } else {
215                     $CPAN::Frontend->mywarn("Couldn't find directory $ans\n".
216                                             "or directory is not writable. Please retry.\n");
217                     if (++$loop > 5) {
218                         $CPAN::Frontend->mydie("Giving up");
219                     }
220                 }
221             }
222             $CPAN::Config->{cpan_home} = $ans;
223         }
224
225         if (!$matcher or 'keep_source_where' =~ /$matcher/) {
226             my_dflt_prompt("keep_source_where",
227                            File::Spec->catdir($CPAN::Config->{cpan_home},"sources"),
228                            $matcher,
229                           );
230         }
231
232         if (!$matcher or 'build_dir' =~ /$matcher/) {
233             my_dflt_prompt("build_dir",
234                            File::Spec->catdir($CPAN::Config->{cpan_home},"build"),
235                            $matcher
236                           );
237         }
238
239         if (!$matcher or 'build_dir_reuse' =~ /$matcher/) {
240             my_yn_prompt(build_dir_reuse => "y", $matcher);
241         }
242
243         if (!$matcher or 'prefs_dir' =~ /$matcher/) {
244             my_dflt_prompt("prefs_dir",
245                            File::Spec->catdir($CPAN::Config->{cpan_home},"prefs"),
246                            $matcher
247                           );
248         }
249     }
250
251     #
252     #= Config: auto_commit
253     #
254
255     my_yn_prompt(auto_commit => 0, $matcher);
256
257     #
258     #= Cache size, Index expire
259     #
260
261     if (!$matcher or 'build_cache' =~ /$matcher/){
262         # large enough to build large dists like Tk
263         my_dflt_prompt(build_cache => 100, $matcher);
264     }
265
266     if (!$matcher or 'index_expire' =~ /$matcher/) {
267         my_dflt_prompt(index_expire => 1, $matcher);
268     }
269
270     if (!$matcher or 'scan_cache' =~ /$matcher/){
271         $CPAN::Frontend->myprint($prompts{scan_cache_intro});
272         my_prompt_loop(scan_cache => 'atstart', $matcher, 'atstart|never');
273     }
274
275     #
276     #= cache_metadata
277     #
278
279     my_yn_prompt(cache_metadata => 1, $matcher);
280     my_yn_prompt(use_sqlite => 0, $matcher);
281
282     #
283     #= Do we follow PREREQ_PM?
284     #
285
286     if (!$matcher or 'prerequisites_policy' =~ /$matcher/){
287         $CPAN::Frontend->myprint($prompts{prerequisites_policy_intro});
288
289         my_prompt_loop(prerequisites_policy => 'ask', $matcher,
290                        'follow|ask|ignore');
291     }
292
293     if (!$matcher or 'build_requires_install_policy' =~ /$matcher/){
294         $CPAN::Frontend->myprint($prompts{build_requires_install_policy_intro});
295
296         my_prompt_loop(build_requires_install_policy => 'ask/yes', $matcher,
297                        'yes|no|ask/yes|ask/no');
298     }
299
300     #
301     #= Module::Signature
302     #
303     if (!$matcher or 'check_sigs' =~ /$matcher/) {
304         my_yn_prompt(check_sigs => 0, $matcher);
305     }
306
307     #
308     #= CPAN::Reporter
309     #
310     if (!$matcher or 'test_report' =~ /$matcher/) {
311         my_yn_prompt(test_report => 0, $matcher);
312         if (
313             $CPAN::Config->{test_report} && 
314             $CPAN::META->has_inst("CPAN::Reporter") &&
315             CPAN::Reporter->can('configure')
316            ) {
317             $CPAN::Frontend->myprint("\nProceeding to configure CPAN::Reporter.\n");
318             CPAN::Reporter::configure();
319             $CPAN::Frontend->myprint("\nReturning to CPAN configuration.\n");
320         }
321     }
322
323     #
324     #= YAML vs. YAML::Syck
325     #
326     if (!$matcher or "yaml_module" =~ /$matcher/) {
327         my_dflt_prompt(yaml_module => "YAML", $matcher);
328         unless ($CPAN::META->has_inst($CPAN::Config->{yaml_module})) {
329             $CPAN::Frontend->mywarn
330                 ("Warning (maybe harmless): '$CPAN::Config->{yaml_module}' not installed.\n");
331             $CPAN::Frontend->mysleep(3);
332         }
333     }
334
335     #
336     #= External programs
337     #
338
339     my @external_progs = qw/bzip2 gzip tar unzip
340
341                             make
342
343                             curl lynx wget ncftpget ncftp ftp
344
345                             gpg
346
347                             patch applypatch
348                             /;
349     my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
350     if (!$matcher or "@external_progs" =~ /$matcher/) {
351         $CPAN::Frontend->myprint($prompts{external_progs});
352
353         my $old_warn = $^W;
354         local $^W if $^O eq 'MacOS';
355         local $^W = $old_warn;
356         my $progname;
357         for $progname (@external_progs) {
358             next if $matcher && $progname !~ /$matcher/;
359             if ($^O eq 'MacOS') {
360                 $CPAN::Config->{$progname} = 'not_here';
361                 next;
362             }
363
364             my $progcall = $progname;
365             unless ($matcher) {
366                 # we really don't need ncftp if we have ncftpget, but
367                 # if they chose this dialog via matcher, they shall have it
368                 next if $progname eq "ncftp" && $CPAN::Config->{ncftpget} gt " ";
369             }
370             my $path = $CPAN::Config->{$progname}
371                 || $Config::Config{$progname}
372                     || "";
373             if (File::Spec->file_name_is_absolute($path)) {
374                 # testing existence is not good enough, some have these exe
375                 # extensions
376
377                 # warn "Warning: configured $path does not exist\n" unless -e $path;
378                 # $path = "";
379             } elsif ($path =~ /^\s+$/) {
380                 # preserve disabled programs
381             } else {
382                 $path = '';
383             }
384             unless ($path) {
385                 # e.g. make -> nmake
386                 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
387             }
388
389             $path ||= find_exe($progcall,\@path);
390             unless ($path){ # not -e $path, because find_exe already checked that
391                 local $"=";";
392                 $CPAN::Frontend->mywarn("Warning: $progcall not found in PATH[@path]\n");
393                 if ($progname eq "make") {
394                     $CPAN::Frontend->mywarn("ALERT: 'make' is an essential tool for ".
395                                             "building perl Modules. Please make sure you ".
396                                             "have 'make' (or some equivalent) ".
397                                             "working.\n"
398                                            );
399                     if ($^O eq "MSWin32") {
400                         $CPAN::Frontend->mywarn("
401 Windows users may want to follow this procedure when back in the CPAN shell:
402
403     look YVES/scripts/alien_nmake.pl
404     perl alien_nmake.pl
405
406 This will install nmake on your system which can be used as a 'make'
407 substitute. You can then revisit this dialog with
408
409     o conf init make
410
411 ");
412                     }
413                 }
414             }
415             $ans = prompt("Where is your $progname program?",$path) || $path;
416             $CPAN::Config->{$progname} = $ans;
417         }
418     }
419
420     if (!$matcher or 'pager' =~ /$matcher/) {
421         my $path = $CPAN::Config->{'pager'} || 
422             $ENV{PAGER} || find_exe("less",\@path) || 
423                 find_exe("more",\@path) || ($^O eq 'MacOS' ? $ENV{EDITOR} : 0 )
424                     || "more";
425         $ans = prompt("What is your favorite pager program?",$path);
426         $CPAN::Config->{'pager'} = $ans;
427     }
428
429     if (!$matcher or 'shell' =~ /$matcher/) {
430         my $path = $CPAN::Config->{'shell'};
431         if ($path && File::Spec->file_name_is_absolute($path)) {
432             $CPAN::Frontend->mywarn("Warning: configured $path does not exist\n")
433                 unless -e $path;
434             $path = "";
435         }
436         $path ||= $ENV{SHELL};
437         $path ||= $ENV{COMSPEC} if $^O eq "MSWin32";
438         if ($^O eq 'MacOS') {
439             $CPAN::Config->{'shell'} = 'not_here';
440         } else {
441             $path =~ s,\\,/,g if $^O eq 'os2';  # Cosmetic only
442             $ans = prompt("What is your favorite shell?",$path);
443             $CPAN::Config->{'shell'} = $ans;
444         }
445     }
446
447     #
448     #= Installer, arguments to make etc.
449     #
450
451     if (!$matcher or 'prefer_installer' =~ /$matcher/){
452         $CPAN::Frontend->myprint($prompts{prefer_installer_intro});
453
454         my_prompt_loop(prefer_installer => 'EUMM', $matcher, 'MB|EUMM');
455     }
456
457     if (!$matcher or 'makepl_arg make_arg' =~ /$matcher/){
458         my_dflt_prompt(makepl_arg => "", $matcher);
459         my_dflt_prompt(make_arg => "", $matcher);
460     }
461
462     require CPAN::HandleConfig;
463     if (exists $CPAN::HandleConfig::keys{make_install_make_command}) {
464         # as long as Windows needs $self->_build_command, we cannot
465         # support sudo on windows :-)
466         my_dflt_prompt(make_install_make_command => $CPAN::Config->{make} || "",
467                        $matcher);
468     }
469
470     my_dflt_prompt(make_install_arg => $CPAN::Config->{make_arg} || "", 
471                    $matcher);
472
473     if (!$matcher or 'mbuildpl_arg mbuild_arg' =~ /$matcher/){
474         my_dflt_prompt(mbuildpl_arg => "", $matcher);
475         my_dflt_prompt(mbuild_arg => "", $matcher);
476     }
477
478     if (exists $CPAN::HandleConfig::keys{mbuild_install_build_command}) {
479         # as long as Windows needs $self->_build_command, we cannot
480         # support sudo on windows :-)
481         my_dflt_prompt(mbuild_install_build_command => "./Build", $matcher);
482     }
483
484     my_dflt_prompt(mbuild_install_arg => "", $matcher);
485
486     #
487     #= Alarm period
488     #
489
490     if (!$matcher or 'inactivity_timeout' =~ /$matcher/) {
491         $CPAN::Frontend->myprint($prompts{inactivity_timeout_intro});
492         $default = $CPAN::Config->{inactivity_timeout} || 0;
493         $CPAN::Config->{inactivity_timeout} =
494             prompt("Timeout for inactivity during {Makefile,Build}.PL?",$default);
495     }
496
497     #
498     #= Proxies
499     #
500
501     my @proxy_vars = qw/ftp_proxy http_proxy no_proxy/;
502     my @proxy_user_vars = qw/proxy_user proxy_pass/;
503     if (!$matcher or "@proxy_vars @proxy_user_vars" =~ /$matcher/){
504         $CPAN::Frontend->myprint($prompts{proxy_intro});
505
506         for (@proxy_vars) {
507             if (!$matcher or /$matcher/){
508                 $default = $CPAN::Config->{$_} || $ENV{$_} || "";
509                 $CPAN::Config->{$_} = prompt("Your $_?",$default);
510             }
511         }
512
513         if ($CPAN::Config->{ftp_proxy} ||
514             $CPAN::Config->{http_proxy}) {
515
516             $default = $CPAN::Config->{proxy_user} || $CPAN::LWP::UserAgent::USER || "";
517
518             $CPAN::Frontend->myprint($prompts{proxy_user});
519
520             if ($CPAN::Config->{proxy_user} = prompt("Your proxy user id?",$default)) {
521                 $CPAN::Frontend->myprint($prompts{proxy_pass});
522
523                 if ($CPAN::META->has_inst("Term::ReadKey")) {
524                     Term::ReadKey::ReadMode("noecho");
525                 } else {
526                     $CPAN::Frontend->myprint($prompts{password_warn});
527                 }
528                 $CPAN::Config->{proxy_pass} = prompt_no_strip("Your proxy password?");
529                 if ($CPAN::META->has_inst("Term::ReadKey")) {
530                     Term::ReadKey::ReadMode("restore");
531                 }
532                 $CPAN::Frontend->myprint("\n\n");
533             }
534         }
535     }
536
537     #
538     #= how FTP works
539     #
540
541     my_yn_prompt(ftp_passive => 1, $matcher);
542
543     #
544     #= how cwd works
545     #
546
547     if (!$matcher or 'getcwd' =~ /$matcher/){
548         $CPAN::Frontend->myprint($prompts{getcwd_intro});
549
550         my_prompt_loop(getcwd => 'cwd', $matcher,
551                        'cwd|getcwd|fastcwd|backtickcwd');
552     }
553
554     #
555     #= the CPAN shell itself (prompt, color)
556     #
557
558     my_yn_prompt(commandnumber_in_prompt => 1, $matcher);
559     my_yn_prompt(term_ornaments => 1, $matcher);
560     if ("colorize_output colorize_print colorize_warn colorize_debug" =~ $matcher) {
561         my_yn_prompt(colorize_output => 0, $matcher);
562         if ($CPAN::Config->{colorize_output}) {
563             if ($CPAN::META->has_inst("Term::ANSIColor")) {
564                 my $T="gYw";
565                 print "                                      on_  on_y ".
566                     "        on_ma           on_\n"; 
567                 print "                   on_black on_red  green ellow ".
568                     "on_blue genta on_cyan white\n";
569
570                 for my $FG ("", "bold",
571                             map {$_,"bold $_"} "black","red","green",
572                             "yellow","blue",
573                             "magenta",
574                             "cyan","white"){
575                     printf "%12s ", $FG;
576                     for my $BG ("",map {"on_$_"} qw(black red green yellow
577                                                     blue magenta cyan white)){
578                         print $FG||$BG ?
579                             Term::ANSIColor::colored("  $T  ","$FG $BG") : "  $T  ";
580                     }
581                     print "\n";
582                 }
583                 print "\n";
584             }
585             for my $tuple (
586                            ["colorize_print", "bold blue on_white"],
587                            ["colorize_warn", "bold red on_white"],
588                            ["colorize_debug", "black on_cyan"],
589                           ) {
590                 my_dflt_prompt($tuple->[0] => $tuple->[1], $matcher);
591                 if ($CPAN::META->has_inst("Term::ANSIColor")) {
592                     eval { Term::ANSIColor::color($CPAN::Config->{$tuple->[0]})};
593                     if ($@) {
594                         $CPAN::Config->{$tuple->[0]} = $tuple->[1];
595                         $CPAN::Frontend->mywarn($@."setting to default '$tuple->[1]'\n");
596                     }
597                 }
598             }
599         }
600     }
601
602     #
603     #== term_is_latin
604     #
605
606     if (!$matcher or 'term_is_latin' =~ /$matcher/){
607         $CPAN::Frontend->myprint($prompts{term_is_latin});
608         my_yn_prompt(term_is_latin => 1, $matcher);
609     }
610
611     #
612     #== save history in file 'histfile'
613     #
614
615     if (!$matcher or 'histfile histsize' =~ /$matcher/) {
616         $CPAN::Frontend->myprint($prompts{histfile_intro});
617         defined($default = $CPAN::Config->{histfile}) or
618             $default = File::Spec->catfile($CPAN::Config->{cpan_home},"histfile");
619         $ans = prompt("File to save your history?", $default);
620         $CPAN::Config->{histfile} = $ans;
621
622         if ($CPAN::Config->{histfile}) {
623             defined($default = $CPAN::Config->{histsize}) or $default = 100;
624             $ans = prompt("Number of lines to save?", $default);
625             $CPAN::Config->{histsize} = $ans;
626         }
627     }
628
629     #
630     #== do an ls on the m or the d command
631     #
632     if (!$matcher or 'show_upload_date' =~ /$matcher/) {
633         $CPAN::Frontend->myprint($prompts{show_upload_date_intro});
634
635         defined($default = $CPAN::Config->{show_upload_date}) or
636             $default = 'n';
637         $ans = prompt("Always try to show upload date with 'd' and 'm' command (yes/no)?",
638                       ($default ? 'yes' : 'no'));
639         $CPAN::Config->{show_upload_date} = ($ans =~ /^[y1]/i ? 1 : 0);
640     }
641
642     #
643     #= MIRRORED.BY and conf_sites()
644     #
645
646     if ($matcher){
647         if ("urllist" =~ $matcher) {
648             # conf_sites would go into endless loop with the smash prompt
649             local *_real_prompt;
650             *_real_prompt = \&CPAN::Shell::colorable_makemaker_prompt;
651             conf_sites();
652         }
653         if ("randomize_urllist" =~ $matcher) {
654             my_dflt_prompt(randomize_urllist => 0, $matcher);
655         }
656     } elsif ($fastread) {
657         $CPAN::Frontend->myprint("Autoconfigured everything but 'urllist'.\n".
658                                  "Please call 'o conf init urllist' to configure ".
659                                  "your CPAN server(s) now!");
660     } else {
661         conf_sites();
662     }
663
664     # We don't ask this one now, it's plain silly and maybe is not
665     # even used correctly everywhere.
666     $CPAN::Config->{inhibit_startup_message} = 0;
667
668     $CPAN::Frontend->myprint("\n\n");
669     if ($matcher && !$CPAN::Config->{auto_commit}) {
670         $CPAN::Frontend->myprint("Please remember to call 'o conf commit' to ".
671                                  "make the config permanent!\n\n");
672     } else {
673         CPAN::HandleConfig->commit($configpm);
674     }
675 }
676
677 sub my_dflt_prompt {
678     my ($item, $dflt, $m) = @_;
679     my $default = $CPAN::Config->{$item} || $dflt;
680
681     $DB::single = 1;
682     if (!$m || $item =~ /$m/) {
683         if (my $intro = $prompts{$item . "_intro"}) {
684             $CPAN::Frontend->myprint($intro);
685         }
686         $CPAN::Config->{$item} = prompt($prompts{$item}, $default);
687     } else {
688         $CPAN::Config->{$item} = $default;
689     }
690 }
691
692 sub my_yn_prompt {
693     my ($item, $dflt, $m) = @_;
694     my $default;
695     defined($default = $CPAN::Config->{$item}) or $default = $dflt;
696
697     $DB::single = 1;
698     if (!$m || $item =~ /$m/) {
699         if (my $intro = $prompts{$item . "_intro"}) {
700             $CPAN::Frontend->myprint($intro);
701         }
702         my $ans = prompt($prompts{$item}, $default ? 'yes' : 'no');
703         $CPAN::Config->{$item} = ($ans =~ /^[y1]/i ? 1 : 0);
704     } else {
705         $CPAN::Config->{$item} = $default;
706     }
707 }
708
709 sub my_prompt_loop {
710     my ($item, $dflt, $m, $ok) = @_;
711     my $default = $CPAN::Config->{$item} || $dflt;
712     my $ans;
713
714     $DB::single = 1;
715     if (!$m || $item =~ /$m/) {
716         do { $ans = prompt($prompts{$item}, $default);
717         } until $ans =~ /$ok/;
718         $CPAN::Config->{$item} = $ans;
719     } else {
720         $CPAN::Config->{$item} = $default;
721     }
722 }
723
724
725 sub conf_sites {
726   my $m = 'MIRRORED.BY';
727   my $mby = File::Spec->catfile($CPAN::Config->{keep_source_where},$m);
728   File::Path::mkpath(File::Basename::dirname($mby));
729   if (-f $mby && -f $m && -M $m < -M $mby) {
730     require File::Copy;
731     File::Copy::copy($m,$mby) or die "Could not update $mby: $!";
732   }
733   my $loopcount = 0;
734   local $^T = time;
735   my $overwrite_local = 0;
736   if ($mby && -f $mby && -M _ <= 60 && -s _ > 0) {
737       my $mtime = localtime((stat _)[9]);
738       my $prompt = qq{Found $mby as of $mtime
739
740 I\'d use that as a database of CPAN sites. If that is OK for you,
741 please answer 'y', but if you want me to get a new database now,
742 please answer 'n' to the following question.
743
744 Shall I use the local database in $mby?};
745       my $ans = prompt($prompt,"y");
746       $overwrite_local = 1 unless $ans =~ /^y/i;
747   }
748   while ($mby) {
749     if ($overwrite_local) {
750       $CPAN::Frontend->myprint(qq{Trying to overwrite $mby\n});
751       $mby = CPAN::FTP->localize($m,$mby,3);
752       $overwrite_local = 0;
753     } elsif ( ! -f $mby ){
754       $CPAN::Frontend->myprint(qq{You have no $mby\n  I\'m trying to fetch one\n});
755       $mby = CPAN::FTP->localize($m,$mby,3);
756     } elsif (-M $mby > 60 && $loopcount == 0) {
757         $CPAN::Frontend->myprint(qq{Your $mby is older than 60 days,\n  I\'m trying }.
758                                  qq{to fetch one\n});
759         $mby = CPAN::FTP->localize($m,$mby,3);
760         $loopcount++;
761     } elsif (-s $mby == 0) {
762       $CPAN::Frontend->myprint(qq{You have an empty $mby,\n  I\'m trying to fetch one\n});
763       $mby = CPAN::FTP->localize($m,$mby,3);
764     } else {
765       last;
766     }
767   }
768   local $urllist = [];
769   read_mirrored_by($mby);
770   bring_your_own();
771   $CPAN::Config->{urllist} = $urllist;
772 }
773
774 sub find_exe {
775     my($exe,$path) = @_;
776     my($dir);
777     #warn "in find_exe exe[$exe] path[@$path]";
778     for $dir (@$path) {
779         my $abs = File::Spec->catfile($dir,$exe);
780         if (($abs = MM->maybe_command($abs))) {
781             return $abs;
782         }
783     }
784 }
785
786 sub picklist {
787     my($items,$prompt,$default,$require_nonempty,$empty_warning)=@_;
788     CPAN->debug("picklist('$items','$prompt','$default','$require_nonempty',".
789                 "'$empty_warning')") if $CPAN::DEBUG;
790     $default ||= '';
791
792     my $pos = 0;
793
794     my @nums;
795   SELECTION: while (1) {
796
797         # display, at most, 15 items at a time
798         my $limit = $#{ $items } - $pos;
799         $limit = 15 if $limit > 15;
800
801         # show the next $limit items, get the new position
802         $pos = display_some($items, $limit, $pos, $default);
803         $pos = 0 if $pos >= @$items;
804
805         my $num = prompt($prompt,$default);
806
807         @nums = split (' ', $num);
808         {
809             my %seen;
810             @nums = grep { !$seen{$_}++ } @nums;
811         }
812         my $i = scalar @$items;
813         unrangify(\@nums);
814         if (grep (/\D/ || $_ < 1 || $_ > $i, @nums)){
815             $CPAN::Frontend->mywarn("invalid items entered, try again\n");
816             if ("@nums" =~ /\D/) {
817                 $CPAN::Frontend->mywarn("(we are expecting only numbers between 1 and $i)\n");
818             }
819             next SELECTION;
820         }
821         if ($require_nonempty && !@nums) {
822             $CPAN::Frontend->mywarn("$empty_warning\n");
823         }
824         $CPAN::Frontend->myprint("\n");
825
826         # a blank line continues...
827         next SELECTION unless @nums;
828         last;
829     }
830     for (@nums) { $_-- }
831     @{$items}[@nums];
832 }
833
834 sub unrangify ($) {
835     my($nums) = $_[0];
836     my @nums2 = ();
837     while (@{$nums||[]}) {
838         my $n = shift @$nums;
839         if ($n =~ /^(\d+)-(\d+)$/) {
840             my @range = $1 .. $2;
841             # warn "range[@range]";
842             push @nums2, @range;
843         } else {
844             push @nums2, $n;
845         }
846     }
847     push @$nums, @nums2;
848 }
849
850 sub display_some {
851     my ($items, $limit, $pos, $default) = @_;
852     $pos ||= 0;
853
854     my @displayable = @$items[$pos .. ($pos + $limit)];
855     for my $item (@displayable) {
856         $CPAN::Frontend->myprint(sprintf "(%d) %s\n", ++$pos, $item);
857     }
858     my $hit_what = $default ? "SPACE RETURN" : "RETURN";
859     $CPAN::Frontend->myprint(sprintf("%d more items, hit %s to show them\n",
860                                      (@$items - $pos),
861                                      $hit_what,
862                                     ))
863         if $pos < @$items;
864     return $pos;
865 }
866
867 sub read_mirrored_by {
868     my $local = shift or return;
869     my(%all,$url,$expected_size,$default,$ans,$host,
870        $dst,$country,$continent,@location);
871     my $fh = FileHandle->new;
872     $fh->open($local) or die "Couldn't open $local: $!";
873     local $/ = "\012";
874     while (<$fh>) {
875         ($host) = /^([\w\.\-]+)/ unless defined $host;
876         next unless defined $host;
877         next unless /\s+dst_(dst|location)/;
878         /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
879             ($continent, $country) = @location[-1,-2];
880         $continent =~ s/\s\(.*//;
881         $continent =~ s/\W+$//; # if Jarkko doesn't know latitude/longitude
882         /dst_dst\s+=\s+\"([^\"]+)/  and $dst = $1;
883         next unless $host && $dst && $continent && $country;
884         $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
885         undef $host;
886         $dst=$continent=$country="";
887     }
888     $fh->close;
889     $CPAN::Config->{urllist} ||= [];
890     my @previous_urls = @{$CPAN::Config->{urllist}};
891
892     $CPAN::Frontend->myprint($prompts{urls_intro});
893
894     my (@cont, $cont, %cont, @countries, @urls, %seen);
895     my $no_previous_warn =
896         "Sorry! since you don't have any existing picks, you must make a\n" .
897             "geographic selection.";
898     my $offer_cont = [sort keys %all];
899     if (@previous_urls) {
900         push @$offer_cont, "(edit previous picks)";
901         $default = @$offer_cont;
902     }
903     @cont = picklist($offer_cont,
904                      "Select your continent (or several nearby continents)",
905                      $default,
906                      ! @previous_urls,
907                      $no_previous_warn);
908
909
910     foreach $cont (@cont) {
911         my @c = sort keys %{$all{$cont}};
912         @cont{@c} = map ($cont, 0..$#c);
913         @c = map ("$_ ($cont)", @c) if @cont > 1;
914         push (@countries, @c);
915     }
916     if (@previous_urls && @countries) {
917         push @countries, "(edit previous picks)";
918         $default = @countries;
919     }
920
921     if (@countries) {
922         @countries = picklist (\@countries,
923                                "Select your country (or several nearby countries)",
924                                $default,
925                                ! @previous_urls,
926                                $no_previous_warn);
927         %seen = map (($_ => 1), @previous_urls);
928         # hmmm, should take list of defaults from CPAN::Config->{'urllist'}...
929         foreach $country (@countries) {
930             next if $country =~ /edit previous picks/;
931             (my $bare_country = $country) =~ s/ \(.*\)//;
932             my @u = sort keys %{$all{$cont{$bare_country}}{$bare_country}};
933             @u = grep (! $seen{$_}, @u);
934             @u = map ("$_ ($bare_country)", @u)
935                 if @countries > 1;
936             push (@urls, @u);
937         }
938     }
939     push (@urls, map ("$_ (previous pick)", @previous_urls));
940     my $prompt = "Select as many URLs as you like (by number),
941 put them on one line, separated by blanks, hyphenated ranges allowed
942  e.g. '1 4 5' or '7 1-4 8'";
943     if (@previous_urls) {
944         $default = join (' ', ((scalar @urls) - (scalar @previous_urls) + 1) ..
945                          (scalar @urls));
946         $prompt .= "\n(or just hit RETURN to keep your previous picks)";
947     }
948
949     @urls = picklist (\@urls, $prompt, $default);
950     foreach (@urls) { s/ \(.*\)//; }
951     push @$urllist, @urls;
952 }
953
954 sub bring_your_own {
955     my %seen = map (($_ => 1), @$urllist);
956     my($ans,@urls);
957     my $eacnt = 0; # empty answers
958     do {
959         my $prompt = "Enter another URL or RETURN to quit:";
960         unless (%seen) {
961             $prompt = qq{CPAN.pm needs at least one URL where it can fetch CPAN files from.
962
963 Please enter your CPAN site:};
964         }
965         $ans = prompt ($prompt, "");
966
967         if ($ans) {
968             $ans =~ s|/?\z|/|; # has to end with one slash
969             $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
970             if ($ans =~ /^\w+:\/./) {
971                 push @urls, $ans unless $seen{$ans}++;
972             } else {
973                 $CPAN::Frontend->
974                     myprint(sprintf(qq{"%s" doesn\'t look like an URL at first sight.
975 I\'ll ignore it for now.
976 You can add it to your %s
977 later if you\'re sure it\'s right.\n},
978                                    $ans,
979                                    $INC{'CPAN/MyConfig.pm'}
980                                    || $INC{'CPAN/Config.pm'}
981                                    || "configuration file",
982                                   ));
983             }
984         } else {
985             if (++$eacnt >= 5) {
986                 $CPAN::Frontend->
987                     mywarn("Giving up.\n");
988                 $CPAN::Frontend->mysleep(5);
989                 return;
990             }
991         }
992     } while $ans || !%seen;
993
994     push @$urllist, @urls;
995     # xxx delete or comment these out when you're happy that it works
996     $CPAN::Frontend->myprint("New set of picks:\n");
997     map { $CPAN::Frontend->myprint("  $_\n") } @$urllist;
998 }
999
1000
1001 sub _strip_spaces {
1002     $_[0] =~ s/^\s+//;  # no leading spaces
1003     $_[0] =~ s/\s+\z//; # no trailing spaces
1004 }
1005
1006 sub prompt ($;$) {
1007     unless (defined &_real_prompt) {
1008         *_real_prompt = \&CPAN::Shell::colorable_makemaker_prompt;
1009     }
1010     my $ans = _real_prompt(@_);
1011
1012     _strip_spaces($ans);
1013
1014     return $ans;
1015 }
1016
1017
1018 sub prompt_no_strip ($;$) {
1019     return _real_prompt(@_);
1020 }
1021
1022
1023 BEGIN {
1024
1025 my @prompts = (
1026
1027 manual_config => qq[
1028
1029 CPAN is the world-wide archive of perl resources. It consists of about
1030 300 sites that all replicate the same contents around the globe. Many
1031 countries have at least one CPAN site already. The resources found on
1032 CPAN are easily accessible with the CPAN.pm module. If you want to use
1033 CPAN.pm, lots of things have to be configured. Fortunately, most of
1034 them can be determined automatically. If you prefer the automatic
1035 configuration, answer 'yes' below.
1036
1037 If you prefer to enter a dialog instead, you can answer 'no' to this
1038 question and I'll let you configure in small steps one thing after the
1039 other. (Note: you can revisit this dialog anytime later by typing 'o
1040 conf init' at the cpan prompt.)
1041
1042 ],
1043
1044 config_intro => qq{
1045
1046 The following questions are intended to help you with the
1047 configuration. The CPAN module needs a directory of its own to cache
1048 important index files and maybe keep a temporary mirror of CPAN files.
1049 This may be a site-wide or a personal directory.
1050
1051 },
1052
1053 # cpan_home => qq{ },
1054
1055 cpan_home_where => qq{
1056
1057 First of all, I\'d like to create this directory. Where?
1058
1059 },
1060
1061 keep_source_where => qq{
1062
1063 Unless you are accessing the CPAN via the filesystem directly CPAN.pm
1064 needs to keep the source files it downloads somewhere. Please supply a
1065 directory where the downloaded files are to be kept.},
1066
1067 build_cache_intro => qq{
1068
1069 How big should the disk cache be for keeping the build directories
1070 with all the intermediate files\?
1071
1072 },
1073
1074 build_cache =>
1075 "Cache size for build directory (in MB)?",
1076
1077 build_dir =>
1078
1079 "Directory where the build process takes place?",
1080
1081 build_dir_reuse_intro =>
1082
1083 qq{Until version 1.88 CPAN.pm never trusted the contents of the
1084 build_dir directory between sessions. Since 1.88_58 CPAN.pm has a
1085 YAML-based mechanism that makes it possible to share the contents of
1086 the build_dir/ directory between different sessions with the same
1087 version of perl. People who prefer to test things several days before
1088 installing will like this feature because it safes a lot of time.
1089
1090 If you say yes to the following question, CPAN will try to store
1091 enough information about the build process so that it can pick up in
1092 future sessions at the same state of affairs as it left a previous
1093 session.
1094
1095 },
1096
1097 build_dir_reuse =>
1098
1099 qq{Store and re-use state information about distributions between
1100 CPAN.pm sessions?},
1101
1102 prefs_dir_intro => qq{
1103
1104 CPAN.pm can store customized build environments based on regular
1105 expressions for distribution names. These are YAML files where the
1106 default options for CPAN.pm and the environment can be overridden and
1107 dialog sequences can be stored that can later be executed by an
1108 Expect.pm object. The CPAN.pm distribution comes with some prefab YAML
1109 files that cover sample distributions that can be used as blueprints
1110 to store one own prefs. Please check out the distroprefs/ directory of
1111 the CPAN.pm distribution to get a quick start into the prefs system.
1112
1113 },
1114
1115 prefs_dir =>
1116
1117 "Directory where to store default options/environment/dialogs for
1118 building modules that need some customization?",
1119
1120 scan_cache_intro => qq{
1121
1122 By default, each time the CPAN module is started, cache scanning is
1123 performed to keep the cache size in sync. To prevent this, answer
1124 'never'.
1125
1126 },
1127
1128 scan_cache => "Perform cache scanning (atstart or never)?",
1129
1130 cache_metadata_intro => qq{
1131
1132 To considerably speed up the initial CPAN shell startup, it is
1133 possible to use Storable to create a cache of metadata. If Storable
1134 is not available, the normal index mechanism will be used.
1135
1136 Note: this mechanism is not used when use_sqlite is on and SQLLite is
1137 running.
1138
1139 },
1140
1141 cache_metadata => qq{Cache metadata (yes/no)?},
1142
1143 use_sqlite_intro => qq{
1144
1145 CPAN::SQLite is a layer between the index files that are downloaded
1146 from the CPAN and CPAN.pm that speeds up metadata queries and reduces
1147 memory consumption of CPAN.pm considereably.
1148
1149 },
1150
1151 use_sqlite => qq{Use CPAN::SQLite if available? (yes/no)?},
1152
1153 term_is_latin_intro => qq{
1154
1155 The next option deals with the charset (aka character set) your
1156 terminal supports. In general, CPAN is English speaking territory, so
1157 the charset does not matter much, but some of the aliens out there who
1158 upload their software to CPAN bear names that are outside the ASCII
1159 range. If your terminal supports UTF-8, you should say no to the next
1160 question.  If it supports ISO-8859-1 (also known as LATIN1) then you
1161 should say yes.  If it supports neither, your answer does not matter
1162 because you will not be able to read the names of some authors
1163 anyway. If you answer no, names will be output in UTF-8.
1164
1165 },
1166
1167 term_is_latin => qq{Your terminal expects ISO-8859-1 (yes/no)?},
1168
1169 histfile_intro => qq{
1170
1171 If you have one of the readline packages (Term::ReadLine::Perl,
1172 Term::ReadLine::Gnu, possibly others) installed, the interactive CPAN
1173 shell will have history support. The next two questions deal with the
1174 filename of the history file and with its size. If you do not want to
1175 set this variable, please hit SPACE RETURN to the following question.
1176
1177 },
1178
1179 histfile => qq{File to save your history?},
1180
1181 show_upload_date_intro => qq{
1182
1183 The 'd' and the 'm' command normally only show you information they
1184 have in their in-memory database and thus will never connect to the
1185 internet. If you set the 'show_upload_date' variable to true, 'm' and
1186 'd' will additionally show you the upload date of the module or
1187 distribution. Per default this feature is off because it may require a
1188 net connection to get at the upload date.
1189
1190 },
1191
1192 show_upload_date =>
1193 "Always try to show upload date with 'd' and 'm' command (yes/no)?",
1194
1195 prerequisites_policy_intro => qq{
1196
1197 The CPAN module can detect when a module which you are trying to build
1198 depends on prerequisites. If this happens, it can build the
1199 prerequisites for you automatically ('follow'), ask you for
1200 confirmation ('ask'), or just ignore them ('ignore'). Please set your
1201 policy to one of the three values.
1202
1203 },
1204
1205 prerequisites_policy =>
1206 "Policy on building prerequisites (follow, ask or ignore)?",
1207
1208 check_sigs_intro  => qq{
1209
1210 CPAN packages can be digitally signed by authors and thus verified
1211 with the security provided by strong cryptography. The exact mechanism
1212 is defined in the Module::Signature module. While this is generally
1213 considered a good thing, it is not always convenient to the end user
1214 to install modules that are signed incorrectly or where the key of the
1215 author is not available or where some prerequisite for
1216 Module::Signature has a bug and so on.
1217
1218 With the check_sigs parameter you can turn signature checking on and
1219 off. The default is off for now because the whole tool chain for the
1220 functionality is not yet considered mature by some. The author of
1221 CPAN.pm would recommend setting it to true most of the time and
1222 turning it off only if it turns out to be annoying.
1223
1224 Note that if you do not have Module::Signature installed, no signature
1225 checks will be performed at all.
1226
1227 },
1228
1229 check_sigs =>
1230 qq{Always try to check and verify signatures if a SIGNATURE file is in the package
1231 and Module::Signature is installed (yes/no)?},
1232
1233 test_report_intro =>
1234 qq{
1235
1236 The goal of the CPAN Testers project (http://testers.cpan.org/) is to
1237 test as many CPAN packages as possible on as many platforms as
1238 possible.  This provides valuable feedback to module authors and
1239 potential users to identify bugs or platform compatibility issues and
1240 improves the overall quality and value of CPAN.
1241
1242 One way you can contribute is to send test results for each module
1243 that you install.  If you install the CPAN::Reporter module, you have
1244 the option to automatically generate and email test reports to CPAN
1245 Testers whenever you run tests on a CPAN package.
1246
1247 See the CPAN::Reporter documentation for additional details and
1248 configuration settings.  If your firewall blocks outgoing email,
1249 you will need to configure CPAN::Reporter before sending reports.
1250
1251 },
1252
1253 test_report =>
1254 qq{Email test reports if CPAN::Reporter is installed (yes/no)?},
1255
1256 external_progs => qq{
1257
1258 The CPAN module will need a few external programs to work properly.
1259 Please correct me, if I guess the wrong path for a program. Don\'t
1260 panic if you do not have some of them, just press ENTER for those. To
1261 disable the use of a program, you can type a space followed by ENTER.
1262
1263 },
1264
1265 prefer_installer_intro => qq{
1266
1267 When you have Module::Build installed and a module comes with both a
1268 Makefile.PL and a Build.PL, which shall have precedence? The two
1269 installer modules we have are the old and well established
1270 ExtUtils::MakeMaker (for short: EUMM) which uses the Makefile.PL and
1271 the next generation installer Module::Build (MB) works with the
1272 Build.PL.
1273
1274 },
1275
1276 prefer_installer =>
1277 qq{In case you could choose, which installer would you prefer (EUMM or MB)?},
1278
1279 makepl_arg_intro => qq{
1280
1281 Every Makefile.PL is run by perl in a separate process. Likewise we
1282 run \'make\' and \'make install\' in separate processes. If you have
1283 any parameters \(e.g. PREFIX, LIB, UNINST or the like\) you want to
1284 pass to the calls, please specify them here.
1285
1286 If you don\'t understand this question, just press ENTER.
1287 },
1288
1289 makepl_arg => qq{
1290 Parameters for the 'perl Makefile.PL' command?
1291 Typical frequently used settings:
1292
1293     PREFIX=~/perl    # non-root users (please see manual for more hints)
1294
1295 Your choice: },
1296
1297 make_arg => qq{Parameters for the 'make' command?
1298 Typical frequently used setting:
1299
1300     -j3              # dual processor system (on GNU make)
1301
1302 Your choice: },
1303
1304
1305 make_install_make_command => qq{Do you want to use a different make command for 'make install'?
1306 Cautious people will probably prefer:
1307
1308     su root -c make
1309 or
1310     sudo make
1311 or
1312     /path1/to/sudo -u admin_account /path2/to/make
1313
1314 or some such. Your choice: },
1315
1316
1317 make_install_arg => qq{Parameters for the 'make install' command?
1318 Typical frequently used setting:
1319
1320     UNINST=1         # to always uninstall potentially conflicting files
1321
1322 Your choice: },
1323
1324
1325 mbuildpl_arg_intro => qq{
1326
1327 The next questions deal with Module::Build support.
1328
1329 A Build.PL is run by perl in a separate process. Likewise we run
1330 './Build' and './Build install' in separate processes. If you have any
1331 parameters you want to pass to the calls, please specify them here.
1332
1333 },
1334
1335 mbuildpl_arg => qq{Parameters for the 'perl Build.PL' command?
1336 Typical frequently used settings:
1337
1338     --install_base /home/xxx             # different installation directory
1339
1340 Your choice: },
1341
1342 mbuild_arg => qq{Parameters for the './Build' command?
1343 Setting might be:
1344
1345     --extra_linker_flags -L/usr/foo/lib  # non-standard library location
1346
1347 Your choice: },
1348
1349
1350 mbuild_install_build_command => qq{Do you want to use a different command for './Build install'?
1351 Sudo users will probably prefer:
1352
1353     su root -c ./Build
1354 or
1355     sudo ./Build
1356 or
1357     /path1/to/sudo -u admin_account ./Build
1358
1359 or some such. Your choice: },
1360
1361
1362 mbuild_install_arg => qq{Parameters for the './Build install' command?
1363 Typical frequently used setting:
1364
1365     --uninst 1                           # uninstall conflicting files
1366
1367 Your choice: },
1368
1369
1370
1371 inactivity_timeout_intro => qq{
1372
1373 Sometimes you may wish to leave the processes run by CPAN alone
1374 without caring about them. Because the Makefile.PL or the Build.PL
1375 sometimes contains question you\'re expected to answer, you can set a
1376 timer that will kill a 'perl Makefile.PL' process after the specified
1377 time in seconds.
1378
1379 If you set this value to 0, these processes will wait forever. This is
1380 the default and recommended setting.
1381
1382 },
1383
1384 inactivity_timeout => 
1385 qq{Timeout for inactivity during {Makefile,Build}.PL? },
1386
1387
1388 proxy_intro => qq{
1389
1390 If you\'re accessing the net via proxies, you can specify them in the
1391 CPAN configuration or via environment variables. The variable in
1392 the \$CPAN::Config takes precedence.
1393
1394 },
1395
1396 proxy_user => qq{
1397
1398 If your proxy is an authenticating proxy, you can store your username
1399 permanently. If you do not want that, just press RETURN. You will then
1400 be asked for your username in every future session.
1401
1402 },
1403
1404 proxy_pass => qq{
1405
1406 Your password for the authenticating proxy can also be stored
1407 permanently on disk. If this violates your security policy, just press
1408 RETURN. You will then be asked for the password in every future
1409 session.
1410
1411 },
1412
1413 urls_intro => qq{
1414
1415 Now we need to know where your favorite CPAN sites are located. Push
1416 a few sites onto the array (just in case the first on the array won\'t
1417 work). If you are mirroring CPAN to your local workstation, specify a
1418 file: URL.
1419
1420 First, pick a nearby continent and country by typing in the number(s)
1421 in front of the item(s) you want to select. You can pick several of
1422 each, separated by spaces. Then, you will be presented with a list of
1423 URLs of CPAN mirrors in the countries you selected, along with
1424 previously selected URLs. Select some of those URLs, or just keep the
1425 old list. Finally, you will be prompted for any extra URLs -- file:,
1426 ftp:, or http: -- that host a CPAN mirror.
1427
1428 },
1429
1430 password_warn => qq{
1431
1432 Warning: Term::ReadKey seems not to be available, your password will
1433 be echoed to the terminal!
1434
1435 },
1436
1437 commandnumber_in_prompt => qq{
1438
1439 The prompt of the cpan shell can contain the current command number
1440 for easier tracking of the session or be a plain string. Do you want
1441 the command number in the prompt (yes/no)?},
1442
1443 ftp_passive => qq{
1444
1445 Shall we always set FTP_PASSIVE envariable when dealing with ftp
1446 download (yes/no)?},
1447
1448 # taken from the manpage:
1449 getcwd_intro => qq{
1450
1451 CPAN.pm changes the current working directory often and needs to
1452 determine its own current working directory. Per default it uses
1453 Cwd::cwd but if this doesn't work on your system for some reason,
1454 alternatives can be configured according to the following table:
1455
1456     cwd         Cwd::cwd
1457     getcwd      Cwd::getcwd
1458     fastcwd     Cwd::fastcwd
1459     backtickcwd external command cwd
1460
1461 },
1462
1463 getcwd => qq{Preferred method for determining the current working directory?},
1464
1465 index_expire_intro => qq{
1466
1467 The CPAN indexes are usually rebuilt once or twice per hour, but the
1468 typical CPAN mirror mirrors only once or twice per day. Depending on
1469 the quality of your mirror and your desire to be on the bleeding edge,
1470 you may want to set the following value to more or less than one day
1471 (which is the default). It determines after how many days CPAN.pm
1472 downloads new indexes.
1473
1474 },
1475
1476 index_expire => qq{Let the index expire after how many days?},
1477
1478 term_ornaments => qq{
1479
1480 When using Term::ReadLine, you can turn ornaments on so that your
1481 input stands out against the output from CPAN.pm. Do you want to turn
1482 ornaments on?},
1483
1484 colorize_output => qq{
1485
1486 When you have Term::ANSIColor installed, you can turn on colorized
1487 output to have some visual differences between normal CPAN.pm output,
1488 warnings, debugging output, and the output of the modules being
1489 installed. Set your favorite colors after some experimenting with the
1490 Term::ANSIColor module. Do you want to turn on colored output?},
1491
1492 colorize_print => qq{Color for normal output?},
1493
1494 colorize_warn => qq{Color for warnings?},
1495
1496 colorize_debug => qq{Color for debugging messages?},
1497
1498 build_requires_install_policy_intro => qq{
1499
1500 When a module declares another one as a 'build_requires' prerequisite
1501 this means that the other module is only needed for building or
1502 testing the module but need not be installed permanently. In this case
1503 you may wish to install that other module nonetheless or just keep it
1504 in the 'build_dir' directory to have it available only temporarily.
1505 Installing saves time on future installations but makes the perl
1506 installation bigger.
1507
1508 You can choose if you want to always install (yes), never install (no)
1509 or be always asked. In the latter case you can set the default answer
1510 for the question to yes (ask/yes) or no (ask/no).
1511
1512 },
1513
1514 build_requires_install_policy =>
1515 qq{Policy on installing 'build_requires' modules (yes, no, ask/yes,
1516 ask/no)?},
1517
1518 yaml_module_intro => qq{
1519
1520 At the time of this writing there are two competing YAML modules,
1521 YAML.pm and YAML::Syck. The latter is faster but needs a C compiler
1522 installed on your system. There may be more alternative YAML
1523 conforming modules but at the time of writing a potential third
1524 player, YAML::Tiny, seemed not powerful enough to work with CPAN.pm.
1525
1526 },
1527
1528 yaml_module => qq{Which YAML implementation would you prefer?},
1529
1530 randomize_urllist_intro => qq{
1531
1532 CPAN.pm can introduce some randomness when using hosts for download
1533 that are configured in the urllist parameter. Enter a numeric value
1534 between 0 and 1 to indicate how often you want to let CPAN.pm try a
1535 random host from the urllist. A value of one specifies to always use a
1536 random host as the first try. A value of zero means no randomness at
1537 all. Anything in between specifies how often, on average, a random
1538 host should be tried first.
1539
1540 },
1541
1542 randomize_urllist => "Randomize parameter",
1543
1544 auto_commit_intro => qq{
1545
1546 Normally CPAN.pm keeps config variables in memory and changes need to
1547 be saved in a separate 'o conf commit' command to make them permanent
1548 between sessions. If you set the 'auto_commit' option to true, changes
1549 to a config variable are always automatically committed to disk.
1550
1551 },
1552
1553 auto_commit => qq{Always commit changes to config variables to disk?},
1554
1555               );
1556
1557 die "Coding error in \@prompts declaration.  Odd number of elements, above"
1558   if (@prompts % 2);
1559
1560 %prompts = @prompts;
1561
1562 if (scalar(keys %prompts) != scalar(@prompts)/2) {
1563     my %already;
1564     for my $item (0..$#prompts) {
1565         next if $item % 2;
1566         die "$prompts[$item] is duplicated\n" if $already{$prompts[$item]}++;
1567     }
1568 }
1569
1570 } # EOBEGIN
1571
1572 1;