File Coverage

blib/lib/Dist/Zilla/Role/BundleDeps.pm
Criterion Covered Total %
statement 41 42 97.6
branch 3 4 75.0
condition n/a
subroutine 9 9 100.0
pod 1 1 100.0
total 54 56 96.4


line stmt bran cond sub pod time code
1 2     2   24828 use 5.006;
  2         4  
2 2     2   7 use strict;
  2         4  
  2         41  
3 2     2   13 use warnings;
  2         3  
  2         140  
4              
5             package Dist::Zilla::Role::BundleDeps;
6              
7             our $VERSION = '0.002005';
8              
9             # ABSTRACT: Automatically add all plugins in a bundle as dependencies
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13              
14              
15              
16              
17              
18              
19              
20              
21              
22              
23              
24 2     2   409 use Moose::Role qw( around );
  2         295809  
  2         13  
25              
26              
27              
28              
29              
30              
31              
32              
33              
34              
35              
36              
37              
38              
39              
40              
41              
42              
43              
44              
45              
46              
47              
48             sub bundledeps_defaults {
49             return {
50 1     1 1 5 -phase => 'develop',
51             -relationship => 'requires',
52             };
53             }
54              
55             around bundle_config => sub {
56             my ( $orig, $self, $section, ) = @_;
57             my $myconf = $self->bundledeps_defaults;
58             for my $param (qw( phase relationship )) {
59             my $field = 'bundledeps_' . $param;
60             next unless exists $section->{payload}->{$field};
61             $myconf->{ q[-] . $param } = delete $section->{payload}->{$field};
62             }
63             my (@config) = $self->$orig($section);
64             my $reqs = $self->_extract_plugin_prereqs(@config);
65             return ( @config, $self->_create_prereq_plugin( $reqs => $myconf ) );
66             };
67              
68 2     2   6092 no Moose::Role;
  2         2  
  2         10  
69              
70             sub _bundle_alias {
71 1     1   2 my ($self) = @_;
72 1         11 my $ns = $self->meta->name;
73 1 50       97 if ( $ns =~ /\ADist::Zilla::PluginBundle::(.*\z)/msx ) {
74 0         0 return q[@] . $1;
75             }
76 1         5 return $ns;
77             }
78              
79             sub _extract_plugin_prereqs {
80 1     1   2 my ( undef, @config ) = @_;
81 1         1003 require CPAN::Meta::Requirements;
82 1         7114 my $reqs = CPAN::Meta::Requirements->new();
83 1         27 for my $item (@config) {
84 2         200 my ( undef, $module, $conf ) = @{$item};
  2         11  
85 2         5 my $version = 0;
86 2 100       10 $version = $conf->{':version'} if exists $conf->{':version'};
87 2         9 $reqs->add_string_requirement( $module, $version );
88             }
89 1         57 return $reqs;
90             }
91              
92             sub _create_prereq_plugin {
93 1     1   3 my ( $self, $reqs, $config ) = @_;
94 1         2 my $plugin_conf = { %{$config}, %{ $reqs->as_string_hash } };
  1         6  
  1         5  
95 1         37 my $prereq = [];
96 1         2 push @{$prereq}, $self->_bundle_alias . '/::Role::BundleDeps';
  1         5  
97 1         2 push @{$prereq}, 'Dist::Zilla::Plugin::Prereqs';
  1         3  
98 1         1 push @{$prereq}, $plugin_conf;
  1         2  
99 1         23 return $prereq;
100             }
101              
102             1;
103              
104             __END__
105              
106             =pod
107              
108             =encoding UTF-8
109              
110             =head1 NAME
111              
112             Dist::Zilla::Role::BundleDeps - Automatically add all plugins in a bundle as dependencies
113              
114             =head1 VERSION
115              
116             version 0.002005
117              
118             =head1 SYNOPSIS
119              
120             package blahblahblah;
121             use Moose;
122             ...
123             with 'Dist::Zilla::Role::PluginBundle';
124             with 'Dist::Zilla::Role::BundleDeps';
125              
126             Dependencies appear now for all plugins returned.
127              
128             =head1 DESCRIPTION
129              
130             This role attempts to solve the problem of communicating dependencies to META.* from bundles
131             in a different way.
132              
133             My first attempt was L<< C<[Prereqs::Plugins]>|Dist::Zilla::Plugins::Prereqs::Plugins >>, which added
134             all values that are seen in the C<dist.ini> to dependencies.
135              
136             However, that was inherently limited, as the C<:version> specifier
137             is lost before the plugins appear on C<< $zilla->plugins >>
138              
139             This Role however, can see any declarations of C<:version> your bundle advertises,
140             by standing between your C<bundle_config> method and C<Dist::Zilla>
141              
142             =head1 METHODS
143              
144             =head2 C<bundledeps_defaults>
145              
146             This method provides the C<HashRef> of defaults to use for the generated C<Prereqs> section.
147              
148             Because this role is intended to advertise Plugin Bundle dependencies, and because those
149             dependencies will be "develop" dependencies everywhere other than the bundle itself,
150             our defaults are:
151              
152             {
153             -phase => develop,
154             -relationship => requires,
155             }
156              
157             These can be overridden when consuming a bundle in C<dist.ini>
158              
159             [@Author::MyBundle]
160             ; authordep Dist::Zilla::Role::BundleDeps
161             bundledeps_phase = runtime
162             bundledeps_relationship = requires
163              
164             =begin MetaPOD::JSON v1.1.0
165              
166             {
167             "namespace":"Dist::Zilla::Role::BundleDeps",
168             "interface":"role"
169             }
170              
171              
172             =end MetaPOD::JSON
173              
174             =head1 LIMITATIONS
175              
176             =head2 Self References in develop_requires
177              
178             If you bundle plugins with your bundle, and use those plugins in the bundle,
179             you'll risk a self-reference problem, which may be solved in a future release of Dist::Zilla.
180              
181             Until then, you'll need to possibly use L<< C<[RemovePrereqs]>|Dist::Zilla::Plugin::RemovePrereqs >>
182             to trim self-references.
183              
184             =head2 Bootstrap problems on Bundles
185              
186             When using your bundle to ship itself, the use of this role can imply some confusion if the role is not installed,
187             as C<dzil listdeps> will require this role present to work.
188              
189             It is subsequently recommended to state an explicit C<AuthorDep> in C<dist.ini> to avoid this.
190              
191             [Bootstrap::lib]
192              
193             [@Author::MyBundle]
194             ; authordep Dist::Zilla::Role::BundleDeps
195             bundledeps_phase = runtime
196             bundledeps_relationship = requires
197              
198             =head1 SEE ALSO
199              
200             L<< C<[BundleInspector]>|Dist::Zilla::Plugin::BundleInspector >>
201              
202             =head1 AUTHOR
203              
204             Kent Fredric <kentnl@cpan.org>
205              
206             =head1 COPYRIGHT AND LICENSE
207              
208             This software is copyright (c) 2017 by Kent Fredric <kentfredric@gmail.com>.
209              
210             This is free software; you can redistribute it and/or modify it under
211             the same terms as the Perl 5 programming language system itself.
212              
213             =cut