This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
use $ENV{MAKEMAKEROPT} to set default command line args
[perl5.git] / lib / CPAN / FirstTime.pm
CommitLineData
5f05dabc
PP
1package CPAN::Mirrored::By;
2
3sub new {
4 my($self,@arg) = @_;
5 bless [@arg], $self;
6}
da199366
AK
7sub continent { shift->[0] }
8sub country { shift->[1] }
5f05dabc
PP
9sub url { shift->[2] }
10
11package CPAN::FirstTime;
12
13use strict;
14use ExtUtils::MakeMaker qw(prompt);
05454584 15use FileHandle ();
09d9d230 16use File::Basename ();
05454584 17use File::Path ();
5f05dabc 18use vars qw($VERSION);
09d9d230 19$VERSION = substr q$Revision: 1.29 $, 10;
5f05dabc
PP
20
21=head1 NAME
22
23CPAN::FirstTime - Utility for CPAN::Config file Initialization
24
25=head1 SYNOPSIS
26
27CPAN::FirstTime::init()
28
29=head1 DESCRIPTION
30
31The init routine asks a few questions and writes a CPAN::Config
32file. Nothing special.
33
34=cut
35
36
37sub init {
38 my($configpm) = @_;
39 use Config;
40 require CPAN::Nox;
41 eval {require CPAN::Config;};
42 $CPAN::Config ||= {};
da199366
AK
43 local($/) = "\n";
44 local($\) = "";
13bc20ff 45 local($|) = 1;
da199366 46
5f05dabc
PP
47 my($ans,$default,$local,$cont,$url,$expected_size);
48
da199366
AK
49 #
50 # Files, directories
51 #
52
5f05dabc 53 print qq{
09d9d230
A
54
55CPAN is the world-wide archive of perl resources. It consists of about
56100 sites that all replicate the same contents all around the globe.
57Many countries have at least one CPAN site already. The resources
58found on CPAN are easily accessible with the CPAN.pm module. If you
59want to use CPAN.pm, you have to configure it properly.
60
61If you do not want to enter a dialog now, you can answer 'no' to this
62question and I\'ll try to autoconfigure. (Note: you can revisit this
63dialog anytime later by typing 'o conf init' at the cpan prompt.)
64
65};
66
67 my $manual_conf =
68 ExtUtils::MakeMaker::prompt("Are you ready for manual configuration?",
69 "yes");
70 my $fastread;
71 {
72 local $^W;
73 if ($manual_conf =~ /^\s*y/i) {
74 $fastread = 0;
75 *prompt = \&ExtUtils::MakeMaker::prompt;
76 } else {
77 $fastread = 1;
78 *prompt = sub {
79 my($q,$a) = @_;
80 my($ret) = defined $a ? $a : "";
81 printf qq{%s [%s]\n\n}, $q, $ret;
82 $ret;
83 };
84 }
85 }
86 print qq{
87
88The following questions are intended to help you with the
89configuration. The CPAN module needs a directory of its own to cache
90important index files and maybe keep a temporary mirror of CPAN files.
91This may be a site-wide directory or a personal directory.
92
5f05dabc
PP
93};
94
95 my $cpan_home = $CPAN::Config->{cpan_home} || MM->catdir($ENV{HOME}, ".cpan");
96 if (-d $cpan_home) {
97 print qq{
98
99I see you already have a directory
100 $cpan_home
101Shall we use it as the general CPAN build and cache directory?
102
103};
104 } else {
105 print qq{
106
107First of all, I\'d like to create this directory. Where?
108
109};
110 }
111
112 $default = $cpan_home;
05454584
AK
113 while ($ans = prompt("CPAN build and cache directory?",$default)) {
114 File::Path::mkpath($ans); # dies if it can't
115 if (-d $ans && -w _) {
116 last;
117 } else {
118 warn "Couldn't find directory $ans
10b2abe6 119 or directory is not writable. Please retry.\n";
05454584 120 }
10b2abe6 121 }
5f05dabc
PP
122 $CPAN::Config->{cpan_home} = $ans;
123
124 print qq{
125
126If you want, I can keep the source files after a build in the cpan
127home directory. If you choose so then future builds will take the
128files from there. If you don\'t want to keep them, answer 0 to the
129next question.
130
131};
132
133 $CPAN::Config->{keep_source_where} = MM->catdir($CPAN::Config->{cpan_home},"sources");
134 $CPAN::Config->{build_dir} = MM->catdir($CPAN::Config->{cpan_home},"build");
135
da199366
AK
136 #
137 # Cache size, Index expire
138 #
139
5f05dabc
PP
140 print qq{
141
142How big should the disk cache be for keeping the build directories
143with all the intermediate files?
144
145};
146
147 $default = $CPAN::Config->{build_cache} || 10;
148 $ans = prompt("Cache size for build directory (in MB)?", $default);
149 $CPAN::Config->{build_cache} = $ans;
150
151 # XXX This the time when we refetch the index files (in days)
152 $CPAN::Config->{'index_expire'} = 1;
153
da199366
AK
154 #
155 # External programs
156 #
157
5f05dabc
PP
158 print qq{
159
160The CPAN module will need a few external programs to work
161properly. Please correct me, if I guess the wrong path for a program.
05454584
AK
162Don\'t panic if you do not have some of them, just press ENTER for
163those.
5f05dabc
PP
164
165};
166
55e314ee 167 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
09d9d230
A
168 my $progname;
169 for $progname (qw/gzip tar unzip make lynx ncftp ftp/){
170 my $progcall = $progname;
171 my $path = $CPAN::Config->{$progname}
172 || $Config::Config{$progname}
173 || "";
55e314ee 174 if (MM->file_name_is_absolute($path)) {
09d9d230
A
175 # testing existence is not good enough, some have these exe
176 # extensions
177
178 # warn "Warning: configured $path does not exist\n" unless -e $path;
179 # $path = "";
55e314ee
AK
180 } else {
181 $path = '';
182 }
09d9d230
A
183 unless ($path) {
184 # e.g. make -> nmake
185 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
186 }
187
188 $path ||= find_exe($progcall,[@path]);
189 warn "Warning: $progcall not found in PATH\n" unless
190 $path; # not -e $path, because find_exe already checked that
191 $ans = prompt("Where is your $progname program?",$path) || $path;
192 $CPAN::Config->{$progname} = $ans;
5f05dabc
PP
193 }
194 my $path = $CPAN::Config->{'pager'} ||
195 $ENV{PAGER} || find_exe("less",[@path]) ||
196 find_exe("more",[@path]) || "more";
55e314ee 197 $ans = prompt("What is your favorite pager program?",$path);
5f05dabc 198 $CPAN::Config->{'pager'} = $ans;
55e314ee
AK
199 $path = $CPAN::Config->{'shell'};
200 if (MM->file_name_is_absolute($path)) {
201 warn "Warning: configured $path does not exist\n" unless -e $path;
202 $path = "";
203 }
204 $path ||= $ENV{SHELL};
13bc20ff 205 $path =~ s,\\,/,g if $^O eq 'os2'; # Cosmetic only
55e314ee 206 $ans = prompt("What is your favorite shell?",$path);
05454584 207 $CPAN::Config->{'shell'} = $ans;
da199366
AK
208
209 #
210 # Arguments to make etc.
211 #
212
5f05dabc
PP
213 print qq{
214
da199366 215Every Makefile.PL is run by perl in a separate process. Likewise we
5f05dabc
PP
216run \'make\' and \'make install\' in processes. If you have any parameters
217\(e.g. PREFIX, INSTALLPRIVLIB, UNINST or the like\) you want to pass to
218the calls, please specify them here.
219
05454584
AK
220If you don\'t understand this question, just press ENTER.
221
5f05dabc
PP
222};
223
224 $default = $CPAN::Config->{makepl_arg} || "";
225 $CPAN::Config->{makepl_arg} =
226 prompt("Parameters for the 'perl Makefile.PL' command?",$default);
227 $default = $CPAN::Config->{make_arg} || "";
228 $CPAN::Config->{make_arg} = prompt("Parameters for the 'make' command?",$default);
229
230 $default = $CPAN::Config->{make_install_arg} || $CPAN::Config->{make_arg} || "";
231 $CPAN::Config->{make_install_arg} =
232 prompt("Parameters for the 'make install' command?",$default);
233
da199366
AK
234 #
235 # Alarm period
236 #
237
10b2abe6
CS
238 print qq{
239
240Sometimes you may wish to leave the processes run by CPAN alone
241without caring about them. As sometimes the Makefile.PL contains
242question you\'re expected to answer, you can set a timer that will
243kill a 'perl Makefile.PL' process after the specified time in seconds.
244
e50380aa
AK
245If you set this value to 0, these processes will wait forever. This is
246the default and recommended setting.
10b2abe6
CS
247
248};
249
250 $default = $CPAN::Config->{inactivity_timeout} || 0;
251 $CPAN::Config->{inactivity_timeout} =
09d9d230 252 prompt("Timeout for inactivity during Makefile.PL?",$default);
10b2abe6 253
09d9d230 254 # Proxies
da199366 255
09d9d230 256 print qq{
10b2abe6 257
09d9d230
A
258If you\'re accessing the net via proxies, you can specify them in the
259CPAN configuration or via environment variables. The variable in
260the \$CPAN::Config takes precedence.
5f05dabc 261
05454584 262};
09d9d230
A
263
264 for (qw/ftp_proxy http_proxy no_proxy/) {
265 $default = $CPAN::Config->{$_} || $ENV{$_};
266 $CPAN::Config->{$_} = prompt("Your $_?",$default);
5f05dabc
PP
267 }
268
09d9d230
A
269 #
270 # MIRRORED.BY
271 #
272
273 conf_sites() unless $fastread;
274
d4fd5c69
AK
275 unless (@{$CPAN::Config->{'wait_list'}||[]}) {
276 print qq{
da199366 277
05454584
AK
278WAIT support is available as a Plugin. You need the CPAN::WAIT module
279to actually use it. But we need to know your favorite WAIT server. If
280you don\'t know a WAIT server near you, just press ENTER.
281
282};
d4fd5c69
AK
283 $default = "wait://ls6.informatik.uni-dortmund.de:1404";
284 $ans = prompt("Your favorite WAIT server?\n ",$default);
285 push @{$CPAN::Config->{'wait_list'}}, $ans;
286 }
05454584 287
e50380aa 288 # We don't ask that now, it will be noticed in time, won't it?
5f05dabc 289 $CPAN::Config->{'inhibit_startup_message'} = 0;
e50380aa 290 $CPAN::Config->{'getcwd'} = 'cwd';
5f05dabc
PP
291
292 print "\n\n";
293 CPAN::Config->commit($configpm);
294}
295
09d9d230
A
296sub conf_sites {
297 my $m = 'MIRRORED.BY';
298 my $mby = MM->catfile($CPAN::Config->{keep_source_where},$m);
299 File::Path::mkpath(File::Basename::dirname($mby));
300 if (-f $mby && -f $m && -M $m < -M $mby) {
301 require File::Copy;
302 File::Copy::copy($m,$mby) or die "Could not update $mby: $!";
303 }
304 if ( ! -f $mby ){
305 print qq{You have no $mby
306 I\'m trying to fetch one
307};
308 $mby = CPAN::FTP->localize($m,$mby,3);
309 } elsif (-M $mby > 30 ) {
310 print qq{Your $mby is older than 30 days,
311 I\'m trying to fetch one
312};
313 $mby = CPAN::FTP->localize($m,$mby,3);
314 }
315 read_mirrored_by($mby);
316}
317
5f05dabc
PP
318sub find_exe {
319 my($exe,$path) = @_;
55e314ee
AK
320 my($dir);
321 #warn "in find_exe exe[$exe] path[@$path]";
5f05dabc 322 for $dir (@$path) {
55e314ee 323 my $abs = MM->catfile($dir,$exe);
13bc20ff 324 if (($abs = MM->maybe_command($abs))) {
5f05dabc
PP
325 return $abs;
326 }
327 }
328}
329
330sub read_mirrored_by {
331 my($local) = @_;
332 my(%all,$url,$expected_size,$default,$ans,$host,$dst,$country,$continent,@location);
05454584
AK
333 my $fh = FileHandle->new;
334 $fh->open($local) or die "Couldn't open $local: $!";
335 while (<$fh>) {
5f05dabc
PP
336 ($host) = /^([\w\.\-]+)/ unless defined $host;
337 next unless defined $host;
338 next unless /\s+dst_(dst|location)/;
339 /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
340 ($continent, $country) = @location[-1,-2];
341 $continent =~ s/\s\(.*//;
342 /dst_dst\s+=\s+\"([^\"]+)/ and $dst = $1;
343 next unless $host && $dst && $continent && $country;
344 $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
345 undef $host;
346 $dst=$continent=$country="";
347 }
05454584 348 $fh->close;
5f05dabc
PP
349 $CPAN::Config->{urllist} ||= [];
350 if ($expected_size = @{$CPAN::Config->{urllist}}) {
351 for $url (@{$CPAN::Config->{urllist}}) {
352 # sanity check, scheme+colon, not "q" there:
353 next unless $url =~ /^\w+:\/./;
354 $all{"[From previous setup]"}{"found URL"}{$url}=CPAN::Mirrored::By->new('[From previous setup]','found URL',$url);
355 }
356 $CPAN::Config->{urllist} = [];
357 } else {
358 $expected_size = 6;
359 }
360
361 print qq{
362
363Now we need to know, where your favorite CPAN sites are located. Push
364a few sites onto the array (just in case the first on the array won\'t
365work). If you are mirroring CPAN to your local workstation, specify a
366file: URL.
367
368You can enter the number in front of the URL on the next screen, a
369file:, ftp: or http: URL, or "q" to finish selecting.
370
371};
372
373 $ans = prompt("Press RETURN to continue");
374 my $other;
375 $ans = $other = "";
376 my(%seen);
377
d4fd5c69 378 my $pipe = -t *STDIN ? "| $CPAN::Config->{'pager'}" : ">/dev/null";
5f05dabc 379 while () {
5f05dabc 380 my(@valid,$previous_best);
05454584
AK
381 my $fh = FileHandle->new;
382 $fh->open($pipe);
5f05dabc
PP
383 {
384 my($cont,$country,$url,$item);
385 my(@cont) = sort keys %all;
386 for $cont (@cont) {
09d9d230 387 $fh->print(" $cont\n");
5f05dabc
PP
388 for $country (sort {lc $a cmp lc $b} keys %{$all{$cont}}) {
389 for $url (sort {lc $a cmp lc $b} keys %{$all{$cont}{$country}}) {
390 my $t = sprintf(
09d9d230 391 " %-16s (%2d) %s\n",
5f05dabc
PP
392 $country,
393 ++$item,
394 $url
395 );
396 if ($cont =~ /^\[/) {
397 $previous_best ||= $item;
398 }
399 push @valid, $all{$cont}{$country}{$url};
05454584 400 $fh->print($t);
5f05dabc
PP
401 }
402 }
403 }
404 }
d4fd5c69 405 $fh->close;
09d9d230 406 $previous_best ||= "";
5f05dabc 407 $default =
09d9d230
A
408 @{$CPAN::Config->{urllist}} >=
409 $expected_size ? "q" : $previous_best;
5f05dabc
PP
410 $ans = prompt(
411 "\nSelect an$other ftp or file URL or a number (q to finish)",
412 $default
413 );
414 my $sel;
415 if ($ans =~ /^\d/) {
416 my $this = $valid[$ans-1];
da199366 417 my($con,$cou,$url) = ($this->continent,$this->country,$this->url);
5f05dabc
PP
418 push @{$CPAN::Config->{urllist}}, $url unless $seen{$url}++;
419 delete $all{$con}{$cou}{$url};
420 # print "Was a number [$ans] con[$con] cou[$cou] url[$url]\n";
09d9d230 421 } elsif ($ans =~ /^q/i) {
5f05dabc
PP
422 last;
423 } else {
424 $ans =~ s|/?$|/|; # has to end with one slash
425 $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
426 if ($ans =~ /^\w+:\/./) {
427 push @{$CPAN::Config->{urllist}}, $ans unless $seen{$ans}++;
428 } else {
429 print qq{"$ans" doesn\'t look like an URL at first sight.
430I\'ll ignore it for now. You can add it to lib/CPAN/Config.pm
431later and report a bug in my Makefile.PL to me (andreas koenig).
432Thanks.\n};
433 }
434 }
435 $other ||= "other";
436 }
437}
438
4391;