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