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