File Coverage

lib/Dist/Zilla/Util/BundleInfo.pm
Criterion Covered Total %
statement 74 91 81.3
branch 10 22 45.4
condition n/a
subroutine 16 17 94.1
pod 1 1 100.0
total 101 131 77.1


line stmt bran cond sub pod time code
1 4     4   62692 use 5.006; # our
  4         15  
2 4     4   21 use strict;
  4         5  
  4         89  
3 4     4   18 use warnings;
  4         7  
  4         312  
4              
5             package Dist::Zilla::Util::BundleInfo;
6              
7             our $VERSION = '1.001004';
8              
9             # ABSTRACT: Load and interpret a bundle
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13 4     4   3223 use Moo 1.000008 qw( has );
  4         62605  
  4         26  
14              
15              
16              
17              
18              
19              
20              
21              
22              
23              
24              
25              
26              
27              
28              
29              
30              
31             sub _coerce_bundle_name {
32 3     3   11 my ($name) = @_;
33 3         2720 require Dist::Zilla::Util;
34 3         41813 return Dist::Zilla::Util->expand_config_package_name($name);
35             }
36              
37              
38              
39              
40              
41              
42              
43             sub _isa_bundle {
44 3     3   6 my ($name) = @_;
45 3         22 require Module::Runtime;
46 3         17 Module::Runtime::require_module($name);
47 3 50       192 if ( not $name->can('bundle_config') ) {
48 0         0 require Carp;
49 0         0 Carp::croak("$name is not a bundle, as it does not have a bundle_config method");
50             }
51             }
52              
53              
54              
55              
56              
57              
58              
59              
60              
61              
62             has bundle_name => (
63             is => ro =>,
64             required => 1,
65             coerce => sub { _coerce_bundle_name( $_[0] ) },
66             isa => sub { _isa_bundle( $_[0] ) },
67             );
68              
69              
70              
71              
72              
73              
74              
75              
76              
77              
78              
79             has bundle_dz_name => (
80             is => ro =>,
81             lazy => 1,
82             builder => sub {
83 3     3   1180 return $_[0]->bundle_name;
84             },
85             );
86              
87              
88              
89              
90              
91              
92              
93              
94              
95              
96              
97              
98              
99              
100              
101              
102              
103              
104              
105              
106              
107              
108              
109              
110              
111              
112              
113              
114              
115              
116              
117              
118              
119             has bundle_payload => (
120             is => ro =>,
121             lazy => 1,
122             builder => sub {
123 0     0   0 [];
124             },
125             );
126              
127             has _loaded_module => (
128             is => ro =>,
129             lazy => 1,
130             builder => sub {
131 1     1   393 require Module::Runtime;
132 1         5 Module::Runtime::require_module( $_[0]->bundle_name );
133 1         35 return $_[0]->bundle_name;
134             },
135             );
136              
137             has _mvp_alias_map => (
138             is => ro =>,
139             lazy => 1,
140             builder => sub {
141 1     1   425 my ($self) = @_;
142 1 50       4 return {} unless $self->_loaded_module->can('mvp_aliases');
143 1         22 return $self->_loaded_module->mvp_aliases;
144             },
145             );
146             has _mvp_alias_rmap => (
147             is => ro =>,
148             lazy => 1,
149             builder => sub {
150 1     1   386 my ($self) = @_;
151 1         2 my $rmap = {};
152 1         2 for my $alias_from ( keys %{ $self->_mvp_alias_map } ) {
  1         21  
153 2         46 my $alias_to = $self->_mvp_alias_map->{$alias_from};
154 2 50       20 $rmap->{$alias_to} = [] if not exists $rmap->{$alias_to};
155 2         3 push @{ $rmap->{$alias_to} }, $alias_from;
  2         7  
156             }
157 1         7 return $rmap;
158             },
159             );
160              
161             sub _mvp_alias_for {
162 2     2   3 my ( $self, $alias ) = @_;
163 2 50       24 return unless exists $self->_mvp_alias_rmap->{$alias};
164 0         0 return @{ $self->_mvp_alias_rmap->{$alias} };
  0         0  
165             }
166             has _mvp_multivalue_args => (
167             is => ro =>,
168             lazy => 1,
169             builder => sub {
170 1 50   1   408 return {} unless $_[0]->_loaded_module->can('mvp_multivalue_args');
171 1         13 my $map = {};
172 1         21 for my $arg ( $_[0]->_loaded_module->mvp_multivalue_args ) {
173 2         15 $map->{$arg} = 1;
174 2         7 for my $alias ( $_[0]->_mvp_alias_for($arg) ) {
175 0         0 $map->{$alias} = 1;
176             }
177             }
178 1         13 return $map;
179             },
180             );
181              
182 4     4   9266 no Moo;
  4         8  
  4         20  
183              
184             sub _property_is_mvp_multi {
185 4     4   8 my ( $self, $property ) = @_;
186 4         60 return exists $self->_mvp_multivalue_args->{$property};
187             }
188              
189             sub _array_to_hash {
190 2     2   5 my ( $self, @orig_payload ) = @_;
191 2         3 my $payload = {};
192 2         5 my ( $key_i, $value_i ) = ( 0, 1 );
193 2         9 while ( $value_i <= $#orig_payload ) {
194 4         7 my ($inputkey) = $orig_payload[$key_i];
195 4         7 my ($value) = $orig_payload[$value_i];
196 4         6 my ($key) = $inputkey;
197 4 50       64 if ( exists $self->_mvp_alias_map->{$inputkey} ) {
198 4         108 $key = $self->_mvp_alias_map->{$inputkey};
199             }
200 4 50       32 if ( $self->_property_is_mvp_multi($key) ) {
201 0 0       0 $payload->{$key} = [] if not exists $payload->{$key};
202 0         0 push @{ $payload->{$key} }, $value;
  0         0  
203 0         0 next;
204             }
205 4 50       32 if ( exists $payload->{$key} ) {
206 0         0 require Carp;
207 0         0 Carp::carp( "Multiple specification of non-multivalue key $key for bundle" . $self->bundle_name );
208 0 0       0 if ( not ref $payload->{$key} ) {
209 0         0 $payload->{$key} = [ $payload->{$key} ];
210             }
211 0         0 push @{ $payload->{$key} }, $value;
  0         0  
212 0         0 next;
213             }
214 4         10 $payload->{$key} = $value;
215             }
216             continue {
217 4         7 $key_i += 2;
218 4         11 $value_i += 2;
219             }
220 2         6 return $payload;
221             }
222              
223              
224              
225              
226              
227              
228              
229              
230             sub plugins {
231 4     4 1 759 my ( $self, ) = @_;
232 4         43 my $payload = $self->bundle_payload;
233 4         1438 my $bundle = $self->bundle_name;
234 4         35 my $bundle_dz_name = $self->bundle_dz_name;
235 4         2041 require Dist::Zilla::Util::BundleInfo::Plugin;
236 4         11 my @out;
237 4 100       20 if ( 'ARRAY' eq ref $payload ) {
238 2         4 $payload = $self->_array_to_hash( @{$payload} );
  2         7  
239             }
240 4         35 for my $plugin ( $bundle->bundle_config( { name => $bundle_dz_name, payload => $payload } ) ) {
241 33         1972 push @out, Dist::Zilla::Util::BundleInfo::Plugin->inflate_bundle_entry($plugin);
242             }
243 4         93 return @out;
244             }
245              
246             1;
247              
248             __END__
249              
250             =pod
251              
252             =encoding UTF-8
253              
254             =head1 NAME
255              
256             Dist::Zilla::Util::BundleInfo - Load and interpret a bundle
257              
258             =head1 VERSION
259              
260             version 1.001004
261              
262             =head1 SYNOPSIS
263              
264             use Dist::Zilla::Util::BundleInfo;
265              
266             # [@RJBS]
267             # -myparam = foo
268             # param = bar
269             # param = quux
270             #
271             my $info = Dist::Zilla::Util::BundleInfo->new(
272             bundle_name => '@RJBS',
273             bundle_payload => [
274             '-myparam' => 'foo',
275             'param' => 'bar',
276             'param' => 'quux'
277             ]
278             );
279             for my $plugin ( $info->plugins ) {
280             print $plugin->to_dist_ini; # emit each plugin in order in dist.ini format.
281             }
282              
283             =head1 METHODS
284              
285             =head2 C<plugins>
286              
287             Returns a list of L<< C<::BundleInfo::Plugin>|Dist::Zilla::Util::BundleInfo::Plugin >> instances
288             representing the configuration data for each section returned by the bundle.
289              
290             =head1 ATTRIBUTES
291              
292             =head2 C<bundle_name>
293              
294             The name of the bundle to get info from
295              
296             ->new( bundle_name => '@RJBS' )
297             ->new( bundle_name => 'Dist::Zilla::PluginBundle::RJBS' )
298              
299             =head2 C<bundle_dz_name>
300              
301             The name to pass to the bundle in the C<name> parameter.
302              
303             This is synonymous to the value of C<Foo> in
304              
305             [@Bundle / Foo]
306              
307             =head2 C<bundle_payload>
308              
309             The parameter list to pass to the bundle.
310              
311             This is synonymous with the properties passed in C<dist.ini>
312              
313             {
314             foo => 'bar',
315             quux => 'do',
316             multivalue => [ 'a' , 'b', 'c' ]
317             }
318              
319             C<==>
320              
321             [
322             'foo' => 'bar',
323             'quux' => 'do',
324             'multivalue' => 'a',
325             'multivalue' => 'b',
326             'multivalue' => 'c',
327             ]
328              
329             C<==>
330              
331             foo = bar
332             quux = do
333             multivalue = a
334             multivalue = b
335             multivalue = c
336              
337             =head1 PRIVATE FUNCTIONS
338              
339             =head2 C<_coerce_bundle_name>
340              
341             _coerce_bundle_name('@Foo') # Dist::Zilla::PluginBundle::Foo
342              
343             =head2 C<_isa_bundle>
344              
345             _isa_bundle('Foo::Bar::Baz') # fatals if Foo::Bar::Baz can't do ->bundle_config
346              
347             =begin MetaPOD::JSON v1.1.0
348              
349             {
350             "namespace":"Dist::Zilla::Util::BundleInfo",
351             "interface":"class",
352             "inherits":"Moo::Object"
353             }
354              
355              
356             =end MetaPOD::JSON
357              
358             =head1 AUTHOR
359              
360             Kent Fredric <kentnl@cpan.org>
361              
362             =head1 COPYRIGHT AND LICENSE
363              
364             This software is copyright (c) 2015 by Kent Fredric <kentfredric@gmail.com>.
365              
366             This is free software; you can redistribute it and/or modify it under
367             the same terms as the Perl 5 programming language system itself.
368              
369             =cut