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