Module::Install extends not-typing lead over Module::Build

Alias on 2009-03-27T07:10:42

If you've been following this journal for a while, you might have noticed the main long term trend in my stewardship of Module::Install.

Because Module::Install has the great ability of being able to change without having to concern itself with back-compatibility, I've been able to gradually push it in a golfish direction, to reduce the number of characters I need to type towards zero, while improving the clarity of both the Makefile.PL and your code.

Much of this effort falls into the "_from" family of metadata commands. These commands encourage you to put your metadata into your main .pm file in a "standard" way. Rather than declare that information again, the Makefile.PL can suck it out of the canonical source.

To the current list of commands, I've added a new requires_from command which sucks your dependencies out of your code.

The tricky bit in this process is doing so without polluting everything because of use strict etc statements.

The requires_from command will look in your code for module loading statements with specific version requiresments and convert them into Module::Install "requires" commands.

For example: use strict; use Carp (); use File::Spec 0.80 ();

In the above example, the 'strict' and 'Carp' lines will be ignored, and a "requires 'File::Spec' => '0.80'" command will be issued.

One of the more annoying patterns I see (especially with my own code) is that people put "use File::Spec" in their module, and the only place the version for the dependency is defined is in the Makefile.PL.

Not only will requires_from mean less typing, it should encourage authors to crystalise their dependencies in the .pm modules, not just in the Makefile.PL.

This also has a couple of nice side-effects in that misbehaviour by the CPAN client will no longer be tolerated. If the CPAN client ignores your dependencies and tries to run the tests anyway, the movement of the versions to the .pm code will cause them to correctly fail on a missing dependency, rather than failing spuriously because of a specific bug in a module that is moot if the version isn't new enough.

In the same Module::Install 0.81 release, I've also rewritten the Module::Install Domain Specific Language, so that it doesn't require a second use line.

As a result, the two following examples are now equivalent.

Previous Makefile.PL use inc::Module::Install 0.79; use Module::Install::DSL;

all_from lib/My/Module.pm requires File::Spec 0.80 requires Config::Tiny 2.00 requires CSS::Tiny 1.10 requires Digest::MD5 2.33 requires Digest::SHA 5.34 requires Params::Util 0.35 test_requires Test::More 0.42


New Makefile.PL use inc::Module::Install::DSL 0.81;

all_from lib/My/Module.pm requires_from lib/My/Module.pm test_requires Test::More 0.42


The difference, of course, is particularly noticable for modules with large numbers of dependencies.

Taking a look at further typing reduction options, I'm considering rolling requires_from into all_from in a few releases from now, if the current version is well received.

Doing a test_requires_from may also be a good idea as well. It's all part of the general drive to make Module::Build looks embarrasingly ugly in comparison. :)


test_requires_from and dev-support test modules

MidLifeXis on 2009-03-27T10:26:50

Any thoughts on how you would support "optional", development support testing modules?

For example, in the documentation for Test::Pod::Coverage, it recommends putting the module requirements behind an eval and skip_all statement, so that you, as the developer, can ensure that your POD is covered, but the end user doesn't need to have the testing modules installed.

While I, as a developer may care that the documentation is complete, I, as an end user, do not.

There might be a better example than what I provided, but I think the idea is at least laid out.

--MLX

Re:test_requires_from and dev-support test modules

Alias on 2009-03-28T16:30:36

The best method is to also put it behind a RELEASE_TESTING (or at the least AUTOMATED_TESTING) environment check.

Here's the pod check test that I use, which as far as I'm aware encapsulates the current best practice.

#!/usr/bin/perl

# Test that the syntax of our POD documentation is valid

use strict;
BEGIN {
        $| = 1;
        $^W = 1;
}

my @MODULES = (
        'Pod::Simple 3.07',
        'Test::Pod 1.26',
);

# Don't run tests for installs
use Test::More;
unless ( $ENV{AUTOMATED_TESTING} or $ENV{RELEASE_TESTING} ) {
        plan( skip_all => "Author tests not required for installation" );
}

# Load the testing modules
foreach my $MODULE ( @MODULES ) {
        eval "use $MODULE";
        if ( $@ ) {
                $ENV{RELEASE_TESTING}
                ? die( "Failed to load required release-testing module $MODULE" )
                : plan( skip_all => "$MODULE not available for testing" );
        }
}

all_pod_files_ok();

Re:test_requires_from and dev-support test modules

Hinrik on 2009-03-28T22:21:33

Really? I would just use Module::Install::AuthorTests.

A suggestion: How about a Makefile.PL directive which causes Module::Install to do a requires_from on all .pm files in lib/, and perhaps a test_requires_from on all .t files in t/ ?