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