This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[differences between cumulative patch application and perl-5.003_97c]
[perl5.git] / lib / CPAN / FirstTime.pm
CommitLineData
5f05dabc 1package CPAN::Mirrored::By;
2
3sub new {
4 my($self,@arg) = @_;
5 bless [@arg], $self;
6}
da199366
A
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
A
15use FileHandle ();
16use File::Path ();
5f05dabc 17use vars qw($VERSION);
e50380aa 18$VERSION = substr q$Revision: 1.18 $, 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
A
42 local($/) = "\n";
43 local($\) = "";
44
5f05dabc 45 my($ans,$default,$local,$cont,$url,$expected_size);
46
da199366
A
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
A
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
A
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
A
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
A
124Don\'t panic if you do not have some of them, just press ENTER for
125those.
5f05dabc 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 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
A
141 $path = $CPAN::Config->{'shell'} || $ENV{SHELL} || "";
142 $ans = prompt("What is your favorite shell?",$path) || $path;
05454584 143 $CPAN::Config->{'shell'} = $ans;
da199366
A
144
145 #
146 # Arguments to make etc.
147 #
148
5f05dabc 149 print qq{
150
da199366 151Every Makefile.PL is run by perl in a separate process. Likewise we
5f05dabc 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
A
156If you don\'t understand this question, just press ENTER.
157
5f05dabc 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
A
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
A
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
A
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 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
A
203 } elsif (
204 -s $local
205 &&
206 -M $local < 30
207 ) {
5f05dabc 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
A
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 232 }
233 }
234
d4fd5c69
A
235 unless (@{$CPAN::Config->{'wait_list'}||[]}) {
236 print qq{
da199366 237
05454584
A
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
A
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
A
247
248 print qq{
249
da199366
A
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 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
A
285 my $fh = FileHandle->new;
286 $fh->open($local) or die "Couldn't open $local: $!";
287 while (<$fh>) {
5f05dabc 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 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
A
333 my $fh = FileHandle->new;
334 $fh->open($pipe);
5f05dabc 335 {
336 my($cont,$country,$url,$item);
337 my(@cont) = sort keys %all;
338 for $cont (@cont) {
05454584 339 $fh->print(" $cont\n");
5f05dabc 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 353 }
354 }
355 }
356 }
d4fd5c69 357 $fh->close;
5f05dabc 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 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;