Converting to Dist::Zilla
I’ve converted a number of distributions from $something to Dist::Zilla for release management, and every time I forget something … so this time I’m making notes as I go along.
Worst case, future-me will thank present-me (or will that be past-me?)
What follows is the transition for WebService::NotifyMyAndroid. It might have a couple of places where common sense needs to be applied, but it’s ‘good enough’.
Prerequisites
I’m assuming you’ve already got a perl distribution and that you’re managing it with git.
I’m also asssuming you already have Dist::Zilla installed.
Custom dist.ini
My distributions are minted using this file as a template for dist.ini.
Let’s Go!
Just to be safe we’ll work from anew branch based on our current master:
git checkout master
git pull --rebase
git co -b dzil master
Now we’re ready to rock and roll!
Create our dist.ini
I’m ‘lazy’ and don’t like to write mine by hand, so I’ll let Dist::Zilla do the work for me:
dzil new WebService::NotifyMyAndroid
mv WebService-NotifyMyAndroid/dist.ini .
rm -rf WebService-NotifyMyAndroid/
git add dist.ini
If you don’t already have it, it’s worth adding
[AutoPrereqs]
to your dist.ini.
Make the build process happy
To make ‘CheckChangesHasContent’ happy add the following before the most recent release:
{{$NEXT}}
Convert to Dist::Zilla
then add it to the staged area:
git add Changes
Cleanup some files
Get rid of the files that we used to manage ourselves manually:
dzil build --notgz 2>&1 |grep 'multiple times' |cut -d' ' -f 5
If you don’t get any output at all it’s worth re-running without the piped-cut to make sure it didn’t abort the build earlier than expected.
The output should look something like this:
MANIFEST
META.yml
README
Makefile.PL
Checking the files, all the files, bar README, are autogenerated. Looking at the README we decide we’d like to keep this file, but under a different name:
git mv README README.install
Then remove the other files:
for f in $( \
dzil build --notgz 2>&1 \
|grep 'multiple times' \
|cut -d' ' -f 5 \
); do
# make sure we don't git manage them
git rm -f $f;
# make sure they aren't artifacts form previous builds
rm -f $f;
done;
We also no longer need these files:
rm -rf blib/ _build/
git rm Build.PL
rm -rf blib/ _build/ Build
Nor do we want any META files hanging around:
for f in MANIFEST* *META*; do
git rm -f $f 2>/dev/null; \
rm -f $f; \
done
Dist::Zilla generates build directories and files based on our dist name; let’s ignore them:
echo '/WebService-NotifyMyAndroid*tar.gz' >> .gitignore
echo '/WebService-NotifyMyAndroid*/' >> .gitignore
echo '/.build/' >> .gitignore
git add .gitignore
Deal with versioning
Anywhere we’ve manually specified $VERSION we should simple remove it:
# remove manual version setting in thse files
vim $(/bin/grep -rl 'our $VERSION' lib/)
# git status
# git add <files we edited>
Add missing abstracts
To list files with missing abstracts simple do he following:
dzil build --notgz |grep "couldn't find abstract" |cut -d' ' -f 7
You should edit these manually and add an appropriate:
# ABSTRACT: <one line abstract>
line to each of the files. I prefer to put my comment at the end of the file (but before the END marker:
1;# Magic true value required at end of module
# ABSTRACT: Perl interface to Notify My Android web API
__END__
Don’t forget to ‘git add’ any files you’ve edited.
Cleanup POD
Assuming you also use the PodWeaver plugin, you should work through all the perl and POD files in your distribution to make the following alterations:
Module NAME and abstract line
No need to add the NAME section:
=head1 NAME
WebService::NotifyMyAndroid - Perl interface to Notify My Android web API
Version numbers in POD
No need to manually specify and update the VERSION block:
=head1 VERSION
This document describes WebService::NotifyMyAndroid version 0.0.3.
Licence and Copyright
This is added automatically, so you can remove any of these sections
Authors and Contributors
In lieu of a ‘Contributor plugin’ you may wish to promote your contributors to authors - otherwise you end up with them in different parts of the woven POD.
Make sure you specify your authors in dist.ini:
author = Steve Huff <shuff@cpan.org>
author = Chisel <chisel@chizography.net>
and remove any ‘AUTHOR’ and ‘CONTRIBUTOR’ sections in your POD.
Custom step
I did this just for this distro, just to cleanup:
git rm README.mkd
Commit And Push
We’re in the final stages now; time to push our work to our remote to keep it safe:
git commit -m 'Convert dist to use Dist::Zilla'
git push -u origin master
Test a release candidate
From my experience, you’ll always miss something obvious, or silly when converting to Dist::Zilla, so it’s probably best to release a developer release of the module until there’s enough feedback from CPAN Testers for us to fix everything, or decide it’s good enought to release to the world:
dzil clean && \
V=0.0.5_01 dzil release
Keep Testing
If you’re anything like me, you’ll miss a few things on your first release, no matter how careful you are. You’ll also probably find you get failures for unexpected and surprising reasons.
Don’t despair, just chip away at the niggles until you have a developer release that shows as a pass for all (or near enough) reports on CPAN Testers.
Hi
Is it just me, or does this seem like a hell of a lot of work!?
To convert from "manually manage everything about every release, every time" to a setup where I can just type "dzil release" and have numerous things happen automatically? Yes, there are a few things that need to happen to get to the good place.
I'm not using the "stock" dist.ini (link near the start) so I have extra features to prepare for.
If you reread the actual work needed, and skip over the explanation around it, you should hopefully see that there isn't really all that much going on:
- clean-up files dzil will manage for us
- make git ignore a few files
- deal with missing metadata
- test for silly omissions
You can reduce the amount of work you need to do to use dzil by using a cut down list of plugins but for me this is a good set that gives me some useful things, automatically, every release. More importantly, I get these things done for me and I'm producing high quality distro fastballs without the post release cycle of "oops, forgot to update Changes", "oops forgot to manually update the version number in one package", and other corrections I used to make but can no longer remember.
By all means just run "dzil new My::Module" with a stock profile, and you've got something you can use and release with - but this isn't leveraging the true power of Dist::Zilla in my opinion.
I'm sure it goes to each person's preference. I have moved away from dzil back to M::B. Yes every now and again I do "oops". dzil is great when what you want to do and what it wants to do line up. When that doesn't happen its easier to just do it yourself IMO.
My biggest grip about dzil isn't so much in itself but its users. Any time I want to hack on a project, and that project uses some giant "convenience" bundle that that author prefers (but only uses a tiny fraction), I end up either installing half of CPAN or sending untested patches (sadly, usually the latter).
Between podselect, perl-reversion, mojo cpanify and if (rarely) needed M::B subclasses, I can do just about everything dzil can.
Releasing to CPAN can and should be a very individual process, I liked brian's take on this a while back: https://blogs.perl.org/users/brian_d_foy/2012/08/should-my-perl-release-process-be-yours.html
@joel I like my take, which is basically, build branches... you can apply patches to that, just please don't try to modify files dzil generated (people seem to like doing that, I wish dzil added "generated" comments ). On the few occasions of patches I haven't had problems applying them because git is smart, and a cherry-pick tends to just work.
At first, yes. But for the next distributions it becomes very quick and easy. I usually spend 1-2 minutes preparing a dist. Just copy dist.ini from an existing dist, modify a few lines, then type 'dzil build'. Your dist will be ready in several seconds.
I'm not saying dzil is perfect or even one of my favorite software, but a distribution builder tool helps a lot.
I should also point out that one of the things that I most certainly need to do in dzil is setting up so that the line numbers do not change between the original source code and the one in the dist built by dzil. So:
1. Put all your POD at the bottom of source code.
2. Put your #ABSTRACT at the bottom of source code.
3. Replace PkgVersion with OurPkgVersion.
I don't like having dzil change my files as much as it does, either, which means I don't use any pod-changing plugins. The whole 'cleanup POD' section is something I would ignore.