1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
2 package CPAN::Mirrored::By;
9 sub continent { shift->[0] }
10 sub country { shift->[1] }
11 sub url { shift->[2] }
13 package CPAN::FirstTime;
16 use ExtUtils::MakeMaker ();
18 use File::Basename ();
21 use vars qw($VERSION $urllist);
22 $VERSION = sprintf "%.6f", substr(q$Rev: 1086 $,4)/1000000 + 5.4;
26 CPAN::FirstTime - Utility for CPAN::Config file Initialization
30 CPAN::FirstTime::init()
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).
39 This program is free software; you can redistribute it and/or
40 modify it under the same terms as Perl itself.
44 use vars qw( %prompts );
47 my($configpm, %args) = @_;
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
57 $CPAN::Frontend->mywarn("Ignoring excessive arguments '@{$args{args}}'");
58 $CPAN::Frontend->mysleep(2);
60 } elsif (0 == length $matcher) {
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");
69 $matcher = "\\b(".join("|",@{$args{args}}).")\\b";
71 CPAN->debug("matcher[$matcher]") if $CPAN::DEBUG;
73 unless ($CPAN::VERSION) {
76 require CPAN::HandleConfig;
77 CPAN::HandleConfig::require_myconfig_or_config();
90 $CPAN::Frontend->myprint($prompts{manual_config});
96 if ( $args{autoconfig} ) {
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";
105 CPAN->debug("manual_conf[$manual_conf]") if $CPAN::DEBUG;
108 if ($manual_conf =~ /^y/i) {
112 $CPAN::Config->{urllist} ||= [];
115 # prototype should match that of &MakeMaker::prompt
116 my $current_second = time;
117 my $current_second_count = 0;
119 *_real_prompt = sub ($;$) {
121 my($ret) = defined $a ? $a : "";
122 $CPAN::Frontend->myprint(sprintf qq{%s [%s]\n\n}, $q, $ret);
123 eval { require Time::HiRes };
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
132 $current_second = time;
133 $current_second_count = 0;
134 $i_am_mad-- if $i_am_mad>0;
138 #Carp::cluck("SLEEEEEEEEPIIIIIIIIIIINGGGGGGGGGGG");
139 Time::HiRes::sleep(0.1);
147 if (!$matcher or 'cpan_home keep_source_where build_dir prefs_dir' =~ /$matcher/){
148 $CPAN::Frontend->myprint($prompts{config_intro});
150 if (!$matcher or 'cpan_home' =~ /$matcher/) {
151 my $cpan_home = $CPAN::Config->{cpan_home}
152 || File::Spec->catdir($ENV{HOME}, ".cpan");
155 $CPAN::Frontend->myprint(qq{
157 I see you already have a directory
159 Shall we use it as the general CPAN build and cache directory?
163 # no cpan-home, must prompt and get one
164 $CPAN::Frontend->myprint($prompts{cpan_home_where});
167 $default = $cpan_home;
169 while ($ans = prompt("CPAN build and cache directory?",$default)) {
170 unless (File::Spec->file_name_is_absolute($ans)) {
172 my $cwd = Cwd::cwd();
173 my $absans = File::Spec->catdir($cwd,$ans);
174 $CPAN::Frontend->mywarn("The path '$ans' is not an ".
175 "absolute path. Please specify ".
176 "an absolute path\n");
180 eval { File::Path::mkpath($ans); }; # dies if it can't
182 $CPAN::Frontend->mywarn("Couldn't create directory $ans.\n".
186 if (-d $ans && -w _) {
189 $CPAN::Frontend->mywarn("Couldn't find directory $ans\n".
190 "or directory is not writable. Please retry.\n");
192 $CPAN::Frontend->mydie("Giving up");
196 $CPAN::Config->{cpan_home} = $ans;
199 if (!$matcher or 'keep_source_where' =~ /$matcher/) {
200 my_dflt_prompt("keep_source_where",
201 File::Spec->catdir($CPAN::Config->{cpan_home},"sources"),
206 if (!$matcher or 'build_dir' =~ /$matcher/) {
207 my_dflt_prompt("build_dir",
208 File::Spec->catdir($CPAN::Config->{cpan_home},"build"),
213 if (!$matcher or 'prefs_dir' =~ /$matcher/) {
214 my_dflt_prompt("prefs_dir",
215 File::Spec->catdir($CPAN::Config->{cpan_home},"prefs"),
222 #= Cache size, Index expire
225 if (!$matcher or 'build_cache' =~ /$matcher/){
226 # large enough to build large dists like Tk
227 my_dflt_prompt(build_cache => 100, $matcher);
230 if (!$matcher or 'index_expire' =~ /$matcher/) {
231 my_dflt_prompt(index_expire => 1, $matcher);
234 if (!$matcher or 'scan_cache' =~ /$matcher/){
235 $CPAN::Frontend->myprint($prompts{scan_cache_intro});
236 my_prompt_loop(scan_cache => 'atstart', $matcher, 'atstart|never');
243 my_yn_prompt(cache_metadata => 1, $matcher);
246 #= Do we follow PREREQ_PM?
249 if (!$matcher or 'prerequisites_policy' =~ /$matcher/){
250 $CPAN::Frontend->myprint($prompts{prerequisites_policy_intro});
252 my_prompt_loop(prerequisites_policy => 'ask', $matcher,
253 'follow|ask|ignore');
256 if (!$matcher or 'build_requires_install_policy' =~ /$matcher/){
257 $CPAN::Frontend->myprint($prompts{build_requires_install_policy_intro});
259 my_prompt_loop(build_requires_install_policy => 'ask/yes', $matcher,
260 'yes|no|ask/yes|ask/no');
266 if (!$matcher or 'check_sigs' =~ /$matcher/) {
267 my_yn_prompt(check_sigs => 0, $matcher);
273 if (!$matcher or 'test_report' =~ /$matcher/) {
274 my_yn_prompt(test_report => 0, $matcher);
276 $CPAN::Config->{test_report} &&
277 $CPAN::META->has_inst("CPAN::Reporter") &&
278 CPAN::Reporter->can('configure')
280 $CPAN::Frontend->myprint("\nProceeding to configure CPAN::Reporter.\n");
281 CPAN::Reporter::configure();
282 $CPAN::Frontend->myprint("\nReturning to CPAN configuration.\n");
287 #= YAML vs. YAML::Syck
289 if (!$matcher or "yaml_module" =~ /$matcher/) {
290 my_dflt_prompt(yaml_module => "YAML", $matcher);
297 my @external_progs = qw/bzip2 gzip tar unzip make
298 curl lynx wget ncftpget ncftp ftp
300 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
301 if (!$matcher or "@external_progs" =~ /$matcher/) {
302 $CPAN::Frontend->myprint($prompts{external_progs});
305 local $^W if $^O eq 'MacOS';
306 local $^W = $old_warn;
308 for $progname (@external_progs) {
309 next if $matcher && $progname !~ /$matcher/;
310 if ($^O eq 'MacOS') {
311 $CPAN::Config->{$progname} = 'not_here';
315 my $progcall = $progname;
317 # we really don't need ncftp if we have ncftpget, but
318 # if they chose this dialog via matcher, they shall have it
319 next if $progname eq "ncftp" && $CPAN::Config->{ncftpget} gt " ";
321 my $path = $CPAN::Config->{$progname}
322 || $Config::Config{$progname}
324 if (File::Spec->file_name_is_absolute($path)) {
325 # testing existence is not good enough, some have these exe
328 # warn "Warning: configured $path does not exist\n" unless -e $path;
330 } elsif ($path =~ /^\s+$/) {
331 # preserve disabled programs
337 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
340 $path ||= find_exe($progcall,\@path);
343 $CPAN::Frontend->mywarn("Warning: $progcall not found in PATH[@path]\n") unless
344 $path; # not -e $path, because find_exe already checked that
346 $ans = prompt("Where is your $progname program?",$path) || $path;
347 $CPAN::Config->{$progname} = $ans;
351 if (!$matcher or 'pager' =~ /$matcher/) {
352 my $path = $CPAN::Config->{'pager'} ||
353 $ENV{PAGER} || find_exe("less",\@path) ||
354 find_exe("more",\@path) || ($^O eq 'MacOS' ? $ENV{EDITOR} : 0 )
356 $ans = prompt("What is your favorite pager program?",$path);
357 $CPAN::Config->{'pager'} = $ans;
360 if (!$matcher or 'shell' =~ /$matcher/) {
361 my $path = $CPAN::Config->{'shell'};
362 if ($path && File::Spec->file_name_is_absolute($path)) {
363 $CPAN::Frontend->mywarn("Warning: configured $path does not exist\n")
367 $path ||= $ENV{SHELL};
368 $path ||= $ENV{COMSPEC} if $^O eq "MSWin32";
369 if ($^O eq 'MacOS') {
370 $CPAN::Config->{'shell'} = 'not_here';
372 $path =~ s,\\,/,g if $^O eq 'os2'; # Cosmetic only
373 $ans = prompt("What is your favorite shell?",$path);
374 $CPAN::Config->{'shell'} = $ans;
379 #= Installer, arguments to make etc.
382 if (!$matcher or 'prefer_installer' =~ /$matcher/){
383 $CPAN::Frontend->myprint($prompts{prefer_installer_intro});
385 my_prompt_loop(prefer_installer => 'EUMM', $matcher, 'MB|EUMM');
388 if (!$matcher or 'makepl_arg make_arg' =~ /$matcher/){
389 my_dflt_prompt(makepl_arg => "", $matcher);
390 my_dflt_prompt(make_arg => "", $matcher);
393 require CPAN::HandleConfig;
394 if (exists $CPAN::HandleConfig::keys{make_install_make_command}) {
395 # as long as Windows needs $self->_build_command, we cannot
396 # support sudo on windows :-)
397 my_dflt_prompt(make_install_make_command => $CPAN::Config->{make} || "",
401 my_dflt_prompt(make_install_arg => $CPAN::Config->{make_arg} || "",
404 if (!$matcher or 'mbuildpl_arg mbuild_arg' =~ /$matcher/){
405 my_dflt_prompt(mbuildpl_arg => "", $matcher);
406 my_dflt_prompt(mbuild_arg => "", $matcher);
409 if (exists $CPAN::HandleConfig::keys{mbuild_install_build_command}) {
410 # as long as Windows needs $self->_build_command, we cannot
411 # support sudo on windows :-)
412 my_dflt_prompt(mbuild_install_build_command => "./Build", $matcher);
415 my_dflt_prompt(mbuild_install_arg => "", $matcher);
421 if (!$matcher or 'inactivity_timeout' =~ /$matcher/) {
422 $CPAN::Frontend->myprint($prompts{inactivity_timeout_intro});
423 $default = $CPAN::Config->{inactivity_timeout} || 0;
424 $CPAN::Config->{inactivity_timeout} =
425 prompt("Timeout for inactivity during {Makefile,Build}.PL?",$default);
432 my @proxy_vars = qw/ftp_proxy http_proxy no_proxy/;
433 my @proxy_user_vars = qw/proxy_user proxy_pass/;
434 if (!$matcher or "@proxy_vars @proxy_user_vars" =~ /$matcher/){
435 $CPAN::Frontend->myprint($prompts{proxy_intro});
438 if (!$matcher or /$matcher/){
439 $default = $CPAN::Config->{$_} || $ENV{$_} || "";
440 $CPAN::Config->{$_} = prompt("Your $_?",$default);
444 if ($CPAN::Config->{ftp_proxy} ||
445 $CPAN::Config->{http_proxy}) {
447 $default = $CPAN::Config->{proxy_user} || $CPAN::LWP::UserAgent::USER || "";
449 $CPAN::Frontend->myprint($prompts{proxy_user});
451 if ($CPAN::Config->{proxy_user} = prompt("Your proxy user id?",$default)) {
452 $CPAN::Frontend->myprint($prompts{proxy_pass});
454 if ($CPAN::META->has_inst("Term::ReadKey")) {
455 Term::ReadKey::ReadMode("noecho");
457 $CPAN::Frontend->myprint($prompts{password_warn});
459 $CPAN::Config->{proxy_pass} = prompt_no_strip("Your proxy password?");
460 if ($CPAN::META->has_inst("Term::ReadKey")) {
461 Term::ReadKey::ReadMode("restore");
463 $CPAN::Frontend->myprint("\n\n");
472 my_yn_prompt(ftp_passive => 1, $matcher);
478 if (!$matcher or 'getcwd' =~ /$matcher/){
479 $CPAN::Frontend->myprint($prompts{getcwd_intro});
481 my_prompt_loop(getcwd => 'cwd', $matcher,
482 'cwd|getcwd|fastcwd|backtickcwd');
486 #= the CPAN shell itself
489 my_yn_prompt(commandnumber_in_prompt => 1, $matcher);
490 my_yn_prompt(term_ornaments => 1, $matcher);
491 if ("colorize_output colorize_print colorize_warn" =~ $matcher) {
492 my_yn_prompt(colorize_output => 0, $matcher);
493 if ($CPAN::Config->{colorize_output}) {
495 ["colorize_print", "bold blue on_white"],
496 ["colorize_warn", "bold red on_white"],
498 my_dflt_prompt($tuple->[0] => $tuple->[1], $matcher);
499 if ($CPAN::META->has_inst("Term::ANSIColor")) {
500 eval { Term::ANSIColor::color($CPAN::Config->{$tuple->[0]})};
502 $CPAN::Config->{$tuple->[0]} = $tuple->[1];
503 $CPAN::Frontend->mywarn($@."setting to default '$tuple->[1]'\n");
514 if (!$matcher or 'term_is_latin' =~ /$matcher/){
515 $CPAN::Frontend->myprint($prompts{term_is_latin});
516 my_yn_prompt(term_is_latin => 1, $matcher);
520 #== save history in file 'histfile'
523 if (!$matcher or 'histfile histsize' =~ /$matcher/) {
524 $CPAN::Frontend->myprint($prompts{histfile_intro});
525 defined($default = $CPAN::Config->{histfile}) or
526 $default = File::Spec->catfile($CPAN::Config->{cpan_home},"histfile");
527 $ans = prompt("File to save your history?", $default);
528 $CPAN::Config->{histfile} = $ans;
530 if ($CPAN::Config->{histfile}) {
531 defined($default = $CPAN::Config->{histsize}) or $default = 100;
532 $ans = prompt("Number of lines to save?", $default);
533 $CPAN::Config->{histsize} = $ans;
538 #== do an ls on the m or the d command
540 if (!$matcher or 'show_upload_date' =~ /$matcher/) {
541 $CPAN::Frontend->myprint($prompts{show_upload_date_intro});
543 defined($default = $CPAN::Config->{show_upload_date}) or
545 $ans = prompt("Always try to show upload date with 'd' and 'm' command (yes/no)?",
546 ($default ? 'yes' : 'no'));
547 $CPAN::Config->{show_upload_date} = ($ans =~ /^[y1]/i ? 1 : 0);
551 #= MIRRORED.BY and conf_sites()
555 if ("urllist" =~ $matcher) {
556 # conf_sites would go into endless loop with the smash prompt
558 *_real_prompt = \&CPAN::Shell::colorable_makemaker_prompt;
561 } elsif ($fastread) {
562 $CPAN::Frontend->myprint("Autoconfigured everything but 'urllist'.\n".
563 "Please call 'o conf init urllist' to configure ".
564 "your CPAN server(s) now!");
569 # We don't ask this one now, it's plain silly and maybe is not
570 # even used correctly everywhere.
571 $CPAN::Config->{inhibit_startup_message} = 0;
573 $CPAN::Frontend->myprint("\n\n");
575 $CPAN::Frontend->myprint("Please remember to call 'o conf commit' to ".
576 "make the config permanent!\n\n");
578 CPAN::HandleConfig->commit($configpm);
583 my ($item, $dflt, $m) = @_;
584 my $default = $CPAN::Config->{$item} || $dflt;
587 if (!$m || $item =~ /$m/) {
588 if (my $intro = $prompts{$item . "_intro"}) {
589 $CPAN::Frontend->myprint($intro);
591 $CPAN::Config->{$item} = prompt($prompts{$item}, $default);
593 $CPAN::Config->{$item} = $default;
598 my ($item, $dflt, $m) = @_;
600 defined($default = $CPAN::Config->{$item}) or $default = $dflt;
603 if (!$m || $item =~ /$m/) {
604 if (my $intro = $prompts{$item . "_intro"}) {
605 $CPAN::Frontend->myprint($intro);
607 my $ans = prompt($prompts{$item}, $default ? 'yes' : 'no');
608 $CPAN::Config->{$item} = ($ans =~ /^[y1]/i ? 1 : 0);
610 $CPAN::Config->{$item} = $default;
615 my ($item, $dflt, $m, $ok) = @_;
616 my $default = $CPAN::Config->{$item} || $dflt;
620 if (!$m || $item =~ /$m/) {
621 do { $ans = prompt($prompts{$item}, $default);
622 } until $ans =~ /$ok/;
623 $CPAN::Config->{$item} = $ans;
625 $CPAN::Config->{$item} = $default;
631 my $m = 'MIRRORED.BY';
632 my $mby = File::Spec->catfile($CPAN::Config->{keep_source_where},$m);
633 File::Path::mkpath(File::Basename::dirname($mby));
634 if (-f $mby && -f $m && -M $m < -M $mby) {
636 File::Copy::copy($m,$mby) or die "Could not update $mby: $!";
640 my $overwrite_local = 0;
641 if ($mby && -f $mby && -M _ <= 60 && -s _ > 0) {
642 my $mtime = localtime((stat _)[9]);
643 my $prompt = qq{Found $mby as of $mtime
645 I\'d use that as a database of CPAN sites. If that is OK for you,
646 please answer 'y', but if you want me to get a new database now,
647 please answer 'n' to the following question.
649 Shall I use the local database in $mby?};
650 my $ans = prompt($prompt,"y");
651 $overwrite_local = 1 unless $ans =~ /^y/i;
654 if ($overwrite_local) {
655 $CPAN::Frontend->myprint(qq{Trying to overwrite $mby\n});
656 $mby = CPAN::FTP->localize($m,$mby,3);
657 $overwrite_local = 0;
658 } elsif ( ! -f $mby ){
659 $CPAN::Frontend->myprint(qq{You have no $mby\n I\'m trying to fetch one\n});
660 $mby = CPAN::FTP->localize($m,$mby,3);
661 } elsif (-M $mby > 60 && $loopcount == 0) {
662 $CPAN::Frontend->myprint(qq{Your $mby is older than 60 days,\n I\'m trying }.
664 $mby = CPAN::FTP->localize($m,$mby,3);
666 } elsif (-s $mby == 0) {
667 $CPAN::Frontend->myprint(qq{You have an empty $mby,\n I\'m trying to fetch one\n});
668 $mby = CPAN::FTP->localize($m,$mby,3);
674 read_mirrored_by($mby);
676 $CPAN::Config->{urllist} = $urllist;
682 #warn "in find_exe exe[$exe] path[@$path]";
684 my $abs = File::Spec->catfile($dir,$exe);
685 if (($abs = MM->maybe_command($abs))) {
692 my($items,$prompt,$default,$require_nonempty,$empty_warning)=@_;
693 CPAN->debug("picklist('$items','$prompt','$default','$require_nonempty',".
694 "'$empty_warning')") if $CPAN::DEBUG;
700 SELECTION: while (1) {
702 # display, at most, 15 items at a time
703 my $limit = $#{ $items } - $pos;
704 $limit = 15 if $limit > 15;
706 # show the next $limit items, get the new position
707 $pos = display_some($items, $limit, $pos, $default);
708 $pos = 0 if $pos >= @$items;
710 my $num = prompt($prompt,$default);
712 @nums = split (' ', $num);
715 @nums = grep { !$seen{$_}++ } @nums;
717 my $i = scalar @$items;
719 if (grep (/\D/ || $_ < 1 || $_ > $i, @nums)){
720 $CPAN::Frontend->mywarn("invalid items entered, try again\n");
721 if ("@nums" =~ /\D/) {
722 $CPAN::Frontend->mywarn("(we are expecting only numbers between 1 and $i)\n");
726 if ($require_nonempty && !@nums) {
727 $CPAN::Frontend->mywarn("$empty_warning\n");
729 $CPAN::Frontend->myprint("\n");
731 # a blank line continues...
732 next SELECTION unless @nums;
742 while (@{$nums||[]}) {
743 my $n = shift @$nums;
744 if ($n =~ /^(\d+)-(\d+)$/) {
745 my @range = $1 .. $2;
746 # warn "range[@range]";
756 my ($items, $limit, $pos, $default) = @_;
759 my @displayable = @$items[$pos .. ($pos + $limit)];
760 for my $item (@displayable) {
761 $CPAN::Frontend->myprint(sprintf "(%d) %s\n", ++$pos, $item);
763 my $hit_what = $default ? "SPACE RETURN" : "RETURN";
764 $CPAN::Frontend->myprint(sprintf("%d more items, hit %s to show them\n",
772 sub read_mirrored_by {
773 my $local = shift or return;
774 my(%all,$url,$expected_size,$default,$ans,$host,
775 $dst,$country,$continent,@location);
776 my $fh = FileHandle->new;
777 $fh->open($local) or die "Couldn't open $local: $!";
780 ($host) = /^([\w\.\-]+)/ unless defined $host;
781 next unless defined $host;
782 next unless /\s+dst_(dst|location)/;
783 /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
784 ($continent, $country) = @location[-1,-2];
785 $continent =~ s/\s\(.*//;
786 $continent =~ s/\W+$//; # if Jarkko doesn't know latitude/longitude
787 /dst_dst\s+=\s+\"([^\"]+)/ and $dst = $1;
788 next unless $host && $dst && $continent && $country;
789 $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
791 $dst=$continent=$country="";
794 $CPAN::Config->{urllist} ||= [];
795 my @previous_urls = @{$CPAN::Config->{urllist}};
797 $CPAN::Frontend->myprint($prompts{urls_intro});
799 my (@cont, $cont, %cont, @countries, @urls, %seen);
800 my $no_previous_warn =
801 "Sorry! since you don't have any existing picks, you must make a\n" .
802 "geographic selection.";
803 my $offer_cont = [sort keys %all];
804 if (@previous_urls) {
805 push @$offer_cont, "(edit previous picks)";
806 $default = @$offer_cont;
808 @cont = picklist($offer_cont,
809 "Select your continent (or several nearby continents)",
815 foreach $cont (@cont) {
816 my @c = sort keys %{$all{$cont}};
817 @cont{@c} = map ($cont, 0..$#c);
818 @c = map ("$_ ($cont)", @c) if @cont > 1;
819 push (@countries, @c);
821 if (@previous_urls && @countries) {
822 push @countries, "(edit previous picks)";
823 $default = @countries;
827 @countries = picklist (\@countries,
828 "Select your country (or several nearby countries)",
832 %seen = map (($_ => 1), @previous_urls);
833 # hmmm, should take list of defaults from CPAN::Config->{'urllist'}...
834 foreach $country (@countries) {
835 next if $country =~ /edit previous picks/;
836 (my $bare_country = $country) =~ s/ \(.*\)//;
837 my @u = sort keys %{$all{$cont{$bare_country}}{$bare_country}};
838 @u = grep (! $seen{$_}, @u);
839 @u = map ("$_ ($bare_country)", @u)
844 push (@urls, map ("$_ (previous pick)", @previous_urls));
845 my $prompt = "Select as many URLs as you like (by number),
846 put them on one line, separated by blanks, hyphenated ranges allowed
847 e.g. '1 4 5' or '7 1-4 8'";
848 if (@previous_urls) {
849 $default = join (' ', ((scalar @urls) - (scalar @previous_urls) + 1) ..
851 $prompt .= "\n(or just hit RETURN to keep your previous picks)";
854 @urls = picklist (\@urls, $prompt, $default);
855 foreach (@urls) { s/ \(.*\)//; }
856 push @$urllist, @urls;
860 my %seen = map (($_ => 1), @$urllist);
862 my $eacnt = 0; # empty answers
864 my $prompt = "Enter another URL or RETURN to quit:";
866 $prompt = qq{CPAN.pm needs at least one URL where it can fetch CPAN files from.
868 Please enter your CPAN site:};
870 $ans = prompt ($prompt, "");
873 $ans =~ s|/?\z|/|; # has to end with one slash
874 $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
875 if ($ans =~ /^\w+:\/./) {
876 push @urls, $ans unless $seen{$ans}++;
879 myprint(sprintf(qq{"%s" doesn\'t look like an URL at first sight.
880 I\'ll ignore it for now.
881 You can add it to your %s
882 later if you\'re sure it\'s right.\n},
884 $INC{'CPAN/MyConfig.pm'}
885 || $INC{'CPAN/Config.pm'}
886 || "configuration file",
892 mywarn("Giving up.\n");
893 $CPAN::Frontend->mysleep(5);
897 } while $ans || !%seen;
899 push @$urllist, @urls;
900 # xxx delete or comment these out when you're happy that it works
901 $CPAN::Frontend->myprint("New set of picks:\n");
902 map { $CPAN::Frontend->myprint(" $_\n") } @$urllist;
907 $_[0] =~ s/^\s+//; # no leading spaces
908 $_[0] =~ s/\s+\z//; # no trailing spaces
912 unless (defined &_real_prompt) {
913 *_real_prompt = \&CPAN::Shell::colorable_makemaker_prompt;
915 my $ans = _real_prompt(@_);
923 sub prompt_no_strip ($;$) {
924 return _real_prompt(@_);
934 CPAN is the world-wide archive of perl resources. It consists of about
935 300 sites that all replicate the same contents around the globe. Many
936 countries have at least one CPAN site already. The resources found on
937 CPAN are easily accessible with the CPAN.pm module. If you want to use
938 CPAN.pm, lots of things have to be configured. Fortunately, most of
939 them can be determined automatically. If you prefer the automatic
940 configuration, answer 'yes' below.
942 If you prefer to enter a dialog instead, you can answer 'no' to this
943 question and I'll let you configure in small steps one thing after the
944 other. (Note: you can revisit this dialog anytime later by typing 'o
945 conf init' at the cpan prompt.)
951 The following questions are intended to help you with the
952 configuration. The CPAN module needs a directory of its own to cache
953 important index files and maybe keep a temporary mirror of CPAN files.
954 This may be a site-wide or a personal directory.
958 # cpan_home => qq{ },
960 cpan_home_where => qq{
962 First of all, I\'d like to create this directory. Where?
966 keep_source_where => qq{
968 Unless you are accessing the CPAN via the filesystem directly CPAN.pm
969 needs to keep the source files it downloads somewhere. Please supply a
970 directory where the downloaded files are to be kept.},
972 build_cache_intro => qq{
974 How big should the disk cache be for keeping the build directories
975 with all the intermediate files\?
980 "Cache size for build directory (in MB)?",
984 "Directory where the build process takes place?",
986 prefs_dir_intro => qq{
988 CPAN.pm can store customized build environments based on regular
989 expressions for distribution names. These are YAML files where the
990 default options for CPAN.pm and the environment can be overridden and
991 dialog sequences can be stored that can later be executed by an
992 Expect.pm object. The CPAN.pm distribution comes with some prefab YAML
993 files that cover sample distributions that can be used as blueprints
994 to store one own prefs. Please check out the distroprefs/ directory of
995 the CPAN.pm distribution to get a quick start into the prefs system.
1001 "Directory where to store default options/environment/dialogs for
1002 building modules that need some customization?",
1004 scan_cache_intro => qq{
1006 By default, each time the CPAN module is started, cache scanning is
1007 performed to keep the cache size in sync. To prevent this, answer
1012 scan_cache => "Perform cache scanning (atstart or never)?",
1014 cache_metadata_intro => qq{
1016 To considerably speed up the initial CPAN shell startup, it is
1017 possible to use Storable to create a cache of metadata. If Storable
1018 is not available, the normal index mechanism will be used.
1022 cache_metadata => qq{Cache metadata (yes/no)?},
1024 term_is_latin_intro => qq{
1026 The next option deals with the charset (aka character set) your
1027 terminal supports. In general, CPAN is English speaking territory, so
1028 the charset does not matter much, but some of the aliens out there who
1029 upload their software to CPAN bear names that are outside the ASCII
1030 range. If your terminal supports UTF-8, you should say no to the next
1031 question. If it supports ISO-8859-1 (also known as LATIN1) then you
1032 should say yes. If it supports neither, your answer does not matter
1033 because you will not be able to read the names of some authors
1034 anyway. If you answer no, names will be output in UTF-8.
1038 term_is_latin => qq{Your terminal expects ISO-8859-1 (yes/no)?},
1040 histfile_intro => qq{
1042 If you have one of the readline packages (Term::ReadLine::Perl,
1043 Term::ReadLine::Gnu, possibly others) installed, the interactive CPAN
1044 shell will have history support. The next two questions deal with the
1045 filename of the history file and with its size. If you do not want to
1046 set this variable, please hit SPACE RETURN to the following question.
1050 histfile => qq{File to save your history?},
1052 show_upload_date_intro => qq{
1054 The 'd' and the 'm' command normally only show you information they
1055 have in their in-memory database and thus will never connect to the
1056 internet. If you set the 'show_upload_date' variable to true, 'm' and
1057 'd' will additionally show you the upload date of the module or
1058 distribution. Per default this feature is off because it may require a
1059 net connection to get at the upload date.
1064 "Always try to show upload date with 'd' and 'm' command (yes/no)?",
1066 prerequisites_policy_intro => qq{
1068 The CPAN module can detect when a module which you are trying to build
1069 depends on prerequisites. If this happens, it can build the
1070 prerequisites for you automatically ('follow'), ask you for
1071 confirmation ('ask'), or just ignore them ('ignore'). Please set your
1072 policy to one of the three values.
1076 prerequisites_policy =>
1077 "Policy on building prerequisites (follow, ask or ignore)?",
1079 check_sigs_intro => qq{
1081 CPAN packages can be digitally signed by authors and thus verified
1082 with the security provided by strong cryptography. The exact mechanism
1083 is defined in the Module::Signature module. While this is generally
1084 considered a good thing, it is not always convenient to the end user
1085 to install modules that are signed incorrectly or where the key of the
1086 author is not available or where some prerequisite for
1087 Module::Signature has a bug and so on.
1089 With the check_sigs parameter you can turn signature checking on and
1090 off. The default is off for now because the whole tool chain for the
1091 functionality is not yet considered mature by some. The author of
1092 CPAN.pm would recommend setting it to true most of the time and
1093 turning it off only if it turns out to be annoying.
1095 Note that if you do not have Module::Signature installed, no signature
1096 checks will be performed at all.
1101 qq{Always try to check and verify signatures if a SIGNATURE file is in the package
1102 and Module::Signature is installed (yes/no)?},
1104 test_report_intro =>
1107 The goal of the CPAN Testers project (http://testers.cpan.org/) is to
1108 test as many CPAN packages as possible on as many platforms as
1109 possible. This provides valuable feedback to module authors and
1110 potential users to identify bugs or platform compatibility issues and
1111 improves the overall quality and value of CPAN.
1113 One way you can contribute is to send test results for each module
1114 that you install. If you install the CPAN::Reporter module, you have
1115 the option to automatically generate and email test reports to CPAN
1116 Testers whenever you run tests on a CPAN package.
1118 See the CPAN::Reporter documentation for additional details and
1119 configuration settings. If your firewall blocks outgoing email,
1120 you will need to configure CPAN::Reporter before sending reports.
1125 qq{Email test reports if CPAN::Reporter is installed (yes/no)?},
1127 external_progs => qq{
1129 The CPAN module will need a few external programs to work properly.
1130 Please correct me, if I guess the wrong path for a program. Don\'t
1131 panic if you do not have some of them, just press ENTER for those. To
1132 disable the use of a program, you can type a space followed by ENTER.
1136 prefer_installer_intro => qq{
1138 When you have Module::Build installed and a module comes with both a
1139 Makefile.PL and a Build.PL, which shall have precedence? The two
1140 installer modules we have are the old and well established
1141 ExtUtils::MakeMaker (for short: EUMM) which uses the Makefile.PL and
1142 the next generation installer Module::Build (MB) works with the
1148 qq{In case you could choose, which installer would you prefer (EUMM or MB)?},
1150 makepl_arg_intro => qq{
1152 Every Makefile.PL is run by perl in a separate process. Likewise we
1153 run \'make\' and \'make install\' in separate processes. If you have
1154 any parameters \(e.g. PREFIX, LIB, UNINST or the like\) you want to
1155 pass to the calls, please specify them here.
1157 If you don\'t understand this question, just press ENTER.
1161 Parameters for the 'perl Makefile.PL' command?
1162 Typical frequently used settings:
1164 PREFIX=~/perl # non-root users (please see manual for more hints)
1168 make_arg => qq{Parameters for the 'make' command?
1169 Typical frequently used setting:
1171 -j3 # dual processor system
1176 make_install_make_command => qq{Do you want to use a different make command for 'make install'?
1177 Cautious people will probably prefer:
1183 /path1/to/sudo -u admin_account /path2/to/make
1185 or some such. Your choice: },
1188 make_install_arg => qq{Parameters for the 'make install' command?
1189 Typical frequently used setting:
1191 UNINST=1 # to always uninstall potentially conflicting files
1196 mbuildpl_arg_intro => qq{
1198 The next questions deal with Module::Build support.
1200 A Build.PL is run by perl in a separate process. Likewise we run
1201 './Build' and './Build install' in separate processes. If you have any
1202 parameters you want to pass to the calls, please specify them here.
1206 mbuildpl_arg => qq{Parameters for the 'perl Build.PL' command?
1207 Typical frequently used settings:
1209 --install_base /home/xxx # different installation directory
1213 mbuild_arg => qq{Parameters for the './Build' command?
1216 --extra_linker_flags -L/usr/foo/lib # non-standard library location
1221 mbuild_install_build_command => qq{Do you want to use a different command for './Build install'?
1222 Sudo users will probably prefer:
1228 /path1/to/sudo -u admin_account ./Build
1230 or some such. Your choice: },
1233 mbuild_install_arg => qq{Parameters for the './Build install' command?
1234 Typical frequently used setting:
1236 --uninst 1 # uninstall conflicting files
1242 inactivity_timeout_intro => qq{
1244 Sometimes you may wish to leave the processes run by CPAN alone
1245 without caring about them. Because the Makefile.PL or the Build.PL
1246 sometimes contains question you\'re expected to answer, you can set a
1247 timer that will kill a 'perl Makefile.PL' process after the specified
1250 If you set this value to 0, these processes will wait forever. This is
1251 the default and recommended setting.
1255 inactivity_timeout =>
1256 qq{Timeout for inactivity during {Makefile,Build}.PL? },
1261 If you\'re accessing the net via proxies, you can specify them in the
1262 CPAN configuration or via environment variables. The variable in
1263 the \$CPAN::Config takes precedence.
1269 If your proxy is an authenticating proxy, you can store your username
1270 permanently. If you do not want that, just press RETURN. You will then
1271 be asked for your username in every future session.
1277 Your password for the authenticating proxy can also be stored
1278 permanently on disk. If this violates your security policy, just press
1279 RETURN. You will then be asked for the password in every future
1286 Now we need to know where your favorite CPAN sites are located. Push
1287 a few sites onto the array (just in case the first on the array won\'t
1288 work). If you are mirroring CPAN to your local workstation, specify a
1291 First, pick a nearby continent and country by typing in the number(s)
1292 in front of the item(s) you want to select. You can pick several of
1293 each, separated by spaces. Then, you will be presented with a list of
1294 URLs of CPAN mirrors in the countries you selected, along with
1295 previously selected URLs. Select some of those URLs, or just keep the
1296 old list. Finally, you will be prompted for any extra URLs -- file:,
1297 ftp:, or http: -- that host a CPAN mirror.
1301 password_warn => qq{
1303 Warning: Term::ReadKey seems not to be available, your password will
1304 be echoed to the terminal!
1308 commandnumber_in_prompt => qq{
1310 The prompt of the cpan shell can contain the current command number
1311 for easier tracking of the session or be a plain string. Do you want
1312 the command number in the prompt (yes/no)?},
1316 Shall we always set FTP_PASSIVE envariable when dealing with ftp
1317 download (yes/no)?},
1319 # taken from the manpage:
1322 CPAN.pm changes the current working directory often and needs to
1323 determine its own current working directory. Per default it uses
1324 Cwd::cwd but if this doesn't work on your system for some reason,
1325 alternatives can be configured according to the following table:
1329 fastcwd Cwd::fastcwd
1330 backtickcwd external command cwd
1334 getcwd => qq{Preferred method for determining the current working directory?},
1336 index_expire_intro => qq{
1338 The CPAN indexes are usually rebuilt once or twice per hour, but the
1339 typical CPAN mirror mirrors only once or twice per day. Depending on
1340 the quality of your mirror and your desire to be on the bleeding edge,
1341 you may want to set the following value to more or less than one day
1342 (which is the default). It determines after how many days CPAN.pm
1343 downloads new indexes.
1347 index_expire => qq{Let the index expire after how many days?},
1349 term_ornaments => qq{
1351 When using Term::ReadLine, you can turn ornaments on so that your
1352 input stands out against the output from CPAN.pm. Do you want to turn
1355 colorize_output => qq{
1357 When you have Term::ANSIColor installed, you can turn on colorized
1358 output to have some visual differences between normal CPAN.pm output,
1359 warnings, and the output of the modules being installed. Set your
1360 favorite colors after some experimenting with the Term::ANSIColor
1361 module. Do you want to turn on colored output?},
1363 colorize_print => qq{Color for normal output?},
1365 colorize_warn => qq{Color for warnings?},
1367 build_requires_install_policy_intro => qq{
1369 When a module declares another one as a 'build_requires' prerequisite
1370 this means that the other module is only needed for building or
1371 testing the module but need not be installed permanently. In this case
1372 you may wish to install that other module nonetheless or just keep it
1373 in the 'build_dir' directory to have it available only temporarily.
1374 Installing saves time on future installations but makes the perl
1375 installation bigger.
1377 You can choose if you want to always install (yes), never install (no)
1378 or be always asked. In the latter case you can set the default answer
1379 for the question to yes (ask/yes) or no (ask/no).
1383 build_requires_install_policy =>
1384 qq{Policy on installing 'build_requires' modules (yes, no, ask/yes,
1387 yaml_module_intro => qq{
1389 At the time of this writing there are two competing YAML modules,
1390 YAML.pm and YAML::Syck. The latter is faster but needs a C compiler
1391 installed on your system. There may be more alternative YAML
1392 conforming modules but at the time of writing a potential third
1393 player, YAML::Tiny, is not yet sufficiently similar to the other two.
1397 yaml_module => qq{Which YAML implementation would you prefer?},
1401 die "Coding error in \@prompts declaration. Odd number of elements, above"
1404 %prompts = @prompts;
1406 if (scalar(keys %prompts) != scalar(@prompts)/2) {
1408 for my $item (0..$#prompts) {
1410 die "$prompts[$item] is duplicated\n" if $already{$prompts[$item]}++;