Recently, I needed to clone a distribution on CPAN and release it under a new name. I also need to keep it in sync with the original distribution. Rather than do any of that by hand, I decided to whip up a Dist::Zilla plugin (two, actually) to do the job for me.
The background for this particular situation involves the role that YAML plays in the Perl 5 module toolchain. For many years, now, CPAN distributions have included META.yml files containing distribution metadata. For CPAN clients to read this metadata, the Parse::CPAN::Meta module (P::C::M) was added to the Perl 5 core in Perl 5.10.1. P::C::M is (unfortunately) a read-only copy of YAML::Tiny.
The situation became more complex after the Oslo Consensus, which agreed on using the META.yml format as a standard way for module toolchain components to communicate post-configuration dependencies. This means module builders like Module::Build and ExtUtils::MakeMaker need to be able to write metadata files, not just read them. Thus, Module::Build::YAML was added, which is a full-fledged copy of YAML::Tiny that allows Module::Build to bootstrap if YAML::Tiny is not installed. Likewise, ExtUtils::MakeMaker needs ExtUtils::MakeMaker::YAML for its own bootstrap.
Thus, we seemed destined for three copies of YAML::TIny of various degrees of fidelity to be tucked away in the Perl 5 core under alternate names.
This situation is, frankly, nuts. Fortunately, the Perl 5 pumpking agrees.
Thus, it seemed that YAML::Tiny was destined for the Perl 5 core, instead. But a wrinkle emerged. YAML::Tiny is not really YAML, but only a subset. It is sufficient for META.yml files, but whatever goes is core to support that should not be considered a 'preferred' YAML library. A compromise was struck, to call it CPAN::Meta::YAML instead.
Now, I needed to create CPAN::Meta::YAML and make it easy to track YAML::Tiny.
The first Dist::Zilla plugin I wrote was Doppelgaenger, which downloads the latest stable release of a module and uses it as the basis for a new, renamed distribution. It also strips the Pod and version number from the source. The second plugin is AppendExternalData, which I use to add new Pod that is specific to CPAN::Meta::YAML.
The final CPAN::Meta::YAML repository contains only four files:
Changes dist.ini pod/lib/CPAN/Meta/YAML.pm MANIFEST.SKIP
And here is the dist.ini file:
name = CPAN-Meta-YAML author = Adam Kennedy <email@example.com> author = David Golden <firstname.lastname@example.org> license = Perl_5 copyright_holder = Adam Kennedy copyright_year = 2010 [Doppelgaenger] source_module = YAML::Tiny strip_pod = 1 strip_version = 1 [AppendExternalData] source_dir = pod [MetaResources] ;repository.url = git://github.com/dagolden/cpan-meta-yaml.git ;repository.web = http://github.com/dagolden/cpan-meta-yaml/ ;bugtracker.web = http://rt.cpan.org/NoAuth/Bugs.html?Dist=CPAN-Meta-YAML [@Filter] -bundle = @DAGOLDEN -remove = Prepender -remove = PodCoverageTests -remove = PortabilityTests git_remote = github [RemovePrereqs] remove = YAML remove = YAML::Perl remove = YAML::Syck remove = YAML::XS remove = t::lib::Test
With that, all I need to do is run
dzil release and -- tada! -- a new CPAN::Meta::YAML is created, tested and released to CPAN. And whenever a new YAML::Tiny is released, I just run
dzil release again. It's that easy.
Hooray for Dist::Zilla!