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
6 Comments
someone needs to convince RJBS to add some convenience methods to Dist::Zilla to eliminate the "gobbledy-gook at the top"
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.
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.
Curtis is incorrect. The dist object is passed in as $zilla.
I seem to have misread my own code. Expect to see this fixed immediately.
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.