1 package CPAN::Mirrored::By;
7 sub continent { shift->[0] }
8 sub country { shift->[1] }
11 package CPAN::FirstTime;
14 use ExtUtils::MakeMaker qw(prompt);
16 use File::Basename ();
18 use vars qw($VERSION);
19 $VERSION = substr q$Revision: 1.33 $, 10;
23 CPAN::FirstTime - Utility for CPAN::Config file Initialization
27 CPAN::FirstTime::init()
31 The init routine asks a few questions and writes a CPAN::Config
32 file. Nothing special.
40 unless ($CPAN::VERSION) {
43 eval {require CPAN::Config;};
49 my($ans,$default,$local,$cont,$url,$expected_size);
57 CPAN is the world-wide archive of perl resources. It consists of about
58 100 sites that all replicate the same contents all around the globe.
59 Many countries have at least one CPAN site already. The resources
60 found on CPAN are easily accessible with the CPAN.pm module. If you
61 want to use CPAN.pm, you have to configure it properly.
63 If you do not want to enter a dialog now, you can answer 'no' to this
64 question and I\'ll try to autoconfigure. (Note: you can revisit this
65 dialog anytime later by typing 'o conf init' at the cpan prompt.)
70 ExtUtils::MakeMaker::prompt("Are you ready for manual configuration?",
75 if ($manual_conf =~ /^\s*y/i) {
77 *prompt = \&ExtUtils::MakeMaker::prompt;
82 my($ret) = defined $a ? $a : "";
83 printf qq{%s [%s]\n\n}, $q, $ret;
90 The following questions are intended to help you with the
91 configuration. The CPAN module needs a directory of its own to cache
92 important index files and maybe keep a temporary mirror of CPAN files.
93 This may be a site-wide directory or a personal directory.
97 my $cpan_home = $CPAN::Config->{cpan_home} || MM->catdir($ENV{HOME}, ".cpan");
101 I see you already have a directory
103 Shall we use it as the general CPAN build and cache directory?
109 First of all, I\'d like to create this directory. Where?
114 $default = $cpan_home;
115 while ($ans = prompt("CPAN build and cache directory?",$default)) {
116 File::Path::mkpath($ans); # dies if it can't
117 if (-d $ans && -w _) {
120 warn "Couldn't find directory $ans
121 or directory is not writable. Please retry.\n";
124 $CPAN::Config->{cpan_home} = $ans;
128 If you want, I can keep the source files after a build in the cpan
129 home directory. If you choose so then future builds will take the
130 files from there. If you don\'t want to keep them, answer 0 to the
135 $CPAN::Config->{keep_source_where} = MM->catdir($CPAN::Config->{cpan_home},"sources");
136 $CPAN::Config->{build_dir} = MM->catdir($CPAN::Config->{cpan_home},"build");
139 # Cache size, Index expire
144 How big should the disk cache be for keeping the build directories
145 with all the intermediate files?
149 $default = $CPAN::Config->{build_cache} || 10;
150 $ans = prompt("Cache size for build directory (in MB)?", $default);
151 $CPAN::Config->{build_cache} = $ans;
153 # XXX This the time when we refetch the index files (in days)
154 $CPAN::Config->{'index_expire'} = 1;
158 By default, each time the CPAN module is started, cache scanning
159 is performed to keep the cache size in sync. To prevent from this,
160 disable the cache scanning with 'never'.
164 $default = $CPAN::Config->{scan_cache} || 'atstart';
166 $ans = prompt("Perform cache scanning (atstart or never)?", $default);
167 } while ($ans ne 'atstart' && $ans ne 'never');
168 $CPAN::Config->{scan_cache} = $ans;
171 # prerequisites_policy
172 # Do we follow PREREQ_PM?
176 The CPAN module can detect when a module that which you are trying to
177 build depends on prerequisites. If this happens, it can build the
178 prerequisites for you automatically ('follow'), ask you for
179 confirmation ('ask'), or just ignore them ('ignore'). Please set your
180 policy to one of the three values.
184 $default = $CPAN::Config->{prerequisites_policy} || 'follow';
186 $ans = prompt("Perform cache scanning (follow, ask or ignore)?", $default);
187 } while ($ans ne 'follow' && $ans ne 'ask' && $ans ne 'ignore');
188 $CPAN::Config->{prerequisites_policy} = $ans;
196 The CPAN module will need a few external programs to work
197 properly. Please correct me, if I guess the wrong path for a program.
198 Don\'t panic if you do not have some of them, just press ENTER for
203 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
205 for $progname (qw/gzip tar unzip make lynx ncftpget ncftp ftp/){
206 my $progcall = $progname;
207 # we don't need ncftp if we have ncftpget
208 next if $progname eq "ncftp" && $CPAN::Config->{ncftpget} gt " ";
209 my $path = $CPAN::Config->{$progname}
210 || $Config::Config{$progname}
212 if (MM->file_name_is_absolute($path)) {
213 # testing existence is not good enough, some have these exe
216 # warn "Warning: configured $path does not exist\n" unless -e $path;
223 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
226 $path ||= find_exe($progcall,[@path]);
227 warn "Warning: $progcall not found in PATH\n" unless
228 $path; # not -e $path, because find_exe already checked that
229 $ans = prompt("Where is your $progname program?",$path) || $path;
230 $CPAN::Config->{$progname} = $ans;
232 my $path = $CPAN::Config->{'pager'} ||
233 $ENV{PAGER} || find_exe("less",[@path]) ||
234 find_exe("more",[@path]) || "more";
235 $ans = prompt("What is your favorite pager program?",$path);
236 $CPAN::Config->{'pager'} = $ans;
237 $path = $CPAN::Config->{'shell'};
238 if (MM->file_name_is_absolute($path)) {
239 warn "Warning: configured $path does not exist\n" unless -e $path;
242 $path ||= $ENV{SHELL};
243 $path =~ s,\\,/,g if $^O eq 'os2'; # Cosmetic only
244 $ans = prompt("What is your favorite shell?",$path);
245 $CPAN::Config->{'shell'} = $ans;
248 # Arguments to make etc.
253 Every Makefile.PL is run by perl in a separate process. Likewise we
254 run \'make\' and \'make install\' in processes. If you have any parameters
255 \(e.g. PREFIX, INSTALLPRIVLIB, UNINST or the like\) you want to pass to
256 the calls, please specify them here.
258 If you don\'t understand this question, just press ENTER.
262 $default = $CPAN::Config->{makepl_arg} || "";
263 $CPAN::Config->{makepl_arg} =
264 prompt("Parameters for the 'perl Makefile.PL' command?",$default);
265 $default = $CPAN::Config->{make_arg} || "";
266 $CPAN::Config->{make_arg} = prompt("Parameters for the 'make' command?",$default);
268 $default = $CPAN::Config->{make_install_arg} || $CPAN::Config->{make_arg} || "";
269 $CPAN::Config->{make_install_arg} =
270 prompt("Parameters for the 'make install' command?",$default);
278 Sometimes you may wish to leave the processes run by CPAN alone
279 without caring about them. As sometimes the Makefile.PL contains
280 question you\'re expected to answer, you can set a timer that will
281 kill a 'perl Makefile.PL' process after the specified time in seconds.
283 If you set this value to 0, these processes will wait forever. This is
284 the default and recommended setting.
288 $default = $CPAN::Config->{inactivity_timeout} || 0;
289 $CPAN::Config->{inactivity_timeout} =
290 prompt("Timeout for inactivity during Makefile.PL?",$default);
296 If you\'re accessing the net via proxies, you can specify them in the
297 CPAN configuration or via environment variables. The variable in
298 the \$CPAN::Config takes precedence.
302 for (qw/ftp_proxy http_proxy no_proxy/) {
303 $default = $CPAN::Config->{$_} || $ENV{$_};
304 $CPAN::Config->{$_} = prompt("Your $_?",$default);
311 conf_sites() unless $fastread;
313 unless (@{$CPAN::Config->{'wait_list'}||[]}) {
316 WAIT support is available as a Plugin. You need the CPAN::WAIT module
317 to actually use it. But we need to know your favorite WAIT server. If
318 you don\'t know a WAIT server near you, just press ENTER.
321 $default = "wait://ls6.informatik.uni-dortmund.de:1404";
322 $ans = prompt("Your favorite WAIT server?\n ",$default);
323 push @{$CPAN::Config->{'wait_list'}}, $ans;
326 # We don't ask that now, it will be noticed in time, won't it?
327 $CPAN::Config->{'inhibit_startup_message'} = 0;
328 $CPAN::Config->{'getcwd'} = 'cwd';
331 CPAN::Config->commit($configpm);
335 my $m = 'MIRRORED.BY';
336 my $mby = MM->catfile($CPAN::Config->{keep_source_where},$m);
337 File::Path::mkpath(File::Basename::dirname($mby));
338 if (-f $mby && -f $m && -M $m < -M $mby) {
340 File::Copy::copy($m,$mby) or die "Could not update $mby: $!";
343 print qq{You have no $mby
344 I\'m trying to fetch one
346 $mby = CPAN::FTP->localize($m,$mby,3);
347 } elsif (-M $mby > 30 ) {
348 print qq{Your $mby is older than 30 days,
349 I\'m trying to fetch one
351 $mby = CPAN::FTP->localize($m,$mby,3);
353 read_mirrored_by($mby);
359 #warn "in find_exe exe[$exe] path[@$path]";
361 my $abs = MM->catfile($dir,$exe);
362 if (($abs = MM->maybe_command($abs))) {
369 my($items,$prompt,$default,$require_nonempty,$empty_warning)=@_;
373 for $item (@$items) {
374 printf "(%d) %s\n", ++$i, $item;
379 my $num = prompt($prompt,$default);
380 @nums = split (' ', $num);
381 (warn "invalid items entered, try again\n"), next
382 if grep (/\D/ || $_ < 1 || $_ > $i, @nums);
383 if ($require_nonempty) {
384 (warn "$empty_warning\n"), next
394 sub read_mirrored_by {
396 my(%all,$url,$expected_size,$default,$ans,$host,$dst,$country,$continent,@location);
397 my $fh = FileHandle->new;
398 $fh->open($local) or die "Couldn't open $local: $!";
400 ($host) = /^([\w\.\-]+)/ unless defined $host;
401 next unless defined $host;
402 next unless /\s+dst_(dst|location)/;
403 /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
404 ($continent, $country) = @location[-1,-2];
405 $continent =~ s/\s\(.*//;
406 $continent =~ s/\W+$//; # if Jarkko doesn't know latitude/longitude
407 /dst_dst\s+=\s+\"([^\"]+)/ and $dst = $1;
408 next unless $host && $dst && $continent && $country;
409 $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
411 $dst=$continent=$country="";
414 $CPAN::Config->{urllist} ||= [];
416 if (@previous_urls = @{$CPAN::Config->{urllist}}) {
417 $CPAN::Config->{urllist} = [];
422 Now we need to know where your favorite CPAN sites are located. Push
423 a few sites onto the array (just in case the first on the array won\'t
424 work). If you are mirroring CPAN to your local workstation, specify a
427 First, pick a nearby continent and country (you can pick several of
428 each, separated by spaces, or none if you just want to keep your
429 existing selections). Then, you will be presented with a list of URLs
430 of CPAN mirrors in the countries you selected, along with previously
431 selected URLs. Select some of those URLs, or just keep the old list.
432 Finally, you will be prompted for any extra URLs -- file:, ftp:, or
433 http: -- that host a CPAN mirror.
437 my (@cont, $cont, %cont, @countries, @urls, %seen);
438 my $no_previous_warn =
439 "Sorry! since you don't have any existing picks, you must make a\n" .
440 "geographic selection.";
441 @cont = picklist([sort keys %all],
442 "Select your continent (or several nearby continents)",
448 foreach $cont (@cont) {
449 my @c = sort keys %{$all{$cont}};
450 @cont{@c} = map ($cont, 0..$#c);
451 @c = map ("$_ ($cont)", @c) if @cont > 1;
452 push (@countries, @c);
456 @countries = picklist (\@countries,
457 "Select your country (or several nearby countries)",
461 %seen = map (($_ => 1), @previous_urls);
462 # hmmm, should take list of defaults from CPAN::Config->{'urllist'}...
463 foreach $country (@countries) {
464 (my $bare_country = $country) =~ s/ \(.*\)//;
465 my @u = sort keys %{$all{$cont{$bare_country}}{$bare_country}};
466 @u = grep (! $seen{$_}, @u);
467 @u = map ("$_ ($bare_country)", @u)
472 push (@urls, map ("$_ (previous pick)", @previous_urls));
473 my $prompt = "Select as many URLs as you like";
474 if (@previous_urls) {
475 $default = join (' ', ((scalar @urls) - (scalar @previous_urls) + 1) ..
477 $prompt .= "\n(or just hit RETURN to keep your previous picks)";
480 @urls = picklist (\@urls, $prompt, $default);
481 foreach (@urls) { s/ \(.*\)//; }
482 %seen = map (($_ => 1), @urls);
485 $ans = prompt ("Enter another URL or RETURN to quit:", "");
488 $ans =~ s|/?$|/|; # has to end with one slash
489 $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
490 if ($ans =~ /^\w+:\/./) {
495 print qq{"$ans" doesn\'t look like an URL at first sight.
496 I\'ll ignore it for now. You can add it to $INC{'CPAN/MyConfig.pm'}
497 later if you\'re sure it\'s right.\n};
502 push @{$CPAN::Config->{urllist}}, @urls;
503 # xxx delete or comment these out when you're happy that it works
504 print "New set of picks:\n";
505 map { print " $_\n" } @{$CPAN::Config->{urllist}};