Redesigning Package::Strictures

Package::Strictures on metacpan Design goals
  1. An infrastructure for having “optional” code blocks that can be eliminated prior to execution.
  2. Ideally, these code blocks can be toggled by calling code and then eliminated from the execution tree at the OP level.
  3. In essence, delegate 100% of the “Speed vs Correctness” concern to the consumer of the code, not the implementer.…

Musing on Perl::Critic config

I've been exploring the Perl::Critic configuration file somewhat, and something struck me as unusual.

It seems fine for using for the usecase of "inherit some predefined set of rules and apply them selectively", which works fine if you just want to adopt some other standard that is pre-existing, and just make minor adjustments.

However, if you're wanting to create policy sets for others to use, it seems poorly suited.

1. Existing Systems

1.1. Severity level/var/www/users/kentnl_kent_fredric/index.html

Please Ensure ABSTRACT and LICENSE fields in your META.yml/json

I've been opening quite a few bugs lately for distributions failing these 2 criteria, so, I figured I'd save everyone some effort and unify it cohesively.


While it may seem a trivial squabble, ABSTRACT and LICENSE components of your meta-data are reasonably important for communicating what your dist is to the world, for both human and automated consumers.

The ABSTRACT field manifests itself in quite a few places:

And the LICENSE field appears in a few places as well:

For me personally, these 2 fields are essential data which I have to use in downstream packaging ( Gentoo Ebuilds ), and having the fields correctly populated makes it much easier to automate packaging in a reliable way.

Licensing Options

What values you can use for a license descriptor depends somewhat on what toolchain you're using, and what level of the CPAN Meta Spec it supports.

Meta v1

The V1 metaspec has a rather short selection of licenses you can choose from.

These licenses are listed in the Module::Build::API:

  • apache - Apache License, Version 2.0.
  • apache_1_1 - Apache Software License, Version 1.1
  • artistic - Artistic License
  • artistic_2 - Artistic 2.0 License
  • bsd - BSD License
  • gpl - GNU General Public License
  • lgpl - GNU Lesser General Public License
  • mit - MIT License
  • mozilla - Mozilla Public License.
  • open_source - Some other Open Source Initiative-approved license listed at
  • perl - The same terms as Perl itself.User may choose between either the GPL or the Artistic license.
  • restrictive - The distribution may not be redistributed without special permission from the author and/or copyright holder.
  • unrestricted - The distribution is licensed under a license that is not approved by but that allows distribution without restrictions.

Meta v2

The Meta v2 Spec has a much wider and more accurate set of supported licenses, as well as the capacity to specify multiple licenses.

These licenses are for the most part documented in Software::License :

  • agpl_3 - GNU Affero General Public License, Version 3
  • apache_1_1 - The Apache Software License, Version 1.1
  • apache_2_0 - The Apache License, Version 2.0
  • artistic_1 - The Artistic License
  • artistic_2 - The Artistic License 2.0
  • bsd - The (three-clause) BSD License
  • unrestricted - the "public domain"-like CC0 license, version 1.0
  • freebsd - The FreeBSD License (aka two-clause BSD)
  • gfdl_1_2 - The GNU Free Documentation License v1.2
  • gfdl_1_3 - The GNU Free Documentation License v1.3
  • gpl_1 - GNU General Public License, Version 1
  • gpl_2 - GNU General Public License, Version 2
  • gpl_3 - GNU General Public License, Version 3
  • lgpl_2_1 - GNU Lesser General Public License, Version 2.1
  • lgpl_3_0 - GNU Lesser General Public License, Version 3
  • mit - The MIT (aka X11) License
  • mozilla_1_0 - Mozilla Public License 1.0
  • mozilla_1_1 - The Mozilla Public License 1.1
  • restricted - describes a "license" that gives no license for re-use
  • openssl - The OpenSSL License
  • perl_5 - The Perl 5 License (Artistic 1 & GPL 1)
  • open_source - Some other Open Source Initiative-approved license listed at
  • qpl_1_0 - The Q Public License, Version 1.0
  • ssleay - The Original SSLeay License
  • sun - Sun Internet Standards Source License (SISSL)
  • zlib - The zlib License

Specifying the metadata


ExtUtils::MakeMaker as far as I'm aware only officially supports Meta v1 license types.

[CORRECTION] But, it would appear, that, assuming you have a recent enough version of CPAN::Meta and ExtUtils::MakeMaker installed, you can specify either a v2-style license or a v1-style license. If you specify a v1 style license, CPAN::Meta will upconvert it before it emits META.json, and if you specify a v2 style license, that will go as-is in META.json and be downconverted to v1 style before going into META.yml. ( Make sure you read the section on the caveats later ).

Though, I'd advise using v2 style where possible, as you're less likely to lose intent in downconversion.

Setting Abstract and License can be done a variety of ways:

# Explictitly Set Abstract
ABSTRACT => 'A module that eats bees'

# Try get the abstract from a module

# Explicitly Set a v1 License
LICENSE => 'perl'

( )


Despite being mostly a wrapper of sorts for ExtUtils::MakeMaker, Module::Install provides some enhancement with ability to parse and extract metadata from existing files. But alas, it is still limited to the v1 license set.

# try determine license/abstract ( amongst other things ) from Foo::Bar
all_from 'lib/Foo/'

# explicitly specify the abstract
abstract 'Something that eats elephants'

# try determine abstract from a file
abstract_from 'lib/Mammoth/'

# explicitly define a v1 license
license 'perl'; 

# try determine license from a file
license_from 'lib/Great/'

( )


I personally like Module::Build better than the previous 2 modules, but everyone is free to disagree and have their personal preferences. And indeed, it would appear Module::Build versions greater than 0.3624 can specify version 2 license types by referring to the appropriate subclass of Software::License

    # Explicitly define abstract
    dist_abstract => 'Something that eats Cthulhus',

    # If not explicitly defined, MB looks for the same module it got the version from
    # and tries to get the abstract out of that

    # Explicitly set to use Software::License::GPL_2 
    license => 'GPL_2',
    #   v1 => gpl
    #   v2 => gpl_2


Dist::Zilla has in my opinion a much higher standard of metadata quality, and making Abstract and License available are practically a requirement of building a dist with it.

 ; dist.ini
 license = Perl_5

Determining the abstract is usually done automatically, and most prefer this approach. It does so by determining the "Main Module" ( usually the one with the shortest string length ), and then extracting the abstract from that.

This can be overridden via:

main_module = path/to/

And you can always define the abstract explicitly:

abstract = Dist::Zilla goes RAWR and BITES OFF CTHULHUS NOSES.

V1 Caveats

Unfortunately, there are some problems with all the toolchains that only understand v1 spec natively, and thats even when they do emit a META.json file, that file is upconverted from a v1 META.yml format, which yeilds a few difficulties.

Mostly, the license you specified in the configuration might not be the license that ends up in the V2 meta file, and likewise, might not be the value that gets displayed via MetaCPAN's API.

This is due to the inherent limitation of the initial license types.

V1 for example, only had gpl, not gpl_1 , gpl_2 and gpl_3, so when you upconvert gpl to a meta2 license type, it can't guess which one you meant, and instead, defaults to simply open_source. ( see more licenses upconversion issues )

And inversely, if you have a V2-only system, anything that downconverts META.json to v1 if it needs a v1 file( instead of doing the right thing and reading the META.yml, which is already in v1 format ) , will risk having the license type broken:

( Nice big list of the downconversions here: )

Anything that simultaneously sets v1 and v2 licenses by using Software::License should be fine however, its just the conversions between Meta versions that causes issues. But its still sadly something that needs to be taken into account till all parts of the toolchain and running on the v2 spec.