The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    Dist::Zilla::Role::PluginBundle::Merged - Mindnumbingly easy way to
    create a PluginBundle

SYNOPSIS
        # Yes, three lines of code works!
        package Dist::Zilla::PluginBundle::Foobar;
        Moose::with 'Dist::Zilla::Role::PluginBundle::Merged';
        sub configure { shift->add_merged( qw[ Plugin1 Plugin2 Plugin3 Plugin4 ] ); }
 
        # Or, as a more complex example...
        package Dist::Zilla::PluginBundle::Foobar;
        use Moose;
 
        with 'Dist::Zilla::Role::PluginBundle::Merged' => {
           mv_plugins => [ qw( Plugin1 =Dist::Zilla::Bizarro::Foobar Plugin2 ) ],
        };
 
        sub configure {
           my $self = shift;
           $self->add_merged(
              qw( Plugin1 @Bundle1 =Dist::Zilla::Bizarro::Foobar ),
              {},  # force no options on the following plugins
              qw( ArglessPlugin1 ArglessPlugin2 ),
              $self->config_rename(plugin_dupearg => 'dupearg', removearg => undef),
              qw( Plugin2 ),
              $self->config_short_merge(['Plugin3', 'Plugin4'], { defaultarg => 1 }),
           );
        }

DESCRIPTION
    This is a PluginBundle role, based partially on the underlying code from
    Dist::Zilla::PluginBundle::Git. As you can see from the example above,
    it's incredibly easy to make a bundle from this role. It uses
    Dist::Zilla::Role::PluginBundle::Easy, so you have access to those same
    methods.

METHODS
  add_merged
    The "add_merged" method takes a list (not arrayref) of plugin names,
    bundle names (with the "@" prefix), or full module names (with the "="
    prefix). This method combines "add_plugins" & "add_bundle", and handles
    all of the payload merging for you. For example, if your bundle is
    passed the following options:

        [@Bundle]
        arg1 = blah
        arg2 = foobar

    Then it will pass the "arg1/arg2" options to each of the plugins, IF
    they support the option. Specifically, it does a "$class->can($arg)"
    check. (Bundles are passed the entire payload set.) If "arg1" exists for
    multiple plugins, it will pass the same option to all of them. If you
    need separate options, you should consider using the "config_rename"
    method.

    It will also accept hashrefs anywhere in the list, which will replace
    the payload arguments while it processes. This is useful for changing
    the options "on-the-fly" as plugins get processed. The replacement is
    done in order, and the changes will persist until it reaches the end of
    the list, or receives another replacement.

    If passed an arrayref, it will be directly passed to add_plugins. Useful
    for plugins that use BUILDARGS or some other non-standard configuration
    setup.

  config_rename
    This method is sort of like the config_slice method, but is more
    implicit than explicit. It starts off with the entire payload (cloned),
    and renames any hash pair that was passed:

        my $hash = $self->config_rename(foobar_arg1 => 'arg1');

    This example will change the argument "foobar_arg1" to "arg1". This is
    handy if you want to make a specific option for the plugin "Foobar" that
    doesn't clash with "arg1" on plugin "Baz":

        $self->add_merged(
           'Baz',
           $self->config_rename(foobar_arg1 => 'arg1', killme => ''),
           'Foobar',
        );

    Any destination options are replaced. Also, if the destination value is
    undef (or non-true), the key will simply be deleted. Keep in mind that
    this is all a clone of the payload, so extra calls to this method will
    still start out with the original payload.

  config_short_merge
    Like "config_rename", this is meant to be used within an "add_merged"
    block. It takes either a single plugin (scalar) or multiple ones
    (arrayref) as the first parameter, and a hashref of argument/value pairs
    as the second one. This will merge in your own argument/value pairs to
    the existing payload, pass the module list, and then pass the original
    payload back. For example:

        $self->add_merged(
           $self->config_short_merge(['Baz', 'Foobar'], { arg1 => 1 }),  # these two plugins have payload + arg1
           'Boom',  # only has the original payload
        );

    Furthermore, the argument hash is expanded prior to the payload, so they
    can be overwritten by the payload. Think of this as default arguments to
    pass to the plugins.

ROLE PARAMETERS
  mv_plugins
    Certain configuration parameters are "multi-value" ones (or MVPs), and
    Config::MVP uses the "mvp_multivalue_args" sub in each class to identify
    which ones exist. Since you are trying to merge the configuration
    parameters of multiple plugins, you'll need to make sure your new plugin
    bundle identifies those same MVPs.

    Because the INI reader is closer to the beginning of the DZ plugin
    process, it would be too late for "add_merged" to start adding in keys
    to your "mvp_multivalue_args" array. Thus, this role is parameterized
    with this single parameter, and comes with its own "mvp_multivalue_args"
    method. The syntax is a single arrayref of strings in the same prefix
    structure as "add_merged". For example:

        with 'Dist::Zilla::Role::PluginBundle::Merged' => {
           mv_plugins => [ qw( Plugin1 Plugin2 ) ],
        };

    The above will identify these two plugins has having MVPs. When
    Config::MVP calls your "mvp_multivalue_args" sub (which is built into
    this role), it will load these two plugin classes and populate the
    contents of their "mvp_multivalue_args" sub as a combined list to pass
    over to Config::MVP. In other words, as long as you identify all of the
    plugins that would have multiple values, your stuff "just works".

    If you need to identify any extra parameters as MVPs (like your own
    custom MVPs or "dupe preventing" parameters that happen to be MVPs), you
    should consider combining "mv_plugins" with an "after
    mvp_multivalue_args" sub.

SUMMARY OF PARAMETERS
    Here are all of the different options you can pass to "add_merged":

        $self->add_merged(
           ### SCALARs ###
           # These are all passed to add_plugins with an implicit payload
           'Plugin',
           '@PluginBundle',
           '=Dist::Zilla::Bizarro::Plugin',  # explicit class of plugin
 
           ### ARRAYs ###
           # These are all passed to add_plugins with an explicit payload
           ['Plugin'],
           ['Plugin', 'NewName'],
           ['Plugin', \%new_payload ],
           ['Plugin', 'NewName', \%new_payload ],
 
           ### HASHs ###
           {},              # force no options until reset
           $self->payload,  # reset to original payload
           \%new_payload,   # only pass those arg/value pairs as the payload
 
           $self->config_slice(qw( arg1 arg2 )),                    # only pass those args -from- the payload
           $self->config_slice('arg1', { foobar_arg2 => 'arg2' }),  # only pass those args -from- the payload (with arg renaming)
 
           $self->config_rename(foobar_arg1 => 'arg1'),             # rename args in the payload (and pass everything else)
           $self->config_rename(killme => ''),                      # remove args in the payload (and pass everything else)
 
           ### Combinations ###
           $self->config_short_merge('Plugin', \%add_on_payload),   # add args to the payload, pass to Plugin, and reset to original
           $self->config_short_merge(
              [ qw( Plugin1 Plugin2 ) ],    # add args to the payload, pass to plugin list, and reset to original payload
              \%add_on_payload
           ),
        );

CAVEATS
    *   Plugins that use non-standard payload methods will not be passed
        their options via "add_merged", unless passed an arrayref to
        "add_merged" with an specific payload. The "config_merge" method
        will warn you of this, because it knows that you really want to use
        that argument. Others will not.

    *   Doing things more implicitly grants greater flexibility while
        sacrificing control. YMMV.

AVAILABILITY
    The project homepage is
    <https://github.com/SineSwiper/Dist-Zilla-Role-PluginBundle-Merged/wiki>
    .

    The latest version of this module is available from the Comprehensive
    Perl Archive Network (CPAN). Visit <http://www.perl.com/CPAN/> to find a
    CPAN site near you, or see
    <https://metacpan.org/module/Dist::Zilla::Role::PluginBundle::Merged/>.

SUPPORT
  Internet Relay Chat
    You can get live help by using IRC ( Internet Relay Chat ). If you don't
    know what IRC is, please read this excellent guide:
    <http://en.wikipedia.org/wiki/Internet_Relay_Chat>. Please be courteous
    and patient when talking to us, as we might be busy or sleeping! You can
    join those networks/channels and get help:

    *   irc.perl.org

        You can connect to the server at 'irc.perl.org' and talk to this
        person for help: SineSwiper.

  Bugs / Feature Requests
    Please report any bugs or feature requests via
    <https://github.com/SineSwiper/Dist-Zilla-Role-PluginBundle-Merged/issue
    s>.

AUTHOR
    Brendan Byrd <bbyrd@cpan.org>

COPYRIGHT AND LICENSE
    This software is Copyright (c) 2013 by Brendan Byrd.

    This is free software, licensed under:

      The Artistic License 2.0 (GPL Compatible)