File Coverage

blib/lib/Pod/Weaver/PluginBundle/Author/KENTNL/Role/Easy.pm
Criterion Covered Total %
statement 60 70 85.7
branch 4 16 25.0
condition 1 3 33.3
subroutine 17 18 94.4
pod 3 4 75.0
total 85 111 76.5


line stmt bran cond sub pod time code
1 7     7   42132 use 5.006; # our
  7         19  
2 7     7   28 use strict;
  7         9  
  7         138  
3 7     7   25 use warnings;
  7         8  
  7         430  
4              
5             package Pod::Weaver::PluginBundle::Author::KENTNL::Role::Easy;
6              
7             our $VERSION = '0.001003';
8              
9             # ABSTRACT: Moo based instance based sugar syntax for mutable configuration declaration
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13 7     7   28 use Carp qw( carp );
  7         6  
  7         370  
14 7     7   438 use Moo::Role qw( has requires );
  7         12860  
  7         40  
15 7     7   4208 use Try::Tiny qw( try catch );
  7         5650  
  7         358  
16 7     7   33 use Module::Runtime qw( require_module );
  7         10  
  7         43  
17 7     7   3221 use Pod::Weaver::Config::Assembler;
  7         4436802  
  7         3533  
18              
19             has '_state' => ( init_arg => undef, is => 'ro' =>, lazy => 1, default => sub { [] } );
20              
21              
22              
23              
24              
25              
26              
27             requires 'bundle_prefix';
28              
29              
30              
31              
32              
33              
34              
35             requires 'instance_config';
36              
37              
38              
39              
40              
41              
42              
43              
44              
45              
46              
47              
48              
49              
50              
51             sub _prefixify {
52 55     55   44 my ( $self, $oldname, ) = @_; # called as ->( name, $pluginame ) just in case
53 55         95 return $self->bundle_prefix . q[/] . $oldname;
54             }
55              
56              
57              
58              
59              
60              
61              
62              
63              
64             sub _push_state {
65 55     55   44 my ( $self, $name, $plugin, $config ) = @_;
66 55         38 push @{ $self->_state }, [ $name, $plugin, $config ];
  55         711  
67 55         214 return;
68             }
69              
70              
71              
72              
73              
74              
75              
76              
77              
78             sub _push_state_prefixed {
79 55     55   49 my ( $self, $name, $plugin, $config ) = @_;
80 55         62 $self->_push_state( $self->_prefixify( $name, $plugin ), $plugin, $config );
81 55         57 return;
82             }
83              
84              
85              
86              
87              
88              
89              
90              
91              
92              
93              
94              
95              
96              
97              
98              
99              
100              
101              
102             sub add_entry {
103 8     8 1 51 my ( $self, $name, $config ) = @_;
104 8 100       21 $config = {} unless defined $config;
105 8         26 my $plugin = Pod::Weaver::Config::Assembler->expand_package($name);
106 8         428 $self->_push_state_prefixed( $name, $plugin, $config );
107 8         11 return;
108             }
109              
110              
111              
112              
113              
114              
115              
116              
117              
118              
119              
120              
121              
122              
123              
124              
125              
126              
127              
128              
129              
130              
131              
132              
133              
134              
135              
136              
137              
138              
139              
140              
141              
142             sub add_named_entry {
143 17     17 1 19 my ( $self, $alias, $plugin_name, $config ) = @_;
144 17 50       25 $config = {} unless defined $config;
145 17         39 my $plugin = Pod::Weaver::Config::Assembler->expand_package($plugin_name);
146 17         617 $self->_push_state_prefixed( $alias, $plugin, $config );
147 17         26 return;
148             }
149              
150              
151              
152              
153              
154              
155              
156              
157              
158              
159              
160              
161              
162              
163              
164             sub inhale_bundle {
165 6     6 1 8 my ( $self, $name, @args ) = @_;
166 6         18 my $plugin = Pod::Weaver::Config::Assembler->expand_package($name);
167             try {
168 6     6   225 require_module($plugin);
169 6         217820 for my $entry ( $plugin->mvp_bundle_config(@args) ) {
170 30         58 $self->_push_state_prefixed( @{$entry} );
  30         42  
171             }
172             }
173             catch {
174 0     0   0 carp "Could not inhale $name: $_";
175 6         258 };
176 6         80 return;
177             }
178              
179              
180              
181              
182              
183             sub mvp_bundle_config {
184 6     6 0 961 my ( $class, $arg ) = @_;
185 6         6 my @args;
186 6 50 33     19 if ( $arg and 'HASH' eq ref $arg ) {
187 0 0       0 push @args, ( 'name' => $arg->{name} ) if exists $arg->{name};
188 0 0       0 push @args, ( 'package' => $arg->{package} ) if exists $arg->{name};
189 0 0       0 if ( exists $arg->{payload} ) {
190 0 0       0 if ( 'HASH' eq ref $arg->{payload} ) {
    0          
191 0         0 push @args, %{ $arg->{payload} };
  0         0  
192             }
193             elsif ( 'ARRAY' eq ref $arg->{payload} ) {
194 0         0 push @args, @{ $arg->{payload} };
  0         0  
195             }
196             else {
197 0         0 carp 'Good luck with that payload buddy';
198             }
199             }
200             }
201 6         31 my $instance = $class->new(@args);
202 6         3093 $instance->instance_config;
203 6         6 return @{ $instance->_state };
  6         73  
204             }
205              
206 7     7   53 no Moo;
  7         8  
  7         53  
207              
208             1;
209              
210             __END__
211              
212             =pod
213              
214             =encoding UTF-8
215              
216             =head1 NAME
217              
218             Pod::Weaver::PluginBundle::Author::KENTNL::Role::Easy - Moo based instance based sugar syntax for mutable configuration declaration
219              
220             =head1 VERSION
221              
222             version 0.001003
223              
224             =head1 QUICK REFERENCE
225              
226             [>] bundle_prefix() # [>] String
227             [>] instance_config() # [>] mutator
228             ->add_entry( $plugin_name, $confighash ) # mutator
229             ->add_named_entry( $name, $plugin_name, $confighash ) # mutator
230             ->inhale_bundle( $name, $arg ) # mutator
231              
232             ->mvp_bundle_config( $arg ) # List
233              
234             ->_push_state_prefixed( $name, $plugin_name, $confighash ) # mutator
235             ->_push_state( $name, $plugin_name, $confighash ) # mutator
236             ->_prefixify( $name, $plugin_name ) # String
237             ->_state() # ArrayRef
238              
239              
240             -~- MVP Magic -~-
241             [>?] mvp_multivalue_args # [>] List[Str]
242             [>?] mvp_aliases # [>] HashRef
243             [>?] mvp_bundle_config # [>] List
244              
245             =head1 SYNOPSIS
246              
247             package Foo;
248             use Moo qw( with );
249             with 'Pod::Weaver::PluginBundle::Author::KENTNL::Role::Easy'; # this is the hardest part ;)
250              
251             sub bundle_prefix { 'some_identifier_@foo_is_good' }
252              
253             has 'ox_bollocks' => ( is => ro => ..., default => sub { 1 } );
254             has 'an_mvp_thinger' => ( is => ro => ..., default => sub { [] } );
255              
256             sub mvp_multivalue_args { 'an_mvp_thinger' };
257              
258             sub instance_config {
259             my ( $self ) = @_;
260             $self->add_entry( $pluginname, $config );
261             if ( $self->ox_bollocks ) {
262             $self->add_named_entry( $alias, $pluginname, $config );
263             }
264             for my $thing ( @{ $self->an_mvp_thinger } ) {
265             ... # more things
266             }
267             $self->inhale_bundle( '@bundle', $maybeconfig );
268             }
269             1;
270              
271             =head1 REQUIRED METHODS
272              
273             =head2 C<bundle_prefix>
274              
275             Must return a string to prefix on B<ALL> entries.
276              
277             =head2 C<instance_config>
278              
279             Will be called for you to mutate state prior to returning the generated state.
280              
281             =head1 METHODS
282              
283             =head2 C<add_entry>
284              
285             Add a simple plugin to this bundle.
286              
287             ->add_entry( "Foo" , { a => 1 , b => [ 1, 2 ] } );
288             ->add_entry( $name , { $config } );
289              
290             Roughly corresponds to
291              
292             [Foo / SomePrefix/Foo]
293             a = 1
294             b = 1
295             b = 2
296              
297             For things that need to have unique names for plugins, use C<add_named_entry>
298              
299             =head2 C<add_named_entry>
300              
301             ->add_named_entry( "Foo" , "Bar" , { a => 1, b => [1, 2]});
302             ->add_entry( $name , { $config } );
303              
304             Roughly corresponds to
305              
306             [Bar / SomePrefix/Foo]
307             a = 1
308             b = 1
309             b = 2
310              
311             B<NOTE:> C<$name> is subject to prefix expansion. Use C<$config> explicitly to avoid
312             side effects. That is, this mechanism only serves to create unique identifiers I<within> a bundle.
313              
314             Bundle prefixing should make sure it stays unique beyond that.
315              
316             Relying on "name" field to communicate state within a bundle will break as soon as your bundle is C<inhaled>.
317              
318             So. Use C<$config> ;)
319              
320             ->add_named_entry("SYNOPSIS", "Generic"); # Bad, will look for MyPrefix/SYNOPSIS, which won't exist.
321              
322             ->add_named_entry("SYNOPSIS", "Generic", { header => 'SYNOPSIS' }); # Resilient code.
323             # { name => "MyPrefix/SYNOPIS",
324             # package => "Pod::Weaver::Section::Generic",
325             # payload => { header => 'SYNOPSIS' }
326             # }
327              
328             =head2 C<inhale_bundle>
329              
330             Include another bundle prefixed as a component of your own.
331              
332             ->inhale_bundle('@foobundle'); # Beginners mode
333             ->inhale_bundle('@foobundle', $confighash ); # EXPERT MODE
334              
335             Also, be aware that any bundle that has not been designed to be prefix resilient ( see L</add_named_entry> )
336             will be likely broken if it relies on the "name" element to be meaningful.
337              
338             You can circumvent this if you wear your expert hat and overload L</_prefixify> and/or do it all yourself with L</_push_state>
339              
340             =head1 PRIVATE METHODS
341              
342             =head2 C<_prefixify>
343              
344             Expands simple aliases into prefixed ones
345              
346             ->_prefixify( $oldname, $plugin_package ) >> String
347              
348             Default implementation is simply
349              
350             ->bundle_prefix . q[/] . $oldname
351              
352             And C<$plugin_package> is passed for overloading convenience if you ever want to do something magical.
353              
354             =head2 C<_push_state>
355              
356             Appends a configuration line to the internal array
357              
358             ->_push_state( $raw_name, $plugin_package, $config_hash )
359              
360             =head2 C<_push_state_prefixed>
361              
362             Appends a configuration line to the internal array with C<$unprefixed_name> prefixed
363              
364             ->_push_state_prefixed( $unprefixed_name, $plugin_package, $config_hash )
365              
366             =for Pod::Coverage mvp_bundle_config
367              
368             =head1 AUTHOR
369              
370             Kent Fredric <kentnl@cpan.org>
371              
372             =head1 COPYRIGHT AND LICENSE
373              
374             This software is copyright (c) 2017 by Kent Fredric <kentfredric@gmail.com>.
375              
376             This is free software; you can redistribute it and/or modify it under
377             the same terms as the Perl 5 programming language system itself.
378              
379             =cut