17

I have a Perl script that has two dependencies that exist in CPAN. What I'd like to do is have the script itself prompt the user to install the necessary dependencies so the script will run properly. If the user needs to enter in some kind of authentication to install the dependencies that's fine: what I'm trying to avoid is the following workflow:

Run script -> Watch it fail -> Scour CPAN aimlessly -> Lynch the script writer

Instead I'm hoping for something like:

Run script -> Auto-download script dependencies (authenticating as necessary) -> Script succeeds -> Buy the script writer a beer

Can this be done?

fbrereto
  • 35,429
  • 19
  • 126
  • 178
  • Yes. Unfortunately I forget how. – luqui Oct 05 '11 at 16:52
  • 4
    Even if this can be done, it is a bad idea. "Install" and "Run" are two different tasks, often performed by different users with different permissions. At most the script should check for dependencies and tell me how to install them... If I ever ran a script that tried that "atuomatically" I would want to lynch the author. – Nemo Oct 05 '11 at 17:12

2 Answers2

19

Each of the standard build paradigms has their own way of specifying dependencies. In all of these cases, the build process will attempt to install your dependencies, automatically in some contexts.

In ExtUtils::MakeMaker, you pass a hash reference in the PREREQ_PM field to WriteMakefile:

# Makefile.PL for My::Module
use ExtUtils::MakeMaker;

WriteMakefile (
    NAME => 'My::Module',
    AUTHOR => ...,
    ...,
    PREREQ_PM => {
        'Some::Dependency' => 0,             # any version
        'Some::Other::Dependency' => 0.42,   # at least version 0.42
        ...
    },
    ...
 );

In Module::Build, you pass a hashref to the build_requires field:

# Build.PL
use Module::Build;
...
my $builderclass = Module::Build->subclass( ... customizations ... );
my $builder = $builderclass->new(
    module_name => 'My::Module',
    ...,
    build_requires => {
        'Some::Dependency' => 0,
        'Some::Other::Dependency' => 0.42,
    },
    ...
);
$builderclass->create_build_script();

In Module::Install, you execute one or more requires commands before calling the command to write the Makefile:

# Makefile.PL
use inc::Module::Install;
...
requires 'Some::Dependency' => 0;
requires 'Some::Other::Dependency' => 0.42;
test_requires 'Test::More' => 0.89;
...
WriteAll;
mob
  • 117,087
  • 18
  • 149
  • 283
  • I agree, create an install file for your script that installs the dependencies, likely using one of these options. – AFresh1 Oct 06 '11 at 05:38
-2

You can probably just execute this from inside your script.

perl -MCPAN -e 'install MyModule::MyDepends'

Sean McCully
  • 1,122
  • 3
  • 12
  • 21
  • 1
    -1 not useful because of the [separation of permissions Nemo mentioned](http://stackoverflow.com/questions/7664829/can-a-perl-script-install-its-own-cpan-dependencies#comment-9314571). – daxim Oct 08 '11 at 13:53