Dist::Zilla::PluginBundle::Author::TABULO - A plugin bundle for distributions built by TABULO


version 0.198


In your dist.ini:



This is the plug-in bundle that TABULO uses for his distributions whose starting point was ETHER's.

It exists mostly because TABULO is very lazy and wants others to be using what he's using if they want to be doing work on his modules, just like KENTNL and many others, I suppose...

But since TABULO is probably even lazier than most folks; instead of starting his bundle from scratch, he just shopped around to find a bundle that had the most overlap with his taste or whatever; and then just slurped the whole thing, even including its documentation which is what you see here and in the related modules.:-)

Admittedly, the fact that TABULO was so late in migrating to dzil worked to his advantage for this particular task at least, since by that time the bold and the brave had already made delicious stuff!

Thank you ETHER!

Thank you, too, KENTNL and DAGOLDEN, as your plugin-bundles also seem to be quite good sources of inspiration!


Please note that, although this module needs to be on CPAN for obvious reasons, it is really intended to be a collection of personal preferences, which are expected to be in great flux, at least for the time being.

Therefore, please do NOT base your own distributions on this one, since anything can change at any moment without prior notice, while I get accustomed to dzil myself and form those preferences in the first place... Absolutely nothing in this distribution is guaranteed to remain constant or be maintained at this point. Who knows, I may even give up on dzil altogether...

You have been warned.

And now comes the rest of the documentation slurped right in from ETHER's GitHub repo ... :-)


This Dist::Zilla plugin bundle is very approximately equal to the following dist.ini (following the preamble), minus some optimizations:

    ;;; BeforeBuild
    [PromptIfStale / stale modules, build]
    phase = build
    module = Dist::Zilla::Plugin::Author::TABULO
    [PromptIfStale / stale modules, release]
    phase = release
    check_all_plugins = 1
    check_all_prereqs = 1

    ;;; ExecFiles
    dir = script    ; only if script dir exists

    ;;; Finders
    [FileFinder::ByName / Examples]
    dir = examples

    ;;; Gather Files
    :version = 2.016
    exclude_filename = CONTRIBUTING
    exclude_filename = INSTALL
    exclude_filename = LICENCE
    exclude_filename = LICENSE
    exclude_filename = META.json
    exclude_filename = Makefile.PL
    exclude_filename =
    exclude_filename = README.pod
    exclude_filename = TODO
    exclude_filename = cpanfile
    exclude_filename = inc/ExtUtils/MakeMaker/Dist/Zilla/
    exclude_filename = ppport.h

    :version = 5.038
    filename = LICENCE  ; for distributions where I have authority

    [GenerateFile::FromShareDir / generate CONTRIBUTING]
    -dist = Dist-Zilla-PluginBundle-Author-TABULO
    -filename = CONTRIBUTING
    has_xs = <dynamically-determined flag>
    :version = 1.200005

    :version = 2.039
    bail_out_on_fail = 1
    xt_mode = 1
    script_finder = :PerlExecFiles
    script_finder = Examples

    :version = 0.08
    finder = :InstallModules
    finder = :ExecFiles
    finder = Examples
    finder = :TestFiles
    finder = :ExtraTestFiles

    :version = 0.17
    finder = :InstallModules
    finder = :ExecFiles
    finder = Examples
    finder = :TestFiles
    finder = :ExtraTestFiles

    :version = 0.012
    :version = 2.000003
    max_target_perl = 5.006
    :version = 5.040
    :version = 5.040
    :version = 2.006003
    stopwords = irc
    directory = examples
    directory = lib
    directory = script
    directory = t
    directory = xt

    ;[Test::Pod::LinkCheck]     many outstanding bugs
    :version = 1.003
    :version = 2.10
    filename = xt/author/kwalitee.t
    :version = 0.8
    :version = 0.022
    verify_prereqs = 1
    version_extractor = Module::Metadata
    include = JSON::PP
    include = Pod::Coverage
    include = Sub::Name
    include = YAML
    include = autodie
    :version = 2.000007
    :version = 0.006

    ;;; Munge Files
    :version = 0.004
    on_package_line = 1

    [PodWeaver] (or [SurgicalPodWeaver])
    :version = 4.005
    config_plugin = @Author::TABULO ; unless weaver.ini is present
    replacer = replace_with_comment
    post_code_replacer = replace_with_nothing

    ;;; Metadata
    [GithubMeta]    ; (if server = 'github' or omitted)
    :version = 0.54
    homepage = 0
    issues = 0

    bugtracker.rt = 1
    ; (plus repository.* = 1 if server = 'gitmo' or 'p5sagit')

    :version = 1.009
    authority = cpan:TABULO
    do_munging = 0

    directory = corpus
    directory = demo
    directory = examples
    directory = fatlib
    directory = inc
    directory = local
    directory = perl5
    directory = share
    directory = t
    directory = xt

    :version = 1.15000002
    finder = :InstallModules
    meta_noindex = 1
    inherit_version = 0
    inherit_missing = 0

    :version = 0.004

    ; if we are releasing with a new perl with -DDEFAULT_INC_EXCLUDES_DOT set
    dot_in_INC = 0

    ;[Git::Contributors]    ; below
    ;[StaticInstall]        ; below

    ;;; Register Prereqs
    :version = 5.038
    relation = suggests
    :version = 1.006
    configure_finder = :NoFiles

    [Prereqs / prereqs for @Author::TABULO]
    -phase = develop
    -relationship = suggests
    ...all the plugins this bundle uses...

    [Prereqs / pluginbundle_version]
    -phase = develop
    -relationship = recommends
    Dist::Zilla::PluginBundle::Author::TABULO = <current installed version>

    ;;; Install Tool
    ; <specified installer(s)>

    :version = 0.029
    order_by = commits

    :version = 0.005
    mode = auto
    dry_run = 1  ; only if authority is not ETHER

    ;;; Test Runner
    ; <specified installer(s)>
    :version = 0.024
    default_jobs = 9

    ;;; After Build

    [Run::AfterBuild / .ackrc]
    :version = 0.038
    quiet = 1
    run = bash -c "test -e .ackrc && grep -q -- '--ignore-dir=.latest' .ackrc || echo '--ignore-dir=.latest' >> .ackrc; if [[ `dirname '%d'` != .build ]]; then test -e .ackrc && grep -q -- '--ignore-dir=%d' .ackrc || echo '--ignore-dir=%d' >> .ackrc; fi"
    [Run::AfterBuild / .latest]
    :version = 0.041
    quiet = 1
    fatal_errors = 0
    eval = if ('%d' =~ /^%n-[.[:xdigit:]]+$/) { unlink '.latest'; symlink '%d', '.latest'; }

    ;;; Before Release
    decimal_only = 1


    [Git::Check / initial check]
    allow_dirty =


    :version = 0.004
    release_branch = master

    branch = master
    remote_branch = master

    :version = 0.019
    [Git::Check / after tests]
    allow_dirty =

    ;;; Releaser

    ;;; AfterRelease
    [Run::AfterRelease / remove old LICENCE]    ; if switching from LICENCE -> LICENSE
    :version = 0.038
    quiet = 1
    eval = unlink 'LICENCE'

    [Run::AfterRelease / remove old LICENSE]    ; if switching from LICENSE -> LICENCE
    :version = 0.038
    quiet = 1
    eval = unlink 'LICENSE'

    [Run::AfterRelease / remove old READMEs]
    :version = 0.038
    quiet = 1
    eval = unlink ''

    [CopyFilesFromRelease / copy generated files]
    filename = CONTRIBUTING
    filename = INSTALL
    filename = LICENCE
    filename = LICENSE
    filename = ppport.h

    :version = 0.142180
    type = pod
    location = root
    phase = release

    ;;;;;; begin [@Git::VersionManager]

    ; this is actually a VersionProvider and FileMunger
    :version = 0.004
    global = 1
    fallback_version_provider = Git::NextVersion
    version_regexp = ^v([\d._]+)(-TRIAL)?$

    [CopyFilesFromRelease / copy Changes]
    filename = Changes

    [Git::Commit / release snapshot]
    :version = 2.020
    add_files_in = .
    allow_dirty = CONTRIBUTING
    allow_dirty = Changes
    allow_dirty = INSTALL
    allow_dirty = LICENCE
    allow_dirty = LICENSE
    allow_dirty =
    allow_dirty = README.pod
    allow_dirty = ppport.h
    commit_msg = %N-%v%t%n%n%c

    tag_message = v%v%t

    :version = 0.004
    global = 1

    :version = 5.033
    time_zone = UTC
    format = %-8v  %{yyyy-MM-dd HH:mm:ss'Z'}d%{ (TRIAL RELEASE)}T

    [Git::Commit / post-release commit]
    :version = 2.020
    allow_dirty = Changes
    allow_dirty_match = ^lib/.*\.pm$
    commit_msg = increment $VERSION after %v release

    ;;;;;; end [@Git::VersionManager]


    [GitHub::Update]    ; (if server = 'github' or omitted)
    :version = 0.40
    metacpan = 1

    [Run::AfterRelease / install release]
    :version = 0.031
    fatal_errors = 0
    run = cpanm

    [Run::AfterRelease / release complete]
    :version = 0.038
    quiet = 1
    eval = print "release complete!\xa"

    ; listed late, to allow all other plugins which do BeforeRelease checks to run first.

    ; listed last, to be sure we run at the very end of each phase
    ; only performed if $ENV{USER} matches /^tabulo$/
    [VerifyPhases / PHASE VERIFICATION]
    :version = 0.015

The distribution's code is assumed to be hosted at github; RT is used as the issue tracker. The home page in the metadata points to github, while the home page on github is updated on release to point to metacpan. The version and other metadata is derived directly from the local git repository.



Use V=<version> in the shell to override the version of the distribution being built; otherwise the version is incremented after each release, in the *.pm files.

pod coverage

Subroutines can be considered "covered" for pod coverage tests by adding a directive to pod (as many as you'd like), as described in Pod::Coverage::TrustPod:

    =for Pod::Coverage foo bar baz

spelling stopwords

Stopwords for spelling tests can be added by adding a directive to pod (as many as you'd like), as described in "ADDING STOPWORDS" in Pod::Spell:

    =for stopwords foo bar baz

It is also possible to use the [%PodWeaver] stash in 'dist.ini' to add stopwords, like so : [%PodWeaver] -StopWords.include = foo bar baz

Such words will be recognized by the [StopWords]|Pod::Weaver::Plugin::StopWords plugin for Pod::Weaver, which will gather them at the top of your POD (since we set its 'gather' parameter).

See also [Test::PodSpelling].


Available since 0.007.

The installer back-end(s) to use (can be specified more than once); defaults to ModuleBuildTiny::Fallback and MakeMaker::Fallback (which generates a Build.PL for normal use with no-configure-requires protection, and Makefile.PL as a fallback, containing an upgrade warning). For toolchain-grade modules, you should only use Makefile.PL-generating installers.

You can select other backends (by plugin name, without the []), with the installer option, or none if you are supplying your own, as a separate plugin(s).

Encouraged choices are:

  • installer = ModuleBuildTiny

  • installer = MakeMaker

  • installer = MakeMaker::Fallback (when used in combination with ModuleBuildTiny)

  • installer = =inc::Foo (if no configs are needed for this plugin; e.g. subclassed from [MakeMaker::Awesome])

  • installer = none (if you are providing your own elsewhere in the file, with configs)


Available since 0.019.

If provided, must be one of:

  • github

    (default) metadata and release plugins are tailored to github.

  • gitmo

    metadata and release plugins are tailored to

  • p5sagit

    metadata and release plugins are tailored to

  • catagits

    metadata and release plugins are tailored to

  • none

    no special configuration of metadata (relating to repositories etc) is done -- you'll need to provide this yourself.


Available since 0.053.

A boolean option that, when set, removes the use of all plugins that use the network (generally for comparing metadata against PAUSE, and querying the remote git server), as well as blocking the use of the release command. Defaults to false; can also be set with the environment variable DZIL_AIRPLANE.


Available in this form since 0.076.

A file, to be present in the build, which is copied back to the source repository at release time and committed to git. Can be used more than once. Defaults to: LICENCE, LICENSE, CONTRIBUTING, Changes, ppport.h, INSTALL; defaults are appended to, rather than overwritten.


Available since 0.051.

A boolean option that, when set, uses [SurgicalPodWeaver] instead of [PodWeaver], but with all the same options. Defaults to false.


Available since 0.076.

An integer that specifies how many columns (right-padded with whitespace) are allocated in Changes entries to the version string. Defaults to 10 in general (and 12 for TABULO).

licence (or license)

Available since 0.101.

A string that specifies the name to use for the license file. Defaults to LICENCE for distributions where ETHER or any other known authors who prefer LICENCE have first-come permissions, or LICENSE otherwise. (The pod section for legal information is also adjusted appropriately.)


Available since 0.117.

A string of the form cpan:PAUSEID that references the PAUSE ID of the user who has primary ("first-come") authority over the distribution and main module namespace. If not provided, it is extracted from the configuration passed through to the [Authority] plugin, and finally defaults to cpan:TABULO. It is presently used for setting x_authority metadata and deciding which spelling is used for the LICENCE file (if the licence configuration is not provided).


Available since 0.122.

A boolean option that, when set, removes [UploadToCPAN] from the plugin list and replaces it with [FakeRelease]. Defaults to false; can also be set with the environment variable FAKE_RELEASE.

other customization options

This bundle makes use of Dist::Zilla::Role::PluginBundle::PluginRemover and Dist::Zilla::Role::PluginBundle::Config::Slicer to allow further customization. (Note that even though some overridden values are inspected in this class, they are still overlaid on top of whatever this bundle eventually decides to pass - so what is in the dist.ini always trumps everything else.)

Plugins are not loaded until they are actually needed, so it is possible to --force-install this plugin bundle and -remove some plugins that do not install or are otherwise problematic.

If a weaver.ini is present in the distribution, pod is woven using it; otherwise, the behaviour is as with a weaver.ini containing the single line [@Author::TABULO] (see Pod::Weaver::PluginBundle::Author::TABULO).


This distribution follows best practices for author-oriented plugin bundles; for more information, see KENTNL's distribution.


This distribution is based on Dist::Zilla::PluginBundle::Author::ETHER by :

Karen Etheridge cpan:ETHER

Thank you ETHER!



Bugs may be submitted through the RT bug tracker (or


Tabulo <>


  • Karen Etheridge <>

  • Edward Betts <>

  • Graham Knop <>

  • Randy Stauner <>

  • Roy Ivy III <>

  • Сергей Романов <>

  • Dave Rolsky <>


This software is copyright (c) 2018 by Tabulo.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.