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.37 $, 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;
80 $CPAN::Config->{urllist} ||= [];
83 my($ret) = defined $a ? $a : "";
84 printf qq{%s [%s]\n\n}, $q, $ret;
91 The following questions are intended to help you with the
92 configuration. The CPAN module needs a directory of its own to cache
93 important index files and maybe keep a temporary mirror of CPAN files.
94 This may be a site-wide directory or a personal directory.
98 my $cpan_home = $CPAN::Config->{cpan_home} || MM->catdir($ENV{HOME}, ".cpan");
102 I see you already have a directory
104 Shall we use it as the general CPAN build and cache directory?
110 First of all, I\'d like to create this directory. Where?
115 $default = $cpan_home;
116 while ($ans = prompt("CPAN build and cache directory?",$default)) {
117 eval { File::Path::mkpath($ans); }; # dies if it can't
119 warn "Couldn't create directory $ans.
123 if (-d $ans && -w _) {
126 warn "Couldn't find directory $ans
127 or directory is not writable. Please retry.\n";
130 $CPAN::Config->{cpan_home} = $ans;
134 If you want, I can keep the source files after a build in the cpan
135 home directory. If you choose so then future builds will take the
136 files from there. If you don\'t want to keep them, answer 0 to the
141 $CPAN::Config->{keep_source_where} = MM->catdir($CPAN::Config->{cpan_home},"sources");
142 $CPAN::Config->{build_dir} = MM->catdir($CPAN::Config->{cpan_home},"build");
145 # Cache size, Index expire
150 How big should the disk cache be for keeping the build directories
151 with all the intermediate files?
155 $default = $CPAN::Config->{build_cache} || 10;
156 $ans = prompt("Cache size for build directory (in MB)?", $default);
157 $CPAN::Config->{build_cache} = $ans;
159 # XXX This the time when we refetch the index files (in days)
160 $CPAN::Config->{'index_expire'} = 1;
164 By default, each time the CPAN module is started, cache scanning
165 is performed to keep the cache size in sync. To prevent from this,
166 disable the cache scanning with 'never'.
170 $default = $CPAN::Config->{scan_cache} || 'atstart';
172 $ans = prompt("Perform cache scanning (atstart or never)?", $default);
173 } while ($ans ne 'atstart' && $ans ne 'never');
174 $CPAN::Config->{scan_cache} = $ans;
177 # prerequisites_policy
178 # Do we follow PREREQ_PM?
182 The CPAN module can detect when a module that which you are trying to
183 build depends on prerequisites. If this happens, it can build the
184 prerequisites for you automatically ('follow'), ask you for
185 confirmation ('ask'), or just ignore them ('ignore'). Please set your
186 policy to one of the three values.
190 $default = $CPAN::Config->{prerequisites_policy} || 'follow';
193 prompt("Policy on building prerequisites (follow, ask or ignore)?",
195 } while ($ans ne 'follow' && $ans ne 'ask' && $ans ne 'ignore');
196 $CPAN::Config->{prerequisites_policy} = $ans;
204 The CPAN module will need a few external programs to work
205 properly. Please correct me, if I guess the wrong path for a program.
206 Don\'t panic if you do not have some of them, just press ENTER for
212 local $^W if $^O eq 'MacOS';
213 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
214 local $^W = $old_warn;
216 for $progname (qw/gzip tar unzip make lynx ncftpget ncftp ftp/){
217 if ($^O eq 'MacOS') {
218 $CPAN::Config->{$progname} = 'not_here';
221 my $progcall = $progname;
222 # we don't need ncftp if we have ncftpget
223 next if $progname eq "ncftp" && $CPAN::Config->{ncftpget} gt " ";
224 my $path = $CPAN::Config->{$progname}
225 || $Config::Config{$progname}
227 if (MM->file_name_is_absolute($path)) {
228 # testing existence is not good enough, some have these exe
231 # warn "Warning: configured $path does not exist\n" unless -e $path;
238 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
241 $path ||= find_exe($progcall,[@path]);
242 warn "Warning: $progcall not found in PATH\n" unless
243 $path; # not -e $path, because find_exe already checked that
244 $ans = prompt("Where is your $progname program?",$path) || $path;
245 $CPAN::Config->{$progname} = $ans;
247 my $path = $CPAN::Config->{'pager'} ||
248 $ENV{PAGER} || find_exe("less",[@path]) ||
249 find_exe("more",[@path]) || ($^O eq 'MacOS' ? $ENV{EDITOR} : 0 )
251 $ans = prompt("What is your favorite pager program?",$path);
252 $CPAN::Config->{'pager'} = $ans;
253 $path = $CPAN::Config->{'shell'};
254 if (MM->file_name_is_absolute($path)) {
255 warn "Warning: configured $path does not exist\n" unless -e $path;
258 $path ||= $ENV{SHELL};
259 if ($^O eq 'MacOS') {
260 $CPAN::Config->{'shell'} = 'not_here';
262 $path =~ s,\\,/,g if $^O eq 'os2'; # Cosmetic only
263 $ans = prompt("What is your favorite shell?",$path);
264 $CPAN::Config->{'shell'} = $ans;
268 # Arguments to make etc.
273 Every Makefile.PL is run by perl in a separate process. Likewise we
274 run \'make\' and \'make install\' in processes. If you have any parameters
275 \(e.g. PREFIX, INSTALLPRIVLIB, UNINST or the like\) you want to pass to
276 the calls, please specify them here.
278 If you don\'t understand this question, just press ENTER.
282 $default = $CPAN::Config->{makepl_arg} || "";
283 $CPAN::Config->{makepl_arg} =
284 prompt("Parameters for the 'perl Makefile.PL' command?",$default);
285 $default = $CPAN::Config->{make_arg} || "";
286 $CPAN::Config->{make_arg} = prompt("Parameters for the 'make' command?",$default);
288 $default = $CPAN::Config->{make_install_arg} || $CPAN::Config->{make_arg} || "";
289 $CPAN::Config->{make_install_arg} =
290 prompt("Parameters for the 'make install' command?",$default);
298 Sometimes you may wish to leave the processes run by CPAN alone
299 without caring about them. As sometimes the Makefile.PL contains
300 question you\'re expected to answer, you can set a timer that will
301 kill a 'perl Makefile.PL' process after the specified time in seconds.
303 If you set this value to 0, these processes will wait forever. This is
304 the default and recommended setting.
308 $default = $CPAN::Config->{inactivity_timeout} || 0;
309 $CPAN::Config->{inactivity_timeout} =
310 prompt("Timeout for inactivity during Makefile.PL?",$default);
316 If you\'re accessing the net via proxies, you can specify them in the
317 CPAN configuration or via environment variables. The variable in
318 the \$CPAN::Config takes precedence.
322 for (qw/ftp_proxy http_proxy no_proxy/) {
323 $default = $CPAN::Config->{$_} || $ENV{$_};
324 $CPAN::Config->{$_} = prompt("Your $_?",$default);
331 conf_sites() unless $fastread;
333 unless (@{$CPAN::Config->{'wait_list'}||[]}) {
336 WAIT support is available as a Plugin. You need the CPAN::WAIT module
337 to actually use it. But we need to know your favorite WAIT server. If
338 you don\'t know a WAIT server near you, just press ENTER.
341 $default = "wait://ls6.informatik.uni-dortmund.de:1404";
342 $ans = prompt("Your favorite WAIT server?\n ",$default);
343 push @{$CPAN::Config->{'wait_list'}}, $ans;
346 # We don't ask that now, it will be noticed in time, won't it?
347 $CPAN::Config->{'inhibit_startup_message'} = 0;
348 $CPAN::Config->{'getcwd'} = 'cwd';
351 CPAN::Config->commit($configpm);
355 my $m = 'MIRRORED.BY';
356 my $mby = MM->catfile($CPAN::Config->{keep_source_where},$m);
357 File::Path::mkpath(File::Basename::dirname($mby));
358 if (-f $mby && -f $m && -M $m < -M $mby) {
360 File::Copy::copy($m,$mby) or die "Could not update $mby: $!";
364 print qq{You have no $mby
365 I\'m trying to fetch one
367 $mby = CPAN::FTP->localize($m,$mby,3);
368 } elsif (-M $mby > 30 ) {
369 print qq{Your $mby is older than 30 days,
370 I\'m trying to fetch one
372 $mby = CPAN::FTP->localize($m,$mby,3);
373 } elsif (-s $mby == 0) {
374 print qq{You have an empty $mby,
375 I\'m trying to fetch one
377 $mby = CPAN::FTP->localize($m,$mby,3);
382 read_mirrored_by($mby);
388 #warn "in find_exe exe[$exe] path[@$path]";
390 my $abs = MM->catfile($dir,$exe);
391 if (($abs = MM->maybe_command($abs))) {
398 my($items,$prompt,$default,$require_nonempty,$empty_warning)=@_;
402 for $item (@$items) {
403 printf "(%d) %s\n", ++$i, $item;
408 my $num = prompt($prompt,$default);
409 @nums = split (' ', $num);
410 (warn "invalid items entered, try again\n"), next
411 if grep (/\D/ || $_ < 1 || $_ > $i, @nums);
412 if ($require_nonempty) {
413 (warn "$empty_warning\n"), next
423 sub read_mirrored_by {
425 my(%all,$url,$expected_size,$default,$ans,$host,$dst,$country,$continent,@location);
426 my $fh = FileHandle->new;
427 $fh->open($local) or die "Couldn't open $local: $!";
430 ($host) = /^([\w\.\-]+)/ unless defined $host;
431 next unless defined $host;
432 next unless /\s+dst_(dst|location)/;
433 /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
434 ($continent, $country) = @location[-1,-2];
435 $continent =~ s/\s\(.*//;
436 $continent =~ s/\W+$//; # if Jarkko doesn't know latitude/longitude
437 /dst_dst\s+=\s+\"([^\"]+)/ and $dst = $1;
438 next unless $host && $dst && $continent && $country;
439 $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
441 $dst=$continent=$country="";
444 $CPAN::Config->{urllist} ||= [];
446 if (@previous_urls = @{$CPAN::Config->{urllist}}) {
447 $CPAN::Config->{urllist} = [];
452 Now we need to know where your favorite CPAN sites are located. Push
453 a few sites onto the array (just in case the first on the array won\'t
454 work). If you are mirroring CPAN to your local workstation, specify a
457 First, pick a nearby continent and country (you can pick several of
458 each, separated by spaces, or none if you just want to keep your
459 existing selections). Then, you will be presented with a list of URLs
460 of CPAN mirrors in the countries you selected, along with previously
461 selected URLs. Select some of those URLs, or just keep the old list.
462 Finally, you will be prompted for any extra URLs -- file:, ftp:, or
463 http: -- that host a CPAN mirror.
467 my (@cont, $cont, %cont, @countries, @urls, %seen);
468 my $no_previous_warn =
469 "Sorry! since you don't have any existing picks, you must make a\n" .
470 "geographic selection.";
471 @cont = picklist([sort keys %all],
472 "Select your continent (or several nearby continents)",
478 foreach $cont (@cont) {
479 my @c = sort keys %{$all{$cont}};
480 @cont{@c} = map ($cont, 0..$#c);
481 @c = map ("$_ ($cont)", @c) if @cont > 1;
482 push (@countries, @c);
486 @countries = picklist (\@countries,
487 "Select your country (or several nearby countries)",
491 %seen = map (($_ => 1), @previous_urls);
492 # hmmm, should take list of defaults from CPAN::Config->{'urllist'}...
493 foreach $country (@countries) {
494 (my $bare_country = $country) =~ s/ \(.*\)//;
495 my @u = sort keys %{$all{$cont{$bare_country}}{$bare_country}};
496 @u = grep (! $seen{$_}, @u);
497 @u = map ("$_ ($bare_country)", @u)
502 push (@urls, map ("$_ (previous pick)", @previous_urls));
503 my $prompt = "Select as many URLs as you like";
504 if (@previous_urls) {
505 $default = join (' ', ((scalar @urls) - (scalar @previous_urls) + 1) ..
507 $prompt .= "\n(or just hit RETURN to keep your previous picks)";
510 @urls = picklist (\@urls, $prompt, $default);
511 foreach (@urls) { s/ \(.*\)//; }
512 %seen = map (($_ => 1), @urls);
515 $ans = prompt ("Enter another URL or RETURN to quit:", "");
518 $ans =~ s|/?$|/|; # has to end with one slash
519 $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
520 if ($ans =~ /^\w+:\/./) {
525 print qq{"$ans" doesn\'t look like an URL at first sight.
526 I\'ll ignore it for now. You can add it to $INC{'CPAN/MyConfig.pm'}
527 later if you\'re sure it\'s right.\n};
532 push @{$CPAN::Config->{urllist}}, @urls;
533 # xxx delete or comment these out when you're happy that it works
534 print "New set of picks:\n";
535 map { print " $_\n" } @{$CPAN::Config->{urllist}};