Please note:I am not dead, I'm recovering a very fucked up hard disk :( Jan2012

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

 Subscribe

Author

A cat, from the internet.

  • Does not like wet paws
  • Does enjoy nip and sleeping in the sun


Cats & Kittens

Other cats worth reading:


Coming up!

It seems like it might be worth just picking a sensible blog engine, but that's not as much fun.

I have rushed to this mojomojo deployment since the free hosting guys I was with before finally pulled the plug on me (after I ingored their "we're removing free plans" emails for 3 months)

  • sane rss feeds
  • publishing and permissions settings
  • reasonable commenting and feedback

Other