Fixing prereqs in dist.ini automatically

This post is relevant to CPAN authors who use Dist::Zilla as their building tool.

Unless you’re using a plugin like DZP:DynamicPrereqs, you’ll be listing prerequisites manually in dist.ini in the [Prereqs/*] sections.

By default, dzil doesn’t check that the prereqs you specify in dist.ini are actually used in the code. So you might potentially put extraneous prereqs: prereqs that are not actually used by your distribution. Or missing prereqs: prereqs that are needed but not yet listed.

I’ve written a script called lint-prereqs (installable via cpanm -n App::LintPrereqs) to check this (I guess I should also provide a dzil plugin version, maybe later). Just run the script in your top-level distribution directory and it’ll report something like:

% lint-prereqs
+------------+-------+---------+---------------------------------+------------------------------------------------------------------+
| module     | req_v | is_core | error                           | remedy                                                           |
+------------+-------+---------+---------------------------------+------------------------------------------------------------------+
| strict     | 0     | 1       | Used but not listed in dist.ini | Put 'strict=0' in dist.ini (e.g. in [Prereqs/RuntimeRequires])   |
| warnings   | 0     | 1       | Used but not listed in dist.ini | Put 'warnings=0' in dist.ini (e.g. in [Prereqs/RuntimeRequires]) |
| Test::More | 0     | 1       | Used but not listed in dist.ini | Put 'Test::More=0' in dist.ini (e.g. in [Prereqs/TestRequires])  |
+------------+-------+---------+---------------------------------+------------------------------------------------------------------+

In addition to extraneous/missing prereqs, lint-prereqs can also check mismatching prereq version: different version is being specified in the source code vs in dist.ini (for example, in your source code you specify use Test::More 0.98; but in dist.ini you put under [Prereqs/TestRequires] the line Test::More=0.96.

lint-prereqs can also check misplaced prereq phase: modules that are only used in tests (under t/ or xt/) but put under [Prereqs/RuntimeRequires], or vice versa modules that are used for runtime (under lib/ or bin/) but put under [Prereqs/TestRequires].

Up until recently I’ve skipped specifying core modules from dist.ini, but now I’m listing all prerequisites, be them core or not. As I maintain hundreds of dists, this requires editing hundreds of dist.ini files, putting in lines like strict=0 or warnings=0. Over the course of a few weeks I’ve run through about 200-300 of them, but boy that got old quickly. So Perl again to the rescue…

As of version 0.39, lint-prereqs sports a --fix option to try to automatically fix the prereq errors. It can add/remove/move the prereqs in dist.ini. But not all types of errors can be fixed. For example, if there is a version mismatch between the one specified in the source code vs in dist.ini, lint-prereqs will let you decide which one is actually correct and which should be corrected.

Let’s see this in action:

% lint-prereqs --fix
pdrutil: Added prereq 'strict=0' to section [Prereqs]
pdrutil: Added prereq 'warnings=0' to section [Prereqs]
pdrutil: Added prereq 'Test::More=0' to section [Prereqs / TestRequires]
pdrutil: Sorted prereqs
+------------+-------+---------+---------------------------------+--------------------------------------------------------------------------+
| module     | req_v | is_core | error                           | remedy                                                                   |
+------------+-------+---------+---------------------------------+--------------------------------------------------------------------------+
| strict     | 0     | 1       | Used but not listed in dist.ini | Put 'strict=0' in dist.ini (e.g. in [Prereqs/RuntimeRequires]) (fixed)   |
| warnings   | 0     | 1       | Used but not listed in dist.ini | Put 'warnings=0' in dist.ini (e.g. in [Prereqs/RuntimeRequires]) (fixed) |
| Test::More | 0     | 1       | Used but not listed in dist.ini | Put 'Test::More=0' in dist.ini (e.g. in [Prereqs/TestRequires]) (fixed)  |
+------------+-------+---------+---------------------------------+--------------------------------------------------------------------------+

As a bonus, because the configuration is in INI format, and Config::IOD is used to modify the .ini file, all comments and formatting are left intact after the script’s modification (although I do add a final sorting step to keep the prereqs nicely ordered).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s