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.35 $, 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';
187 prompt("Policy on building prerequisites (follow, ask or ignore)?",
189 } while ($ans ne 'follow' && $ans ne 'ask' && $ans ne 'ignore');
190 $CPAN::Config->{prerequisites_policy} = $ans;
198 The CPAN module will need a few external programs to work
199 properly. Please correct me, if I guess the wrong path for a program.
200 Don\'t panic if you do not have some of them, just press ENTER for
206 local $^W if $^O eq 'MacOS';
207 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
208 local $^W = $old_warn;
210 for $progname (qw/gzip tar unzip make lynx ncftpget ncftp ftp/){
211 if ($^O eq 'MacOS') {
212 $CPAN::Config->{$progname} = 'not_here';
215 my $progcall = $progname;
216 # we don't need ncftp if we have ncftpget
217 next if $progname eq "ncftp" && $CPAN::Config->{ncftpget} gt " ";
218 my $path = $CPAN::Config->{$progname}
219 || $Config::Config{$progname}
221 if (MM->file_name_is_absolute($path)) {
222 # testing existence is not good enough, some have these exe
225 # warn "Warning: configured $path does not exist\n" unless -e $path;
232 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
235 $path ||= find_exe($progcall,[@path]);
236 warn "Warning: $progcall not found in PATH\n" unless
237 $path; # not -e $path, because find_exe already checked that
238 $ans = prompt("Where is your $progname program?",$path) || $path;
239 $CPAN::Config->{$progname} = $ans;
241 my $path = $CPAN::Config->{'pager'} ||
242 $ENV{PAGER} || find_exe("less",[@path]) ||
243 find_exe("more",[@path]) || ($^O eq 'MacOS' ? $ENV{EDITOR} : 0 )
245 $ans = prompt("What is your favorite pager program?",$path);
246 $CPAN::Config->{'pager'} = $ans;
247 $path = $CPAN::Config->{'shell'};
248 if (MM->file_name_is_absolute($path)) {
249 warn "Warning: configured $path does not exist\n" unless -e $path;
252 $path ||= $ENV{SHELL};
253 if ($^O eq 'MacOS') {
254 $CPAN::Config->{'shell'} = 'not_here';
256 $path =~ s,\\,/,g if $^O eq 'os2'; # Cosmetic only
257 $ans = prompt("What is your favorite shell?",$path);
258 $CPAN::Config->{'shell'} = $ans;
262 # Arguments to make etc.
267 Every Makefile.PL is run by perl in a separate process. Likewise we
268 run \'make\' and \'make install\' in processes. If you have any parameters
269 \(e.g. PREFIX, INSTALLPRIVLIB, UNINST or the like\) you want to pass to
270 the calls, please specify them here.
272 If you don\'t understand this question, just press ENTER.
276 $default = $CPAN::Config->{makepl_arg} || "";
277 $CPAN::Config->{makepl_arg} =
278 prompt("Parameters for the 'perl Makefile.PL' command?",$default);
279 $default = $CPAN::Config->{make_arg} || "";
280 $CPAN::Config->{make_arg} = prompt("Parameters for the 'make' command?",$default);
282 $default = $CPAN::Config->{make_install_arg} || $CPAN::Config->{make_arg} || "";
283 $CPAN::Config->{make_install_arg} =
284 prompt("Parameters for the 'make install' command?",$default);
292 Sometimes you may wish to leave the processes run by CPAN alone
293 without caring about them. As sometimes the Makefile.PL contains
294 question you\'re expected to answer, you can set a timer that will
295 kill a 'perl Makefile.PL' process after the specified time in seconds.
297 If you set this value to 0, these processes will wait forever. This is
298 the default and recommended setting.
302 $default = $CPAN::Config->{inactivity_timeout} || 0;
303 $CPAN::Config->{inactivity_timeout} =
304 prompt("Timeout for inactivity during Makefile.PL?",$default);
310 If you\'re accessing the net via proxies, you can specify them in the
311 CPAN configuration or via environment variables. The variable in
312 the \$CPAN::Config takes precedence.
316 for (qw/ftp_proxy http_proxy no_proxy/) {
317 $default = $CPAN::Config->{$_} || $ENV{$_};
318 $CPAN::Config->{$_} = prompt("Your $_?",$default);
325 conf_sites() unless $fastread;
327 unless (@{$CPAN::Config->{'wait_list'}||[]}) {
330 WAIT support is available as a Plugin. You need the CPAN::WAIT module
331 to actually use it. But we need to know your favorite WAIT server. If
332 you don\'t know a WAIT server near you, just press ENTER.
335 $default = "wait://ls6.informatik.uni-dortmund.de:1404";
336 $ans = prompt("Your favorite WAIT server?\n ",$default);
337 push @{$CPAN::Config->{'wait_list'}}, $ans;
340 # We don't ask that now, it will be noticed in time, won't it?
341 $CPAN::Config->{'inhibit_startup_message'} = 0;
342 $CPAN::Config->{'getcwd'} = 'cwd';
345 CPAN::Config->commit($configpm);
349 my $m = 'MIRRORED.BY';
350 my $mby = MM->catfile($CPAN::Config->{keep_source_where},$m);
351 File::Path::mkpath(File::Basename::dirname($mby));
352 if (-f $mby && -f $m && -M $m < -M $mby) {
354 File::Copy::copy($m,$mby) or die "Could not update $mby: $!";
357 print qq{You have no $mby
358 I\'m trying to fetch one
360 $mby = CPAN::FTP->localize($m,$mby,3);
361 } elsif (-M $mby > 30 ) {
362 print qq{Your $mby is older than 30 days,
363 I\'m trying to fetch one
365 $mby = CPAN::FTP->localize($m,$mby,3);
367 read_mirrored_by($mby);
373 #warn "in find_exe exe[$exe] path[@$path]";
375 my $abs = MM->catfile($dir,$exe);
376 if (($abs = MM->maybe_command($abs))) {
383 my($items,$prompt,$default,$require_nonempty,$empty_warning)=@_;
387 for $item (@$items) {
388 printf "(%d) %s\n", ++$i, $item;
393 my $num = prompt($prompt,$default);
394 @nums = split (' ', $num);
395 (warn "invalid items entered, try again\n"), next
396 if grep (/\D/ || $_ < 1 || $_ > $i, @nums);
397 if ($require_nonempty) {
398 (warn "$empty_warning\n"), next
408 sub read_mirrored_by {
410 my(%all,$url,$expected_size,$default,$ans,$host,$dst,$country,$continent,@location);
411 my $fh = FileHandle->new;
412 $fh->open($local) or die "Couldn't open $local: $!";
415 ($host) = /^([\w\.\-]+)/ unless defined $host;
416 next unless defined $host;
417 next unless /\s+dst_(dst|location)/;
418 /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
419 ($continent, $country) = @location[-1,-2];
420 $continent =~ s/\s\(.*//;
421 $continent =~ s/\W+$//; # if Jarkko doesn't know latitude/longitude
422 /dst_dst\s+=\s+\"([^\"]+)/ and $dst = $1;
423 next unless $host && $dst && $continent && $country;
424 $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
426 $dst=$continent=$country="";
429 $CPAN::Config->{urllist} ||= [];
431 if (@previous_urls = @{$CPAN::Config->{urllist}}) {
432 $CPAN::Config->{urllist} = [];
437 Now we need to know where your favorite CPAN sites are located. Push
438 a few sites onto the array (just in case the first on the array won\'t
439 work). If you are mirroring CPAN to your local workstation, specify a
442 First, pick a nearby continent and country (you can pick several of
443 each, separated by spaces, or none if you just want to keep your
444 existing selections). Then, you will be presented with a list of URLs
445 of CPAN mirrors in the countries you selected, along with previously
446 selected URLs. Select some of those URLs, or just keep the old list.
447 Finally, you will be prompted for any extra URLs -- file:, ftp:, or
448 http: -- that host a CPAN mirror.
452 my (@cont, $cont, %cont, @countries, @urls, %seen);
453 my $no_previous_warn =
454 "Sorry! since you don't have any existing picks, you must make a\n" .
455 "geographic selection.";
456 @cont = picklist([sort keys %all],
457 "Select your continent (or several nearby continents)",
463 foreach $cont (@cont) {
464 my @c = sort keys %{$all{$cont}};
465 @cont{@c} = map ($cont, 0..$#c);
466 @c = map ("$_ ($cont)", @c) if @cont > 1;
467 push (@countries, @c);
471 @countries = picklist (\@countries,
472 "Select your country (or several nearby countries)",
476 %seen = map (($_ => 1), @previous_urls);
477 # hmmm, should take list of defaults from CPAN::Config->{'urllist'}...
478 foreach $country (@countries) {
479 (my $bare_country = $country) =~ s/ \(.*\)//;
480 my @u = sort keys %{$all{$cont{$bare_country}}{$bare_country}};
481 @u = grep (! $seen{$_}, @u);
482 @u = map ("$_ ($bare_country)", @u)
487 push (@urls, map ("$_ (previous pick)", @previous_urls));
488 my $prompt = "Select as many URLs as you like";
489 if (@previous_urls) {
490 $default = join (' ', ((scalar @urls) - (scalar @previous_urls) + 1) ..
492 $prompt .= "\n(or just hit RETURN to keep your previous picks)";
495 @urls = picklist (\@urls, $prompt, $default);
496 foreach (@urls) { s/ \(.*\)//; }
497 %seen = map (($_ => 1), @urls);
500 $ans = prompt ("Enter another URL or RETURN to quit:", "");
503 $ans =~ s|/?$|/|; # has to end with one slash
504 $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
505 if ($ans =~ /^\w+:\/./) {
510 print qq{"$ans" doesn\'t look like an URL at first sight.
511 I\'ll ignore it for now. You can add it to $INC{'CPAN/MyConfig.pm'}
512 later if you\'re sure it\'s right.\n};
517 push @{$CPAN::Config->{urllist}}, @urls;
518 # xxx delete or comment these out when you're happy that it works
519 print "New set of picks:\n";
520 map { print " $_\n" } @{$CPAN::Config->{urllist}};