Sam's Blog

App::podweaver and Pod::Weaver::PluginBundle::ReplaceBoilerplate

Date: Monday, 23 August 2010, 13:16.

Categories: perl, ironman, git, pod-weaver.

As mentioned in my previous article, "Still Alive and What I've Been Up To", I've been working on a way to let me use Pod::Weaver without being forced down the route of using Dist::Zilla.

(The reason for not using Dist::Zilla is that its work-flow doesn't fit mine.)

To that end I've developed App::podweaver, Pod::Weaver::Role::SectionReplacer, and Pod::Weaver::PluginBundle::ReplaceBoilerplate.

All the above are GitHub because they're not yet ready for CPAN release, since they lack important things like, oh, tests that they don't go nuts and delete all your code.

That said they're at a stable enough stage that I've used them to weave their own documentation without trouble, and are potentially of enough use and interest for me to put them up for early adopters to take a look at, or for people to copy the guts to do their own thing with.

For more details on what does what, carry on reading below the cut.


Pod::Weaver::Role::SectionReplacer is the bit that lets Pod::Weaver be run in a "chained" manner, ie the output of the current run can be used as the input for the next run, allowing in-place edits.

It's a role that requires the consuming plugin to supply a name for the section, and optionally some aliases, it then looks through the input document for sections that match those names/aliases and prunes them from the input, storing the first section found under $plugin->original_section.

This allows you to write Section plugins that replace any existing section of that name, rather than just always appending a new duplicate copy.


Pod::Weaver::PluginBundle::ReplaceBoilerplate is essentially all the Section plugins from the base Pod::Weaver extended to use PW::Role::SectionReplacer, plus a PluginBundle to use in place of @Default that will use the new plugins.

This is a kind of ghastly way of doing things, but it was the easiest way to get things up and running.


App::podweaver is a simple command-line script that you run in your distribution dir, which invokes Pod::Weaver across any Pod-containing files it finds in that distribution.

It grabs some bits from your META.json/META.yml, does some backups, AND BY DEFAULT IT MODIFIES YOUR WORKING SOURCE CODE, so you probably want to be careful with that.

You really probably ought to create a weaver.ini in your distribution root dir telling Pod::Weaver to use the @ReplaceBoilerplate plugin bundle too, since you're going to keep adding duplicate sections with the default Pod::Weaver behaviour.

Use of this script is written with the intent of being part of your manual release process, and permitting your "released source" to match your "development source", so your work-flow will be something like:

$ git commit -m 'This is my real edits finished.' $ podweave $ git commit -a -m 'Replaced boilerplate in the Pod.' $ ./Build dist

The end result of that work-flow is as if you'd edited the Pod yourself by hand as part of your regular editing process, rather than it being a magic step that happens as part of the build of the dist.

If you're using PW::Role::SectionReplacer-enabled plugins, you can run the podweave stage as many times as you like, because the woven sections will overwrite their previous version, rather than append a new copy.

What's next?

Well some tests would be good. I won't be releasing the code to CPAN until I've added a proper test-suite: as I've said above, this script overwrites your source code, so it needs some pretty robust testing before official release.

The podweave script needs a major refactor, it works but the code is basically all inline in the script which makes testing near impossible and prevents any reuse. Functionality needs splitting into useful chunks and moving into the module from the the script, then maybe some of it could be reused to allow Pod::Weaver invocation in other dist-building tools (./Build podweave would be something I'd rather like as a Module::Build user.)

I'm sure there's other things I'll think of soon enough too, but for now... take a look and let me know your thoughts.

Browse Sam's Blog Subscribe to Sam's Blog

By day of August: 16, 23, 26.

By month of 2010: March, April, May, June, July, August, September, November.

By year: 2010, 2011, 2012, 2013.

Or by: category or series.


blog comments powered by Disqus
© 2009-2013 Sam Graham, unless otherwise noted. All rights reserved.