=head1 Converting a Dist to Dist::Zilla =for html
This tutorial page is adapted from the Perl Pub article L =for html
Switching your old code to use Dist::Zilla is easy, and you can be conservative or go whole hog. We'll walk through the process of converting one of my dists, F. To follow along, clone L and start with the commit tagged C. If you don't want to use C, that's fine. You'll still be able to see what's going on. =head3 Replacing Makefile.PL The first thing we'll replace is F, the traditional program for building and installing distributions (or "dists"). If you started with a L-based distribution, we'd replace F, instead. Dist::Zilla will build those files for you in the dist you ship so that installing users have them, but you'll never need to think about them again. Number::Nary was packaged with L, the library that inspired me to build Dist::Zilla. Its F looked like this: #!perl use inc::Module::Install; all_from('lib/Number/Nary.pm'); requires('Carp' => 0); requires('List::MoreUtils' => 0.09); requires('Sub::Exporter' => 0.90); requires('UDCode' => 0); auto_manifest; extra_tests; WriteAll; If it had been using ExtUtils::MakeMaker, it might've looked something like this: #!perl use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Number::Nary', DISTNAME => 'Number-Nary', AUTHOR => 'Ricardo Signes ', ABSTRACT => 'encode and decode numbers as n-ary strings', VERSION => '0.108', LICENSE => 'perl', PREREQ_PM => { 'Carp' => 0 'List::MoreUtils' => '0.09', 'Sub::Exporter' => 0, 'UDCode' => 0, } ); We can just delete that file and replace it with the file F, looking like this: #!vim dosini name = Number-Nary version = 0.108 author = Ricardo Signes license = Perl_5 copyright_holder = Ricardo Signes [GatherDir] [MetaYAML] [MakeMaker] [Manifest] [Prereqs] Carp = 0 List::MoreUtils = 0.09 Sub::Exporter = 0.90 UDCode = 0 Right now, we've gained lines, but don't worry -- that won't last long. Most of this should be self-explanatory, but the cluster of square-bracketed names isn't. Each one sets up another plugin, and every plugin helps with part of the well-defined process of building your dist. The ones above set up the absolute minimum needed to replace F: they pull in all the files in your checkout and when you build the dist they add the extra files you need to ship. At this point, if you just wanted to build a tarball to release, you could run C (instead of C<< perl Makefile.PL && make dist >>) and upload the resulting file. We want to start seeing the savings, though, so here we go... =head3 Eliminating Pointless Packaging Files The F file tells other packaging tools which files to exclude. You could keep using it (with the ManifestSkip plugin), but you can almost always just drop the file and use the PruneCruft plugin. It prunes all the files people usually put in their skip file. The CPAN community has a tradition of shipping lots of good documentation, written in Pod. Despite this, a number of tools expect a plain README file. The Readme plugin will generate one for you. Downstream distributors (like Linux distributions) like to see really clear license statements, especially in the form of a F file. Because your F knows the details of your license, it can generate this file for you. So, we've deleted three whole files -- F, F, and F -- and added exactly the following to our configuration: #!vim dosini [PruneCruft] [License] [Readme] Not bad, especially when you remember that now when you edit your dist version, license, or abstract, these files will be guaranteed to contain the new data. =head3 Stock Tests There are a bunch of tests that people expect CPAN authors to run before releasing these days. Number::Nary had three of them: xt/release/perl-critic.t xt/release/pod-coverage.t xt/release/pod-syntax.t They were in the F<./xt/release> directory to indicate that they should only be run when testing a new release candidate, not by every installing user. These files are pretty simple, but the last thing you want is to find out that you've been copying and pasting a slightly buggy version of the file around. Instead, you can just generate these files as needed, and if there's a bug, you fix the plugin and everything gets the fix on the next rebuild. Once again, we can delete those three files in favor of these plugins: #!vim dosini [ExtraTests] [Test::Perl::Critic] [PodCoverageTests] [PodSyntaxTests] Test::Perl::Critic and the Pod test plugins add test files to your F<./xt> directory and ExtraTests rewrites them to live in F<./t>, but only under the correct circumstances, like during release testing. If you'd customized your Pod coverage tests to consider certain methods trusted despite having no docs, you can move that configuration into your Pod itself, adding a line like this: #!vim pod =for Pod::Coverage some_method some_other_method this_is_covered_too The Test::Perl::Critic plugin, by the way, does not come with Dist::Zilla. It's a third party plugin. There are a bunch of those on the CPAN, and they're easy to install. C<< [Test::Perl::Critic] >> tells Dist::Zilla to load Dist::Zilla::Plugin::Test::Perl::Critic. Just install that with F or your package manager and you're ready to use the plugin. =head3 The @Basic Bundle and Cutting Releases Since most of the time you want to use the same config everywhere, Dist::Zilla makes it easy to reuse configuration. We're using something very close to the "Basic" plugin bundle shipped with Dist::Zilla. We could replace all the plugin configuration (except for Prereqs) with this: #!vim dosini [@Basic] [PodSyntaxTests] [PodCoverageTests] [CriticTests] ...so we're finally getting back to a nice, small config file. Classic gets us a few other plugins, too, but most of them aren't worth mentioning right now. One that is, though, is UploadToCPAN. It enables the command C, which lets you L easily. =head3 Letting Dist::Zilla Alter Our Modules So far, we've just let Dist::Zilla build extra files like tests and packaging files. You can get a lot more out of Dist::Zilla if you let it mess around with your library files, too. For example, we could add the PkgVersion and PodVersion plugins to let Dist::Zilla take care of setting the version in all our libraries. They find F<.pm> files and add a C<< our $VERSION = ... >> declaration and a C<< =head1 VERSION >> section to the Pod -- which means we could go delete all those from our code and not worry about keeping them up to date anymore. Another thing that Dist::Zilla can help with is managing our prerequisites. Right now, our dist.ini has a long list of prerequisites, just like our old Makefile.PL did: [Prereqs] Carp = 0 List::MoreUtils = 0.09 Sub::Exporter = 0.90 UDCode = 0 We can get rid of all that with AutoPrereqs, which will analyze our code to find all the libraries we need and the versions needed. We just pull out Prereqs and add AutoPrereqs. Dist::Zilla can also automatically provide sections of boilerplate Pod like C, C or C. =for cyoa ? prereq ? learn about declaring or detecting prerequisites ? versioning ? learn about managing version numbers with Dist::Zilla ? writing-docs ? learn how get rid of boilerplate docs with Dist::Zilla ? testing ? learn how to test your distribution ? release ? learn how to release your distribution to the CPAN ? vcs ? learn how to integrate Dist::Zilla with your version control