dzil: modular distribution bundler without the peskynes.
I've been playing a bit with dzil,
partly because that kent\n critter mentioned it when I used module-starter in my TDD post,
and partly because have had another critter from Debian emailed me asking about rtpaste...
Since I'm sharing the code anyway, I figured I might as well make a dist of it...
Check your local cpan mirrors for App-rtpaste
By popular demand,
rtpaste is now on cpan.
cpan App::rtpaste
Packaging a script with dzil
From here, we're going to be exploring dzil, and showing how discoverable it is (mostly by playing with it, having only skimmed the docs)
~/_/ $: My prompt now includes the path, and a $, and ~/_ is my projects directory... I'm pretty sure I remember who I logged in as, and to which machine, so I don't show that...
First thing's first, we need to install Dist::Zilla, so we'll ask cpan to do that for us...
~ $ cpan Dist::Zilla <some time passes> ... Installing /usr/local/bin/dzil ... /usr/bin/make install -- OK
So we'll have a bit of a look at the docs...
~ $ perldoc Dist::Zilla ... If you have access to the web, you can learn more and find an interactive tutorial at dzil.org. If not, try Dist::Zilla::Tutorial. ...
I also recommend pestering some of the folks on irc.perl.org#distzilla
Let's see if we can bluff dzil into doing some stuff for me...
~/_/ $ dzil
Available commands:
commands: list the application's commands
help: display a command's help screen
authordeps: list your distribution's author dependencies
build: build your dist
clean: clean up after build, test, or install
install: install your dist
listdeps: print your distribution's prerequisites
new: mint a new dist
nop: do nothing: initialize dzil, then exit
release: release your dist
run: run stuff in a dir where your dist is built
setup: set up a basic global config file
smoke: smoke your dist
test: test your dist
Seems reasonable, I'm sure I'm reading either commands or help. (turns out that it's both!)
Since I've not used dzil before, I suppose setup is a good place to start...
~/_/ $ dzil setup What's your name? FOOLISH What's your email address? FOOLISH@cpan.org Who, by default, holds the copyright on your code? [FOOLISH]: What license will you use by default (Perl_5, BSD, etc.)? [Perl_5]: Do you want to enter your PAUSE account details? [y/N]: Y What is your PAUSE id? FOOLISH What is your PAUSE password? toosneaky config.ini file created!
let's see what we have here ... nothing new in $CWD, this is a Unix-like, so it might be in a dotfile in ~ somewhere...
~/_/ $ cat ~/.dzil/config.ini [%User] name = FOOLISH email = FOOLISH@cpan.org [%Rights] license_class = Perl_5 copyright_holder = FOOLISH [%PAUSE] username = FOOLISH password = toosneaky
Yep, those are definately the things I just told it... .ini seems an odd choice, but that's fine.
moving on, the help mentioned new: mint a new dist, so let's have a little of that....
~/_/ $ dzil new
Error: dzil new takes exactly one argument
Usage: dzil [-Iv] [long options...] <command>
-v --verbose log additional output
-I --lib-inc additional @INC dirs
dzil [-Pp] [long options...] <ModuleName>
-p --profile name of the profile to use
-P --provider name of the profile provider to use
fair enough... I guess... Let's give it a <ModuleName> and see what happens.
~/_/ $ dzil new App-rtpaste [DZ] making target dir /home/f00li5h/_/App-rtpaste [DZ] writing files to /home/f00li5h/_/App-rtpaste [DZ] dist minted in ./App-rtpaste
Oh, it's created some stuff!
~/_/ $ find App-rtpaste App-rtpaste/ App-rtpaste/dist.ini App-rtpaste/lib App-rtpaste/lib/App App-rtpaste/lib/App/rtpaste.pm
fair enough, well, that's good for modules, but I'm not shipping one, I'm just bundling up a script...
~/_/App-rtpaste/ $ rm -r lib
" $ mkdir bin/
" $ cp ~/crap-from-my-blog/rtpaste bin/
~/_/App-rtpaste/ $ ls ls bin
rtpaste
I'm sure I have to tell Dist::Zilla about these changes... let's see. so I'll add these bits to my dist.ini
main_module = bin/rtpaste
That seems a little bit silly, since it's not a module, but I'm sure it'll be ok.
I'll also add [AutoPrereqs] and [ExecDir] dir = bin to get things rolling giving me a dist.ini that looks a little bit like this
name = App-rtpaste author = FOOLISH <FOOLISH@cpan.org> license = Perl_5 copyright_holder = FOOLISH copyright_year = 2010 version = 0.0001 main_module = bin/rtpaste [ExecDir] dir = bin [AutoPrereqs] [FakeRelease] ;[@Basic] <- ; comments things in .ini [@Filter] -bundle = @Basic -remove = UploadToCPAN
plug-ins and bundles
dzil is all about plug-ins, you go about loading them by [PluginName]ing in dist.init.
[@Basic] in your dist.ini is talking about Dist::Zilla::PluginBundle::Basic, it includes a whole bundle of helpful things.
[@Basic] - a bundle of helpful things to get you started
This is put in here by dzil new, you might want to remove it, it might be changed in the future (since I complained bitterly about).
[AutoPrereqs] and [Prereqs] - plug-ins for pre-requites
Here I'm loading AutoPrereqs, which surprisingly enough figures out your depends for you so you don't have to list them with [Prereqs] by hand which you'd have to do with something like this:
[Prereqs] Foo::Bar = 1.002 MRO::Compat = 10 Sub::Exporter = 0
Just in case you've got some kind of late loading eval based craziness somewhere in your code.
let's see what dzil thinks about the whole thing... listdeps: print your distribution's prerequisites looks like a sensible way to see what dzil thinks about the whole thing...
~/_/App-rtpaste/ $ dzil listdeps App::Rad Data::Dumper Error ExtUtils::MakeMaker File::Basename File::Spec::Functions RT::Client::REST
It seems that dzil has picked up all the depends of rtpaste here, which is handy.
[ExecDir] - for installing scripts
[ExecDir] dir = bin
so this'll get everything in bin/ somewhere in $PATH at the other end.
[FatPacker] - bundle everything up into your scripts
This would be something handy to keep in mind if you want to bundle up all your depends and stuff them into your script, you can see an example of fatpackery at http://cpanmin.us/
[Plugin::Run] - which lets you run stuff around your dist-making
This one gives you [Run::BeforeRelease], [Run::Release] and [Run::AfterRelease] which let you do stuff to the archive generated by dist
[FakeRelease] and [UploadToCPAN] - share your stuff with the internet
Put it on the internet, or pretend to!
note that UploadToCPAN is in @Basic, that is, having [@Basic] and a [%PAUSE] section in your config, your crap is going on PAUSE
You can use an @Filter to remove UploadToCPAN (as above) or you can just not use @Basic... you will want it back when you're done playing with dzil ... so you can have it upload the dist for you
I know the pieces fit
... 'Cause I watched them tumble down. No fault, none to blame . -- tool.
The whole thing is made out of lots of tiny bits and pieces, that are loaded based on your ini, and then run in phases...
You can readily write your own Dist::Zilla::PluginBundle to include plug ins you commonly use for your own distributions, as well as writing your own Dist::Zilla::Plugin too...
Testing your distribution
Every sensible distribution includes tests, often many. You really should have some too. If you're not sure why, feel free to also read Perl based Test Driven Development, jfdi.
Release your code
At this point,
I figured it might be worth playing with dzl's release stuff...
release: release your dist looks like the option I want
[FakeRelease] will release your code to nowhere,
[UploadToCPAN] will upload your your code to PAUSE
Not that *every* plug in of each type is run,
this means that both [UploadToCPAN] *and* [FakeRelease] are both run...
that is to say,
dzil helpfully released my code to both nowhere,
and PAUSE,
and you'll get something like this:
~/_/App-rtpaste $ dzil release [DZ] beginning to build App-rtpaste [DZ] dist's main_module is bin/rtpaste [DZ] extracting distribution abstract from bin/rtpaste [DZ] writing App-rtpaste in App-rtpaste-0.0001 [DZ] writing archive to App-rtpaste-0.0001.tar.gz [@Basic/TestRelease] Extracting /home/f00li5h/_/App-rtpaste/App-rtpaste-0.0001.tar.gz to .build/HvV1EdkHVZ Checking if your kit is complete... Looks good Writing Makefile for App::rtpaste cp bin/rtpaste blib/script/rtpaste /usr/bin/perl -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/rtpaste Manifying blib/man1/rtpaste.1p PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t t/00-cats.t .. ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.04 usr 0.01 sys + 0.04 cusr 0.02 csys = 0.11 CPU) Result: PASS [@Basic/TestRelease] all's well; removing .build/HvV1EdkHVZ *** Preparing to upload App-rtpaste-0.0001.tar.gz to CPAN *** Do you want to continue the release process? [y/N]: Y [@Basic/UploadToCPAN] registering upload with PAUSE web server # <-- LOL, PUTTING DIST ON PAUSE [@Basic/UploadToCPAN] POSTing upload for App-rtpaste-0.0001.tar.gz [@Basic/UploadToCPAN] PAUSE add message sent ok [200] [FakeRelease] Fake release happening (nothing was really done) # <-- ALSO, RELEASING TO NOWHERE
(but this won't happen to you, because I've already told you how to avoid this)
but you're only running dzil release when you're ready to release.
There are a bundle of plug ins to let you use your version control suite to generate your module version numbers, generate documentation from other markup languages, and even to post to twitter when you release a distribution...
All exciting things, but these are trimmings that will have to wait for another post...
My feelings on the subject
Helpful docs, Helpful people, and most importantly, helpful --help...
All up, it was relatively painless, and easily discoverable. No painful hacking on Makefiles, or messing with bundles of boilerplate documentation.
The package up on cpan, and people can see it at:
http://cpansearch.perl.org/src/FOOLISH/App-rtpaste-0.0001/bin/rtpaste
although it was released a little before I expected, the script is packaged and its depends are listed nicely the POD is pretty shabby... sounds like a 0.0002 in the making...
Basically dzil gives people one less reason to not publish their code.
In the mean time...
... have fun with App-rtpaste and let me know if you find bugs, want features or have patches!
Mad props to the critters on #distzilla on irc.perl.org
Many thanks to:
rjbs at http://rjbs.manxome.org/journal,
sheepx at http://search.cpan.org/~mithaldu/,
oliver at http://search.cpan.org/perldoc?Dist::Zilla::PluginBundle::OLIVER,
kentnl at http://blog.fox.geek.nz/,
all of whom helped out and listened to my complaining when dzil did things I didn't expect, apparently this kind of "feedback" is helpful!
Related Reading
Dist::Zilla - Tutorial - Start Here! - the (official) Choose Your Own Tutorial.
Walking Through a Real dist.ini - recommended by sheepx
Why I'm using Dist::Zilla - by dagolden
Showing changes from previous revision. Removed | Added