This is day 3 of the Perl-QA Hackathon in Lyon, France, and I decided it was time to fix some issues with the older dist.ini I was using. Erik Colson asked about my dist.ini, so I thought I should explain it here, along with comments.

The following dist.ini is designed to match my workflow, but also to make it easy for contributors to participate, thus mitigating one of the strongest complaints people have about Dist::Zilla. It's also rather git/github centric.

name = Test-Class-Moose author = Curtis "Ovid" Poe <ovid@cpan.org> license = Perl_5 copyright_holder = Curtis "Ovid" Poe copyright_year = 2014 version = 0.50 [AutoPrereqs] skip = Person skip = ^TestsFor [@Basic] [MetaJSON] [GithubMeta] issues = 1 user = Ovid [@Git] [PodWeaver] [CheckChangeLog] [PkgVersion] [Prereqs] perl = 5.010 [Prereqs / RuntimeRecommends] Sub::Attribute = 0.05 Parallel::ForkManager = 0.7.6 [ ReadmeAnyFromPod / MarkdownInRoot ] filename = README.md [Run::BeforeBuild] run = test -f Makefile.PL && rm Makefile.PL [Run::AfterBuild] run = cp %d/Makefile.PL ./ run = git status --porcelain | grep 'M Makefile.PL' && git commit -m 'auto-committed by dist.ini' Makefile.PL || echo Makefile.PL up to date

The top part should be self-explanatory:

name = Test-Class-Moose author = Curtis "Ovid" Poe <ovid@cpan.org> license = Perl_5 copyright_holder = Curtis "Ovid" Poe copyright_year = 2014 version = 0.50

The prerequisites listed in the Makefile.PL are generated here:

[AutoPrereqs] skip = Person skip = ^TestsFor

The skip section is to ensure that classes I've created in my tests aren't accidentally picked up as prereqs because they're bundled with the distribution.

The [@Basic] section is from Dist::Zilla::PluginBundle::Basic. This includes many utilities that make building your distribution easier, but doesn't alter your code. Without going into detail, it includes the following:

Dist::Zilla::Plugin::GatherDir - Gather all of the files in your distribution for a build

Dist::Zilla::Plugin::PruneCruft - Get rid of stuff you don't need in the build, such as blib or Makefile

or Dist::Zilla::Plugin::ManifestSkip - If you have a MANIFEST.SKIP file, don't build files listed in it

file, don't build files listed in it Dist::Zilla::Plugin::MetaYAML - Build a META.yml file

file Dist::Zilla::Plugin::License - create a LICENSE file

Dist::Zilla::Plugin::Readme - create a README

Dist::Zilla::Plugin::ExtraTests - rewrites your xt/ tests to t/ tests that are skipped if you're not the author

tests to tests that are skipped if you're not the author Dist::Zilla::Plugin::ExecDir - install scripts as executable

Dist::Zilla::Plugin::ShareDir - install a directory's contents as "ShareDir" content

Dist::Zilla::Plugin::MakeMaker - Create your Makefile.PL

Dist::Zilla::Plugin::Manifest - Create a MANIFEST

Dist::Zilla::Plugin::TestRelease - Test your distribution before releasing

Dist::Zilla::Plugin::ConfirmRelease - Ask before releasing

Dist::Zilla::Plugin::UploadToCPAN - Upload to the cpan (login credentials are usually stored in ~/.dzil/config.ini )

The [MetaJSON] creates a META.json file.

Then there's my github section:

[GithubMeta] issues = 1 user = Ovid

The issues = 1 lets CPAN use the github bugtracker rather than RT. The user section lets you define a canonical user. Otherwise, if you have several people hacking on your project, the github user listed may change.

The [@Git] section does a number of various things, including tagging your releases with the correct version number.

The [PodWeaver] builds a lot of POD for you, including adding license information, copyright information, and makes your POD easier to write.

[CheckChangeLog] won't let you release unless you've remembered to update your change log. I'm constantly forgetting to do that, so it's a big win for me.

[PkgVersion] automatically adds the version number to your files.

You can guess what this does:

[Prereqs] perl = 5.010

And this:

[Prereqs / RuntimeRecommends] Sub::Attribute = 0.05 Parallel::ForkManager = 0.7.6

This section creates a markdown version of README. That's useful for github to display your readme correctly.

[ ReadmeAnyFromPod / MarkdownInRoot ] filename = README.md

And here's the bit I'm adding now for Makefiles. This first bit checks to see if we have a Makefile.PL and deletes it if it exists to ensure that an old copy isn't copied to the build directory (you can also exclude it in GatherDir).

[Run::BeforeBuild] run = test -f Makefile.PL && rm Makefile.PL

And this is my first pass at creating the feature so many people want:

[Run::AfterBuild] run = cp %d/Makefile.PL ./ run = git status --porcelain | grep 'M Makefile.PL' && git commit -m 'auto-committed by dist.ini' Makefile.PL || echo Makefile.PL up to date

After the build is done, this copies the generated makefile into your directory and commits it if it's changed. This allows someone downloading your distribution to fall back to using the normal perl Makefile.PL incantation to install deps.

The downside of this technique is that if you install using this Makefile.PL, you'll get an installed module with no version number. David Golden mentioned that he was thinking about taking a swing at this problem later. Be sure to remind him about this :)

With the above workflow, contributors can use the Makefile.PL like normal, but dzil users can use their workflow, too. For me, I can run dzil build repeatedly to rebuild the distribution and just type dzil release when I'm ready to release it. It makes my life much, much simpler.

Many thanks to Ricardo Signes, Karen Etheridge, David Golden and several others at the Perl-QA hackathon for helping me figure out the best approach. Any errors are, of course, theirs (kidding!)