File Coverage

blib/lib/Dist/Zilla/Util/EmulatePhase.pm
Criterion Covered Total %
statement 97 108 89.8
branch 24 28 85.7
condition 6 9 66.6
subroutine 11 11 100.0
pod 5 5 100.0
total 143 161 88.8


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