Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / Module / AutoInstall.pm
1 package Module::AutoInstall;
2
3 use strict;
4 use Cwd                 ();
5 use ExtUtils::MakeMaker ();
6
7 use vars qw{$VERSION};
8 BEGIN {
9         $VERSION = '1.03';
10 }
11
12 # special map on pre-defined feature sets
13 my %FeatureMap = (
14     ''      => 'Core Features',    # XXX: deprecated
15     '-core' => 'Core Features',
16 );
17
18 # various lexical flags
19 my ( @Missing, @Existing,  %DisabledTests, $UnderCPAN,     $HasCPANPLUS );
20 my (
21     $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps
22 );
23 my ( $PostambleActions, $PostambleUsed );
24
25 # See if it's a testing or non-interactive session
26 _accept_default( $ENV{AUTOMATED_TESTING} or ! -t STDIN ); 
27 _init();
28
29 sub _accept_default {
30     $AcceptDefault = shift;
31 }
32
33 sub missing_modules {
34     return @Missing;
35 }
36
37 sub do_install {
38     __PACKAGE__->install(
39         [
40             $Config
41             ? ( UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} )
42             : ()
43         ],
44         @Missing,
45     );
46 }
47
48 # initialize various flags, and/or perform install
49 sub _init {
50     foreach my $arg (
51         @ARGV,
52         split(
53             /[\s\t]+/,
54             $ENV{PERL_AUTOINSTALL} || $ENV{PERL_EXTUTILS_AUTOINSTALL} || ''
55         )
56       )
57     {
58         if ( $arg =~ /^--config=(.*)$/ ) {
59             $Config = [ split( ',', $1 ) ];
60         }
61         elsif ( $arg =~ /^--installdeps=(.*)$/ ) {
62             __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) );
63             exit 0;
64         }
65         elsif ( $arg =~ /^--default(?:deps)?$/ ) {
66             $AcceptDefault = 1;
67         }
68         elsif ( $arg =~ /^--check(?:deps)?$/ ) {
69             $CheckOnly = 1;
70         }
71         elsif ( $arg =~ /^--skip(?:deps)?$/ ) {
72             $SkipInstall = 1;
73         }
74         elsif ( $arg =~ /^--test(?:only)?$/ ) {
75             $TestOnly = 1;
76         }
77         elsif ( $arg =~ /^--all(?:deps)?$/ ) {
78             $AllDeps = 1;
79         }
80     }
81 }
82
83 # overrides MakeMaker's prompt() to automatically accept the default choice
84 sub _prompt {
85     goto &ExtUtils::MakeMaker::prompt unless $AcceptDefault;
86
87     my ( $prompt, $default ) = @_;
88     my $y = ( $default =~ /^[Yy]/ );
89
90     print $prompt, ' [', ( $y ? 'Y' : 'y' ), '/', ( $y ? 'n' : 'N' ), '] ';
91     print "$default\n";
92     return $default;
93 }
94
95 # the workhorse
96 sub import {
97     my $class = shift;
98     my @args  = @_ or return;
99     my $core_all;
100
101     print "*** $class version " . $class->VERSION . "\n";
102     print "*** Checking for Perl dependencies...\n";
103
104     my $cwd = Cwd::cwd();
105
106     $Config = [];
107
108     my $maxlen = length(
109         (
110             sort   { length($b) <=> length($a) }
111               grep { /^[^\-]/ }
112               map  {
113                 ref($_)
114                   ? ( ( ref($_) eq 'HASH' ) ? keys(%$_) : @{$_} )
115                   : ''
116               }
117               map { +{@args}->{$_} }
118               grep { /^[^\-]/ or /^-core$/i } keys %{ +{@args} }
119         )[0]
120     );
121
122     # We want to know if we're under CPAN early to avoid prompting, but
123     # if we aren't going to try and install anything anyway then skip the
124     # check entirely since we don't want to have to load (and configure)
125     # an old CPAN just for a cosmetic message
126
127     $UnderCPAN = _check_lock(1) unless $SkipInstall;
128
129     while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) {
130         my ( @required, @tests, @skiptests );
131         my $default  = 1;
132         my $conflict = 0;
133
134         if ( $feature =~ m/^-(\w+)$/ ) {
135             my $option = lc($1);
136
137             # check for a newer version of myself
138             _update_to( $modules, @_ ) and return if $option eq 'version';
139
140             # sets CPAN configuration options
141             $Config = $modules if $option eq 'config';
142
143             # promote every features to core status
144             $core_all = ( $modules =~ /^all$/i ) and next
145               if $option eq 'core';
146
147             next unless $option eq 'core';
148         }
149
150         print "[" . ( $FeatureMap{ lc($feature) } || $feature ) . "]\n";
151
152         $modules = [ %{$modules} ] if UNIVERSAL::isa( $modules, 'HASH' );
153
154         unshift @$modules, -default => &{ shift(@$modules) }
155           if ( ref( $modules->[0] ) eq 'CODE' );    # XXX: bugward combatability
156
157         while ( my ( $mod, $arg ) = splice( @$modules, 0, 2 ) ) {
158             if ( $mod =~ m/^-(\w+)$/ ) {
159                 my $option = lc($1);
160
161                 $default   = $arg    if ( $option eq 'default' );
162                 $conflict  = $arg    if ( $option eq 'conflict' );
163                 @tests     = @{$arg} if ( $option eq 'tests' );
164                 @skiptests = @{$arg} if ( $option eq 'skiptests' );
165
166                 next;
167             }
168
169             printf( "- %-${maxlen}s ...", $mod );
170
171             if ( $arg and $arg =~ /^\D/ ) {
172                 unshift @$modules, $arg;
173                 $arg = 0;
174             }
175
176             # XXX: check for conflicts and uninstalls(!) them.
177             my $cur = _load($mod);
178             if (_version_cmp ($cur, $arg) >= 0)
179             {
180                 print "loaded. ($cur" . ( $arg ? " >= $arg" : '' ) . ")\n";
181                 push @Existing, $mod => $arg;
182                 $DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
183             }
184             else {
185                 if (not defined $cur)   # indeed missing
186                 {
187                     print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n";
188                 }
189                 else
190                 {
191                     # no need to check $arg as _version_cmp ($cur, undef) would satisfy >= above
192                     print "too old. ($cur < $arg)\n";
193                 }
194
195                 push @required, $mod => $arg;
196             }
197         }
198
199         next unless @required;
200
201         my $mandatory = ( $feature eq '-core' or $core_all );
202
203         if (
204             !$SkipInstall
205             and (
206                 $CheckOnly
207                 or ($mandatory and $UnderCPAN)
208                 or $AllDeps
209                 or _prompt(
210                     qq{==> Auto-install the }
211                       . ( @required / 2 )
212                       . ( $mandatory ? ' mandatory' : ' optional' )
213                       . qq{ module(s) from CPAN?},
214                     $default ? 'y' : 'n',
215                 ) =~ /^[Yy]/
216             )
217           )
218         {
219             push( @Missing, @required );
220             $DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
221         }
222
223         elsif ( !$SkipInstall
224             and $default
225             and $mandatory
226             and
227             _prompt( qq{==> The module(s) are mandatory! Really skip?}, 'n', )
228             =~ /^[Nn]/ )
229         {
230             push( @Missing, @required );
231             $DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
232         }
233
234         else {
235             $DisabledTests{$_} = 1 for map { glob($_) } @tests;
236         }
237     }
238
239     if ( @Missing and not( $CheckOnly or $UnderCPAN ) ) {
240         require Config;
241         print
242 "*** Dependencies will be installed the next time you type '$Config::Config{make}'.\n";
243
244         # make an educated guess of whether we'll need root permission.
245         print "    (You may need to do that as the 'root' user.)\n"
246           if eval '$>';
247     }
248     print "*** $class configuration finished.\n";
249
250     chdir $cwd;
251
252     # import to main::
253     no strict 'refs';
254     *{'main::WriteMakefile'} = \&Write if caller(0) eq 'main';
255 }
256
257 sub _running_under {
258     my $thing = shift;
259     print <<"END_MESSAGE";
260 *** Since we're running under ${thing}, I'll just let it take care
261     of the dependency's installation later.
262 END_MESSAGE
263     return 1;
264 }
265
266 # Check to see if we are currently running under CPAN.pm and/or CPANPLUS;
267 # if we are, then we simply let it taking care of our dependencies
268 sub _check_lock {
269     return unless @Missing or @_;
270
271     my $cpan_env = $ENV{PERL5_CPAN_IS_RUNNING};
272
273     if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) {
274         return _running_under($cpan_env ? 'CPAN' : 'CPANPLUS');
275     }
276
277     require CPAN;
278
279     if ($CPAN::VERSION > '1.89') {
280         if ($cpan_env) {
281             return _running_under('CPAN');
282         }
283         return; # CPAN.pm new enough, don't need to check further
284     }
285
286     # last ditch attempt, this -will- configure CPAN, very sorry
287
288     _load_cpan(1); # force initialize even though it's already loaded
289
290     # Find the CPAN lock-file
291     my $lock = MM->catfile( $CPAN::Config->{cpan_home}, ".lock" );
292     return unless -f $lock;
293
294     # Check the lock
295     local *LOCK;
296     return unless open(LOCK, $lock);
297
298     if (
299             ( $^O eq 'MSWin32' ? _under_cpan() : <LOCK> == getppid() )
300         and ( $CPAN::Config->{prerequisites_policy} || '' ) ne 'ignore'
301     ) {
302         print <<'END_MESSAGE';
303
304 *** Since we're running under CPAN, I'll just let it take care
305     of the dependency's installation later.
306 END_MESSAGE
307         return 1;
308     }
309
310     close LOCK;
311     return;
312 }
313
314 sub install {
315     my $class = shift;
316
317     my $i;    # used below to strip leading '-' from config keys
318     my @config = ( map { s/^-// if ++$i; $_ } @{ +shift } );
319
320     my ( @modules, @installed );
321     while ( my ( $pkg, $ver ) = splice( @_, 0, 2 ) ) {
322
323         # grep out those already installed
324         if ( _version_cmp( _load($pkg), $ver ) >= 0 ) {
325             push @installed, $pkg;
326         }
327         else {
328             push @modules, $pkg, $ver;
329         }
330     }
331
332     return @installed unless @modules;  # nothing to do
333     return @installed if _check_lock(); # defer to the CPAN shell
334
335     print "*** Installing dependencies...\n";
336
337     return unless _connected_to('cpan.org');
338
339     my %args = @config;
340     my %failed;
341     local *FAILED;
342     if ( $args{do_once} and open( FAILED, '.#autoinstall.failed' ) ) {
343         while (<FAILED>) { chomp; $failed{$_}++ }
344         close FAILED;
345
346         my @newmod;
347         while ( my ( $k, $v ) = splice( @modules, 0, 2 ) ) {
348             push @newmod, ( $k => $v ) unless $failed{$k};
349         }
350         @modules = @newmod;
351     }
352
353     if ( _has_cpanplus() and not $ENV{PERL_AUTOINSTALL_PREFER_CPAN} ) {
354         _install_cpanplus( \@modules, \@config );
355     } else {
356         _install_cpan( \@modules, \@config );
357     }
358
359     print "*** $class installation finished.\n";
360
361     # see if we have successfully installed them
362     while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
363         if ( _version_cmp( _load($pkg), $ver ) >= 0 ) {
364             push @installed, $pkg;
365         }
366         elsif ( $args{do_once} and open( FAILED, '>> .#autoinstall.failed' ) ) {
367             print FAILED "$pkg\n";
368         }
369     }
370
371     close FAILED if $args{do_once};
372
373     return @installed;
374 }
375
376 sub _install_cpanplus {
377     my @modules   = @{ +shift };
378     my @config    = _cpanplus_config( @{ +shift } );
379     my $installed = 0;
380
381     require CPANPLUS::Backend;
382     my $cp   = CPANPLUS::Backend->new;
383     my $conf = $cp->configure_object;
384
385     return unless $conf->can('conf') # 0.05x+ with "sudo" support
386                or _can_write($conf->_get_build('base'));  # 0.04x
387
388     # if we're root, set UNINST=1 to avoid trouble unless user asked for it.
389     my $makeflags = $conf->get_conf('makeflags') || '';
390     if ( UNIVERSAL::isa( $makeflags, 'HASH' ) ) {
391         # 0.03+ uses a hashref here
392         $makeflags->{UNINST} = 1 unless exists $makeflags->{UNINST};
393
394     } else {
395         # 0.02 and below uses a scalar
396         $makeflags = join( ' ', split( ' ', $makeflags ), 'UNINST=1' )
397           if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } );
398
399     }
400     $conf->set_conf( makeflags => $makeflags );
401     $conf->set_conf( prereqs   => 1 );
402
403     
404
405     while ( my ( $key, $val ) = splice( @config, 0, 2 ) ) {
406         $conf->set_conf( $key, $val );
407     }
408
409     my $modtree = $cp->module_tree;
410     while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
411         print "*** Installing $pkg...\n";
412
413         MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall;
414
415         my $success;
416         my $obj = $modtree->{$pkg};
417
418         if ( $obj and _version_cmp( $obj->{version}, $ver ) >= 0 ) {
419             my $pathname = $pkg;
420             $pathname =~ s/::/\\W/;
421
422             foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) {
423                 delete $INC{$inc};
424             }
425
426             my $rv = $cp->install( modules => [ $obj->{module} ] );
427
428             if ( $rv and ( $rv->{ $obj->{module} } or $rv->{ok} ) ) {
429                 print "*** $pkg successfully installed.\n";
430                 $success = 1;
431             } else {
432                 print "*** $pkg installation cancelled.\n";
433                 $success = 0;
434             }
435
436             $installed += $success;
437         } else {
438             print << ".";
439 *** Could not find a version $ver or above for $pkg; skipping.
440 .
441         }
442
443         MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall;
444     }
445
446     return $installed;
447 }
448
449 sub _cpanplus_config {
450         my @config = ();
451         while ( @_ ) {
452                 my ($key, $value) = (shift(), shift());
453                 if ( $key eq 'prerequisites_policy' ) {
454                         if ( $value eq 'follow' ) {
455                                 $value = CPANPLUS::Internals::Constants::PREREQ_INSTALL();
456                         } elsif ( $value eq 'ask' ) {
457                                 $value = CPANPLUS::Internals::Constants::PREREQ_ASK();
458                         } elsif ( $value eq 'ignore' ) {
459                                 $value = CPANPLUS::Internals::Constants::PREREQ_IGNORE();
460                         } else {
461                                 die "*** Cannot convert option $key = '$value' to CPANPLUS version.\n";
462                         }
463                 } else {
464                         die "*** Cannot convert option $key to CPANPLUS version.\n";
465                 }
466         }
467         return @config;
468 }
469
470 sub _install_cpan {
471     my @modules   = @{ +shift };
472     my @config    = @{ +shift };
473     my $installed = 0;
474     my %args;
475
476     _load_cpan();
477     require Config;
478
479     if (CPAN->VERSION < 1.80) {
480         # no "sudo" support, probe for writableness
481         return unless _can_write( MM->catfile( $CPAN::Config->{cpan_home}, 'sources' ) )
482                   and _can_write( $Config::Config{sitelib} );
483     }
484
485     # if we're root, set UNINST=1 to avoid trouble unless user asked for it.
486     my $makeflags = $CPAN::Config->{make_install_arg} || '';
487     $CPAN::Config->{make_install_arg} =
488       join( ' ', split( ' ', $makeflags ), 'UNINST=1' )
489       if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } );
490
491     # don't show start-up info
492     $CPAN::Config->{inhibit_startup_message} = 1;
493
494     # set additional options
495     while ( my ( $opt, $arg ) = splice( @config, 0, 2 ) ) {
496         ( $args{$opt} = $arg, next )
497           if $opt =~ /^force$/;    # pseudo-option
498         $CPAN::Config->{$opt} = $arg;
499     }
500
501     local $CPAN::Config->{prerequisites_policy} = 'follow';
502
503     while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
504         MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall;
505
506         print "*** Installing $pkg...\n";
507
508         my $obj     = CPAN::Shell->expand( Module => $pkg );
509         my $success = 0;
510
511         if ( $obj and _version_cmp( $obj->cpan_version, $ver ) >= 0 ) {
512             my $pathname = $pkg;
513             $pathname =~ s/::/\\W/;
514
515             foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) {
516                 delete $INC{$inc};
517             }
518
519             my $rv = $args{force} ? CPAN::Shell->force( install => $pkg )
520                                   : CPAN::Shell->install($pkg);
521             $rv ||= eval {
522                 $CPAN::META->instance( 'CPAN::Distribution', $obj->cpan_file, )
523                   ->{install}
524                   if $CPAN::META;
525             };
526
527             if ( $rv eq 'YES' ) {
528                 print "*** $pkg successfully installed.\n";
529                 $success = 1;
530             }
531             else {
532                 print "*** $pkg installation failed.\n";
533                 $success = 0;
534             }
535
536             $installed += $success;
537         }
538         else {
539             print << ".";
540 *** Could not find a version $ver or above for $pkg; skipping.
541 .
542         }
543
544         MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall;
545     }
546
547     return $installed;
548 }
549
550 sub _has_cpanplus {
551     return (
552         $HasCPANPLUS = (
553             $INC{'CPANPLUS/Config.pm'}
554               or _load('CPANPLUS::Shell::Default')
555         )
556     );
557 }
558
559 # make guesses on whether we're under the CPAN installation directory
560 sub _under_cpan {
561     require Cwd;
562     require File::Spec;
563
564     my $cwd  = File::Spec->canonpath( Cwd::cwd() );
565     my $cpan = File::Spec->canonpath( $CPAN::Config->{cpan_home} );
566
567     return ( index( $cwd, $cpan ) > -1 );
568 }
569
570 sub _update_to {
571     my $class = __PACKAGE__;
572     my $ver   = shift;
573
574     return
575       if _version_cmp( _load($class), $ver ) >= 0;  # no need to upgrade
576
577     if (
578         _prompt( "==> A newer version of $class ($ver) is required. Install?",
579             'y' ) =~ /^[Nn]/
580       )
581     {
582         die "*** Please install $class $ver manually.\n";
583     }
584
585     print << ".";
586 *** Trying to fetch it from CPAN...
587 .
588
589     # install ourselves
590     _load($class) and return $class->import(@_)
591       if $class->install( [], $class, $ver );
592
593     print << '.'; exit 1;
594
595 *** Cannot bootstrap myself. :-( Installation terminated.
596 .
597 }
598
599 # check if we're connected to some host, using inet_aton
600 sub _connected_to {
601     my $site = shift;
602
603     return (
604         ( _load('Socket') and Socket::inet_aton($site) ) or _prompt(
605             qq(
606 *** Your host cannot resolve the domain name '$site', which
607     probably means the Internet connections are unavailable.
608 ==> Should we try to install the required module(s) anyway?), 'n'
609           ) =~ /^[Yy]/
610     );
611 }
612
613 # check if a directory is writable; may create it on demand
614 sub _can_write {
615     my $path = shift;
616     mkdir( $path, 0755 ) unless -e $path;
617
618     return 1 if -w $path;
619
620     print << ".";
621 *** You are not allowed to write to the directory '$path';
622     the installation may fail due to insufficient permissions.
623 .
624
625     if (
626         eval '$>' and lc(`sudo -V`) =~ /version/ and _prompt(
627             qq(
628 ==> Should we try to re-execute the autoinstall process with 'sudo'?),
629             ((-t STDIN) ? 'y' : 'n')
630         ) =~ /^[Yy]/
631       )
632     {
633
634         # try to bootstrap ourselves from sudo
635         print << ".";
636 *** Trying to re-execute the autoinstall process with 'sudo'...
637 .
638         my $missing = join( ',', @Missing );
639         my $config = join( ',',
640             UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} )
641           if $Config;
642
643         return
644           unless system( 'sudo', $^X, $0, "--config=$config",
645             "--installdeps=$missing" );
646
647         print << ".";
648 *** The 'sudo' command exited with error!  Resuming...
649 .
650     }
651
652     return _prompt(
653         qq(
654 ==> Should we try to install the required module(s) anyway?), 'n'
655     ) =~ /^[Yy]/;
656 }
657
658 # load a module and return the version it reports
659 sub _load {
660     my $mod  = pop;    # class/instance doesn't matter
661     my $file = $mod;
662
663     $file =~ s|::|/|g;
664     $file .= '.pm';
665
666     local $@;
667     return eval { require $file; $mod->VERSION } || ( $@ ? undef: 0 );
668 }
669
670 # Load CPAN.pm and it's configuration
671 sub _load_cpan {
672     return if $CPAN::VERSION and $CPAN::Config and not @_;
673     require CPAN;
674     if ( $CPAN::HandleConfig::VERSION ) {
675         # Newer versions of CPAN have a HandleConfig module
676         CPAN::HandleConfig->load;
677     } else {
678         # Older versions had the load method in Config directly
679         CPAN::Config->load;
680     }
681 }
682
683 # compare two versions, either use Sort::Versions or plain comparison
684 # return values same as <=>
685 sub _version_cmp {
686     my ( $cur, $min ) = @_;
687     return -1 unless defined $cur;  # if 0 keep comparing
688     return 1 unless $min;
689
690     $cur =~ s/\s+$//;
691
692     # check for version numbers that are not in decimal format
693     if ( ref($cur) or ref($min) or $cur =~ /v|\..*\./ or $min =~ /v|\..*\./ ) {
694         if ( ( $version::VERSION or defined( _load('version') )) and
695              version->can('new') 
696             ) {
697
698             # use version.pm if it is installed.
699             return version->new($cur) <=> version->new($min);
700         }
701         elsif ( $Sort::Versions::VERSION or defined( _load('Sort::Versions') ) )
702         {
703
704             # use Sort::Versions as the sorting algorithm for a.b.c versions
705             return Sort::Versions::versioncmp( $cur, $min );
706         }
707
708         warn "Cannot reliably compare non-decimal formatted versions.\n"
709           . "Please install version.pm or Sort::Versions.\n";
710     }
711
712     # plain comparison
713     local $^W = 0;    # shuts off 'not numeric' bugs
714     return $cur <=> $min;
715 }
716
717 # nothing; this usage is deprecated.
718 sub main::PREREQ_PM { return {}; }
719
720 sub _make_args {
721     my %args = @_;
722
723     $args{PREREQ_PM} = { %{ $args{PREREQ_PM} || {} }, @Existing, @Missing }
724       if $UnderCPAN or $TestOnly;
725
726     if ( $args{EXE_FILES} and -e 'MANIFEST' ) {
727         require ExtUtils::Manifest;
728         my $manifest = ExtUtils::Manifest::maniread('MANIFEST');
729
730         $args{EXE_FILES} =
731           [ grep { exists $manifest->{$_} } @{ $args{EXE_FILES} } ];
732     }
733
734     $args{test}{TESTS} ||= 't/*.t';
735     $args{test}{TESTS} = join( ' ',
736         grep { !exists( $DisabledTests{$_} ) }
737           map { glob($_) } split( /\s+/, $args{test}{TESTS} ) );
738
739     my $missing = join( ',', @Missing );
740     my $config =
741       join( ',', UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} )
742       if $Config;
743
744     $PostambleActions = (
745         ($missing and not $UnderCPAN)
746         ? "\$(PERL) $0 --config=$config --installdeps=$missing"
747         : "\$(NOECHO) \$(NOOP)"
748     );
749
750     return %args;
751 }
752
753 # a wrapper to ExtUtils::MakeMaker::WriteMakefile
754 sub Write {
755     require Carp;
756     Carp::croak "WriteMakefile: Need even number of args" if @_ % 2;
757
758     if ($CheckOnly) {
759         print << ".";
760 *** Makefile not written in check-only mode.
761 .
762         return;
763     }
764
765     my %args = _make_args(@_);
766
767     no strict 'refs';
768
769     $PostambleUsed = 0;
770     local *MY::postamble = \&postamble unless defined &MY::postamble;
771     ExtUtils::MakeMaker::WriteMakefile(%args);
772
773     print << "." unless $PostambleUsed;
774 *** WARNING: Makefile written with customized MY::postamble() without
775     including contents from Module::AutoInstall::postamble() --
776     auto installation features disabled.  Please contact the author.
777 .
778
779     return 1;
780 }
781
782 sub postamble {
783     $PostambleUsed = 1;
784
785     return <<"END_MAKE";
786
787 config :: installdeps
788 \t\$(NOECHO) \$(NOOP)
789
790 checkdeps ::
791 \t\$(PERL) $0 --checkdeps
792
793 installdeps ::
794 \t$PostambleActions
795
796 END_MAKE
797
798 }
799
800 1;
801
802 __END__
803
804 =pod
805
806 =head1 NAME
807
808 Module::AutoInstall - Automatic install of dependencies via CPAN
809
810 =head1 SYNOPSIS
811
812 In F<Makefile.PL>, with L<Module::Install> available on the author's system:
813
814     use inc::Module::Install;
815     
816     name        'Joe-Hacker';
817     abstract    'Perl Interface to Joe Hacker';
818     author      'Joe Hacker <joe@hacker.org>';
819     include     'Module::AutoInstall';
820     
821     requires    'Module0';          # mandatory modules
822     
823     feature     'Feature1',
824         -default    => 0,
825         'Module2'   => '0.1';
826     
827     feature     'Feature2',
828         -default    => 0,
829         'Module3'   => '1.0';
830     
831     auto_install(
832         make_args   => '--hello',   # option(s) for CPAN::Config
833         force       => 1,           # pseudo-option to force install
834         do_once     => 1,           # skip previously failed modules
835     );
836     
837     WriteAll;
838
839 Invoking the resulting F<Makefile.PL>:
840
841     % perl Makefile.PL                  # interactive behaviour
842     % perl Makefile.PL --defaultdeps    # accept default value on prompts
843     % perl Makefile.PL --checkdeps      # check only, no Makefile produced
844     % perl Makefile.PL --skipdeps       # ignores all dependencies
845     % perl Makefile.PL --testonly       # don't write installation targets
846
847 Note that the trailing 'deps' of arguments may be omitted, too.
848
849 Using C<--defaultdeps> will make F<Makefile.PL> behave similarly to a regular
850 Makefile.PL file with C<PREREQ_PM> dependencies.
851
852 One can use environment variables (see "ENVIRONMENT") below to set a default
853 behavior instead of specifying it in the command line for every invocation
854 of F<Makefile.PL>.
855
856 Using F<make> (or F<nmake>):
857
858     % make [all|test|install]           # install dependencies first
859     % make checkdeps                    # same as the --checkdeps above
860     % make installdeps                  # install dependencies only
861
862 =head1 DESCRIPTION
863
864 B<Module::AutoInstall> lets module writers to specify a more
865 sophisticated form of dependency information than the C<PREREQ_PM>
866 option offered by B<ExtUtils::MakeMaker>.
867
868 This module works best with the B<Module::Install> framework,
869 a drop-in replacement for MakeMaker.  However, this module also
870 supports F<Makefile.PL> files based on MakeMaker; see L</EXAMPLES>
871 for instructions.
872
873 =head2 Prerequisites and Features
874
875 Prerequisites are grouped into B<features>, and the user could choose
876 yes/no on each one's dependencies; the module writer may also supply a
877 boolean value via C<-default> to specify the default choice.
878
879 The B<Core Features> marked by the name C<-core> will double-check with
880 the user, if the user chooses not to install the mandatory modules.
881 This differs from the pre-0.26 'silent install' behaviour.
882
883 Starting from version 0.27, if C<-core> is set to the string C<all>
884 (case-insensitive), every feature will be considered mandatory.
885
886 The dependencies are expressed as pairs of C<Module> => C<version>
887 inside an array reference.  If the order does not matter, and there
888 are no C<-default>, C<-tests> or C<-skiptests> directives for that
889 feature, you may also use a hash reference.
890
891 =head2 The Installation Process
892
893 Once B<Module::AutoInstall> has determined which module(s) are needed,
894 it checks whether it's running under the B<CPAN> shell and should
895 therefore let B<CPAN> handle the dependency.
896
897 Finally, the C<WriteMakefile()> is overridden to perform some additional
898 checks, as well as skips tests associated with disabled features by the
899 C<-tests> option.
900
901 The actual installation happens at the end of the C<make config> target;
902 both C<make test> and C<make install> will trigger the installation of
903 required modules.
904
905 If it's not running under B<CPAN>, the installer will probe for an
906 active connection by trying to resolve the domain C<cpan.org>, and check
907 for the user's permission to use B<CPAN>.  If all went well, a separate
908     B<CPAN> instance is created to install the required modules.
909
910 If you have the B<CPANPLUS> package installed in your system, it is
911 preferred by default over B<CPAN>; it also accepts some extra options
912 (e.g. C<-target =E<gt> 'skiptest', -skiptest =E<gt> 1> to skip testing).
913
914 All modules scheduled to be installed will be deleted from C<%INC>
915 first, so B<ExtUtils::MakeMaker> will check the newly installed modules.
916
917 Additionally, you could use the C<make installdeps> target to install
918 the modules, and the C<make checkdeps> target to check dependencies
919 without actually installing them; the C<perl Makefile.PL --checkdeps>
920 command has an equivalent effect.
921
922 If the F<Makefile.PL> itself needs to use an independent module (e.g.
923 B<Acme::KillarApp>, v1.21 or greater), then use something like below:
924
925     BEGIN {
926         require Module::AutoInstall;
927         # the first argument is an arrayref of the -config flags
928         Module::AutoInstall->install([], 'Acme::KillerApp' => 1.21);
929     }
930     use Acme::KillerApp 1.21;
931
932     Module::AutoInstall->import(
933         # ... arguments as usual ...
934     );
935
936 Note the version test in the use clause; if you are so close to the
937 cutting edge that B<Acme::KillerApp> 1.20 is the latest version on CPAN,
938 this will prevent your module from going awry.
939
940 =head2 User-Defined Hooks
941
942 User-defined I<pre-installation> and I<post-installation> hooks are
943 available via C<MY::preinstall> and C<MY::postinstall> subroutines,
944 as shown below:
945
946     # pre-install handler; takes $module_name and $version
947     sub MY::preinstall  { return 1; } # return false to skip install
948
949     # post-install handler; takes $module_name, $version, $success
950     sub MY::postinstall { return; }   # the return value doesn't matter
951
952 Note that since B<Module::AutoInstall> performs installation at the
953 time of C<use> (i.e. before perl parses the remainder of
954 F<Makefile.PL>), you have to declare those two handlers I<before> the
955 C<use> statement for them to take effect.
956
957 If the user did not choose to install a module or it already exists on
958 the system, neither of the handlers is invoked.  Both handlers are invoked
959 exactly once for each module when installation is attempted.
960
961 C<MY::preinstall> takes two arguments, C<$module_name> and C<$version>;
962 if it returns a false value, installation for that module will be
963 skipped, and C<MY::postinstall> won't be called at all.
964
965 C<MY::postinstall> takes three arguments, C<$module_name>, C<$version>
966 and C<$success>.  The last one denotes whether the installation
967 succeeded or not: C<1> means installation completed successfully, C<0>
968 means failure during install, and C<undef> means that the installation
969 was not attempted at all, possibly due to connection problems, or that
970 module does not exist on CPAN at all.
971
972 =head2 Customized C<MY::postamble>
973
974 Starting from version 0.43, B<Module::AutoInstall> supports modules
975 that require a C<MY::postamble> subroutine in their F<Makefile.PL>.
976 The user-defined C<MY::postamble>, if present, is responsible for
977 calling C<Module::AutoInstall::postamble> and include the output in
978 its return value.
979
980 For example, the B<DBD::*> (database driver) modules for the Perl DBI
981 are required to include the postamble generated by the function
982 C<dbd_postamble>, so their F<Makefile.PL> may contain lines like this:
983
984     sub MY::postamble {
985         return &Module::AutoInstall::postamble . &dbd_postamble;
986     }
987
988 Note that the B<Module::AutoInstall> module does not export the
989 C<postamble> function, so the name should always be fully qualified.
990
991 =head1 CAVEATS
992
993 B<Module::AutoInstall> will add C<UNINST=1> to your B<make install>
994 flags if your effective uid is 0 (root), unless you explicitly disable
995 it by setting B<CPAN>'s C<make_install_arg> configuration option (or the
996 C<makeflags> option of B<CPANPLUS>) to include C<UNINST=0>.  This I<may>
997 cause dependency problems if you are using a fine-tuned directory
998 structure for your site.  Please consult L<CPAN/FAQ> for an explanation
999 in detail.
1000
1001 If either B<version> or B<Sort::Versions> is available, they will be
1002 used to compare the required version with the existing module's version
1003 and the CPAN module's.  Otherwise it silently falls back to use I<cmp>.
1004 This may cause inconsistent behaviours in pathetic situations.
1005
1006 =head1 ENVIRONMENT
1007
1008 B<Module::AutoInstall> uses a single environment variable,
1009 C<PERL_AUTOINSTALL>.  It is taken as the command line argument
1010 passed to F<Makefile.PL>; you could set it to C<--alldeps>, C<--defaultdeps>
1011 or C<--skipdeps> to avoid all interactive behaviour.
1012
1013 C<--alldeps> will install all features, while
1014 C<--defaultdeps> will only install features for which the default answer is
1015 'y'.
1016
1017 C<--skipdeps> will refrain from loading L<CPAN> and not install anything, unless
1018 you're running under L<CPAN> or L<CPANPLUS>, in which case required dependencies
1019 will be installed.
1020
1021 It also read from the C<PERL_EXTUTILS_AUTOINSTALL> environment variable if
1022 C<PERL_AUTOINSTALL> is not defined.
1023
1024 =head1 SEE ALSO
1025
1026 L<Module::Install>
1027
1028 L<perlmodlib>, L<ExtUtils::MakeMaker>, L<Sort::Versions>, L<CPAN>,
1029 L<CPANPLUS>
1030
1031 =head1 AUTHORS
1032
1033 Audrey Tang E<lt>autrijus@autrijus.orgE<gt>
1034
1035 Adam Kennedy E<lt>adamk@cpan.orgE<gt>
1036
1037 Matt S Trout E<lt>mst@shadowcat.co.uE<gt>
1038
1039 =head1 IF THIS BREAKS
1040
1041 Report a ticket to bugs-Module-Install <at> rt.cpan.org and cc Matt
1042 - I appear to have volunteered as primary maintainer for this stuff so
1043 if you run into any problems please tell me
1044
1045 =head1 COPYRIGHT
1046
1047 Copyright 2001, 2002, 2003, 2004, 2005, 2006 by Audrey Tang
1048
1049 Some parts copyright 2006 Adam Kennedy
1050
1051 This program is free software; you can redistribute it and/or
1052 modify it under the same terms as Perl itself.
1053
1054 See L<http://www.perl.com/perl/misc/Artistic.html>
1055
1056 =cut