Dist::Zilla Likes Critic

Another test play date in the Dist-Pen today.

“The covers of this book are too far apart.”
― Ambrose Bierce

hmm criticism, of a fashion, but not much good to us in the Perl world, I much prefer;
“Criticism may not be agreeable, but it is necessary. It fulfills the same function as pain in the human body; it calls attention to the development of an unhealthy state of things. If it is heeded in time, danger may be averted; if it is suppressed, a fatal distemper may develop."

― Winston S. Churchill


take on what criticism is as it shows how it can help us in the Perl world. Now that leads me to introduce our very own resident and much respected critic 'Perl::Critic'. Over the years I have seen a few automated code-cleaners, review tools, call the what you will, but few work as well or have such a well grounded philosophy as our own Critic.

Dist::Zilla has a plug-in for that and all you need to do to use it is, first install 'Perl::Critic' and then install 'Dist::Zilla::Plugin::Test::Perl::Critic' once you have done that you need only add this;

...
[Test::Kwalitee]
++[Test::Perl::Critic]
[Git::Check]
to your '.ini' file. You will note here I moved the 'Test' plug-ins to be together, it is always good to keep like together. Now what the above will give you is a basic 'critic.t' test in your distribution. This file is generated when you build or release and you will find in in the 'xt/autor/' the output dir, and the '.tar' file.

 ls Database-Accessor-0.01/xt/author/
critic.t
Not much sense having a look in the file as it is only about seven or eight lines of code. To get the test to run use the same command from my last post

 dzil xtest
and now what happens is this

...
Building Database-Accessor
xt/author/critic.t ..... 1/?
#   Failed test 'Test::Perl::Critic for "blib/lib/Database/Accessor.pm"'
#   at /usr/local/share/perl/5.18.2/Test/Perl/Critic.pm line 104.
#
#   Code before strictures are enabled at line 1, column 1.  See page 429 of PBP.  (Severity: 5)
#   Expression form of "eval" at line 108, column 17.  See page 161 of PBP.  (Severity: 5)

# Failed test 'Test::Perl::Critic for "blib/lib/Database/Accessor/Constants.pm"'
# at /usr/local/share/perl/5.18.2/Test/Perl/Critic.pm line 104.
#
# Code before strictures are enabled at line 3, column 1. See page 429 of PBP. (Severity: 5)
xt/author/critic.t ..... 3/?
# Failed test 'Test::Perl::Critic for "blib/lib/Database/Accessor/Types.pm"'
# at /usr/local/share/perl/5.18.2/Test/Perl/Critic.pm line 104.
#
# Code before strictures are enabled at line 3, column 1. See page 429 of PBP. (Severity: 5)
xt/author/critic.t ..... Dubious, test returned 1 (wstat 256, 0x100)
Failed 3/3 subtests
xt/release/kwalitee.t .. ok

Test Summary Report ------------------- xt/author/critic.t (Wstat: 256 Tests: 3 Failed: 3) Failed tests: 1-3 Non-zero exit status: 1 Files=2, Tests=20, 5 wallclock secs ( 0.06 usr 0.01 sys + 4.80 cusr 0.18 csys = 5.05 CPU) Result: FAIL Failed xt tests left failed dist in place at .build/0TwgDfXUFC
Ok I have a few things to fix in my Perl but you also see that it also ran my 'xt/release/kwalitee.t ' test as well. At this point I do not mind that as it does not get in the way but I can stop this by calling xtest like this

 dzil xtest author
and it will only run the test cases in the 'xt/author' dir so I would get this
...
xt/author/critic.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 3/3 subtests

Test Summary Report
-------------------
xt/author/critic.t (Wstat: 256 Tests: 3 Failed: 3)
Failed tests: 1-3
Non-zero exit status: 1
Files=1, Tests=3, 3 wallclock secs ( 0.05 usr 0.00 sys + 2.88 cusr 0.11 csys = 3.04 CPU)
Result: FAIL
Failed xt tests


No kwalitee.t case run. Useful when you only want to look at a few test cases.

So I see that I have a few little things in there all severity 5 so no big problems. So far I have been using the default 'perlcritic.rc' I can change that with this plug-in. Lets boost up 'verbose' to the max by first adding a local '.rc' file with this in it

verbose = 11;
and then in my '.ini' I add in

[Test::Kwalitee]
[Test::Perl::Critic]
++critic_config = perlcritic.rc
[Git::Check]
which now points Perl::Critic to that config file and if I ran my tests it again I would get allot more info for example on the 'eval' error

#   Expression form of "eval" at line 108, near 'eval "require $classname";'.
#   BuiltinFunctions::ProhibitStringyEval (Severity: 5)
#     The string form of `eval' is recompiled every time it is executed,
#     whereas the block form is only compiled once. Also, the string form
#     doesn't give compile-time warnings.
#
#         eval "print $foo";        # not ok
#         eval {print $foo};        # ok
Normally one would not put an '.rc' profile in a distribution but you would use this attribute to point to where ever it happens to be on your system.

Now the first code fixes where easy as all I had to do in Accessor.pm was get rid of the first set of {} before my package statement and warp the eval on line 108 in {}.

When I reran again I got

#   Failed test 'Test::Perl::Critic for "blib/lib/Database/Accessor.pm"'
#   at /usr/local/share/perl/5.18.2/Test/Perl/Critic.pm line 104.
#
#   Code before strictures are enabled at line 5, near '$Database::Accessor::VERSION = '0.01';'.
#   TestingAndDebugging::RequireUseStrict (Severity: 5)
Opps! This is not right and what you are seeing here is a coflict between my [PkgVersion] plugin and the [Test::Perl::Critic] plugin. My present code is

    package Database::Accessor;
# Dist::Zilla: +PkgVersion

# ABSTRACT: CRUD Interface for any DB

use Moose; …
and what is happening is that 'PkgVersion' sticks a version statement right after the package statement so when Perl::Critic looks at the build file in the output dir it is now this;

  package Database::Accessor;
# Dist::Zilla: +PkgVersion
  $Database::Accessor::VERSION = '0.01';
# ABSTRACT: CRUD Interface for any DB

use Moose;


which is a violation of the perl critic rules as I need that 'use Moose' before that $VESRSION to pass.

Ahh the joys of automated code generation. If I want to keep that PkgVersion plugin I have a choice to make either I change my Perl::Critic not to fail with only 1 strictures test or add a use strict at the top of my files. Though messy I quickly added 'use strict' at the top of my packages and reran my test and I got

xt/author/critic.t .. ok
All tests successful.
Files=1, Tests=3,  3 wallclock secs ( 0.05 usr  0.00 sys +  2.79 cusr  0.13 csys =  2.97 CPU)
Result: PASS 
All in all not a bas days work but I really do not like this

    use strict;
     package Database::Accessor;
# Dist::Zilla: +PkgVersion

# ABSTRACT: CRUD Interface for any DB

use Moose;

in my code. I wonder if I can change the plug-in to stick the version under where it finds '# Dist::Zilla: +PkgVersion'??

mothar.jpg


Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations