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