File Coverage

blib/lib/Dist/Zilla/Role/PluginBundle/Easy.pm
Criterion Covered Total %
statement 31 51 60.7
branch 1 20 5.0
condition 0 2 0.0
subroutine 8 10 80.0
pod 3 4 75.0
total 43 87 49.4


line stmt bran cond sub pod time code
1             package Dist::Zilla::Role::PluginBundle::Easy 6.037;
2             # ABSTRACT: something that bundles a bunch of plugins easily
3             # This plugin was originally contributed by Christopher J. Madsen
4              
5 11     11   1056424 use Moose::Role;
  11         10370  
  11         102  
6             with 'Dist::Zilla::Role::PluginBundle';
7              
8 11     11   64012 use Dist::Zilla::Pragmas;
  11         38  
  11         102  
9              
10 11     11   82 use Module::Runtime 'use_module';
  11         25  
  11         99  
11 11     11   660 use namespace::autoclean;
  11         24  
  11         82  
12              
13             #pod =head1 SYNOPSIS
14             #pod
15             #pod package Dist::Zilla::PluginBundle::Example;
16             #pod use Moose;
17             #pod with 'Dist::Zilla::Role::PluginBundle::Easy';
18             #pod
19             #pod sub configure {
20             #pod my $self = shift;
21             #pod
22             #pod $self->add_plugins('VersionFromModule');
23             #pod $self->add_bundle('Basic');
24             #pod }
25             #pod
26             #pod =head1 DESCRIPTION
27             #pod
28             #pod This role builds upon the PluginBundle role, adding methods to take most of the
29             #pod grunt work out of creating a bundle. It supplies the C<bundle_config> method
30             #pod for you. In exchange, you must supply a C<configure> method, which will store
31             #pod the bundle's configuration in the C<plugins> attribute by calling
32             #pod C<add_plugins> and/or C<add_bundle>.
33             #pod
34             #pod =cut
35              
36 11     11   1978 use MooseX::Types::Moose qw(Str ArrayRef HashRef);
  11         53697  
  11         150  
37              
38             use String::RewritePrefix 0.005
39 11         138 rewrite => {
40             -as => '_plugin_class',
41             prefixes => {
42             '=' => '',
43             '%' => 'Dist::Zilla::Stash::',
44             '' => 'Dist::Zilla::Plugin::',
45             },
46             },
47             rewrite => {
48             -as => '_bundle_class',
49             prefixes => {
50             '' => 'Dist::Zilla::PluginBundle::',
51             '@' => 'Dist::Zilla::PluginBundle::',
52             '=' => ''
53             },
54 11     11   62561 };
  11         1928  
55              
56             requires 'configure';
57              
58             #pod =attr name
59             #pod
60             #pod This is the bundle name, taken from the Section passed to
61             #pod C<bundle_config>.
62             #pod
63             #pod =cut
64              
65             has name => (
66             is => 'ro',
67             isa => Str,
68             required => 1,
69             );
70              
71             #pod =attr payload
72             #pod
73             #pod This hashref contains the bundle's parameters (if any), taken from the
74             #pod Section passed to C<bundle_config>.
75             #pod
76             #pod =cut
77              
78             has payload => (
79             is => 'ro',
80             isa => HashRef,
81             required => 1,
82             );
83              
84             #pod =attr plugins
85             #pod
86             #pod This arrayref contains the configuration that will be returned by
87             #pod C<bundle_config>. You normally modify this by using the
88             #pod C<add_plugins> and C<add_bundle> methods.
89             #pod
90             #pod =cut
91              
92             has plugins => (
93             is => 'ro',
94             isa => ArrayRef,
95             default => sub { [] },
96             );
97              
98             sub bundle_config {
99 12     12 0 571936 my ($class, $section) = @_;
100              
101 12         365 my $self = $class->new($section);
102              
103 12         1351 $self->configure;
104              
105 12         716 return $self->plugins->@*;
106             }
107              
108             #pod =method add_plugins
109             #pod
110             #pod $self->add_plugins('Plugin1', [ Plugin2 => \%plugin2config ])
111             #pod
112             #pod Use this method to add plugins to your bundle.
113             #pod
114             #pod It is passed a list of plugin specifiers, which can be one of a few things:
115             #pod
116             #pod =for :list
117             #pod * a plugin moniker (like you might provide in your config file)
118             #pod * an arrayref of: C<< [ $moniker, $plugin_name, \%plugin_config ] >>
119             #pod
120             #pod In the case of an arrayref, both C<$plugin_name> and C<\%plugin_config> are
121             #pod optional.
122             #pod
123             #pod The plugins are added to the config in the order given.
124             #pod
125             #pod =cut
126              
127             sub add_plugins {
128 12     12 1 66 my ($self, @plugin_specs) = @_;
129              
130 12         371 my $prefix = $self->name . '/';
131 12         381 my $plugins = $self->plugins;
132              
133 12         34 foreach my $this_spec (@plugin_specs) {
134 185         3114 my $moniker;
135             my $name;
136 185         0 my $payload;
137              
138 185 50       667 if (! ref $this_spec) {
    0          
    0          
139 185         316 ($moniker, $name, $payload) = ($this_spec, $this_spec, {});
140             } elsif (@$this_spec == 1) {
141 0         0 ($moniker, $name, $payload) = ($this_spec->[0], $this_spec->[0], {});
142             } elsif (@$this_spec == 2) {
143 0         0 $moniker = $this_spec->[0];
144 0 0       0 $name = ref $this_spec->[1] ? $moniker : $this_spec->[1];
145 0 0       0 $payload = ref $this_spec->[1] ? $this_spec->[1] : {};
146             } else {
147 0         0 ($moniker, $name, $payload) = @$this_spec;
148             }
149              
150 185         458 push @$plugins, [ $prefix . $name => _plugin_class($moniker) => $payload ];
151             }
152             }
153              
154             #pod =method add_bundle
155             #pod
156             #pod $self->add_bundle(BundleName => \%bundle_config)
157             #pod
158             #pod Use this method to add all the plugins from another bundle to your bundle. If
159             #pod you omit C<%bundle_config>, an empty hashref will be supplied.
160             #pod
161             #pod =cut
162              
163             sub add_bundle {
164 0     0 1   my ($self, $bundle, $payload) = @_;
165              
166 0           my $package = _bundle_class($bundle);
167 0   0       $payload ||= {};
168              
169             &use_module(
170             $package,
171 0 0         $payload->{':version'} ? $payload->{':version'} : (),
172             );
173              
174 0 0         $bundle = "\@$bundle" unless $bundle =~ /^@/;
175              
176 0           push $self->plugins->@*,
177             $package->bundle_config({
178             name => $self->name . '/' . $bundle,
179             package => $package,
180             payload => $payload,
181             });
182             }
183              
184             #pod =method config_slice
185             #pod
186             #pod $hash_ref = $self->config_slice(arg1, { arg2 => 'plugin_arg2' })
187             #pod
188             #pod Use this method to extract parameters from your bundle's C<payload> so
189             #pod that you can pass them to a plugin or subsidiary bundle. It supports
190             #pod easy renaming of parameters, since a plugin may expect a parameter
191             #pod name that's too generic to be suitable for a bundle.
192             #pod
193             #pod Each arg is either a key in C<payload>, or a hashref that maps keys in
194             #pod C<payload> to keys in the hash being constructed. If any specified
195             #pod key does not exist in C<payload>, then it is omitted from the result.
196             #pod
197             #pod =cut
198              
199             sub config_slice {
200 0     0 1   my $self = shift;
201              
202 0           my $payload = $self->payload;
203              
204 0           my %arg;
205              
206 0           foreach my $arg (@_) {
207 0 0         if (ref $arg) {
208 0           while (my ($in, $out) = each %$arg) {
209 0 0         $arg{$out} = $payload->{$in} if exists $payload->{$in};
210             }
211             } else {
212 0 0         $arg{$arg} = $payload->{$arg} if exists $payload->{$arg};
213             }
214             }
215              
216 0           return \%arg;
217             }
218              
219             1;
220              
221             __END__
222              
223             =pod
224              
225             =encoding UTF-8
226              
227             =head1 NAME
228              
229             Dist::Zilla::Role::PluginBundle::Easy - something that bundles a bunch of plugins easily
230              
231             =head1 VERSION
232              
233             version 6.037
234              
235             =head1 SYNOPSIS
236              
237             package Dist::Zilla::PluginBundle::Example;
238             use Moose;
239             with 'Dist::Zilla::Role::PluginBundle::Easy';
240              
241             sub configure {
242             my $self = shift;
243              
244             $self->add_plugins('VersionFromModule');
245             $self->add_bundle('Basic');
246             }
247              
248             =head1 DESCRIPTION
249              
250             This role builds upon the PluginBundle role, adding methods to take most of the
251             grunt work out of creating a bundle. It supplies the C<bundle_config> method
252             for you. In exchange, you must supply a C<configure> method, which will store
253             the bundle's configuration in the C<plugins> attribute by calling
254             C<add_plugins> and/or C<add_bundle>.
255              
256             =head1 PERL VERSION
257              
258             This module should work on any version of perl still receiving updates from
259             the Perl 5 Porters. This means it should work on any version of perl
260             released in the last two to three years. (That is, if the most recently
261             released version is v5.40, then this module should work on both v5.40 and
262             v5.38.)
263              
264             Although it may work on older versions of perl, no guarantee is made that the
265             minimum required version will not be increased. The version may be increased
266             for any reason, and there is no promise that patches will be accepted to
267             lower the minimum required perl.
268              
269             =head1 ATTRIBUTES
270              
271             =head2 name
272              
273             This is the bundle name, taken from the Section passed to
274             C<bundle_config>.
275              
276             =head2 payload
277              
278             This hashref contains the bundle's parameters (if any), taken from the
279             Section passed to C<bundle_config>.
280              
281             =head2 plugins
282              
283             This arrayref contains the configuration that will be returned by
284             C<bundle_config>. You normally modify this by using the
285             C<add_plugins> and C<add_bundle> methods.
286              
287             =head1 METHODS
288              
289             =head2 add_plugins
290              
291             $self->add_plugins('Plugin1', [ Plugin2 => \%plugin2config ])
292              
293             Use this method to add plugins to your bundle.
294              
295             It is passed a list of plugin specifiers, which can be one of a few things:
296              
297             =over 4
298              
299             =item *
300              
301             a plugin moniker (like you might provide in your config file)
302              
303             =item *
304              
305             an arrayref of: C<< [ $moniker, $plugin_name, \%plugin_config ] >>
306              
307             =back
308              
309             In the case of an arrayref, both C<$plugin_name> and C<\%plugin_config> are
310             optional.
311              
312             The plugins are added to the config in the order given.
313              
314             =head2 add_bundle
315              
316             $self->add_bundle(BundleName => \%bundle_config)
317              
318             Use this method to add all the plugins from another bundle to your bundle. If
319             you omit C<%bundle_config>, an empty hashref will be supplied.
320              
321             =head2 config_slice
322              
323             $hash_ref = $self->config_slice(arg1, { arg2 => 'plugin_arg2' })
324              
325             Use this method to extract parameters from your bundle's C<payload> so
326             that you can pass them to a plugin or subsidiary bundle. It supports
327             easy renaming of parameters, since a plugin may expect a parameter
328             name that's too generic to be suitable for a bundle.
329              
330             Each arg is either a key in C<payload>, or a hashref that maps keys in
331             C<payload> to keys in the hash being constructed. If any specified
332             key does not exist in C<payload>, then it is omitted from the result.
333              
334             =head1 AUTHOR
335              
336             Ricardo SIGNES 😏 <cpan@semiotic.systems>
337              
338             =head1 COPYRIGHT AND LICENSE
339              
340             This software is copyright (c) 2026 by Ricardo SIGNES.
341              
342             This is free software; you can redistribute it and/or modify it under
343             the same terms as the Perl 5 programming language system itself.
344              
345             =cut