Search Icon, Magnifying Glass

Marmanold.com

Graduation Cap Heart Question Mark Magnifying Glass

Perfect Perl Kwalitee

In the time since Date::Lectionary was added to CPAN, I’ve been working hard to get a perfect Kwalitee score and make a really solid distribution. Documentation on how to make a module are all over the place and I’ve yet to see a good, single article or post to explain how to do it. This is my attempt, I hope you find it useful.

Required Files

README

I like keeping my POD within the code of the module I’m developing and having the README file(s) automatically generated from that. Below is a simple shell script I’ve developed as part of my authoring process to generate well-formed readme files in Markdown, POD, and plaintext. Having all three formats means that GitHub and MetaCPAN both have what they need to render my README as best as possible.

PODMOD="$(grep "VERSION_FROM" Makefile.PL | cut -d "'" -f 2-2)"
perldoc -uT $PODMOD > README.pod
perldoc -o Markdown $PODMOD > README.md
pod2text README.pod > README

Changes

You’ll get dinged on Kwalitee if you don’t have a Changes file in your distribution. The documentation isn’t strongly opinionated on how you name the file, but Changes seems to be the expected standard as best as I can tell. The format of the document is pretty simple. It’s version plus the date in YYYY-MM-DD and then a simple list of changes below that.

Revision history for Date::Lectionary

1.20180313 2018-03-13

 - Switched from Try::Tiny to Try::Catch & Try::Tiny::Tiny

1.20180314 2018-03-14

 - Corrected issue with Manifest file
 - Corrected issue with tarball

INSTALL & LICENSE

Both the INSTALL and LICENSE files seem redudant if they are already part of your POD, but Kwalitee disagrees. Have these files and you’ll increase your score.

Enforcement

To enforce the highest Kwalitee standards upon yourself, you are going to need a few tests and several helper modules.

Go ahead and install the following modules:

cpanm Test::More Test::Pod Test::Pod::Coverage Test::MinimumVersion \
    Test::Kwalitee Test::Kwalitee::Extra Test::DistManifest \
    Test::CPAN::Changes Test::Version Test::GreaterVersion

Below I’ll discuss each test I run as part of my author tests and what it does. Be sure to include all your author tests under the xt directory rather than the t directory. To run your tests, prove -l xt/*.t seems to be the best method.

01-pod.t

This test validates that the POD you’ve included in your module is correct.

use strict;
use warnings;
use Test::More;
eval "use Test::Pod 1.51";
plan skip_all => "Test::Pod 1.51 required for testing POD" if $@;
all_pod_files_ok();

02-pod-coverage.t

This test ensures that all the modules in your distribution are covered with POD.

use strict;
use warnings;
use Test::More;
eval "use Test::Pod::Coverage 1.10";
plan skip_all => "Test::Pod::Coverage 1.10 required for testing POD coverage" if $@;
all_pod_coverage_ok();

03-minimum_perl_version.t

You’ll need to update the version below to the minimum verison of Perl you are wanting to support. This test ensures that the minimum verison you’ve given is actually correct. If you use functionality not supported by the minimum verison you’ve given, the test will fail.

use strict;
use warnings;
use Test::More;
eval "use Test::MinimumVersion 0.101082";
plan skip_all => "Test::MinimumVersion 0.101082 required to test minimum Perl version" if $@;
all_minimum_version_ok('5.22');

04-kwalitee.t

This is a biggie. This test ensures that you’re following all the mandatory Kwalitee requirements. You need to correct everything this test calls out if you want to have a distribution of reasonable quality.

use strict;
use warnings;
use Test::More;
eval "use Test::Kwalitee 1.27 qw(kwalitee_ok)";
plan skip_all => "Test::Kwalitee 1.27 required to test distribution Kwalitee" if $@;
kwalitee_ok();
done_testing;

05-kwalitee-extra.t

This is optional, but if you are looking for the best possible Kwalitee score you can get, this will take you there. I’m using the BSD 2-clause license which, for some reason, gives Test::Kwalitee::Extra some problems which is why you see that test has been excluded.

use strict;
use warnings;
use Test::More;
eval { require Test::Kwalitee::Extra; Test::Kwalitee::Extra->import(qw(:experimental !has_known_license_in_source_file)); };
plan( skip_all => "Test::Kwalitee::Extra not installed: $@; skipping") if $@;

06-manifest.t

This ensure not-only that you have a manifest file, but that everything in the manifest acutally exists and that you don’t have any files that should be in the manifest, but aren’t.

use strict;
use warnings;
use Test::More;
eval 'use Test::DistManifest';
if ($@) {
  plan skip_all => 'Test::DistManifest required to test MANIFEST';
}
 
manifest_ok();

07-changes.t

This will make sure you have a valid Changes file as part of your distribution.

use strict;
use warnings;
use Test::More;
eval 'use Test::CPAN::Changes';
plan skip_all => 'Test::CPAN::Changes required for this test' if $@;
changes_ok();

08-version.t

This validates that the versioning system you are using follows general best practices and will be understood by CPAN.

use strict;
use warnings;
use Test::More;
use Test::Version 1.001001 qw( version_all_ok ), {
    is_strict   => 0,
    has_version => 1,
    consistent  => 1,
  };
 
version_all_ok();
 
done_testing();

09-greater-version.t

This ensures that the version you are currently working on has a higher version number than what is recorded in CPAN. I always forget to bump my version numbers, so this is really important for me!

use strict;
use warnings;
use Test::More;
eval 'use Test::GreaterVersion';
plan skip_all => 'Test::GreaterVersion required for this test' if $@;
has_greater_version_than_cpan('Date::Lectionary');
done_testing();