A Simple dist.ini for Dist::Zilla
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
orMakefile
- Dist::Zilla::Plugin::ManifestSkip - If you have a
MANIFEST.SKIP
file, don't build files listed in it - Dist::Zilla::Plugin::MetaYAML - Build a
META.yml
file - Dist::Zilla::Plugin::License - create a LICENSE file
- Dist::Zilla::Plugin::Readme - create a README
- Dist::Zilla::Plugin::ExtraTests - rewrites your
xt/
tests tot/
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!)
I think instead of “
git status --porcelain | grep 'M Makefile.PL'
” you just want “git diff --quiet Makefile.PL
”.Also, the way you’ve written the command line, if the
grep
succeeds but thegit commit
exits non-zero, it will claim “Makefile.PL up to date” which it clearly wouldn’t be. Just write anif
/else
.Try this (untested):
Consider yourself frowned at for encouraging people to put code in their dist.ini files that isn't crossplatform. :(
Please at least update this article to replace the apostrophes in the AfterBuild stuff with quotes.