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 toadd_merged
with an specific payload. Theconfig_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/issues.
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)