File Coverage

lib/Dist/Zilla/Util/EmulatePhase.pm
Criterion Covered Total %
statement 52 112 46.4
branch 10 28 35.7
condition 4 9 44.4
subroutine 12 12 100.0
pod 5 5 100.0
total 83 166 50.0


line stmt bran cond sub pod time code
1 4     4   49244 use 5.008; # utf8
  4         9  
  4         183  
2 4     4   22 use strict;
  4         4  
  4         101  
3 4     4   12 use warnings;
  4         10  
  4         94  
4 4     4   2066 use utf8;
  4         31  
  4         14  
5              
6             package Dist::Zilla::Util::EmulatePhase;
7              
8             our $VERSION = '1.001001';
9              
10             #ABSTRACT: Nasty tools for probing Dist::Zilla's internal state.
11              
12             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
13              
14 4     4   270 use Scalar::Util qw( refaddr );
  4         4  
  4         309  
15 4     4   1492 use Try::Tiny;
  4         5607  
  4         280  
16 4         30 use Sub::Exporter -setup => {
17             exports => [qw( deduplicate expand_modname get_plugins get_metadata get_prereqs)],
18             groups => [ default => [qw( -all )] ],
19 4     4   2062 };
  4         37425  
20              
21              
22              
23              
24              
25              
26              
27              
28              
29              
30              
31              
32              
33              
34              
35              
36              
37              
38              
39              
40              
41             sub deduplicate {
42 3     3 1 50 my ( @args, ) = @_;
43 3         3 my ( %seen, @out );
44 3         6 for my $item (@args) {
45 32 100       53 push @out, $item unless exists $seen{$item};
46 32         37 $seen{$item} = 1;
47             }
48 3         19 return @out;
49             }
50              
51              
52              
53              
54              
55              
56              
57              
58              
59              
60             sub expand_modname {
61             ## no critic ( RegularExpressions::RequireDotMatchAnything RegularExpressions::RequireExtendedFormatting RegularExpressions::RequireLineBoundaryMatching )
62 2     2 1 7 my $v = shift;
63 2         8 $v =~ s/^-/Dist::Zilla::Role::/;
64 2         6 $v =~ s/^=/Dist::Zilla::Plugin::/;
65 2         8 return $v;
66             }
67              
68              
69              
70              
71              
72              
73              
74              
75              
76              
77              
78              
79              
80              
81              
82             sub get_plugins {
83 3     3 1 599 my ($config) = @_;
84 3 100 66     14 if ( not $config or not exists $config->{'zilla'} ) {
85 1         4 require Carp;
86             ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
87 1         178 Carp::croak('get_plugins({ zilla => $something }) is a minimum requirement');
88             }
89 2         3 my $zilla = $config->{zilla};
90              
91 2 50       15 if ( not $zilla->isa('Dist::Zilla') ) {
92              
93             #require Carp;
94             #Carp::cluck('get_plugins({ zilla => $something}) is not Dist::Zilla, might be a bug');
95             }
96              
97 2         3 my $plugins = [];
98              
99 2 100       10 if ( $zilla->can('plugins') ) {
100 1         3 $plugins = $zilla->plugins();
101             }
102             else {
103 1         3 return;
104             }
105              
106 1 50       3 if ( not @{$plugins} ) {
  1         3  
107 1         3 return;
108             }
109              
110 0 0       0 if ( exists $config->{'with'} ) {
111 0         0 my $old_plugins = $plugins;
112 0         0 $plugins = [];
113 0         0 for my $with ( map { expand_modname($_) } @{ $config->{with} } ) {
  0         0  
  0         0  
114 0         0 push @{$plugins}, grep { $_->does($with) } @{$old_plugins};
  0         0  
  0         0  
  0         0  
115             }
116             }
117              
118 0 0       0 if ( exists $config->{'skip_with'} ) {
119 0         0 for my $value ( @{ $config->{'skip_with'} } ) {
  0         0  
120 0         0 my $without = expand_modname($value);
121 0         0 $plugins = [ grep { not $_->does($without) } @{$plugins} ];
  0         0  
  0         0  
122             }
123             }
124              
125 0 0       0 if ( exists $config->{'isa'} ) {
126 0         0 my $old_plugins = $plugins;
127 0         0 $plugins = [];
128 0         0 for my $isa_package ( @{ $config->{isa} } ) {
  0         0  
129 0         0 my $isa = expand_modname($isa_package);
130 0         0 push @{$plugins}, grep { $_->isa($isa) } @{$old_plugins};
  0         0  
  0         0  
  0         0  
131             }
132             }
133              
134 0 0       0 if ( exists $config->{'skip_isa'} ) {
135 0         0 for my $value ( @{ $config->{'skip_isa'} } ) {
  0         0  
136 0         0 my $isnt = expand_modname($value);
137 0         0 $plugins = [ grep { not $_->isa($isnt) } @{$plugins} ];
  0         0  
  0         0  
138             }
139             }
140              
141 0         0 return deduplicate( @{$plugins} );
  0         0  
142             }
143              
144              
145              
146              
147              
148              
149              
150              
151              
152              
153              
154              
155              
156              
157              
158              
159              
160              
161              
162              
163              
164             sub get_metadata {
165 1     1 1 424 my ($config) = @_;
166 1 50 33     6 if ( not $config or not exists $config->{'zilla'} ) {
167 1         5 require Carp;
168             ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
169 1         72 Carp::croak('get_metadata({ zilla => $something }) is a minimum requirement');
170             }
171 0 0       0 $config->{with} = [] unless exists $config->{'with'};
172 0         0 push @{ $config->{'with'} }, '-MetaProvider';
  0         0  
173 0         0 my @plugins = get_plugins($config);
174 0         0 my $meta = {};
175 0         0 for my $value (@plugins) {
176 0         0 require Hash::Merge::Simple;
177 0         0 $meta = Hash::Merge::Simple::merge( $meta, $value->metadata );
178             }
179 0         0 return $meta;
180             }
181              
182              
183              
184              
185              
186              
187              
188              
189              
190              
191              
192              
193              
194              
195              
196              
197              
198              
199              
200              
201              
202             sub get_prereqs {
203 1     1 1 230 my ($config) = @_;
204 1 50 33     5 if ( not $config or not exists $config->{'zilla'} ) {
205 1         4 require Carp;
206             ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
207 1         69 Carp::croak('get_prereqs({ zilla => $something }) is a minimum requirement');
208             }
209              
210 0 0         $config->{'with'} = [] unless exists $config->{'with'};
211 0           push @{ $config->{'with'} }, '-PrereqSource';
  0            
212 0           my @plugins = get_plugins($config);
213              
214             # This is a bit nasty, because prereqs call back into their data and mess with zilla :/
215 0           require Dist::Zilla::Util::EmulatePhase::PrereqCollector;
216 0           my $zilla = Dist::Zilla::Util::EmulatePhase::PrereqCollector->new( shadow_zilla => $config->{zilla} );
217 0           for my $value (@plugins) {
218             { # subverting!
219             ## no critic ( Variables::ProhibitLocalVars )
220 0           local $value->{zilla} = $zilla;
  0            
221 0           $value->register_prereqs;
222             }
223 0 0         if ( refaddr($zilla) eq refaddr( $value->{zilla} ) ) {
224 0           require Carp;
225 0           Carp::croak('Zilla did not reset itself');
226             }
227             }
228 0           $zilla->prereqs->finalize;
229 0           return $zilla->prereqs;
230             }
231              
232             1;
233              
234             __END__
235              
236             =pod
237              
238             =encoding UTF-8
239              
240             =head1 NAME
241              
242             Dist::Zilla::Util::EmulatePhase - Nasty tools for probing Dist::Zilla's internal state.
243              
244             =head1 VERSION
245              
246             version 1.001001
247              
248             =head1 QUICK REFERENCE
249              
250             ::deduplicate(list=[]) # ArrayRef
251             ::expand_modname(options=[])
252             0 => $shortname
253             ::get_plugins(options={}) # ArrayRef[Object]
254             ^zilla =>
255             ?with => [rolelist]
256             ?skip_with => [rolelist]
257             ?isa => [isalist]
258             ?skip_isa => [isalist]
259             ::get_metadata(options={}) # HashRef
260             ^zilla =>
261             ?with => [rolelist]
262             ::get_prereqs(options={}) # HashRef
263             ^zilla =>
264             ?with => [rolelist]
265              
266             =head1 METHODS
267              
268             =head2 deduplicate
269              
270             Internal utility that de-duplicates references by ref-addr alone.
271              
272             my $array = [];
273             is_deeply( [ deduplicate( $array, $array ) ],[ $array ] )
274              
275             =head2 expand_modname
276              
277             Internal utility to expand various shorthand notations to full ones.
278              
279             expand_modname('-MetaProvider') == 'Dist::Zilla::Role::MetaProvider';
280             expand_modname('=MetaNoIndex') == 'Dist::Zilla::Plugin::MetaNoIndex';
281              
282             =head2 get_plugins
283              
284             Probe Dist::Zilla's plugin registry and get items matching a specification
285              
286             my @plugins = get_plugins({
287             zilla => $self->zilla,
288             with => [qw( -MetaProvider -SomethingElse )],
289             skip_with => [qw( -SomethingBadThatIsAMetaProvider )],
290             isa => [qw( =SomePlugin =SomeOtherPlugin )],
291             skip_isa => [qw( =OurPlugin )],
292             });
293              
294             =head2 get_metadata
295              
296             Emulates Dist::Zilla's internal metadata aggregation and does it all again.
297              
298             Minimum Usage:
299              
300             my $metadata = get_metadata({ zilla => $self->zilla });
301              
302             Extended usage:
303              
304             my $metadata = get_metadata({
305             $zilla = $self->zilla,
306             ... more params to get_plugins ...
307             ... ie: ...
308             with => [qw( -MetaProvider )],
309             isa => [qw( =MetaNoIndex )],
310             });
311              
312             =head2 get_prereqs
313              
314             Emulates Dist::Zilla's internal prereqs aggregation and does it all again.
315              
316             Minimum Usage:
317              
318             my $prereqs = get_prereqs({ zilla => $self->zilla });
319              
320             Extended usage:
321              
322             my $metadata = get_prereqs({
323             $zilla = $self->zilla,
324             ... more params to get_plugins ...
325             ... ie: ...
326             with => [qw( -PrereqSource )],
327             isa => [qw( =AutoPrereqs )],
328             });
329              
330             =begin MetaPOD::JSON v1.1.0
331              
332             {
333             "namespace":"Dist::Zilla::Util::EmulatePhase",
334             "interface":"exporter"
335             }
336              
337              
338             =end MetaPOD::JSON
339              
340             =head1 AUTHOR
341              
342             Kent Fredric <kentnl@cpan.org>
343              
344             =head1 COPYRIGHT AND LICENSE
345              
346             This software is copyright (c) 2014 by Kent Fredric <kentnl@cpan.org>.
347              
348             This is free software; you can redistribute it and/or modify it under
349             the same terms as the Perl 5 programming language system itself.
350              
351             =cut