man ExtUtils::AutoInstall () - Automatic install of dependencies via CPAN

NAME

ExtUtils::AutoInstall - Automatic install of dependencies via CPAN

VERSION

This document describes version 0.61 of ExtUtils::AutoInstall, released October 19, 2004.

SYNOPSIS

In Makefile.PL, with Module::Install available on the author's system:

    use inc::Module::Install;

    name        ('Joe-Hacker');
    abstract    ('Perl Interface to Joe Hacker');
    author      ('Joe Hacker <joe@hacker.org>');
    include     ('ExtUtils::AutoInstall');

    requires    ('Module0');            # mandatory modules
    features    (
        -config         => {
            make_args   => '--hello',   # option(s) for CPAN::Config
            force       => 1,           # pseudo-option to force install
            do_once     => 1,           # skip previously failed modules
        },
        'Feature1' => [
            'Module2'   => '0.1',
        ],
        'Feature2' => [
            'Module3'   => '1.0',
        ],
    );
    auto_install();
    &WriteAll;

Invoking the resulting Makefile.PL:

    % perl Makefile.PL                  # interactive behaviour
    % perl Makefile.PL --defaultdeps    # accept default value on prompts
    % perl Makefile.PL --checkdeps      # check only, no Makefile produced
    % perl Makefile.PL --skipdeps       # ignores all dependencies
    % perl Makefile.PL --testonly       # don't write installation targets

Note that the trailing 'deps' of arguments may be omitted, too.

Using make (or nmake):

    % make [all|test|install]           # install dependencies first
    % make checkdeps                    # same as the --checkdeps above
    % make installdeps                  # install dependencies only

DESCRIPTION

ExtUtils::AutoInstall lets module writers to specify a more sophisticated form of dependency information than the CWPREREQ_PM option offered by ExtUtils::MakeMaker.

This module works best with the Module::Install framework, a drop-in replacement for MakeMaker. However, this module also supports Makefile.PL files based on MakeMaker; see EXAMPLES for instructions.

Prerequisites and Features

Prerequisites are grouped into features, and the user could choose yes/no on each one's dependencies; the module writer may also supply a boolean value via CW-default to specify the default choice.

The Core Features marked by the name CW-core will double-check with the user, if the user chooses not to install the mandatory modules. This differs from the pre-0.26 'silent install' behaviour.

Starting from version 0.27, if CW-core is set to the string CWall (case-insensitive), every feature will be considered mandatory.

The dependencies are expressed as pairs of CWModule => CWversion inside an array reference. If the order does not matter, and there are no CW-default, CW-tests or CW-skiptests directives for that feature, you may also use a hash reference.

The Installation Process

Once ExtUtils::AutoInstall has determined which module(s) are needed, it checks whether it's running under the CPAN shell and should therefore let CPAN handle the dependency.

Finally, the CWWriteMakefile() is overridden to perform some additional checks, as well as skips tests associated with disabled features by the CW-tests option.

The actual installation happens at the end of the CWmake config target; both CWmake test and CWmake install will trigger the installation of required modules.

If it's not running under CPAN, the installer will probe for an active connection by trying to resolve the domain CWcpan.org, and check for the user's permission to use CPAN. If all went well, a separate CPAN instance is created to install the required modules.

If you have the CPANPLUS package installed in your system, it is preferred by default over CPAN; it also accepts some extra options (e.g. CW-target => 'skiptest', -skiptest => 1 to skip testing).

All modules scheduled to be installed will be deleted from CW%INC first, so ExtUtils::MakeMaker will check the newly installed modules.

Additionally, you could use the CWmake installdeps target to install the modules, and the CWmake checkdeps target to check dependencies without actually installing them; the CWperl Makefile.PL --checkdeps command has an equivalent effect.

If the Makefile.PL itself needs to use an independent module (e.g. Acme::KillarApp, v1.21 or greater), then use something like below:

    BEGIN {
        require ExtUtils::AutoInstall;
        # the first argument is an arrayref of the -config flags
        ExtUtils::AutoInstall->install([], 'Acme::KillerApp' => 1.21);
    }
    use Acme::KillerApp 1.21;

    ExtUtils::AutoInstall->import(
        # ... arguments as usual ...
    );

Note the version test in the use clause; if you are so close to the cutting edge that Acme::KillerApp 1.20 is the latest version on CPAN, this will prevent your module from going awry.

User-Defined Hooks

User-defined pre-installation and post-installation hooks are available via CWMY::preinstall and CWMY::postinstall subroutines, as shown below:

    # pre-install handler; takes $module_name and $version
    sub MY::preinstall  { return 1; } # return false to skip install

    # post-install handler; takes $module_name, $version, $success
    sub MY::postinstall { return; }   # the return value doesn't matter

Note that since ExtUtils::AutoInstall performs installation at the time of CWuse (i.e. before perl parses the remainder of Makefile.PL), you have to declare those two handlers before the CWuse statement for them to take effect.

If the user did not choose to install a module or it already exists on the system, neither of the handlers is invoked. Both handlers are invoked exactly once for each module when installation is attempted.

CWMY::preinstall takes two arguments, CW$module_name and CW$version; if it returns a false value, installation for that module will be skipped, and CWMY::postinstall won't be called at all.

CWMY::postinstall takes three arguments, CW$module_name, CW$version and CW$success. The last one denotes whether the installation succeeded or not: CW1 means installation completed successfully, CW0 means failure during install, and CWundef means that the installation was not attempted at all, possibly due to connection problems, or that module does not exist on CPAN at all. Starting from version 0.43, ExtUtils::AutoInstall supports modules that require a CWMY::postamble subroutine in their Makefile.PL. The user-defined CWMY::postamble, if present, is responsible for calling CWExtUtils::AutoInstall::postamble and include the output in its return value.

For example, the DBD::* (database driver) modules for the Perl DBI are required to include the postamble generated by the function CWdbd_postamble, so their Makefile.PL may contain lines like this:

    sub MY::postamble {
        return &ExtUtils::AutoInstall::postamble . &dbd_postamble;
    }

Note that the ExtUtils::AutoInstall module does not export the CWpostamble function, so the name should always be fully qualified.

CAVEATS

ExtUtils::AutoInstall will add CWUNINST=1 to your make install flags if your effective uid is 0 (root), unless you explicitly disable it by setting CPAN's CWmake_install_arg configuration option (or the CWmakeflags option of CPANPLUS) to include CWUNINST=0. This may cause dependency problems if you are using a fine-tuned directory structure for your site. Please consult FAQ in CPAN for an explanation in detail.

If either version or Sort::Versions is available, they will be used to compare the required version with the existing module's version and the CPAN module's. Otherwise it silently falls back to use cmp. This may cause inconsistent behaviours in pathetic situations.

NOTES

Since this module is needed before writing Makefile, it makes little use as a CPAN module; hence each distribution must include it in full. The only alternative I'm aware of, namely prompting in Makefile.PL to force user install it (cf. the Template Toolkit's dependency on AppConfig) is not very desirable either.

The current compromise is to add the bootstrap code listed in the SYNOPSIS before every script, but that does not look pretty, and will not work without an Internet connection.

Since we do not want all future options of ExtUtils::AutoInstall to be painfully detected manually like above, this module provides a bootstrapping mechanism via the CW-version flag. If a newer version is needed by the Makefile.PL, it will go ahead to fetch a new version, reload it into memory, and pass the arguments forward.

If you have any suggestions, please let me know. Thanks.

ENVIRONMENT

ExtUtils::AutoInstall uses a single environment variable, CWPERL_EXTUTILS_AUTOINSTALL. It is taken as the command line argument passed to Makefile.PL; you could set it to either CW--defaultdeps or CW--skipdeps to avoid interactive behaviour.

EXAMPLES

Using MakeMaker with AutoInstall

To use this module with ExtUtils::MakeMaker, first make a inc/ExtUtils/ subdirectory in the directory containing your Makefile.PL, and put a copy this module under it as inc/ExtUtils/AutoInstall.pm. You can find out where this module has been installed by typing CWperldoc -l ExtUtils::AutoInstall in the command line.

Your Makefile.PL should look like this:

    # pull in ExtUtils/AutoInstall.pm from 'inc'
    use lib 'inc';
    use ExtUtils::AutoInstall (
        -core           => [            # mandatory modules
            'Module0'   => '',          # any version would suffice
        ],
        'Feature1'      => [
            # do we want to install this feature by default?
            -default    => ( system('feature1 --version') == 0 ),
            Module1     => '0.01',
        ],
        'Feature2'      => [
            # associate tests to be disabled if this feature is missing
            -tests      => [ <t/feature2*.t> ],
            # associate tests to be disabled if this feature is present
            -skiptests  => [ <t/nofeature2*.t> ],
            Module2     => '0.02',
        ],
        'Feature3'      => {            # hash reference works, too
            # force installation even if tests fail
            Module2     => '0.03',
        }
    );

    WriteMakefile(
        AUTHOR          => 'Joe Hacker <joe@hacker.org>',
        ABSTRACT        => 'Perl Interface to Joe Hacker',
        NAME            => 'Joe::Hacker',
        VERSION_FROM    => 'Hacker.pm',
        DISTNAME        => 'Joe-Hacker',
    );

Self-Download Code

If you do not wish to put a copy of ExtUtils::AutoInstall under inc/, and are confident that users will have internet access, you may replace the CWuse lib 'inc'; line with this block of code:

    # ExtUtils::AutoInstall Bootstrap Code, version 7.
    BEGIN{my$p='ExtUtils::AutoInstall';my$v=0.45;$p->VERSION||0>=$v
    or+eval"use $p $v;1"or+do{my$e=$ENV{PERL_EXTUTILS_AUTOINSTALL};
    (!defined($e)||$e!~m/--(?:default|skip|testonly)/and-t STDIN or
    eval"use ExtUtils::MakeMaker;WriteMakefile(PREREQ_PM=>{'$p',$v}
    );1"and exit)and print"==> $p $v required. Install it from CP".
    "AN? [Y/n] "and<STDIN>!~/^n/i and print"*** Installing $p\n"and
    do{if (eval '$>' and lc(`sudo -V`) =~ /version/){system('sudo',
    $^X,"-MCPANPLUS","-e","CPANPLUS::install $p");eval"use $p $v;1"
    ||system('sudo', $^X, "-MCPAN", "-e", "CPAN::install $p")}eval{
    require CPANPLUS;CPANPLUS::install$p};eval"use $p $v;1"or eval{
    require CPAN;CPAN::install$p};eval"use $p $v;1"||die"*** Please
    manually install $p $v from cpan.org first...\n"}}}

If the user did not have ExtUtils::AutoInstall installed, the block of code above will automatically download and install it.

However, due to its space-compressed (and obfuscated) nature, you should think twice before employing this block of code; it is usually much more desirable to just use Module::Install instead.

SEE ALSO

perlmodlib, ExtUtils::MakeMaker, Sort::Versions, CPAN, CPANPLUS, Module::Install

ACKNOWLEDGEMENTS

The test script included in the ExtUtils::AutoInstall distribution contains code adapted from Michael Schwern's Test::More under the Perl License. Please consult to t/AutoInstall.t for details.

See the AUTHORS file in this module's source distribution for the list of contributors.

AUTHORS

Autrijus Tang <autrijus@autrijus.org>

COPYRIGHT

Copyright 2001, 2002, 2003, 2004 by Autrijus Tang <autrijus@autrijus.org>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See <http://www.perl.com/perl/misc/Artistic.html>