Prerequisite Plugins
A big part of Dist::Zilla's job is to create installer programs that install
your modules on other machines. A big part of the installer's job is to ensure
that your module has the modules it needs to work on the machine it's getting
installed to. The modules your module relies on are called prerequisites or
dependencies. We need a way to tell the installer about these prerequisites.
This is the job of the prerequisite plugins that we introduce in this tutorial.
As we saw, the [@Starter] module provides the [Test::ReportPrereqs] plugin
to test and report whether a machine has all the necessary modules to install,
test, configure and execute your module. However, this report is incomplete. By
default, the report only includes modules that the plugins need to function but
it doesn't know anything about your module's prerequisites. For example, the
[MakeMaker] plugin adds a module requirement for the ExtUtils::MakeMaker
module to the report but the report says nothing about the Greetings module
your module needs to work.
We use the prerequisite plugins to tell Dist::Zilla about our module's
dependencies. It uses the information from these plugins to make the appropriate
modifications to the dstribution's installer (usually Makefile.PL) and META
files.
The [Prereqs] Plugin
With the [Prereqs] plugin, you manullay tell [Dist::Zilla] what your
module's dependencies are by giving it a list of prequisites in the dist.ini
file as a simple list of key value pairs. The name of the prerequisite is the
key and the minimum version number for the prerequisite is the value. With this
in mind, add these two lines to the dist.ini file in your App::sayhi work
area:
[Prereqs]
Greetings = 0.002
If you don't care what version of a module is used, set the value to 0. But you
may recall we created two versions of the Greetings module, the second one
provided our hw_shout function which we need. So we set our version to 0.002
to make sure that function is available. Now let's check our
[Test::ReportPrereqs] report:
dzil test
You'll now see a new section in the report:
# === Runtime Requires ===
#
# Module Want Have
# --------- ----- -----
# Greetings 0.002 undef
You'll also see this warning at the end of the report:
# *** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***
#
# The following REQUIRED prerequisites were not satisfied:
#
# Greetings version 'undef' is not in required range '0.002'
Zilla monster is grumbling. What's wrong? The problem is that Dist::Zilla has
no way of determining what version our Greetings module is. But wait, didn't
we add the version in the dist.ini file in Greetings? We did, this is true,
but that version number does not make its way into our actual distribution and
that's why it is reported as "undefined." The version number was used by
Dist::Zilla to generate the name of distribution's directory and the related
tarball but that's it.
So how do we give the Greetings the ability to tell the world about its
version? We need to go back and improve how our Greetings module handles
versioning.
Setting Your Module's Distribution Version
You can set the Greetings distribution version by adding the following line
directly into the lib/Greetings.pm file just below the package Greetings
line:
our $VERSION = '0.002';
After you make the change, install this version of the Greetings module:
dzil install
Now move over to App::sayhi to check our prerequisite report:
dzil test
Zilla monster is doing a happy dance for us again and the report tells us the
prerequisite for the Greetings module is satisfied.
OK, but now you're unhappy because you are stuck having to change the version
number in two different places: dist.ini and the module. We will address this
issue in a future tutorial.
There is a bit more to the [Prereqs] module. For example, you can report other
details like whether the dependency is needed for testing only or it's a hard
and fast prerequisite or only a recommendation. We don't need to concern
ourselves about that now.
The [AutoPrereqs] Plugin
An alternative approach to manually adding prerequisites with the [Prereqs]
plugin is to use the [AutoPrereqs] plugin which will scan your module's code
and attempt to determine your module's dependencies. Modify your dist.ini file
by removing the parameter to the [Prereqs] plugin and replace the [Prereqs]
plugin name with [AutoPrereqs]. Run:
dzil test
Look at the Runtime Requires section of the prerequisite report now:
# === Runtime Requires ===
#
# Module Want Have
# ---------------- ---- -----
# App::Cmd::Simple any 0.331
# Greetings any 0.002
# base any 2.23
# strict any 1.11
# warnings any 1.36
Cool. Not only has our Greetings prerequisite been found, it also identified
that we need App::Cmd::Simple and some other modules as well.
What's not so cool is that it says "any" version of the Greetings module will
do but this isn't the case. How do we fix that? We simply add the [Prereqs]
plugin back into the dist.ini file:
[Prereqs]
Greetings = 0.002
And now we have the best of both worlds.
A word of caution, however. Using [AutoPrereqs] may have some downsides. For
example, it my start falsely identify modules in your test library as
prerequisites when they really aren't. And developers with more complicated
dependency needs may have an easier time managing their dependencies without
[AutoPrereqs] plugin. However, for simpler modules, using [AutoPrereqs] will
not usually present a problem.
The [Prereqs::FromCPANfile] Plugin
The last plugin commonly used to generate the prerequisites is the
[Prereqs::FromCPANFile]. As you can probably guess by the name, this plugin
reads the CPANfile that may accompany your module. If you aren't using a
CPANfile with your module, this plugin is not for you.
You can learn more about what a CPANfile is by reading it's documentation.