Update CPAN.pm to 1.93_03
[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
810a0276 5sub new {
5f05dabc 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;
5f05dabc 14use strict;
135a59c2 15
f915a99a 16use ExtUtils::MakeMaker ();
05454584 17use FileHandle ();
09d9d230 18use File::Basename ();
05454584 19use File::Path ();
6658a91b 20use File::Spec ();
8962fc49 21use vars qw($VERSION $urllist);
a7f1e69b 22$VERSION = "5.52";
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
c9869e1c 34The init routine asks a few questions and writes a CPAN/Config.pm or
35CPAN/MyConfig.pm file (depending on what it is currently using).
36
547d3dfd 37In the following all questions and explanations regarding config
38variables are collected.
5f05dabc 39
40=cut
41
547d3dfd 42# down until the next =back the manpage must be parsed by the program
43# because the text is used in the init dialogues.
9ddc4ed0 44
547d3dfd 45=over 2
554a9ef5 46
547d3dfd 47=item auto_commit
da199366 48
547d3dfd 49Normally CPAN.pm keeps config variables in memory and changes need to
50be saved in a separate 'o conf commit' command to make them permanent
51between sessions. If you set the 'auto_commit' option to true, changes
52to a config variable are always automatically committed to disk.
f610777f 53
547d3dfd 54Always commit changes to config variables to disk?
da199366 55
547d3dfd 56=item build_cache
09d9d230 57
547d3dfd 58CPAN.pm can limit the size of the disk area for keeping the build
59directories with all the intermediate files.
554a9ef5 60
547d3dfd 61Cache size for build directory (in MB)?
9ddc4ed0 62
547d3dfd 63=item build_dir
9ddc4ed0 64
547d3dfd 65Directory where the build process takes place?
5f05dabc 66
547d3dfd 67=item build_dir_reuse
5f05dabc 68
547d3dfd 69Until version 1.88 CPAN.pm never trusted the contents of the build_dir
70directory between sessions. Since 1.88_58 CPAN.pm has a YAML-based
71mechanism that makes it possible to share the contents of the
72build_dir/ directory between different sessions with the same version
73of perl. People who prefer to test things several days before
74installing will like this feature because it safes a lot of time.
5f05dabc 75
547d3dfd 76If you say yes to the following question, CPAN will try to store
77enough information about the build process so that it can pick up in
78future sessions at the same state of affairs as it left a previous
79session.
f610777f 80
547d3dfd 81Store and re-use state information about distributions between
82CPAN.pm sessions?
5f05dabc 83
547d3dfd 84=item build_requires_install_policy
5f05dabc 85
547d3dfd 86When a module declares another one as a 'build_requires' prerequisite
87this means that the other module is only needed for building or
88testing the module but need not be installed permanently. In this case
89you may wish to install that other module nonetheless or just keep it
90in the 'build_dir' directory to have it available only temporarily.
91Installing saves time on future installations but makes the perl
92installation bigger.
1e8f9a0a 93
547d3dfd 94You can choose if you want to always install (yes), never install (no)
95or be always asked. In the latter case you can set the default answer
96for the question to yes (ask/yes) or no (ask/no).
05bab18e 97
547d3dfd 98Policy on installing 'build_requires' modules (yes, no, ask/yes,
99ask/no)?
5f05dabc 100
547d3dfd 101=item cache_metadata
b72dd56f 102
547d3dfd 103To considerably speed up the initial CPAN shell startup, it is
104possible to use Storable to create a cache of metadata. If Storable is
105not available, the normal index mechanism will be used.
b72dd56f 106
547d3dfd 107Note: this mechanism is not used when use_sqlite is on and SQLLite is
108running.
da199366 109
547d3dfd 110Cache metadata (yes/no)?
5e05dca5 111
547d3dfd 112=item check_sigs
9d61fa1d 113
547d3dfd 114CPAN packages can be digitally signed by authors and thus verified
115with the security provided by strong cryptography. The exact mechanism
116is defined in the Module::Signature module. While this is generally
117considered a good thing, it is not always convenient to the end user
118to install modules that are signed incorrectly or where the key of the
119author is not available or where some prerequisite for
120Module::Signature has a bug and so on.
9d61fa1d 121
547d3dfd 122With the check_sigs parameter you can turn signature checking on and
123off. The default is off for now because the whole tool chain for the
124functionality is not yet considered mature by some. The author of
125CPAN.pm would recommend setting it to true most of the time and
126turning it off only if it turns out to be annoying.
5fc0f0f6 127
547d3dfd 128Note that if you do not have Module::Signature installed, no signature
129checks will be performed at all.
5fc0f0f6 130
547d3dfd 131Always try to check and verify signatures if a SIGNATURE file is in
132the package and Module::Signature is installed (yes/no)?
554a9ef5 133
547d3dfd 134=item colorize_output
9ddc4ed0 135
547d3dfd 136When you have Term::ANSIColor installed, you can turn on colorized
137output to have some visual differences between normal CPAN.pm output,
138warnings, debugging output, and the output of the modules being
139installed. Set your favorite colors after some experimenting with the
140Term::ANSIColor module.
554a9ef5 141
547d3dfd 142Do you want to turn on colored output?
135a59c2 143
547d3dfd 144=item colorize_print
135a59c2 145
547d3dfd 146Color for normal output?
f610777f 147
547d3dfd 148=item colorize_warn
ed84aac9 149
547d3dfd 150Color for warnings?
1e8f9a0a 151
547d3dfd 152=item colorize_debug
da199366 153
547d3dfd 154Color for debugging messages?
b72dd56f 155
547d3dfd 156=item commandnumber_in_prompt
b72dd56f 157
547d3dfd 158The prompt of the cpan shell can contain the current command number
159for easier tracking of the session or be a plain string.
b72dd56f 160
547d3dfd 161Do you want the command number in the prompt (yes/no)?
b72dd56f 162
5254b38e 163=item connect_to_internet_ok
164
165If you have never defined your own C<urllist> in your configuration
166then C<CPAN.pm> will be hesitant to use the built in default sites for
167downloading. It will ask you once per session if a connection to the
168internet is OK and only if you say yes, it will try to connect. But to
169avoid this question, you can choose your favorite download sites once
170and get away with it. Or, if you have no favorite download sites
171answer yes to the following question.
172
173If no urllist has been chosen yet, would you prefer CPAN.pm to connect
174to the built-in default sites without asking? (yes/no)?
175
547d3dfd 176=item ftp_passive
8962fc49 177
547d3dfd 178Shall we always set the FTP_PASSIVE environment variable when dealing
179with ftp download (yes/no)?
8962fc49 180
5254b38e 181=item ftpstats_period
182
183Statistics about downloads are truncated by size and period
184simultaneously.
185
186How many days shall we keep statistics about downloads?
187
188=item ftpstats_size
189
190Statistics about downloads are truncated by size and period
191simultaneously.
192
193How many items shall we keep in the statistics about downloads?
194
547d3dfd 195=item getcwd
8962fc49 196
547d3dfd 197CPAN.pm changes the current working directory often and needs to
198determine its own current working directory. Per default it uses
199Cwd::cwd but if this doesn't work on your system for some reason,
200alternatives can be configured according to the following table:
09d9d230 201
547d3dfd 202 cwd Cwd::cwd
203 getcwd Cwd::getcwd
204 fastcwd Cwd::fastcwd
205 backtickcwd external command cwd
2b3bde2a 206
547d3dfd 207Preferred method for determining the current working directory?
2b3bde2a 208
5254b38e 209=item halt_on_failure
210
211Normaly, CPAN.pm continues processing the full list of targets and
212dependencies, even if one of them fails. However, you can specify
213that CPAN should halt after the first failure.
214
215Do you want to halt on failure (yes/no)?
216
547d3dfd 217=item histfile
2b3bde2a 218
547d3dfd 219If you have one of the readline packages (Term::ReadLine::Perl,
220Term::ReadLine::Gnu, possibly others) installed, the interactive CPAN
221shell will have history support. The next two questions deal with the
222filename of the history file and with its size. If you do not want to
223set this variable, please hit SPACE RETURN to the following question.
2b3bde2a 224
547d3dfd 225File to save your history?
8962fc49 226
547d3dfd 227=item histsize
8962fc49 228
547d3dfd 229Number of lines to save?
da199366 230
547d3dfd 231=item inactivity_timeout
da199366 232
547d3dfd 233Sometimes you may wish to leave the processes run by CPAN alone
234without caring about them. Because the Makefile.PL or the Build.PL
235sometimes contains question you're expected to answer, you can set a
236timer that will kill a 'perl Makefile.PL' process after the specified
237time in seconds.
e82b9348 238
547d3dfd 239If you set this value to 0, these processes will wait forever. This is
240the default and recommended setting.
e82b9348 241
547d3dfd 242Timeout for inactivity during {Makefile,Build}.PL?
e82b9348 243
547d3dfd 244=item index_expire
e82b9348 245
547d3dfd 246The CPAN indexes are usually rebuilt once or twice per hour, but the
247typical CPAN mirror mirrors only once or twice per day. Depending on
248the quality of your mirror and your desire to be on the bleeding edge,
249you may want to set the following value to more or less than one day
250(which is the default). It determines after how many days CPAN.pm
251downloads new indexes.
e82b9348 252
547d3dfd 253Let the index expire after how many days?
e82b9348 254
547d3dfd 255=item inhibit_startup_message
8d97e4a1 256
547d3dfd 257When the CPAN shell is started it normally displays a greeting message
258that contains the running version and the status of readline support.
5f05dabc 259
547d3dfd 260Do you want to turn this message off?
8962fc49 261
547d3dfd 262=item keep_source_where
8962fc49 263
547d3dfd 264Unless you are accessing the CPAN on your filesystem via a file: URL,
265CPAN.pm needs to keep the source files it downloads somewhere. Please
266supply a directory where the downloaded files are to be kept.
da199366 267
547d3dfd 268Download target directory?
10b2abe6 269
547d3dfd 270=item load_module_verbosity
10b2abe6 271
547d3dfd 272When CPAN.pm loads a module it needs for some optional feature, it
273usually reports about module name and version. Choose 'v' to get this
274message, 'none' to suppress it.
10b2abe6 275
547d3dfd 276Verbosity level for loading modules (none or v)?
da199366 277
547d3dfd 278=item makepl_arg
09d9d230 279
547d3dfd 280Every Makefile.PL is run by perl in a separate process. Likewise we
281run 'make' and 'make install' in separate processes. If you have
5254b38e 282any parameters (e.g. PREFIX, UNINST or the like) you want to
547d3dfd 283pass to the calls, please specify them here.
c9869e1c 284
547d3dfd 285If you don't understand this question, just press ENTER.
5f05dabc 286
547d3dfd 287Typical frequently used settings:
9ddc4ed0 288
547d3dfd 289 PREFIX=~/perl # non-root users (please see manual for more hints)
c049f953 290
547d3dfd 291Parameters for the 'perl Makefile.PL' command?
c049f953 292
547d3dfd 293=item make_arg
c049f953 294
547d3dfd 295Parameters for the 'make' command? Typical frequently used setting:
8962fc49 296
547d3dfd 297 -j3 # dual processor system (on GNU make)
8962fc49 298
547d3dfd 299Your choice:
b72dd56f 300
547d3dfd 301=item make_install_arg
c049f953 302
547d3dfd 303Parameters for the 'make install' command?
304Typical frequently used setting:
8962fc49 305
547d3dfd 306 UNINST=1 # to always uninstall potentially conflicting files
8962fc49 307
547d3dfd 308Your choice:
8962fc49 309
547d3dfd 310=item make_install_make_command
8962fc49 311
547d3dfd 312Do you want to use a different make command for 'make install'?
313Cautious people will probably prefer:
8962fc49 314
547d3dfd 315 su root -c make
316 or
317 sudo make
318 or
319 /path1/to/sudo -u admin_account /path2/to/make
8962fc49 320
547d3dfd 321or some such. Your choice:
09d9d230 322
547d3dfd 323=item mbuildpl_arg
09d9d230 324
547d3dfd 325A Build.PL is run by perl in a separate process. Likewise we run
326'./Build' and './Build install' in separate processes. If you have any
327parameters you want to pass to the calls, please specify them here.
5f05dabc 328
547d3dfd 329Typical frequently used settings:
5f05dabc 330
547d3dfd 331 --install_base /home/xxx # different installation directory
9ddc4ed0 332
547d3dfd 333Parameters for the 'perl Build.PL' command?
9ddc4ed0 334
547d3dfd 335=item mbuild_arg
8962fc49 336
547d3dfd 337Parameters for the './Build' command? Setting might be:
8962fc49 338
547d3dfd 339 --extra_linker_flags -L/usr/foo/lib # non-standard library location
9ddc4ed0 340
547d3dfd 341Your choice:
9ddc4ed0 342
547d3dfd 343=item mbuild_install_arg
9ddc4ed0 344
547d3dfd 345Parameters for the './Build install' command? Typical frequently used
346setting:
d8773709 347
547d3dfd 348 --uninst 1 # uninstall conflicting files
d8773709 349
547d3dfd 350Your choice:
09d9d230 351
547d3dfd 352=item mbuild_install_build_command
5f05dabc 353
547d3dfd 354Do you want to use a different command for './Build install'? Sudo
355users will probably prefer:
f610777f 356
547d3dfd 357 su root -c ./Build
358 or
359 sudo ./Build
360 or
361 /path1/to/sudo -u admin_account ./Build
f610777f 362
547d3dfd 363or some such. Your choice:
ec385757 364
547d3dfd 365=item pager
5fc0f0f6 366
547d3dfd 367What is your favorite pager program?
5fc0f0f6 368
547d3dfd 369=item prefer_installer
5fc0f0f6 370
547d3dfd 371When you have Module::Build installed and a module comes with both a
372Makefile.PL and a Build.PL, which shall have precedence?
5fc0f0f6 373
547d3dfd 374The main two standard installer modules are the old and well
375established ExtUtils::MakeMaker (for short: EUMM) which uses the
376Makefile.PL. And the next generation installer Module::Build (MB)
377which works with the Build.PL (and often comes with a Makefile.PL
378too). If a module comes only with one of the two we will use that one
379but if both are supplied then a decision must be made between EUMM and
380MB. See also http://rt.cpan.org/Ticket/Display.html?id=29235 for a
381discussion about the right default.
f610777f 382
547d3dfd 383Or, as a third option you can choose RAND which will make a random
384decision (something regular CPAN testers will enjoy).
26844e27 385
547d3dfd 386In case you can choose between running a Makefile.PL or a Build.PL,
387which installer would you prefer (EUMM or MB or RAND)?
ec385757 388
547d3dfd 389=item prefs_dir
ec385757 390
547d3dfd 391CPAN.pm can store customized build environments based on regular
392expressions for distribution names. These are YAML files where the
393default options for CPAN.pm and the environment can be overridden and
394dialog sequences can be stored that can later be executed by an
395Expect.pm object. The CPAN.pm distribution comes with some prefab YAML
396files that cover sample distributions that can be used as blueprints
397to store one own prefs. Please check out the distroprefs/ directory of
398the CPAN.pm distribution to get a quick start into the prefs system.
f610777f 399
547d3dfd 400Directory where to store default options/environment/dialogs for
401building modules that need some customization?
5f05dabc 402
547d3dfd 403=item prerequisites_policy
f610777f 404
547d3dfd 405The CPAN module can detect when a module which you are trying to build
406depends on prerequisites. If this happens, it can build the
407prerequisites for you automatically ('follow'), ask you for
408confirmation ('ask'), or just ignore them ('ignore'). Please set your
409policy to one of the three values.
f610777f 410
547d3dfd 411Policy on building prerequisites (follow, ask or ignore)?
f610777f 412
547d3dfd 413=item randomize_urllist
f610777f 414
547d3dfd 415CPAN.pm can introduce some randomness when using hosts for download
416that are configured in the urllist parameter. Enter a numeric value
417between 0 and 1 to indicate how often you want to let CPAN.pm try a
418random host from the urllist. A value of one specifies to always use a
419random host as the first try. A value of zero means no randomness at
420all. Anything in between specifies how often, on average, a random
421host should be tried first.
f610777f 422
547d3dfd 423Randomize parameter
de34a54b 424
547d3dfd 425=item scan_cache
9ddc4ed0 426
427By default, each time the CPAN module is started, cache scanning is
428performed to keep the cache size in sync. To prevent this, answer
429'never'.
430
547d3dfd 431Perform cache scanning (atstart or never)?
9ddc4ed0 432
547d3dfd 433=item shell
9ddc4ed0 434
547d3dfd 435What is your favorite shell?
8962fc49 436
547d3dfd 437=item show_unparsable_versions
9ddc4ed0 438
547d3dfd 439During the 'r' command CPAN.pm finds modules without version number.
440When the command finishes, it prints a report about this. If you
441want this report to be very verbose, say yes to the following
442variable.
9ddc4ed0 443
547d3dfd 444Show all individual modules that have no $VERSION?
c9869e1c 445
547d3dfd 446=item show_upload_date
9ddc4ed0 447
448The 'd' and the 'm' command normally only show you information they
449have in their in-memory database and thus will never connect to the
450internet. If you set the 'show_upload_date' variable to true, 'm' and
451'd' will additionally show you the upload date of the module or
452distribution. Per default this feature is off because it may require a
453net connection to get at the upload date.
454
547d3dfd 455Always try to show upload date with 'd' and 'm' command (yes/no)?
9ddc4ed0 456
547d3dfd 457=item show_zero_versions
9ddc4ed0 458
547d3dfd 459During the 'r' command CPAN.pm finds modules with a version number of
460zero. When the command finishes, it prints a report about this. If you
461want this report to be very verbose, say yes to the following
462variable.
9ddc4ed0 463
547d3dfd 464Show all individual modules that have a $VERSION of zero?
9ddc4ed0 465
547d3dfd 466=item tar_verbosity
9ddc4ed0 467
547d3dfd 468When CPAN.pm uses the tar command, which switch for the verbosity
469shall be used? Choose 'none' for quiet operation, 'v' for file
470name listing, 'vv' for full listing.
9ddc4ed0 471
547d3dfd 472Tar command verbosity level (none or v or vv)?
ed84aac9 473
547d3dfd 474=item term_is_latin
ed84aac9 475
547d3dfd 476The next option deals with the charset (aka character set) your
477terminal supports. In general, CPAN is English speaking territory, so
478the charset does not matter much but some CPAN have names that are
479outside the ASCII range. If your terminal supports UTF-8, you should
480say no to the next question. If it expects ISO-8859-1 (also known as
481LATIN1) then you should say yes. If it supports neither, your answer
482does not matter because you will not be able to read the names of some
483authors anyway. If you answer no, names will be output in UTF-8.
ed84aac9 484
547d3dfd 485Your terminal expects ISO-8859-1 (yes/no)?
ed84aac9 486
547d3dfd 487=item term_ornaments
488
489When using Term::ReadLine, you can turn ornaments on so that your
490input stands out against the output from CPAN.pm.
ed84aac9 491
547d3dfd 492Do you want to turn ornaments on?
ed84aac9 493
547d3dfd 494=item test_report
8962fc49 495
496The goal of the CPAN Testers project (http://testers.cpan.org/) is to
497test as many CPAN packages as possible on as many platforms as
498possible. This provides valuable feedback to module authors and
499potential users to identify bugs or platform compatibility issues and
500improves the overall quality and value of CPAN.
501
502One way you can contribute is to send test results for each module
503that you install. If you install the CPAN::Reporter module, you have
504the option to automatically generate and email test reports to CPAN
505Testers whenever you run tests on a CPAN package.
506
507See the CPAN::Reporter documentation for additional details and
508configuration settings. If your firewall blocks outgoing email,
509you will need to configure CPAN::Reporter before sending reports.
510
547d3dfd 511Email test reports if CPAN::Reporter is installed (yes/no)?
8962fc49 512
5254b38e 513=item perl5lib_verbosity
514
515When CPAN.pm extends @INC via PERL5LIB, it prints a list of
516directories added (or a summary of how many directories are
517added). Choose 'v' to get this message, 'none' to suppress it.
518
519Verbosity level for PERL5LIB changes (none or v)?
520
521=item trust_test_report_history
522
523When a distribution has already been tested by CPAN::Reporter on
524this machine, CPAN can skip the test phase and just rely on the
525test report history instead.
526
527Note that this will not apply to distributions that failed tests
528because of missing dependencies. Also, tests can be run
529regardless of the history using "force".
530
531Do you want to rely on the test report history (yes/no)?
532
547d3dfd 533=item use_sqlite
8962fc49 534
547d3dfd 535CPAN::SQLite is a layer between the index files that are downloaded
536from the CPAN and CPAN.pm that speeds up metadata queries and reduces
537memory consumption of CPAN.pm considerably.
9ddc4ed0 538
547d3dfd 539Use CPAN::SQLite if available? (yes/no)?
9ddc4ed0 540
547d3dfd 541=item yaml_load_code
9ddc4ed0 542
5254b38e 543Both YAML.pm and YAML::Syck are capable of deserialising code. As this
544requires a string eval, which might be a security risk, you can use
545this option to enable or disable the deserialisation of code via
546CPAN::DeferedCode. (Note: This does not work under perl 5.6)
9ddc4ed0 547
547d3dfd 548Do you want to enable code deserialisation (yes/no)?
9ddc4ed0 549
547d3dfd 550=item yaml_module
9ddc4ed0 551
547d3dfd 552At the time of this writing there are two competing YAML modules,
553YAML.pm and YAML::Syck. The latter is faster but needs a C compiler
554installed on your system. There may be more alternative YAML
555conforming modules but at the time of writing a potential third
556player, YAML::Tiny, seemed not powerful enough to work with CPAN.pm.
9ddc4ed0 557
547d3dfd 558Which YAML implementation would you prefer?
9ddc4ed0 559
547d3dfd 560=back
9ddc4ed0 561
547d3dfd 562=head1 LICENSE
9ddc4ed0 563
547d3dfd 564This program is free software; you can redistribute it and/or
565modify it under the same terms as Perl itself.
9ddc4ed0 566
547d3dfd 567=cut
9ddc4ed0 568
547d3dfd 569use vars qw( %prompts );
9ddc4ed0 570
547d3dfd 571sub init {
572 my($configpm, %args) = @_;
573 use Config;
574 # extra args after 'o conf init'
575 my $matcher = $args{args} && @{$args{args}} ? $args{args}[0] : '';
576 if ($matcher =~ /^\/(.*)\/$/) {
577 # case /regex/ => take the first, ignore the rest
578 $matcher = $1;
579 shift @{$args{args}};
580 if (@{$args{args}}) {
581 local $" = " ";
582 $CPAN::Frontend->mywarn("Ignoring excessive arguments '@{$args{args}}'");
583 $CPAN::Frontend->mysleep(2);
584 }
585 } elsif (0 == length $matcher) {
586 } elsif (0 && $matcher eq "~") { # extremely buggy, but a nice idea
587 my @unconfigured = grep { not exists $CPAN::Config->{$_}
588 or not defined $CPAN::Config->{$_}
589 or not length $CPAN::Config->{$_}
590 } keys %$CPAN::Config;
591 $matcher = "\\b(".join("|", @unconfigured).")\\b";
592 $CPAN::Frontend->mywarn("matcher[$matcher]");
593 } else {
594 # case WORD... => all arguments must be valid
595 for my $arg (@{$args{args}}) {
596 unless (exists $CPAN::HandleConfig::keys{$arg}) {
597 $CPAN::Frontend->mywarn("'$arg' is not a valid configuration variable\n");
598 return;
599 }
600 }
601 $matcher = "\\b(".join("|",@{$args{args}}).")\\b";
602 }
603 CPAN->debug("matcher[$matcher]") if $CPAN::DEBUG;
9ddc4ed0 604
547d3dfd 605 unless ($CPAN::VERSION) {
606 require CPAN::Nox;
607 }
608 require CPAN::HandleConfig;
609 CPAN::HandleConfig::require_myconfig_or_config();
610 $CPAN::Config ||= {};
611 local($/) = "\n";
612 local($\) = "";
613 local($|) = 1;
614
615 my($ans,$default);
616
617 #
618 #= Files, directories
619 #
9ddc4ed0 620
547d3dfd 621 unless ($matcher) {
622 $CPAN::Frontend->myprint($prompts{manual_config});
623 }
624
625 my $manual_conf;
9ddc4ed0 626
547d3dfd 627 local *_real_prompt;
628 if ( $args{autoconfig} ) {
629 $manual_conf = "no";
630 } elsif ($matcher) {
631 $manual_conf = "yes";
632 } else {
633 my $_conf = prompt("Would you like me to configure as much as possible ".
634 "automatically?", "yes");
635 $manual_conf = ($_conf and $_conf =~ /^y/i) ? "no" : "yes";
636 }
637 CPAN->debug("manual_conf[$manual_conf]") if $CPAN::DEBUG;
638 my $fastread;
639 {
640 if ($manual_conf =~ /^y/i) {
641 $fastread = 0;
642 } else {
643 $fastread = 1;
644 $CPAN::Config->{urllist} ||= [];
645
646 local $^W = 0;
647 # prototype should match that of &MakeMaker::prompt
648 my $current_second = time;
649 my $current_second_count = 0;
650 my $i_am_mad = 0;
651 *_real_prompt = sub {
652 my($q,$a) = @_;
653 my($ret) = defined $a ? $a : "";
654 $CPAN::Frontend->myprint(sprintf qq{%s [%s]\n\n}, $q, $ret);
655 eval { require Time::HiRes };
656 unless ($@) {
657 if (time == $current_second) {
658 $current_second_count++;
659 if ($current_second_count > 20) {
660 # I don't like more than 20 prompts per second
661 $i_am_mad++;
662 }
663 } else {
664 $current_second = time;
665 $current_second_count = 0;
666 $i_am_mad-- if $i_am_mad>0;
667 }
668 if ($i_am_mad>0) {
669 #require Carp;
670 #Carp::cluck("SLEEEEEEEEPIIIIIIIIIIINGGGGGGGGGGG");
671 Time::HiRes::sleep(0.1);
672 }
673 }
674 $ret;
675 };
676 }
677 }
678
679 if (!$matcher or q{
680 build_dir
681 build_dir_reuse
682 cpan_home
683 keep_source_where
684 prefs_dir
685 } =~ /$matcher/) {
686 $CPAN::Frontend->myprint($prompts{config_intro});
687
688 if (!$matcher or 'cpan_home' =~ /$matcher/) {
689 my $cpan_home = $CPAN::Config->{cpan_home}
5254b38e 690 || File::Spec->catdir(CPAN::HandleConfig::home(), ".cpan");
547d3dfd 691
692 if (-d $cpan_home) {
693 $CPAN::Frontend->myprint(qq{
694
695I see you already have a directory
696 $cpan_home
697Shall we use it as the general CPAN build and cache directory?
698
699});
700 } else {
701 # no cpan-home, must prompt and get one
702 $CPAN::Frontend->myprint($prompts{cpan_home_where});
703 }
704
705 $default = $cpan_home;
706 my $loop = 0;
707 my $last_ans;
708 $CPAN::Frontend->myprint(" <cpan_home>\n");
709 PROMPT: while ($ans = prompt("CPAN build and cache directory?",$default)) {
710 print "\n";
711 if (File::Spec->file_name_is_absolute($ans)) {
712 my @cpan_home = split /[\/\\]/, $ans;
713 DIR: for my $dir (@cpan_home) {
714 if ($dir =~ /^~/ and (!$last_ans or $ans ne $last_ans)) {
715 $CPAN::Frontend
716 ->mywarn("Warning: a tilde in the path will be ".
717 "taken as a literal tilde. Please ".
718 "confirm again if you want to keep it\n");
719 $last_ans = $default = $ans;
720 next PROMPT;
721 }
722 }
723 } else {
724 require Cwd;
725 my $cwd = Cwd::cwd();
726 my $absans = File::Spec->catdir($cwd,$ans);
727 $CPAN::Frontend->mywarn("The path '$ans' is not an ".
728 "absolute path. Please specify ".
729 "an absolute path\n");
730 $default = $absans;
731 next PROMPT;
732 }
733 eval { File::Path::mkpath($ans); }; # dies if it can't
734 if ($@) {
735 $CPAN::Frontend->mywarn("Couldn't create directory $ans.\n".
736 "Please retry.\n");
737 next PROMPT;
738 }
739 if (-d $ans && -w _) {
740 last PROMPT;
741 } else {
742 $CPAN::Frontend->mywarn("Couldn't find directory $ans\n".
743 "or directory is not writable. Please retry.\n");
744 if (++$loop > 5) {
745 $CPAN::Frontend->mydie("Giving up");
746 }
747 }
748 }
749 $CPAN::Config->{cpan_home} = $ans;
750 }
751
752 if (!$matcher or 'keep_source_where' =~ /$matcher/) {
753 my_dflt_prompt("keep_source_where",
754 File::Spec->catdir($CPAN::Config->{cpan_home},"sources"),
755 $matcher,
756 );
757 }
758
759 if (!$matcher or 'build_dir' =~ /$matcher/) {
760 my_dflt_prompt("build_dir",
761 File::Spec->catdir($CPAN::Config->{cpan_home},"build"),
762 $matcher
763 );
764 }
765
766 if (!$matcher or 'build_dir_reuse' =~ /$matcher/) {
5254b38e 767 my_yn_prompt(build_dir_reuse => 0, $matcher);
547d3dfd 768 }
769
770 if (!$matcher or 'prefs_dir' =~ /$matcher/) {
771 my_dflt_prompt("prefs_dir",
772 File::Spec->catdir($CPAN::Config->{cpan_home},"prefs"),
773 $matcher
774 );
775 }
776 }
777
778 #
779 #= Config: auto_commit
780 #
781
782 my_yn_prompt(auto_commit => 0, $matcher);
783
784 #
785 #= Cache size, Index expire
786 #
787
788 if (!$matcher or 'build_cache' =~ /$matcher/) {
789 # large enough to build large dists like Tk
790 my_dflt_prompt(build_cache => 100, $matcher);
791 }
792
793 if (!$matcher or 'index_expire' =~ /$matcher/) {
794 my_dflt_prompt(index_expire => 1, $matcher);
795 }
796
797 if (!$matcher or 'scan_cache' =~ /$matcher/) {
798 my_prompt_loop(scan_cache => 'atstart', $matcher, 'atstart|never');
799 }
800
801 #
802 #= cache_metadata
803 #
804
805 my_yn_prompt(cache_metadata => 1, $matcher);
806 my_yn_prompt(use_sqlite => 0, $matcher);
807
808 #
809 #= Do we follow PREREQ_PM?
810 #
811
812 if (!$matcher or 'prerequisites_policy' =~ /$matcher/) {
813 my_prompt_loop(prerequisites_policy => 'ask', $matcher,
814 'follow|ask|ignore');
815 }
816
817 if (!$matcher or 'build_requires_install_policy' =~ /$matcher/) {
818 my_prompt_loop(build_requires_install_policy => 'ask/yes', $matcher,
819 'yes|no|ask/yes|ask/no');
820 }
821
822 #
823 #= Module::Signature
824 #
825 if (!$matcher or 'check_sigs' =~ /$matcher/) {
826 my_yn_prompt(check_sigs => 0, $matcher);
827 }
828
829 #
830 #= CPAN::Reporter
831 #
832 if (!$matcher or 'test_report' =~ /$matcher/) {
833 my_yn_prompt(test_report => 0, $matcher);
834 if (
835 $CPAN::Config->{test_report} &&
836 $CPAN::META->has_inst("CPAN::Reporter") &&
837 CPAN::Reporter->can('configure')
838 ) {
839 $CPAN::Frontend->myprint("\nProceeding to configure CPAN::Reporter.\n");
840 CPAN::Reporter::configure();
841 $CPAN::Frontend->myprint("\nReturning to CPAN configuration.\n");
842 }
843 }
844
5254b38e 845 if (!$matcher or 'trust_test_report_history' =~ /$matcher/) {
846 my_yn_prompt(trust_test_report_history => 0, $matcher);
847 }
848
547d3dfd 849 #
850 #= YAML vs. YAML::Syck
851 #
852 if (!$matcher or "yaml_module" =~ /$matcher/) {
853 my_dflt_prompt(yaml_module => "YAML", $matcher);
854 unless ($CPAN::META->has_inst($CPAN::Config->{yaml_module})) {
855 $CPAN::Frontend->mywarn
856 ("Warning (maybe harmless): '$CPAN::Config->{yaml_module}' not installed.\n");
857 $CPAN::Frontend->mysleep(3);
858 }
859 }
860
861 #
862 #= YAML code deserialisation
863 #
864 if (!$matcher or "yaml_load_code" =~ /$matcher/) {
865 my_yn_prompt(yaml_load_code => 0, $matcher);
866 }
867
868 #
869 #= External programs
870 #
871
872 my @external_progs = qw/bzip2 gzip tar unzip
873
874 make
875
876 curl lynx wget ncftpget ncftp ftp
877
878 gpg
879
880 patch applypatch
881 /;
882 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
883 if (!$matcher or "@external_progs" =~ /$matcher/) {
884 $CPAN::Frontend->myprint($prompts{external_progs});
885
886 my $old_warn = $^W;
887 local $^W if $^O eq 'MacOS';
888 local $^W = $old_warn;
889 my $progname;
890 for $progname (@external_progs) {
891 next if $matcher && $progname !~ /$matcher/;
892 if ($^O eq 'MacOS') {
893 $CPAN::Config->{$progname} = 'not_here';
894 next;
895 }
896
897 my $progcall = $progname;
898 unless ($matcher) {
899 # we really don't need ncftp if we have ncftpget, but
900 # if they chose this dialog via matcher, they shall have it
901 next if $progname eq "ncftp" && $CPAN::Config->{ncftpget} gt " ";
902 }
903 my $path = $CPAN::Config->{$progname}
904 || $Config::Config{$progname}
905 || "";
906 if (File::Spec->file_name_is_absolute($path)) {
907 # testing existence is not good enough, some have these exe
908 # extensions
909
910 # warn "Warning: configured $path does not exist\n" unless -e $path;
911 # $path = "";
912 } elsif ($path =~ /^\s+$/) {
913 # preserve disabled programs
914 } else {
915 $path = '';
916 }
917 unless ($path) {
918 # e.g. make -> nmake
919 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
920 }
921
922 $path ||= find_exe($progcall,\@path);
923 unless ($path) { # not -e $path, because find_exe already checked that
924 local $"=";";
925 $CPAN::Frontend->mywarn("Warning: $progcall not found in PATH[@path]\n");
926 if ($progname eq "make") {
927 $CPAN::Frontend->mywarn("ALERT: 'make' is an essential tool for ".
928 "building perl Modules. Please make sure you ".
929 "have 'make' (or some equivalent) ".
930 "working.\n"
931 );
932 if ($^O eq "MSWin32") {
933 $CPAN::Frontend->mywarn("
934Windows users may want to follow this procedure when back in the CPAN shell:
935
936 look YVES/scripts/alien_nmake.pl
937 perl alien_nmake.pl
938
939This will install nmake on your system which can be used as a 'make'
940substitute. You can then revisit this dialog with
941
942 o conf init make
943
944");
945 }
946 }
947 }
948 $prompts{$progname} = "Where is your $progname program?";
949 my_dflt_prompt($progname,$path,$matcher);
950 }
951 }
952
953 if (!$matcher or 'pager' =~ /$matcher/) {
954 my $path = $CPAN::Config->{'pager'} ||
955 $ENV{PAGER} || find_exe("less",\@path) ||
956 find_exe("more",\@path) || ($^O eq 'MacOS' ? $ENV{EDITOR} : 0 )
957 || "more";
958 my_dflt_prompt(pager => $path, $matcher);
959 }
960
961 if (!$matcher or 'shell' =~ /$matcher/) {
962 my $path = $CPAN::Config->{'shell'};
963 if ($path && File::Spec->file_name_is_absolute($path)) {
964 $CPAN::Frontend->mywarn("Warning: configured $path does not exist\n")
965 unless -e $path;
966 $path = "";
967 }
968 $path ||= $ENV{SHELL};
969 $path ||= $ENV{COMSPEC} if $^O eq "MSWin32";
970 if ($^O eq 'MacOS') {
971 $CPAN::Config->{'shell'} = 'not_here';
972 } else {
973 $path =~ s,\\,/,g if $^O eq 'os2'; # Cosmetic only
974 my_dflt_prompt(shell => $path, $matcher);
975 }
976 }
977
978 #
979 # verbosity
980 #
981
982 if (!$matcher or 'tar_verbosity' =~ /$matcher/) {
983 my_prompt_loop(tar_verbosity => 'v', $matcher,
984 'none|v|vv');
985 }
986
987 if (!$matcher or 'load_module_verbosity' =~ /$matcher/) {
988 my_prompt_loop(load_module_verbosity => 'v', $matcher,
989 'none|v');
990 }
991
5254b38e 992 if (!$matcher or 'perl5lib_verbosity' =~ /$matcher/) {
993 my_prompt_loop(perl5lib_verbosity => 'v', $matcher,
994 'none|v');
995 }
996
547d3dfd 997 my_yn_prompt(inhibit_startup_message => 0, $matcher);
998
999 #
1000 #= Installer, arguments to make etc.
1001 #
1002
1003 if (!$matcher or 'prefer_installer' =~ /$matcher/) {
1004 my_prompt_loop(prefer_installer => 'MB', $matcher, 'MB|EUMM|RAND');
1005 }
1006
1007 if (!$matcher or 'makepl_arg make_arg' =~ /$matcher/) {
1008 my_dflt_prompt(makepl_arg => "", $matcher);
1009 my_dflt_prompt(make_arg => "", $matcher);
5254b38e 1010 if ( $CPAN::Config->{makepl_arg} =~ /LIBS=|INC=/ ) {
1011 $CPAN::Frontend->mywarn(
1012 "Warning: Using LIBS or INC in makepl_arg will likely break distributions\n" .
1013 "that specify their own LIBS or INC options in Makefile.PL.\n"
1014 );
1015 }
1016
547d3dfd 1017 }
1018
1019 require CPAN::HandleConfig;
1020 if (exists $CPAN::HandleConfig::keys{make_install_make_command}) {
1021 # as long as Windows needs $self->_build_command, we cannot
1022 # support sudo on windows :-)
1023 my_dflt_prompt(make_install_make_command => $CPAN::Config->{make} || "",
1024 $matcher);
1025 }
1026
1027 my_dflt_prompt(make_install_arg => $CPAN::Config->{make_arg} || "",
1028 $matcher);
1029
1030 my_dflt_prompt(mbuildpl_arg => "", $matcher);
1031 my_dflt_prompt(mbuild_arg => "", $matcher);
1032
5254b38e 1033 if (exists $CPAN::HandleConfig::keys{mbuild_install_build_command}
1034 and $^O ne "MSWin32") {
547d3dfd 1035 # as long as Windows needs $self->_build_command, we cannot
1036 # support sudo on windows :-)
1037 my_dflt_prompt(mbuild_install_build_command => "./Build", $matcher);
1038 }
1039
1040 my_dflt_prompt(mbuild_install_arg => "", $matcher);
1041
1042 #
1043 #= Alarm period
1044 #
1045
1046 my_dflt_prompt(inactivity_timeout => 0, $matcher);
1047
1048 #
5254b38e 1049 #== halt_on_failure
1050 #
1051 if (!$matcher or 'halt_on_failure' =~ /$matcher/) {
1052 my_yn_prompt(halt_on_failure => 0, $matcher);
1053 }
1054
1055 #
547d3dfd 1056 #= Proxies
1057 #
1058
1059 my @proxy_vars = qw/ftp_proxy http_proxy no_proxy/;
1060 my @proxy_user_vars = qw/proxy_user proxy_pass/;
1061 if (!$matcher or "@proxy_vars @proxy_user_vars" =~ /$matcher/) {
1062 $CPAN::Frontend->myprint($prompts{proxy_intro});
1063
1064 for (@proxy_vars) {
1065 $prompts{$_} = "Your $_?";
1066 my_dflt_prompt($_ => $ENV{$_}||"", $matcher);
1067 }
1068
1069 if ($CPAN::Config->{ftp_proxy} ||
1070 $CPAN::Config->{http_proxy}) {
1071
1072 $default = $CPAN::Config->{proxy_user} || $CPAN::LWP::UserAgent::USER || "";
1073
1074 $CPAN::Frontend->myprint($prompts{proxy_user});
1075
1076 if ($CPAN::Config->{proxy_user} = prompt("Your proxy user id?",$default)) {
1077 $CPAN::Frontend->myprint($prompts{proxy_pass});
1078
1079 if ($CPAN::META->has_inst("Term::ReadKey")) {
1080 Term::ReadKey::ReadMode("noecho");
1081 } else {
1082 $CPAN::Frontend->myprint($prompts{password_warn});
1083 }
1084 $CPAN::Config->{proxy_pass} = prompt_no_strip("Your proxy password?");
1085 if ($CPAN::META->has_inst("Term::ReadKey")) {
1086 Term::ReadKey::ReadMode("restore");
1087 }
1088 $CPAN::Frontend->myprint("\n\n");
1089 }
1090 }
1091 }
1092
1093 #
1094 #= how FTP works
1095 #
1096
1097 my_yn_prompt(ftp_passive => 1, $matcher);
1098
1099 #
1100 #= how cwd works
1101 #
1102
1103 if (!$matcher or 'getcwd' =~ /$matcher/) {
1104 my_prompt_loop(getcwd => 'cwd', $matcher,
1105 'cwd|getcwd|fastcwd|backtickcwd');
1106 }
1107
1108 #
1109 #= the CPAN shell itself (prompt, color)
1110 #
1111
1112 my_yn_prompt(commandnumber_in_prompt => 1, $matcher);
1113 my_yn_prompt(term_ornaments => 1, $matcher);
1114 if ("colorize_output colorize_print colorize_warn colorize_debug" =~ $matcher) {
1115 my_yn_prompt(colorize_output => 0, $matcher);
1116 if ($CPAN::Config->{colorize_output}) {
1117 if ($CPAN::META->has_inst("Term::ANSIColor")) {
1118 my $T="gYw";
1119 print " on_ on_y ".
1120 " on_ma on_\n";
1121 print " on_black on_red green ellow ".
1122 "on_blue genta on_cyan white\n";
1123
1124 for my $FG ("", "bold",
1125 map {$_,"bold $_"} "black","red","green",
1126 "yellow","blue",
1127 "magenta",
1128 "cyan","white") {
1129 printf "%12s ", $FG;
1130 for my $BG ("",map {"on_$_"} qw(black red green yellow
1131 blue magenta cyan white)) {
1132 print $FG||$BG ?
1133 Term::ANSIColor::colored(" $T ","$FG $BG") : " $T ";
1134 }
1135 print "\n";
1136 }
1137 print "\n";
1138 }
1139 for my $tuple (
1140 ["colorize_print", "bold blue on_white"],
1141 ["colorize_warn", "bold red on_white"],
1142 ["colorize_debug", "black on_cyan"],
1143 ) {
1144 my_dflt_prompt($tuple->[0] => $tuple->[1], $matcher);
1145 if ($CPAN::META->has_inst("Term::ANSIColor")) {
1146 eval { Term::ANSIColor::color($CPAN::Config->{$tuple->[0]})};
1147 if ($@) {
1148 $CPAN::Config->{$tuple->[0]} = $tuple->[1];
1149 $CPAN::Frontend->mywarn($@."setting to default '$tuple->[1]'\n");
1150 }
1151 }
1152 }
1153 }
1154 }
1155
1156 #
1157 #== term_is_latin
1158 #
1159
1160 if (!$matcher or 'term_is_latin' =~ /$matcher/) {
1161 my_yn_prompt(term_is_latin => 1, $matcher);
1162 }
1163
1164 #
1165 #== save history in file 'histfile'
1166 #
1167
1168 if (!$matcher or 'histfile histsize' =~ /$matcher/) {
1169 $CPAN::Frontend->myprint($prompts{histfile_intro});
1170 defined($default = $CPAN::Config->{histfile}) or
1171 $default = File::Spec->catfile($CPAN::Config->{cpan_home},"histfile");
1172 my_dflt_prompt(histfile => $default, $matcher);
1173
1174 if ($CPAN::Config->{histfile}) {
1175 defined($default = $CPAN::Config->{histsize}) or $default = 100;
1176 my_dflt_prompt(histsize => $default, $matcher);
1177 }
1178 }
1179
1180 #
1181 #== do an ls on the m or the d command
1182 #
1183 my_yn_prompt(show_upload_date => 0, $matcher);
1184
1185 #
1186 #== verbosity at the end of the r command
1187 #
1188 if (!$matcher
1189 or 'show_unparsable_versions' =~ /$matcher/
1190 or 'show_zero_versions' =~ /$matcher/
1191 ) {
1192 $CPAN::Frontend->myprint($prompts{show_unparsable_or_zero_versions_intro});
1193 my_yn_prompt(show_unparsable_versions => 0, $matcher);
1194 my_yn_prompt(show_zero_versions => 0, $matcher);
1195 }
1196
1197 #
1198 #= MIRRORED.BY and conf_sites()
1199 #
1200
a7f1e69b 1201 # remember, this is only triggered if no urllist is given, so 0 is
1202 # fair and protects the default site from being overloaded and
1203 # gives the user more chances to select his own urllist.
1204 my_yn_prompt("connect_to_internet_ok" => 0, $matcher);
547d3dfd 1205 if ($matcher) {
1206 if ("urllist" =~ $matcher) {
1207 # conf_sites would go into endless loop with the smash prompt
1208 local *_real_prompt;
1209 *_real_prompt = \&CPAN::Shell::colorable_makemaker_prompt;
1210 conf_sites();
1211 }
1212 if ("randomize_urllist" =~ $matcher) {
1213 my_dflt_prompt(randomize_urllist => 0, $matcher);
1214 }
5254b38e 1215 if ("ftpstats_size" =~ $matcher) {
1216 my_dflt_prompt(ftpstats_size => 99, $matcher);
1217 }
1218 if ("ftpstats_period" =~ $matcher) {
1219 my_dflt_prompt(ftpstats_period => 14, $matcher);
1220 }
547d3dfd 1221 } elsif ($fastread) {
1222 $CPAN::Frontend->myprint("Autoconfigured everything but 'urllist'.\n".
1223 "Please call 'o conf init urllist' to configure ".
5254b38e 1224 "your CPAN server(s) now!\n\n");
547d3dfd 1225 } else {
1226 conf_sites();
1227 }
1228
1229 $CPAN::Frontend->myprint("\n\n");
1230 if ($matcher && !$CPAN::Config->{auto_commit}) {
1231 $CPAN::Frontend->myprint("Please remember to call 'o conf commit' to ".
1232 "make the config permanent!\n\n");
1233 } else {
1234 CPAN::HandleConfig->commit($configpm);
1235 }
1236}
1237
1238sub my_dflt_prompt {
1239 my ($item, $dflt, $m) = @_;
1240 my $default = $CPAN::Config->{$item} || $dflt;
1241
547d3dfd 1242 if (!$m || $item =~ /$m/) {
1243 if (my $intro = $prompts{$item . "_intro"}) {
1244 $CPAN::Frontend->myprint($intro);
1245 }
1246 $CPAN::Frontend->myprint(" <$item>\n");
1247 $CPAN::Config->{$item} = prompt($prompts{$item}, $default);
1248 print "\n";
1249 } else {
1250 $CPAN::Config->{$item} = $default;
1251 }
1252}
1253
1254sub my_yn_prompt {
1255 my ($item, $dflt, $m) = @_;
1256 my $default;
1257 defined($default = $CPAN::Config->{$item}) or $default = $dflt;
1258
1259 # $DB::single = 1;
1260 if (!$m || $item =~ /$m/) {
1261 if (my $intro = $prompts{$item . "_intro"}) {
1262 $CPAN::Frontend->myprint($intro);
1263 }
1264 $CPAN::Frontend->myprint(" <$item>\n");
1265 my $ans = prompt($prompts{$item}, $default ? 'yes' : 'no');
1266 $CPAN::Config->{$item} = ($ans =~ /^[y1]/i ? 1 : 0);
1267 print "\n";
1268 } else {
1269 $CPAN::Config->{$item} = $default;
1270 }
1271}
1272
1273sub my_prompt_loop {
1274 my ($item, $dflt, $m, $ok) = @_;
1275 my $default = $CPAN::Config->{$item} || $dflt;
1276 my $ans;
1277
547d3dfd 1278 if (!$m || $item =~ /$m/) {
1279 $CPAN::Frontend->myprint($prompts{$item . "_intro"});
1280 $CPAN::Frontend->myprint(" <$item>\n");
1281 do { $ans = prompt($prompts{$item}, $default);
1282 } until $ans =~ /$ok/;
1283 $CPAN::Config->{$item} = $ans;
1284 print "\n";
1285 } else {
1286 $CPAN::Config->{$item} = $default;
1287 }
1288}
1289
1290
1291sub conf_sites {
1292 my $m = 'MIRRORED.BY';
1293 my $mby = File::Spec->catfile($CPAN::Config->{keep_source_where},$m);
1294 File::Path::mkpath(File::Basename::dirname($mby));
1295 if (-f $mby && -f $m && -M $m < -M $mby) {
1296 require File::Copy;
1297 File::Copy::copy($m,$mby) or die "Could not update $mby: $!";
1298 }
1299 my $loopcount = 0;
1300 local $^T = time;
1301 my $overwrite_local = 0;
1302 if ($mby && -f $mby && -M _ <= 60 && -s _ > 0) {
1303 my $mtime = localtime((stat _)[9]);
1304 my $prompt = qq{Found $mby as of $mtime
1305
1306I\'d use that as a database of CPAN sites. If that is OK for you,
1307please answer 'y', but if you want me to get a new database now,
1308please answer 'n' to the following question.
1309
1310Shall I use the local database in $mby?};
1311 my $ans = prompt($prompt,"y");
1312 $overwrite_local = 1 unless $ans =~ /^y/i;
1313 }
1314 while ($mby) {
1315 if ($overwrite_local) {
1316 $CPAN::Frontend->myprint(qq{Trying to overwrite $mby\n});
1317 $mby = CPAN::FTP->localize($m,$mby,3);
1318 $overwrite_local = 0;
1319 } elsif ( ! -f $mby ) {
1320 $CPAN::Frontend->myprint(qq{You have no $mby\n I\'m trying to fetch one\n});
1321 $mby = CPAN::FTP->localize($m,$mby,3);
1322 } elsif (-M $mby > 60 && $loopcount == 0) {
1323 $CPAN::Frontend->myprint(qq{Your $mby is older than 60 days,\n I\'m trying }.
1324 qq{to fetch one\n});
1325 $mby = CPAN::FTP->localize($m,$mby,3);
1326 $loopcount++;
1327 } elsif (-s $mby == 0) {
1328 $CPAN::Frontend->myprint(qq{You have an empty $mby,\n I\'m trying to fetch one\n});
1329 $mby = CPAN::FTP->localize($m,$mby,3);
1330 } else {
1331 last;
1332 }
1333 }
1334 local $urllist = [];
1335 read_mirrored_by($mby);
1336 bring_your_own();
1337 $CPAN::Config->{urllist} = $urllist;
1338}
1339
1340sub find_exe {
1341 my($exe,$path) = @_;
1342 my($dir);
1343 #warn "in find_exe exe[$exe] path[@$path]";
1344 for $dir (@$path) {
1345 my $abs = File::Spec->catfile($dir,$exe);
1346 if (($abs = MM->maybe_command($abs))) {
1347 return $abs;
1348 }
1349 }
1350}
1351
1352sub picklist {
1353 my($items,$prompt,$default,$require_nonempty,$empty_warning)=@_;
1354 CPAN->debug("picklist('$items','$prompt','$default','$require_nonempty',".
1355 "'$empty_warning')") if $CPAN::DEBUG;
1356 $default ||= '';
1357
1358 my $pos = 0;
1359
1360 my @nums;
1361 SELECTION: while (1) {
1362
1363 # display, at most, 15 items at a time
1364 my $limit = $#{ $items } - $pos;
1365 $limit = 15 if $limit > 15;
1366
1367 # show the next $limit items, get the new position
1368 $pos = display_some($items, $limit, $pos, $default);
1369 $pos = 0 if $pos >= @$items;
1370
1371 my $num = prompt($prompt,$default);
1372
1373 @nums = split (' ', $num);
1374 {
1375 my %seen;
1376 @nums = grep { !$seen{$_}++ } @nums;
1377 }
1378 my $i = scalar @$items;
1379 unrangify(\@nums);
1380 if (grep (/\D/ || $_ < 1 || $_ > $i, @nums)) {
1381 $CPAN::Frontend->mywarn("invalid items entered, try again\n");
1382 if ("@nums" =~ /\D/) {
1383 $CPAN::Frontend->mywarn("(we are expecting only numbers between 1 and $i)\n");
1384 }
1385 next SELECTION;
1386 }
1387 if ($require_nonempty && !@nums) {
1388 $CPAN::Frontend->mywarn("$empty_warning\n");
1389 }
1390 $CPAN::Frontend->myprint("\n");
1391
1392 # a blank line continues...
1393 next SELECTION unless @nums;
1394 last;
1395 }
1396 for (@nums) { $_-- }
1397 @{$items}[@nums];
1398}
1399
1400sub unrangify ($) {
1401 my($nums) = $_[0];
1402 my @nums2 = ();
1403 while (@{$nums||[]}) {
1404 my $n = shift @$nums;
1405 if ($n =~ /^(\d+)-(\d+)$/) {
1406 my @range = $1 .. $2;
1407 # warn "range[@range]";
1408 push @nums2, @range;
1409 } else {
1410 push @nums2, $n;
1411 }
1412 }
1413 push @$nums, @nums2;
1414}
1415
1416sub display_some {
1417 my ($items, $limit, $pos, $default) = @_;
1418 $pos ||= 0;
1419
1420 my @displayable = @$items[$pos .. ($pos + $limit)];
1421 for my $item (@displayable) {
1422 $CPAN::Frontend->myprint(sprintf "(%d) %s\n", ++$pos, $item);
1423 }
1424 my $hit_what = $default ? "SPACE RETURN" : "RETURN";
1425 $CPAN::Frontend->myprint(sprintf("%d more items, hit %s to show them\n",
1426 (@$items - $pos),
1427 $hit_what,
1428 ))
1429 if $pos < @$items;
1430 return $pos;
1431}
1432
1433sub read_mirrored_by {
1434 my $local = shift or return;
1435 my(%all,$url,$expected_size,$default,$ans,$host,
1436 $dst,$country,$continent,@location);
1437 my $fh = FileHandle->new;
1438 $fh->open($local) or die "Couldn't open $local: $!";
1439 local $/ = "\012";
1440 while (<$fh>) {
1441 ($host) = /^([\w\.\-]+)/ unless defined $host;
1442 next unless defined $host;
1443 next unless /\s+dst_(dst|location)/;
1444 /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
1445 ($continent, $country) = @location[-1,-2];
1446 $continent =~ s/\s\(.*//;
1447 $continent =~ s/\W+$//; # if Jarkko doesn't know latitude/longitude
1448 /dst_dst\s+=\s+\"([^\"]+)/ and $dst = $1;
1449 next unless $host && $dst && $continent && $country;
1450 $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
1451 undef $host;
1452 $dst=$continent=$country="";
1453 }
1454 $fh->close;
1455 $CPAN::Config->{urllist} ||= [];
1456 my @previous_urls = @{$CPAN::Config->{urllist}};
9ddc4ed0 1457
547d3dfd 1458 $CPAN::Frontend->myprint($prompts{urls_intro});
9ddc4ed0 1459
547d3dfd 1460 my (@cont, $cont, %cont, @countries, @urls, %seen);
1461 my $no_previous_warn =
1462 "Sorry! since you don't have any existing picks, you must make a\n" .
1463 "geographic selection.";
1464 my $offer_cont = [sort keys %all];
1465 if (@previous_urls) {
1466 push @$offer_cont, "(edit previous picks)";
1467 $default = @$offer_cont;
1468 }
1469 @cont = picklist($offer_cont,
1470 "Select your continent (or several nearby continents)",
1471 $default,
1472 ! @previous_urls,
1473 $no_previous_warn);
9ddc4ed0 1474
9ddc4ed0 1475
547d3dfd 1476 foreach $cont (@cont) {
1477 my @c = sort keys %{$all{$cont}};
1478 @cont{@c} = map ($cont, 0..$#c);
1479 @c = map ("$_ ($cont)", @c) if @cont > 1;
1480 push (@countries, @c);
1481 }
1482 if (@previous_urls && @countries) {
1483 push @countries, "(edit previous picks)";
1484 $default = @countries;
1485 }
9ddc4ed0 1486
547d3dfd 1487 if (@countries) {
1488 @countries = picklist (\@countries,
1489 "Select your country (or several nearby countries)",
1490 $default,
1491 ! @previous_urls,
1492 $no_previous_warn);
1493 %seen = map (($_ => 1), @previous_urls);
1494 # hmmm, should take list of defaults from CPAN::Config->{'urllist'}...
1495 foreach $country (@countries) {
1496 next if $country =~ /edit previous picks/;
1497 (my $bare_country = $country) =~ s/ \(.*\)//;
1498 my @u = sort keys %{$all{$cont{$bare_country}}{$bare_country}};
1499 @u = grep (! $seen{$_}, @u);
1500 @u = map ("$_ ($bare_country)", @u)
1501 if @countries > 1;
1502 push (@urls, @u);
1503 }
1504 }
1505 push (@urls, map ("$_ (previous pick)", @previous_urls));
1506 my $prompt = "Select as many URLs as you like (by number),
1507put them on one line, separated by blanks, hyphenated ranges allowed
1508 e.g. '1 4 5' or '7 1-4 8'";
1509 if (@previous_urls) {
1510 $default = join (' ', ((scalar @urls) - (scalar @previous_urls) + 1) ..
1511 (scalar @urls));
1512 $prompt .= "\n(or just hit RETURN to keep your previous picks)";
1513 }
9ddc4ed0 1514
547d3dfd 1515 @urls = picklist (\@urls, $prompt, $default);
1516 foreach (@urls) { s/ \(.*\)//; }
1517 push @$urllist, @urls;
1518}
9ddc4ed0 1519
547d3dfd 1520sub bring_your_own {
1521 my %seen = map (($_ => 1), @$urllist);
1522 my($ans,@urls);
1523 my $eacnt = 0; # empty answers
1524 do {
1525 my $prompt = "Enter another URL or RETURN to quit:";
1526 unless (%seen) {
1527 $prompt = qq{CPAN.pm needs at least one URL where it can fetch CPAN files from.
9ddc4ed0 1528
547d3dfd 1529Please enter your CPAN site:};
1530 }
1531 $ans = prompt ($prompt, "");
9ddc4ed0 1532
547d3dfd 1533 if ($ans) {
1534 $ans =~ s|/?\z|/|; # has to end with one slash
1535 $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
1536 if ($ans =~ /^\w+:\/./) {
1537 push @urls, $ans unless $seen{$ans}++;
1538 } else {
1539 $CPAN::Frontend->
1540 myprint(sprintf(qq{"%s" doesn\'t look like an URL at first sight.
1541I\'ll ignore it for now.
1542You can add it to your %s
1543later if you\'re sure it\'s right.\n},
1544 $ans,
1545 $INC{'CPAN/MyConfig.pm'}
1546 || $INC{'CPAN/Config.pm'}
1547 || "configuration file",
1548 ));
1549 }
1550 } else {
1551 if (++$eacnt >= 5) {
1552 $CPAN::Frontend->
1553 mywarn("Giving up.\n");
1554 $CPAN::Frontend->mysleep(5);
1555 return;
1556 }
1557 }
1558 } while $ans || !%seen;
9ddc4ed0 1559
547d3dfd 1560 push @$urllist, @urls;
1561 # xxx delete or comment these out when you're happy that it works
1562 $CPAN::Frontend->myprint("New set of picks:\n");
1563 map { $CPAN::Frontend->myprint(" $_\n") } @$urllist;
1564}
9ddc4ed0 1565
9ddc4ed0 1566
547d3dfd 1567sub _strip_spaces {
1568 $_[0] =~ s/^\s+//; # no leading spaces
1569 $_[0] =~ s/\s+\z//; # no trailing spaces
1570}
9ddc4ed0 1571
547d3dfd 1572sub prompt ($;$) {
1573 unless (defined &_real_prompt) {
1574 *_real_prompt = \&CPAN::Shell::colorable_makemaker_prompt;
1575 }
1576 my $ans = _real_prompt(@_);
9ddc4ed0 1577
547d3dfd 1578 _strip_spaces($ans);
9ddc4ed0 1579
547d3dfd 1580 return $ans;
1581}
9ddc4ed0 1582
9ddc4ed0 1583
547d3dfd 1584sub prompt_no_strip ($;$) {
1585 return _real_prompt(@_);
1586}
9ddc4ed0 1587
9ddc4ed0 1588
547d3dfd 1589BEGIN {
9ddc4ed0 1590
547d3dfd 1591my @prompts = (
9ddc4ed0 1592
547d3dfd 1593manual_config => qq[
9ddc4ed0 1594
547d3dfd 1595CPAN is the world-wide archive of perl resources. It consists of about
1596300 sites that all replicate the same contents around the globe. Many
1597countries have at least one CPAN site already. The resources found on
1598CPAN are easily accessible with the CPAN.pm module. If you want to use
1599CPAN.pm, lots of things have to be configured. Fortunately, most of
1600them can be determined automatically. If you prefer the automatic
1601configuration, answer 'yes' below.
9ddc4ed0 1602
547d3dfd 1603If you prefer to enter a dialog instead, you can answer 'no' to this
1604question and I'll let you configure in small steps one thing after the
1605other. (Note: you can revisit this dialog anytime later by typing 'o
1606conf init' at the cpan prompt.)
1607],
9ddc4ed0 1608
547d3dfd 1609config_intro => qq{
9ddc4ed0 1610
547d3dfd 1611The following questions are intended to help you with the
1612configuration. The CPAN module needs a directory of its own to cache
1613important index files and maybe keep a temporary mirror of CPAN files.
5254b38e 1614This may be a site-wide or a personal directory.
1615
1616},
9ddc4ed0 1617
547d3dfd 1618# cpan_home => qq{ },
9ddc4ed0 1619
547d3dfd 1620cpan_home_where => qq{
9ddc4ed0 1621
547d3dfd 1622First of all, I'd like to create this directory. Where?
9ddc4ed0 1623
547d3dfd 1624},
9ddc4ed0 1625
547d3dfd 1626external_progs => qq{
9ddc4ed0 1627
547d3dfd 1628The CPAN module will need a few external programs to work properly.
1629Please correct me, if I guess the wrong path for a program. Don't
1630panic if you do not have some of them, just press ENTER for those. To
1631disable the use of a program, you can type a space followed by ENTER.
9ddc4ed0 1632
1633},
1634
c9869e1c 1635proxy_intro => qq{
9ddc4ed0 1636
547d3dfd 1637If you're accessing the net via proxies, you can specify them in the
9ddc4ed0 1638CPAN configuration or via environment variables. The variable in
1639the \$CPAN::Config takes precedence.
1640
1641},
1642
1643proxy_user => qq{
1644
1645If your proxy is an authenticating proxy, you can store your username
1646permanently. If you do not want that, just press RETURN. You will then
1647be asked for your username in every future session.
1648
1649},
1650
1651proxy_pass => qq{
1652
1653Your password for the authenticating proxy can also be stored
1654permanently on disk. If this violates your security policy, just press
1655RETURN. You will then be asked for the password in every future
1656session.
1657
1658},
1659
1660urls_intro => qq{
1661
1662Now we need to know where your favorite CPAN sites are located. Push
1663a few sites onto the array (just in case the first on the array won\'t
1664work). If you are mirroring CPAN to your local workstation, specify a
1665file: URL.
1666
8962fc49 1667First, pick a nearby continent and country by typing in the number(s)
1668in front of the item(s) you want to select. You can pick several of
1669each, separated by spaces. Then, you will be presented with a list of
1670URLs of CPAN mirrors in the countries you selected, along with
1671previously selected URLs. Select some of those URLs, or just keep the
1672old list. Finally, you will be prompted for any extra URLs -- file:,
1673ftp:, or http: -- that host a CPAN mirror.
9ddc4ed0 1674
1675},
1676
1677password_warn => qq{
1678
1679Warning: Term::ReadKey seems not to be available, your password will
1680be echoed to the terminal!
1681
1682},
1683
b72dd56f 1684 );
9ddc4ed0 1685
1686die "Coding error in \@prompts declaration. Odd number of elements, above"
547d3dfd 1687 if (@prompts % 2);
9ddc4ed0 1688
1689%prompts = @prompts;
1690
1691if (scalar(keys %prompts) != scalar(@prompts)/2) {
9ddc4ed0 1692 my %already;
9ddc4ed0 1693 for my $item (0..$#prompts) {
547d3dfd 1694 next if $item % 2;
1695 die "$prompts[$item] is duplicated\n" if $already{$prompts[$item]}++;
1696 }
1697}
1698
1699local *FH;
1700my $pmfile = __FILE__;
1701open FH, $pmfile or die "Could not open '$pmfile': $!";
1702local $/ = "";
1703my @podpara;
1704while (<FH>) {
1705 next if 1 .. /^=over/;
1706 chomp;
1707 push @podpara, $_;
1708 last if /^=back/;
1709}
1710pop @podpara;
1711while (@podpara) {
1712 warn "Alert: cannot parse my own manpage for init dialog" unless $podpara[0] =~ s/^=item\s+//;
1713 my $name = shift @podpara;
1714 my @para;
1715 while (@podpara && $podpara[0] !~ /^=item/) {
1716 push @para, shift @podpara;
1717 }
1718 $prompts{$name} = pop @para;
1719 if (@para) {
1720 $prompts{$name . "_intro"} = join "", map { "$_\n\n" } @para;
9ddc4ed0 1721 }
9ddc4ed0 1722}
1723
8962fc49 1724} # EOBEGIN
9ddc4ed0 1725
5f05dabc 17261;