Document that File::Find doesn't follow symlinks
[p5sagit/p5-mst-13.2.git] / lib / CPAN / FirstTime.pm
CommitLineData
5f05dabc 1package CPAN::Mirrored::By;
2
3sub new {
4 my($self,@arg) = @_;
5 bless [@arg], $self;
6}
da199366 7sub continent { shift->[0] }
8sub country { shift->[1] }
5f05dabc 9sub url { shift->[2] }
10
11package CPAN::FirstTime;
12
13use strict;
14use ExtUtils::MakeMaker qw(prompt);
05454584 15use FileHandle ();
16use File::Path ();
5f05dabc 17use vars qw($VERSION);
55e314ee 18$VERSION = substr q$Revision: 1.20 $, 10;
5f05dabc 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 42 local($/) = "\n";
43 local($\) = "";
44
5f05dabc 45 my($ans,$default,$local,$cont,$url,$expected_size);
46
da199366 47 #
48 # Files, directories
49 #
50
5f05dabc 51 print qq{
5f05dabc 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 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 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 98 #
99 # Cache size, Index expire
100 #
101
5f05dabc 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 116 #
117 # External programs
118 #
119
5f05dabc 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 124Don\'t panic if you do not have some of them, just press ENTER for
125those.
5f05dabc 126
127};
128
55e314ee 129 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
5f05dabc 130 my $prog;
e50380aa 131 for $prog (qw/gzip tar unzip make lynx ncftp ftp/){
55e314ee 132 my $path = $CPAN::Config->{$prog} || "";
133 if (MM->file_name_is_absolute($path)) {
134 warn "Warning: configured $path does not exist\n" unless -e $path;
135 $path = "";
136 } else {
137 $path = '';
138 }
139 $path ||= find_exe($prog,[@path]);
140 warn "Warning: $prog not found in PATH\n" unless -e $path;
5f05dabc 141 $ans = prompt("Where is your $prog program?",$path) || $path;
142 $CPAN::Config->{$prog} = $ans;
143 }
144 my $path = $CPAN::Config->{'pager'} ||
145 $ENV{PAGER} || find_exe("less",[@path]) ||
146 find_exe("more",[@path]) || "more";
55e314ee 147 $ans = prompt("What is your favorite pager program?",$path);
5f05dabc 148 $CPAN::Config->{'pager'} = $ans;
55e314ee 149 $path = $CPAN::Config->{'shell'};
150 if (MM->file_name_is_absolute($path)) {
151 warn "Warning: configured $path does not exist\n" unless -e $path;
152 $path = "";
153 }
154 $path ||= $ENV{SHELL};
155 $ans = prompt("What is your favorite shell?",$path);
05454584 156 $CPAN::Config->{'shell'} = $ans;
da199366 157
158 #
159 # Arguments to make etc.
160 #
161
5f05dabc 162 print qq{
163
da199366 164Every Makefile.PL is run by perl in a separate process. Likewise we
5f05dabc 165run \'make\' and \'make install\' in processes. If you have any parameters
166\(e.g. PREFIX, INSTALLPRIVLIB, UNINST or the like\) you want to pass to
167the calls, please specify them here.
168
05454584 169If you don\'t understand this question, just press ENTER.
170
5f05dabc 171};
172
173 $default = $CPAN::Config->{makepl_arg} || "";
174 $CPAN::Config->{makepl_arg} =
175 prompt("Parameters for the 'perl Makefile.PL' command?",$default);
176 $default = $CPAN::Config->{make_arg} || "";
177 $CPAN::Config->{make_arg} = prompt("Parameters for the 'make' command?",$default);
178
179 $default = $CPAN::Config->{make_install_arg} || $CPAN::Config->{make_arg} || "";
180 $CPAN::Config->{make_install_arg} =
181 prompt("Parameters for the 'make install' command?",$default);
182
da199366 183 #
184 # Alarm period
185 #
186
10b2abe6 187 print qq{
188
189Sometimes you may wish to leave the processes run by CPAN alone
190without caring about them. As sometimes the Makefile.PL contains
191question you\'re expected to answer, you can set a timer that will
192kill a 'perl Makefile.PL' process after the specified time in seconds.
193
e50380aa 194If you set this value to 0, these processes will wait forever. This is
195the default and recommended setting.
10b2abe6 196
197};
198
199 $default = $CPAN::Config->{inactivity_timeout} || 0;
200 $CPAN::Config->{inactivity_timeout} =
55e314ee 201 prompt("Timeout for inacivity during Makefile.PL?",$default);
10b2abe6 202
da199366 203
204 #
205 # MIRRORED.BY
206 #
10b2abe6 207
5f05dabc 208 $local = 'MIRRORED.BY';
05454584 209 $local = MM->catfile($CPAN::Config->{keep_source_where},"MIRRORED.BY") unless -f $local;
5f05dabc 210 if (@{$CPAN::Config->{urllist}||[]}) {
211 print qq{
212I found a list of URLs in CPAN::Config and will use this.
213You can change it later with the 'o conf' command.
214
215}
05454584 216 } elsif (
217 -s $local
218 &&
219 -M $local < 30
220 ) {
5f05dabc 221 read_mirrored_by($local);
222 } else {
223 $CPAN::Config->{urllist} ||= [];
224 while (! @{$CPAN::Config->{urllist}}) {
05454584 225 my($input) = prompt(qq{
5f05dabc 226We need to know the URL of your favorite CPAN site.
05454584 227Please enter it here:});
228 $input =~ s/\s//g;
229 next unless $input;
230 my($wanted) = "MIRRORED.BY";
231 print qq{
232Testing "$input" ...
233};
234 push @{$CPAN::Config->{urllist}}, $input;
235 CPAN::FTP->localize($wanted,$local,"force");
236 if (-s $local) {
237 print qq{
238"$input" seems to work
239};
240 } else {
241 my $ans = prompt(qq{$input doesn\'t seem to work. Keep it in the list?},"n");
242 last unless $ans =~ /^n/i;
243 pop @{$CPAN::Config->{urllist}};
244 }
5f05dabc 245 }
246 }
247
d4fd5c69 248 unless (@{$CPAN::Config->{'wait_list'}||[]}) {
249 print qq{
da199366 250
05454584 251WAIT support is available as a Plugin. You need the CPAN::WAIT module
252to actually use it. But we need to know your favorite WAIT server. If
253you don\'t know a WAIT server near you, just press ENTER.
254
255};
d4fd5c69 256 $default = "wait://ls6.informatik.uni-dortmund.de:1404";
257 $ans = prompt("Your favorite WAIT server?\n ",$default);
258 push @{$CPAN::Config->{'wait_list'}}, $ans;
259 }
05454584 260
261 print qq{
262
da199366 263If you\'re accessing the net via proxies, you can specify them in the
264CPAN configuration or via environment variables. The variable in
265the \$CPAN::Config takes precedence.
266
267};
268
269 for (qw/ftp_proxy http_proxy no_proxy/) {
270 $default = $CPAN::Config->{$_} || $ENV{$_};
271 $CPAN::Config->{$_} = prompt("Your $_?",$default);
272 }
273
e50380aa 274 # We don't ask that now, it will be noticed in time, won't it?
5f05dabc 275 $CPAN::Config->{'inhibit_startup_message'} = 0;
e50380aa 276 $CPAN::Config->{'getcwd'} = 'cwd';
5f05dabc 277
278 print "\n\n";
279 CPAN::Config->commit($configpm);
280}
281
282sub find_exe {
283 my($exe,$path) = @_;
55e314ee 284 my($dir);
285 #warn "in find_exe exe[$exe] path[@$path]";
5f05dabc 286 for $dir (@$path) {
55e314ee 287 my $abs = MM->catfile($dir,$exe);
288 if (MM->maybe_command($abs)) {
5f05dabc 289 return $abs;
290 }
291 }
292}
293
294sub read_mirrored_by {
295 my($local) = @_;
296 my(%all,$url,$expected_size,$default,$ans,$host,$dst,$country,$continent,@location);
05454584 297 my $fh = FileHandle->new;
298 $fh->open($local) or die "Couldn't open $local: $!";
299 while (<$fh>) {
5f05dabc 300 ($host) = /^([\w\.\-]+)/ unless defined $host;
301 next unless defined $host;
302 next unless /\s+dst_(dst|location)/;
303 /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
304 ($continent, $country) = @location[-1,-2];
305 $continent =~ s/\s\(.*//;
306 /dst_dst\s+=\s+\"([^\"]+)/ and $dst = $1;
307 next unless $host && $dst && $continent && $country;
308 $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
309 undef $host;
310 $dst=$continent=$country="";
311 }
05454584 312 $fh->close;
5f05dabc 313 $CPAN::Config->{urllist} ||= [];
314 if ($expected_size = @{$CPAN::Config->{urllist}}) {
315 for $url (@{$CPAN::Config->{urllist}}) {
316 # sanity check, scheme+colon, not "q" there:
317 next unless $url =~ /^\w+:\/./;
318 $all{"[From previous setup]"}{"found URL"}{$url}=CPAN::Mirrored::By->new('[From previous setup]','found URL',$url);
319 }
320 $CPAN::Config->{urllist} = [];
321 } else {
322 $expected_size = 6;
323 }
324
325 print qq{
326
327Now we need to know, where your favorite CPAN sites are located. Push
328a few sites onto the array (just in case the first on the array won\'t
329work). If you are mirroring CPAN to your local workstation, specify a
330file: URL.
331
332You can enter the number in front of the URL on the next screen, a
333file:, ftp: or http: URL, or "q" to finish selecting.
334
335};
336
337 $ans = prompt("Press RETURN to continue");
338 my $other;
339 $ans = $other = "";
340 my(%seen);
341
d4fd5c69 342 my $pipe = -t *STDIN ? "| $CPAN::Config->{'pager'}" : ">/dev/null";
5f05dabc 343 while () {
5f05dabc 344 my(@valid,$previous_best);
05454584 345 my $fh = FileHandle->new;
346 $fh->open($pipe);
5f05dabc 347 {
348 my($cont,$country,$url,$item);
349 my(@cont) = sort keys %all;
350 for $cont (@cont) {
05454584 351 $fh->print(" $cont\n");
5f05dabc 352 for $country (sort {lc $a cmp lc $b} keys %{$all{$cont}}) {
353 for $url (sort {lc $a cmp lc $b} keys %{$all{$cont}{$country}}) {
354 my $t = sprintf(
355 " %-18s (%2d) %s\n",
356 $country,
357 ++$item,
358 $url
359 );
360 if ($cont =~ /^\[/) {
361 $previous_best ||= $item;
362 }
363 push @valid, $all{$cont}{$country}{$url};
05454584 364 $fh->print($t);
5f05dabc 365 }
366 }
367 }
368 }
d4fd5c69 369 $fh->close;
5f05dabc 370 $previous_best ||= 1;
371 $default =
372 @{$CPAN::Config->{urllist}} >= $expected_size ? "q" : $previous_best;
373 $ans = prompt(
374 "\nSelect an$other ftp or file URL or a number (q to finish)",
375 $default
376 );
377 my $sel;
378 if ($ans =~ /^\d/) {
379 my $this = $valid[$ans-1];
da199366 380 my($con,$cou,$url) = ($this->continent,$this->country,$this->url);
5f05dabc 381 push @{$CPAN::Config->{urllist}}, $url unless $seen{$url}++;
382 delete $all{$con}{$cou}{$url};
383 # print "Was a number [$ans] con[$con] cou[$cou] url[$url]\n";
384 } elsif (@{$CPAN::Config->{urllist}} && $ans =~ /^q/i) {
385 last;
386 } else {
387 $ans =~ s|/?$|/|; # has to end with one slash
388 $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
389 if ($ans =~ /^\w+:\/./) {
390 push @{$CPAN::Config->{urllist}}, $ans unless $seen{$ans}++;
391 } else {
392 print qq{"$ans" doesn\'t look like an URL at first sight.
393I\'ll ignore it for now. You can add it to lib/CPAN/Config.pm
394later and report a bug in my Makefile.PL to me (andreas koenig).
395Thanks.\n};
396 }
397 }
398 $other ||= "other";
399 }
400}
401
4021;