Regenerate PODs
[p5sagit/p5-mst-13.2.git] / lib / CPAN / FirstTime.pm
CommitLineData
8d97e4a1 1# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
5f05dabc 2package CPAN::Mirrored::By;
e82b9348 3use strict;
5f05dabc 4
5sub new {
6 my($self,@arg) = @_;
7 bless [@arg], $self;
8}
da199366 9sub continent { shift->[0] }
10sub country { shift->[1] }
5f05dabc 11sub url { shift->[2] }
12
13package CPAN::FirstTime;
14
15use strict;
f915a99a 16use ExtUtils::MakeMaker ();
05454584 17use FileHandle ();
09d9d230 18use File::Basename ();
05454584 19use File::Path ();
5de3f0da 20use File::Spec;
5f05dabc 21use vars qw($VERSION);
e8a27a4e 22$VERSION = sprintf "%.2f", substr(q$Rev: 331 $,4)/100;
5f05dabc 23
24=head1 NAME
25
26CPAN::FirstTime - Utility for CPAN::Config file Initialization
27
28=head1 SYNOPSIS
29
30CPAN::FirstTime::init()
31
32=head1 DESCRIPTION
33
34The init routine asks a few questions and writes a CPAN::Config
35file. Nothing special.
36
37=cut
38
5f05dabc 39sub init {
554a9ef5 40 my($configpm, %args) = @_;
41
5f05dabc 42 use Config;
554a9ef5 43
f610777f 44 unless ($CPAN::VERSION) {
45 require CPAN::Nox;
46 }
5f05dabc 47 eval {require CPAN::Config;};
48 $CPAN::Config ||= {};
da199366 49 local($/) = "\n";
50 local($\) = "";
13bc20ff 51 local($|) = 1;
da199366 52
5fc0f0f6 53 my($ans,$default);
f610777f 54
da199366 55 #
56 # Files, directories
57 #
58
2e2b7522 59 print qq[
09d9d230 60
61CPAN is the world-wide archive of perl resources. It consists of about
62100 sites that all replicate the same contents all around the globe.
63Many countries have at least one CPAN site already. The resources
64found on CPAN are easily accessible with the CPAN.pm module. If you
65want to use CPAN.pm, you have to configure it properly.
66
67If you do not want to enter a dialog now, you can answer 'no' to this
68question and I\'ll try to autoconfigure. (Note: you can revisit this
69dialog anytime later by typing 'o conf init' at the cpan prompt.)
70
2e2b7522 71];
09d9d230 72
554a9ef5 73 my $manual_conf;
74
75 local *_real_prompt = \&ExtUtils::MakeMaker::prompt;
76 if ( $args{autoconfig} ) {
77 $manual_conf = "no";
78 } else {
79 $manual_conf = prompt("Are you ready for manual configuration?", "yes");
80 }
09d9d230 81 my $fastread;
82 {
f915a99a 83 if ($manual_conf =~ /^y/i) {
09d9d230 84 $fastread = 0;
09d9d230 85 } else {
86 $fastread = 1;
36263cb3 87 $CPAN::Config->{urllist} ||= [];
f915a99a 88
89 local $^W = 0;
c9d9b473 90 # prototype should match that of &MakeMaker::prompt
f915a99a 91 *_real_prompt = sub ($;$) {
09d9d230 92 my($q,$a) = @_;
93 my($ret) = defined $a ? $a : "";
554a9ef5 94 $CPAN::Frontend->myprint(sprintf qq{%s [%s]\n\n}, $q, $ret);
95 eval { require Time::HiRes };
96 unless ($@) {
97 Time::HiRes::sleep(0.1);
98 }
09d9d230 99 $ret;
100 };
101 }
102 }
554a9ef5 103 $CPAN::Frontend->myprint(qq{
09d9d230 104
105The following questions are intended to help you with the
106configuration. The CPAN module needs a directory of its own to cache
107important index files and maybe keep a temporary mirror of CPAN files.
108This may be a site-wide directory or a personal directory.
109
554a9ef5 110});
5f05dabc 111
5de3f0da 112 my $cpan_home = $CPAN::Config->{cpan_home} || File::Spec->catdir($ENV{HOME}, ".cpan");
5f05dabc 113 if (-d $cpan_home) {
554a9ef5 114 $CPAN::Frontend->myprint(qq{
5f05dabc 115
116I see you already have a directory
117 $cpan_home
118Shall we use it as the general CPAN build and cache directory?
119
554a9ef5 120});
5f05dabc 121 } else {
554a9ef5 122 $CPAN::Frontend->myprint(qq{
5f05dabc 123
124First of all, I\'d like to create this directory. Where?
125
554a9ef5 126});
5f05dabc 127 }
128
129 $default = $cpan_home;
05454584 130 while ($ans = prompt("CPAN build and cache directory?",$default)) {
5fc0f0f6 131 unless (File::Spec->file_name_is_absolute($ans)) {
132 require Cwd;
133 my $cwd = Cwd::cwd();
134 my $absans = File::Spec->catdir($cwd,$ans);
135 warn "The path '$ans' is not an absolute path. Please specify an absolute path\n";
136 $default = $absans;
137 next;
138 }
36263cb3 139 eval { File::Path::mkpath($ans); }; # dies if it can't
140 if ($@) {
141 warn "Couldn't create directory $ans.
142Please retry.\n";
143 next;
144 }
145 if (-d $ans && -w _) {
146 last;
147 } else {
148 warn "Couldn't find directory $ans
10b2abe6 149 or directory is not writable. Please retry.\n";
36263cb3 150 }
10b2abe6 151 }
5f05dabc 152 $CPAN::Config->{cpan_home} = $ans;
f610777f 153
554a9ef5 154 $CPAN::Frontend->myprint( qq{
5f05dabc 155
554a9ef5 156If you like, I can cache the source files after I build them. Doing
157so means that, if you ever rebuild that module in the future, the
158files will be taken from the cache. The tradeoff is that it takes up
159space. How much space would you like to allocate to this cache? (If
160you don\'t want me to keep a cache, answer 0.)
5f05dabc 161
554a9ef5 162});
5f05dabc 163
5de3f0da 164 $CPAN::Config->{keep_source_where} = File::Spec->catdir($CPAN::Config->{cpan_home},"sources");
165 $CPAN::Config->{build_dir} = File::Spec->catdir($CPAN::Config->{cpan_home},"build");
5f05dabc 166
da199366 167 #
168 # Cache size, Index expire
169 #
170
554a9ef5 171 $CPAN::Frontend->myprint( qq{
5f05dabc 172
173How big should the disk cache be for keeping the build directories
de34a54b 174with all the intermediate files\?
5f05dabc 175
554a9ef5 176});
5f05dabc 177
554a9ef5 178 $default = $CPAN::Config->{build_cache} || 100; # large enough to
179 # build large
180 # dists like Tk
5f05dabc 181 $ans = prompt("Cache size for build directory (in MB)?", $default);
182 $CPAN::Config->{build_cache} = $ans;
183
184 # XXX This the time when we refetch the index files (in days)
185 $CPAN::Config->{'index_expire'} = 1;
186
554a9ef5 187 $CPAN::Frontend->myprint( qq{
f610777f 188
554a9ef5 189By default, each time the CPAN module is started, cache scanning is
190performed to keep the cache size in sync. To prevent this, answer
191'never'.
f610777f 192
554a9ef5 193});
f610777f 194
195 $default = $CPAN::Config->{scan_cache} || 'atstart';
196 do {
197 $ans = prompt("Perform cache scanning (atstart or never)?", $default);
198 } while ($ans ne 'atstart' && $ans ne 'never');
199 $CPAN::Config->{scan_cache} = $ans;
200
9d61fa1d 201 #
202 # cache_metadata
203 #
554a9ef5 204 $CPAN::Frontend->myprint( qq{
5e05dca5 205
5a5fac02 206To considerably speed up the initial CPAN shell startup, it is
207possible to use Storable to create a cache of metadata. If Storable
208is not available, the normal index mechanism will be used.
5e05dca5 209
554a9ef5 210});
5e05dca5 211
5a5fac02 212 defined($default = $CPAN::Config->{cache_metadata}) or $default = 1;
5e05dca5 213 do {
214 $ans = prompt("Cache metadata (yes/no)?", ($default ? 'yes' : 'no'));
f915a99a 215 } while ($ans !~ /^[yn]/i);
216 $CPAN::Config->{cache_metadata} = ($ans =~ /^y/i ? 1 : 0);
5e05dca5 217
f610777f 218 #
9d61fa1d 219 # term_is_latin
220 #
554a9ef5 221 $CPAN::Frontend->myprint( qq{
9d61fa1d 222
554a9ef5 223The next option deals with the charset (aka character set) your
224terminal supports. In general, CPAN is English speaking territory, so
225the charset does not matter much, but some of the aliens out there who
226upload their software to CPAN bear names that are outside the ASCII
227range. If your terminal supports UTF-8, you should say no to the next
228question. If it supports ISO-8859-1 (also known as LATIN1) then you
229should say yes. If it supports neither, your answer does not matter
230because you will not be able to read the names of some authors
231anyway. If you answer no, names will be output in UTF-8.
9d61fa1d 232
554a9ef5 233});
9d61fa1d 234
235 defined($default = $CPAN::Config->{term_is_latin}) or $default = 1;
236 do {
237 $ans = prompt("Your terminal expects ISO-8859-1 (yes/no)?",
238 ($default ? 'yes' : 'no'));
f915a99a 239 } while ($ans !~ /^[yn]/i);
240 $CPAN::Config->{term_is_latin} = ($ans =~ /^y/i ? 1 : 0);
9d61fa1d 241
242 #
5fc0f0f6 243 # save history in file histfile
244 #
554a9ef5 245 $CPAN::Frontend->myprint( qq{
5fc0f0f6 246
247If you have one of the readline packages (Term::ReadLine::Perl,
248Term::ReadLine::Gnu, possibly others) installed, the interactive CPAN
249shell will have history support. The next two questions deal with the
250filename of the history file and with its size. If you do not want to
251set this variable, please hit SPACE RETURN to the following question.
252
554a9ef5 253});
5fc0f0f6 254
255 defined($default = $CPAN::Config->{histfile}) or
256 $default = File::Spec->catfile($CPAN::Config->{cpan_home},"histfile");
257 $ans = prompt("File to save your history?", $default);
5fc0f0f6 258 $CPAN::Config->{histfile} = $ans;
259
260 if ($CPAN::Config->{histfile}) {
261 defined($default = $CPAN::Config->{histsize}) or $default = 100;
262 $ans = prompt("Number of lines to save?", $default);
263 $CPAN::Config->{histsize} = $ans;
264 }
265
266 #
554a9ef5 267 # do an ls on the m or the d command
268 #
269 $CPAN::Frontend->myprint( qq{
270
271The 'd' and the 'm' command normally only show you information they
272have in their in-memory database and thus will never connect to the
273internet. If you set the 'show_upload_date' variable to true, 'm' and
274'd' will additionally show you the upload date of the module or
275distribution. Per default this feature is off because it may require a
276net connection to get at the upload date.
277
278});
279
280 defined($default = $CPAN::Config->{show_upload_date}) or
281 $default = 0;
282 $ans = prompt("Always try to show upload date with 'd' and 'm' command?", $default);
283 $CPAN::Config->{show_upload_date} = $ans;
284
285 #
f610777f 286 # prerequisites_policy
287 # Do we follow PREREQ_PM?
288 #
554a9ef5 289 $CPAN::Frontend->myprint( qq{
f610777f 290
554a9ef5 291The CPAN module can detect when a module which you are trying to build
292depends on prerequisites. If this happens, it can build the
f610777f 293prerequisites for you automatically ('follow'), ask you for
294confirmation ('ask'), or just ignore them ('ignore'). Please set your
295policy to one of the three values.
296
554a9ef5 297});
f610777f 298
de34a54b 299 $default = $CPAN::Config->{prerequisites_policy} || 'ask';
f610777f 300 do {
f14b5cec 301 $ans =
302 prompt("Policy on building prerequisites (follow, ask or ignore)?",
303 $default);
f610777f 304 } while ($ans ne 'follow' && $ans ne 'ask' && $ans ne 'ignore');
305 $CPAN::Config->{prerequisites_policy} = $ans;
306
da199366 307 #
308 # External programs
309 #
310
554a9ef5 311 $CPAN::Frontend->myprint(qq{
5f05dabc 312
9d61fa1d 313The CPAN module will need a few external programs to work properly.
314Please correct me, if I guess the wrong path for a program. Don\'t
315panic if you do not have some of them, just press ENTER for those. To
316disable the use of a download program, you can type a space followed
317by ENTER.
5f05dabc 318
554a9ef5 319});
5f05dabc 320
f14b5cec 321 my $old_warn = $^W;
322 local $^W if $^O eq 'MacOS';
55e314ee 323 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
f14b5cec 324 local $^W = $old_warn;
09d9d230 325 my $progname;
e82b9348 326 for $progname (qw/bzip2 gzip tar unzip make
554a9ef5 327 curl lynx wget ncftpget ncftp ftp
73beb80c 328 gpg/)
329 {
f14b5cec 330 if ($^O eq 'MacOS') {
331 $CPAN::Config->{$progname} = 'not_here';
332 next;
333 }
09d9d230 334 my $progcall = $progname;
2e2b7522 335 # we don't need ncftp if we have ncftpget
336 next if $progname eq "ncftp" && $CPAN::Config->{ncftpget} gt " ";
337 my $path = $CPAN::Config->{$progname}
338 || $Config::Config{$progname}
339 || "";
5de3f0da 340 if (File::Spec->file_name_is_absolute($path)) {
2e2b7522 341 # testing existence is not good enough, some have these exe
342 # extensions
343
344 # warn "Warning: configured $path does not exist\n" unless -e $path;
345 # $path = "";
346 } else {
347 $path = '';
348 }
349 unless ($path) {
350 # e.g. make -> nmake
351 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
352 }
09d9d230 353
2e2b7522 354 $path ||= find_exe($progcall,[@path]);
554a9ef5 355 $CPAN::Frontend->mywarn("Warning: $progcall not found in PATH\n") unless
2e2b7522 356 $path; # not -e $path, because find_exe already checked that
357 $ans = prompt("Where is your $progname program?",$path) || $path;
358 $CPAN::Config->{$progname} = $ans;
5f05dabc 359 }
360 my $path = $CPAN::Config->{'pager'} ||
361 $ENV{PAGER} || find_exe("less",[@path]) ||
f14b5cec 362 find_exe("more",[@path]) || ($^O eq 'MacOS' ? $ENV{EDITOR} : 0 )
363 || "more";
55e314ee 364 $ans = prompt("What is your favorite pager program?",$path);
5f05dabc 365 $CPAN::Config->{'pager'} = $ans;
55e314ee 366 $path = $CPAN::Config->{'shell'};
5de3f0da 367 if (File::Spec->file_name_is_absolute($path)) {
55e314ee 368 warn "Warning: configured $path does not exist\n" unless -e $path;
369 $path = "";
370 }
371 $path ||= $ENV{SHELL};
f14b5cec 372 if ($^O eq 'MacOS') {
373 $CPAN::Config->{'shell'} = 'not_here';
374 } else {
375 $path =~ s,\\,/,g if $^O eq 'os2'; # Cosmetic only
376 $ans = prompt("What is your favorite shell?",$path);
377 $CPAN::Config->{'shell'} = $ans;
378 }
da199366 379
380 #
381 # Arguments to make etc.
382 #
383
554a9ef5 384 $CPAN::Frontend->myprint( qq{
5f05dabc 385
e82b9348 386When you have Module::Build installed and a module comes with both a
387Makefile.PL and a Build.PL, which shall have precedence? The two
388installer modules we have are the old and well established
389ExtUtils::MakeMaker (for short: EUMM) understands the Makefile.PL and
390the next generation installer Module::Build (MB) works with the
391Build.PL.
392
393});
394
395 $default = $CPAN::Config->{prefer_installer} || "";
396 do {
397 $ans =
398 prompt("In case you could choose, which installer would you prefer (EUMM or MB)?",
399 $default);
400 } while (uc $ans ne 'MB' && uc $ans ne 'EUMM');
401 $CPAN::Config->{prefer_installer} = $ans;
402
403 $CPAN::Frontend->myprint( qq{
404
da199366 405Every Makefile.PL is run by perl in a separate process. Likewise we
554a9ef5 406run \'make\' and \'make install\' in separate processes. If you have
407any parameters \(e.g. PREFIX, LIB, UNINST or the like\) you want to
408pass to the calls, please specify them here.
5f05dabc 409
05454584 410If you don\'t understand this question, just press ENTER.
411
554a9ef5 412});
5f05dabc 413
414 $default = $CPAN::Config->{makepl_arg} || "";
415 $CPAN::Config->{makepl_arg} =
8d97e4a1 416 prompt("Parameters for the 'perl Makefile.PL' command?
417Typical frequently used settings:
418
e82b9348 419 PREFIX=~/perl # non-root users (please see manual for more hints)
8d97e4a1 420
421Your choice: ",$default);
5f05dabc 422 $default = $CPAN::Config->{make_arg} || "";
8d97e4a1 423 $CPAN::Config->{make_arg} = prompt("Parameters for the 'make' command?
424Typical frequently used setting:
425
e82b9348 426 -j3 # dual processor system
8d97e4a1 427
428Your choice: ",$default);
5f05dabc 429
554a9ef5 430 $default = $CPAN::Config->{make_install_make_command} || $CPAN::Config->{make} || "";
431 $CPAN::Config->{make_install_make_command} =
432 prompt("Do you want to use a different make command for 'make install'?
433Cautious people will probably prefer:
434
e8a27a4e 435 su root -c make
436or
554a9ef5 437 sudo make
438or
439 /path1/to/sudo -u admin_account /path2/to/make
440
441or some such. Your choice: ",$default);
442
5f05dabc 443 $default = $CPAN::Config->{make_install_arg} || $CPAN::Config->{make_arg} || "";
444 $CPAN::Config->{make_install_arg} =
8d97e4a1 445 prompt("Parameters for the 'make install' command?
446Typical frequently used setting:
447
e82b9348 448 UNINST=1 # to always uninstall potentially conflicting files
449
450Your choice: ",$default);
451
452 $CPAN::Frontend->myprint( qq{
453
454The next questions deal with Module::Build support.
455
456A Build.PL is run by perl in a separate process. Likewise we run
457'./Build' and './Build install' in separate processes. If you have any
458parameters you want to pass to the calls, please specify them here.
459
460});
461
462 $default = $CPAN::Config->{mbuildpl_arg} || "";
463 $CPAN::Config->{mbuildpl_arg} =
464 prompt("Parameters for the 'perl Build.PL' command?
465Typical frequently used settings:
466
467 --install_base /home/xxx # different installation directory
468
469Your choice: ",$default);
470 $default = $CPAN::Config->{mbuild_arg} || "";
471 $CPAN::Config->{mbuild_arg} = prompt("Parameters for the './Build' command?
472Setting might be:
473
474 --extra_linker_flags -L/usr/foo/lib # non-standard library location
475
476Your choice: ",$default);
477
478 $default = $CPAN::Config->{mbuild_install_build_command} || "./Build";
479 $CPAN::Config->{mbuild_install_build_command} =
480 prompt("Do you want to use a different command for './Build install'?
481Sudo users will probably prefer:
482
e8a27a4e 483 su root -c ./Build
484or
e82b9348 485 sudo ./Build
486or
487 /path1/to/sudo -u admin_account ./Build
488
489or some such. Your choice: ",$default);
490
491 $default = $CPAN::Config->{mbuild_install_arg} || "";
492 $CPAN::Config->{mbuild_install_arg} =
493 prompt("Parameters for the './Build install' command?
494Typical frequently used setting:
495
496 --uninst 1 # uninstall conflicting files
8d97e4a1 497
498Your choice: ",$default);
5f05dabc 499
da199366 500 #
501 # Alarm period
502 #
503
554a9ef5 504 $CPAN::Frontend->myprint( qq{
10b2abe6 505
506Sometimes you may wish to leave the processes run by CPAN alone
554a9ef5 507without caring about them. Because the Makefile.PL sometimes contains
10b2abe6 508question you\'re expected to answer, you can set a timer that will
509kill a 'perl Makefile.PL' process after the specified time in seconds.
510
e50380aa 511If you set this value to 0, these processes will wait forever. This is
512the default and recommended setting.
10b2abe6 513
554a9ef5 514});
10b2abe6 515
516 $default = $CPAN::Config->{inactivity_timeout} || 0;
517 $CPAN::Config->{inactivity_timeout} =
e82b9348 518 prompt("Timeout for inactivity during {Makefile,Build}.PL?",$default);
10b2abe6 519
09d9d230 520 # Proxies
da199366 521
554a9ef5 522 $CPAN::Frontend->myprint( qq{
10b2abe6 523
09d9d230 524If you\'re accessing the net via proxies, you can specify them in the
525CPAN configuration or via environment variables. The variable in
526the \$CPAN::Config takes precedence.
5f05dabc 527
554a9ef5 528});
09d9d230 529
530 for (qw/ftp_proxy http_proxy no_proxy/) {
531 $default = $CPAN::Config->{$_} || $ENV{$_};
532 $CPAN::Config->{$_} = prompt("Your $_?",$default);
5f05dabc 533 }
534
c049f953 535 if ($CPAN::Config->{ftp_proxy} ||
536 $CPAN::Config->{http_proxy}) {
537 $default = $CPAN::Config->{proxy_user} || $CPAN::LWP::UserAgent::USER;
554a9ef5 538 $CPAN::Frontend->myprint( qq{
c049f953 539
540If your proxy is an authenticating proxy, you can store your username
541permanently. If you do not want that, just press RETURN. You will then
542be asked for your username in every future session.
543
554a9ef5 544});
c049f953 545 if ($CPAN::Config->{proxy_user} = prompt("Your proxy user id?",$default)) {
554a9ef5 546 $CPAN::Frontend->myprint( qq{
c049f953 547
548Your password for the authenticating proxy can also be stored
549permanently on disk. If this violates your security policy, just press
550RETURN. You will then be asked for the password in every future
551session.
552
554a9ef5 553});
c049f953 554
555 if ($CPAN::META->has_inst("Term::ReadKey")) {
556 Term::ReadKey::ReadMode("noecho");
557 } else {
554a9ef5 558 $CPAN::Frontend->myprint( qq{
c049f953 559
560Warning: Term::ReadKey seems not to be available, your password will
561be echoed to the terminal!
562
554a9ef5 563});
c049f953 564 }
f915a99a 565 $CPAN::Config->{proxy_pass} = prompt_no_strip("Your proxy password?");
c049f953 566 if ($CPAN::META->has_inst("Term::ReadKey")) {
567 Term::ReadKey::ReadMode("restore");
568 }
569 $CPAN::Frontend->myprint("\n\n");
570 }
571 }
572
09d9d230 573 #
574 # MIRRORED.BY
575 #
576
577 conf_sites() unless $fastread;
578
e50380aa 579 # We don't ask that now, it will be noticed in time, won't it?
5f05dabc 580 $CPAN::Config->{'inhibit_startup_message'} = 0;
e50380aa 581 $CPAN::Config->{'getcwd'} = 'cwd';
5f05dabc 582
554a9ef5 583 $CPAN::Frontend->myprint("\n\n");
e82b9348 584 CPAN::HandleConfig->commit($configpm);
5f05dabc 585}
586
09d9d230 587sub conf_sites {
588 my $m = 'MIRRORED.BY';
5de3f0da 589 my $mby = File::Spec->catfile($CPAN::Config->{keep_source_where},$m);
09d9d230 590 File::Path::mkpath(File::Basename::dirname($mby));
591 if (-f $mby && -f $m && -M $m < -M $mby) {
592 require File::Copy;
593 File::Copy::copy($m,$mby) or die "Could not update $mby: $!";
594 }
911a92db 595 my $loopcount = 0;
de34a54b 596 local $^T = time;
d8773709 597 my $overwrite_local = 0;
598 if ($mby && -f $mby && -M _ <= 60 && -s _ > 0) {
599 my $mtime = localtime((stat _)[9]);
600 my $prompt = qq{Found $mby as of $mtime
601
c049f953 602I\'d use that as a database of CPAN sites. If that is OK for you,
603please answer 'y', but if you want me to get a new database now,
604please answer 'n' to the following question.
d8773709 605
c049f953 606Shall I use the local database in $mby?};
d8773709 607 my $ans = prompt($prompt,"y");
608 $overwrite_local = 1 unless $ans =~ /^y/i;
609 }
de34a54b 610 while ($mby) {
d8773709 611 if ($overwrite_local) {
612 print qq{Trying to overwrite $mby
613};
614 $mby = CPAN::FTP->localize($m,$mby,3);
615 $overwrite_local = 0;
616 } elsif ( ! -f $mby ){
36263cb3 617 print qq{You have no $mby
09d9d230 618 I\'m trying to fetch one
619};
36263cb3 620 $mby = CPAN::FTP->localize($m,$mby,3);
911a92db 621 } elsif (-M $mby > 60 && $loopcount == 0) {
622 print qq{Your $mby is older than 60 days,
09d9d230 623 I\'m trying to fetch one
624};
36263cb3 625 $mby = CPAN::FTP->localize($m,$mby,3);
911a92db 626 $loopcount++;
36263cb3 627 } elsif (-s $mby == 0) {
628 print qq{You have an empty $mby,
629 I\'m trying to fetch one
630};
631 $mby = CPAN::FTP->localize($m,$mby,3);
632 } else {
633 last;
634 }
09d9d230 635 }
636 read_mirrored_by($mby);
de34a54b 637 bring_your_own();
09d9d230 638}
639
5f05dabc 640sub find_exe {
641 my($exe,$path) = @_;
55e314ee 642 my($dir);
643 #warn "in find_exe exe[$exe] path[@$path]";
5f05dabc 644 for $dir (@$path) {
5de3f0da 645 my $abs = File::Spec->catfile($dir,$exe);
13bc20ff 646 if (($abs = MM->maybe_command($abs))) {
5f05dabc 647 return $abs;
648 }
649 }
650}
651
f610777f 652sub picklist {
653 my($items,$prompt,$default,$require_nonempty,$empty_warning)=@_;
654 $default ||= '';
655
5fc0f0f6 656 my $pos = 0;
f610777f 657
658 my @nums;
659 while (1) {
ec385757 660
5fc0f0f6 661 # display, at most, 15 items at a time
662 my $limit = $#{ $items } - $pos;
663 $limit = 15 if $limit > 15;
664
665 # show the next $limit items, get the new position
666 $pos = display_some($items, $limit, $pos);
667 $pos = 0 if $pos >= @$items;
668
669 my $num = prompt($prompt,$default);
670
671 @nums = split (' ', $num);
672 my $i = scalar @$items;
673 (warn "invalid items entered, try again\n"), next
674 if grep (/\D/ || $_ < 1 || $_ > $i, @nums);
675 if ($require_nonempty) {
676 (warn "$empty_warning\n");
677 }
678 print "\n";
679
680 # a blank line continues...
681 next unless @nums;
682 last;
f610777f 683 }
f610777f 684 for (@nums) { $_-- }
685 @{$items}[@nums];
686}
687
ec385757 688sub display_some {
689 my ($items, $limit, $pos) = @_;
690 $pos ||= 0;
691
692 my @displayable = @$items[$pos .. ($pos + $limit)];
693 for my $item (@displayable) {
694 printf "(%d) %s\n", ++$pos, $item;
695 }
5fc0f0f6 696 printf("%d more items, hit SPACE RETURN to show them\n",
697 (@$items - $pos)
698 )
699 if $pos < @$items;
ec385757 700 return $pos;
701}
702
5f05dabc 703sub read_mirrored_by {
de34a54b 704 my $local = shift or return;
5f05dabc 705 my(%all,$url,$expected_size,$default,$ans,$host,$dst,$country,$continent,@location);
05454584 706 my $fh = FileHandle->new;
707 $fh->open($local) or die "Couldn't open $local: $!";
f14b5cec 708 local $/ = "\012";
05454584 709 while (<$fh>) {
5f05dabc 710 ($host) = /^([\w\.\-]+)/ unless defined $host;
711 next unless defined $host;
712 next unless /\s+dst_(dst|location)/;
713 /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
714 ($continent, $country) = @location[-1,-2];
715 $continent =~ s/\s\(.*//;
f610777f 716 $continent =~ s/\W+$//; # if Jarkko doesn't know latitude/longitude
5f05dabc 717 /dst_dst\s+=\s+\"([^\"]+)/ and $dst = $1;
718 next unless $host && $dst && $continent && $country;
719 $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
720 undef $host;
721 $dst=$continent=$country="";
722 }
05454584 723 $fh->close;
5f05dabc 724 $CPAN::Config->{urllist} ||= [];
f610777f 725 my(@previous_urls);
726 if (@previous_urls = @{$CPAN::Config->{urllist}}) {
5f05dabc 727 $CPAN::Config->{urllist} = [];
5f05dabc 728 }
f610777f 729
5f05dabc 730 print qq{
731
f610777f 732Now we need to know where your favorite CPAN sites are located. Push
5f05dabc 733a few sites onto the array (just in case the first on the array won\'t
734work). If you are mirroring CPAN to your local workstation, specify a
735file: URL.
736
f610777f 737First, pick a nearby continent and country (you can pick several of
738each, separated by spaces, or none if you just want to keep your
739existing selections). Then, you will be presented with a list of URLs
740of CPAN mirrors in the countries you selected, along with previously
741selected URLs. Select some of those URLs, or just keep the old list.
742Finally, you will be prompted for any extra URLs -- file:, ftp:, or
743http: -- that host a CPAN mirror.
5f05dabc 744
745};
746
f610777f 747 my (@cont, $cont, %cont, @countries, @urls, %seen);
748 my $no_previous_warn =
749 "Sorry! since you don't have any existing picks, you must make a\n" .
750 "geographic selection.";
751 @cont = picklist([sort keys %all],
752 "Select your continent (or several nearby continents)",
753 '',
754 ! @previous_urls,
755 $no_previous_warn);
756
757
758 foreach $cont (@cont) {
759 my @c = sort keys %{$all{$cont}};
760 @cont{@c} = map ($cont, 0..$#c);
761 @c = map ("$_ ($cont)", @c) if @cont > 1;
762 push (@countries, @c);
5f05dabc 763 }
f610777f 764
765 if (@countries) {
766 @countries = picklist (\@countries,
767 "Select your country (or several nearby countries)",
768 '',
769 ! @previous_urls,
770 $no_previous_warn);
771 %seen = map (($_ => 1), @previous_urls);
772 # hmmm, should take list of defaults from CPAN::Config->{'urllist'}...
773 foreach $country (@countries) {
774 (my $bare_country = $country) =~ s/ \(.*\)//;
775 my @u = sort keys %{$all{$cont{$bare_country}}{$bare_country}};
776 @u = grep (! $seen{$_}, @u);
777 @u = map ("$_ ($bare_country)", @u)
778 if @countries > 1;
779 push (@urls, @u);
780 }
781 }
782 push (@urls, map ("$_ (previous pick)", @previous_urls));
5fc0f0f6 783 my $prompt = "Select as many URLs as you like (by number),
784put them on one line, separated by blanks, e.g. '1 4 5'";
f610777f 785 if (@previous_urls) {
786 $default = join (' ', ((scalar @urls) - (scalar @previous_urls) + 1) ..
787 (scalar @urls));
788 $prompt .= "\n(or just hit RETURN to keep your previous picks)";
789 }
790
791 @urls = picklist (\@urls, $prompt, $default);
792 foreach (@urls) { s/ \(.*\)//; }
de34a54b 793 push @{$CPAN::Config->{urllist}}, @urls;
794}
f610777f 795
de34a54b 796sub bring_your_own {
797 my %seen = map (($_ => 1), @{$CPAN::Config->{urllist}});
798 my($ans,@urls);
f610777f 799 do {
de34a54b 800 my $prompt = "Enter another URL or RETURN to quit:";
801 unless (%seen) {
802 $prompt = qq{CPAN.pm needs at least one URL where it can fetch CPAN files from.
803
804Please enter your CPAN site:};
805 }
806 $ans = prompt ($prompt, "");
f610777f 807
808 if ($ans) {
de34a54b 809 $ans =~ s|/?\z|/|; # has to end with one slash
f610777f 810 $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
811 if ($ans =~ /^\w+:\/./) {
8d97e4a1 812 push @urls, $ans unless $seen{$ans}++;
de34a54b 813 } else {
8d97e4a1 814 printf(qq{"%s" doesn\'t look like an URL at first sight.
815I\'ll ignore it for now.
816You can add it to your %s
817later if you\'re sure it\'s right.\n},
818 $ans,
819 $INC{'CPAN/MyConfig.pm'} || $INC{'CPAN/Config.pm'} || "configuration file",
820 );
f610777f 821 }
822 }
de34a54b 823 } while $ans || !%seen;
f610777f 824
825 push @{$CPAN::Config->{urllist}}, @urls;
826 # xxx delete or comment these out when you're happy that it works
827 print "New set of picks:\n";
828 map { print " $_\n" } @{$CPAN::Config->{urllist}};
5f05dabc 829}
830
f915a99a 831
832sub _strip_spaces {
833 $_[0] =~ s/^\s+//; # no leading spaces
834 $_[0] =~ s/\s+\z//; # no trailing spaces
835}
836
837
838sub prompt ($;$) {
839 my $ans = _real_prompt(@_);
840
841 _strip_spaces($ans);
842
843 return $ans;
844}
845
846
847sub prompt_no_strip ($;$) {
848 return _real_prompt(@_);
849}
850
851
5f05dabc 8521;