Creating new distributions with Dist::Zilla

You may already know that Dist::Zilla can create new boilerplate Perl distributions, just like Module::Starter (and other boilerplate generators).

$ dzil new My::Module

If you've ever tried this, you've seen that the built-in boilerplate is very, very minimal and you probably want to know how to customize it to fit your dzil style.

I wrote up the tutorial below and submitted it for consideration for dzil.org. If you use dzil, I hope you'll find it to be a useful step-by-step guide. Feedback is welcome, either in comments below or via my dzil.org branch on github. I also want to thank xenoterracide for writing "Creating new projects with dzil new and templates", which was a huge help to me in figuring out how this works. Several of the examples below were taken or adapted from his article.

Customizing the Minting Process

Dist::Zilla lets you create any number of "minting profiles" to create distributions with different default contents. You might have one for work and one for personal code; one for object-oriented code and one for functional code; or one for web applications and one for command-line applications, etc.

Preparation

For the tasks below you'll want to:

  • install Dist::Zilla, version 4.101780 or later
  • run "dzil setup"

The rest of this document assumes that you haven't already made a custom minting profile, meaning that you haven't got anything in ~/.dzil/profiles. If you have a default profile, just rename it if you want to follow the steps exactly as described below.

Create a default profile

Create a directory called ~/.dzil/profiles/default. This will hold your default minting profile, overriding the very simple default that ships with Dist::Zilla.

The first thing you want to do is change into that directory and create a profile.ini file with the following content:

[TemplateModule/:DefaultModuleMaker]
template = Module.pm

[GatherDir::Template]
root = skel
include_dotfiles = 1

The profile.ini file defines two components for minting your new distribution. The first one, TemplateModule, is given a special name :DefaultModuleMaker, to tell Dist::Zilla that this component will be used for creating the new module file. The template parameter tells it a file to use, so create a Module.pm file (in the same directory as profile.ini) with the following content:

use strict;
use warnings;
package {{$name}};

1;

The second component in profile.ini is GatherDir::Template, which specifies a directory of templates that will also be created in your new distribution. That is where you'll be putting your custom dist.ini, Changes or other files.

Create ~/.dzil/profiles/default/skel and change to that directory.

Next, create a dist.ini file with the following content:

{{
    $license = ref $dist->license;
    if ( $license =~ /^Software::License::(.+)$/ ) {
        $license = $1;
    } else {
        $license = "=$license";
    }

    $authors = join( "\n", map { "author  = $_" } @{$dist->authors} );
    $copyright_year = (localtime)[5] + 1900;
    '';
}}name    = {{$dist->name}}
{{$authors}}
license = {{$license}}
copyright_holder = {{$dist->copyright_holder}}
copyright_year   = {{$copyright_year}}

[@Basic]

Ignore all the gobbledy-gook at the top and notice the [@Basic] line. this will give you a dist.ini in your new directory that uses the @Basic plugin bundle. As you become more familiar with Dist::Zilla, this is where you'll want to add more plugins to customize what Dist::Zilla can do for you.

Change to your work directory and run dzil new My::Module. You should get a new distribution that is almost exactly like the original default included with Dist::Zilla, except that it has the addition of the @Basic plugin bundle in the new dist.ini file.

Now, all you have to do is customize the dist.ini and Module.pm files in minting profile to suit your own personal style.

Enhancing your minting profile

You can create other files in skel as well. For example, if you use git, you might want to create a starter .gitignore:

/{{$dist->name}}*
.build

Or, if you start using the NextRelease plugin, you probably want to have a Changes file that takes advantage of it:

Revision history for {{$dist->name}}

{{ '{{$NEXT}}' }}
    -

In the sample above, you can see the syntax for including template text inside a template, which might be useful for other skeleton files as well.

Setting up an alternate minting profile

The easiest way to set up an alternate profile is to copy your default profile to a new directory. For example, if you wanted to set up a profile that provided a Moose-specific starter module, you could create a copy like this:

$ cp -a ~/.dzil/profiles/default ~/.dzil/profiles/moose

Then, customize the ~/.dzil/profiles/moose/Module.pm file to load Moose and provide any boilerplate you like.

You can run dzil new with the -p flag to use the alternate profile:

$ dzil new -p moose My::Moose::Module
This entry was posted in dzil, perl programming and tagged , . Bookmark the permalink. Both comments and trackbacks are currently closed.

10 Comments

  1. Posted August 4, 2010 at 1:40 pm | Permalink

    someone needs to convince RJBS to add some convenience methods to Dist::Zilla to eliminate the "gobbledy-gook at the top"

  2. dagolden
    Posted August 8, 2010 at 10:45 pm | Permalink

    I have made that suggestion to him. Just as Dist::Zilla got easier to extend from version 1 to version 3 or so, I suspect minting profiles will get easier in the next several months.

  3. Posted August 10, 2010 at 1:35 am | Permalink

    Just a warning... the only thing you get to customize the Module.pm file - at least with the current version of DZ - is the $name. DZ::Plugin::TemplateModule does not pass in the $dist that other files can use (because DZP::GatherDir::Template DOES pass it in.) Just stubbed my toe on it.

  4. Posted August 10, 2010 at 7:38 am | Permalink

    Curtis is incorrect. The dist object is passed in as $zilla.

  5. Posted August 10, 2010 at 7:40 am | Permalink

    I seem to have misread my own code. Expect to see this fixed immediately.

  6. Ryan
    Posted August 19, 2010 at 4:44 am | Permalink

    The one problem I found with dzil's minting capabilities is that if you change your preferred dist.ini settings in the profile skeleton dir, these changes will not be reflected in already-created modules. To fix this, you can create a module that implements your config using Dist::Zilla::Role::PluginBundle::Easy, and then you can replace all the plugins in dist.ini with your one custom plugin bundle. This bundle will be used by all your new modules, and you can update the bundle whenever you like, and your updates will apply to all your old modules as well.

  7. Posted September 13, 2013 at 2:16 am | Permalink

    Could you pretty please add how to even release with dist zilla, and also possibly a github workflow.

    Like release should bump versions in the right place, and create should create a github repo.

    I'm seeing different dist zilla articles all over but each overlap and don't include something and every time it turns out a little bit of a mess.

    • Posted September 13, 2013 at 5:30 am | Permalink

      The best resource is really the tutorials on dzil.org. It will walk you through things step by step, including releasing.

      The reason dzil articles don't overlap is probably because different authors implement things slightly differently. For example, I don't generate a github repo because I already have other tools that do that for me.

      Bumping versions really depends on how you want to do it. The crudest to to use the AutoVersion plugin. I use the Git::NextVersion plugin (which I originally wrote) to bump based on the last git tag.

      • Posted September 13, 2013 at 6:12 am | Permalink

        Thanks for your reply. I did read almost all articles on dzil.org.

        To me it's a little overwhelming, there are just so many damn pieces and I have the obsessive need to know what all of it is doing.

        I also found author bundles like this:
        https://github.com/ollyg/Dist-Zilla-PluginBundle-Author-OLIVER

        This workflow mostly matches mine, I'd like to use it, but nowhere does he mention what I should do!? I've installed the cpan module, now what.

        What happens to my existing dist.ini under my default profile.

        • Posted September 13, 2013 at 9:13 am | Permalink

          There is a big learning curve, but once you're over it, you'll be amazed at what you can do.

          If you can get on IRC, the #dzil channel on irc.perl.org has a lot of very helpful people hanging out who can offer great advice for starting out.

© 2009-2014 David Golden All Rights Reserved