Creating a YAML::Tiny doppelgaenger

Reading time: 3 minutes

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 <adamk@cpan.org>
author = David Golden <dagolden@cpan.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!

•      •      •

If you enjoyed this or have feedback, please let me know by or