File Coverage

blib/lib/Dist/Zilla/Plugin/ModuleBuild.pm
Criterion Covered Total %
statement 79 79 100.0
branch 12 14 85.7
condition 1 2 50.0
subroutine 17 17 100.0
pod 0 6 0.0
total 109 118 92.3


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::ModuleBuild 6.029;
2             # ABSTRACT: build a Build.PL that uses Module::Build
3              
4 3     3   2934 use Moose;
  3         7  
  3         33  
5             with (
6             'Dist::Zilla::Role::BuildPL',
7             'Dist::Zilla::Role::PrereqSource',
8             'Dist::Zilla::Role::FileGatherer',
9             'Dist::Zilla::Role::TextTemplate',
10             );
11              
12 3     3   22790 use Dist::Zilla::Pragmas;
  3         13  
  3         34  
13              
14 3     3   28 use namespace::autoclean;
  3         11  
  3         33  
15              
16 3     3   347 use CPAN::Meta::Requirements 2.121; # requirements_for_module
  3         104  
  3         89  
17 3     3   466 use Dist::Zilla::File::InMemory;
  3         10  
  3         120  
18 3     3   27 use List::Util 'first';
  3         12  
  3         257  
19 3     3   1523 use Data::Dumper;
  3         13368  
  3         4766  
20              
21             #pod =head1 DESCRIPTION
22             #pod
23             #pod This plugin will create a F<Build.PL> for installing the dist using
24             #pod L<Module::Build>.
25             #pod
26             #pod =cut
27              
28             #pod =attr mb_version
29             #pod
30             #pod B<Optional:> Specify the minimum version of L<Module::Build> to depend on.
31             #pod
32             #pod Defaults to 0.3601 if a sharedir is being used, otherwise 0.28.
33             #pod
34             #pod =attr mb_class
35             #pod
36             #pod B<Optional:> Specify the class to use to create the build object. Defaults
37             #pod to C<Module::Build> itself. If another class is specified, then the value
38             #pod of mb_lib will be used to generate a line like C<use lib 'inc'> to be added
39             #pod to the generated Build.PL file.
40             #pod
41             #pod =attr mb_lib
42             #pod
43             #pod B<Optional:> Specify the list of directories to be passed to lib when using
44             #pod mb_class. Defaults to C<inc>.
45             #pod
46             #pod =attr build_element
47             #pod
48             #pod Anything given in a C<build_element> option will be added as a build element
49             #pod with Module::Build's L<add_build_element> method.
50             #pod
51             #pod =cut
52              
53             has 'mb_version' => (
54             isa => 'Str',
55             is => 'rw',
56             lazy => 1,
57             default => sub {
58             my $self = shift;
59             keys %{$self->zilla->_share_dir_map} ? '0.3601' : '0.28';
60             },
61             );
62              
63             has 'mb_class' => (
64             isa => 'Str',
65             is => 'rw',
66             default => 'Module::Build',
67             );
68              
69             has 'mb_lib' => (
70             isa => 'Str',
71             is => 'rw',
72             default => 'inc'
73             );
74              
75             has 'build_element' => (
76             isa => 'ArrayRef[Str]',
77             is => 'rw',
78             default => sub { [] },
79             );
80              
81 7     7 0 1912 sub mvp_multivalue_args { return qw(build_element) }
82              
83             my $template = q|
84             # This file was automatically generated by {{ $generated_by }}.
85             use strict;
86             use warnings;
87              
88             use Module::Build {{ $plugin->mb_version }};
89             {{ $plugin->_use_custom_class }}
90              
91             my {{ $module_build_args }}
92              
93             my {{ $fallback_build_prereqs }}
94              
95             unless ( eval { Module::Build->VERSION(0.4004) } ) {
96             delete $module_build_args{test_requires};
97             $module_build_args{build_requires} = \%fallback_build_requires;
98             }
99              
100             my $build = {{ $plugin->mb_class }}->new(%module_build_args);
101             {{ $plugin->_add_build_elements }}
102              
103             $build->create_build_script;
104             |;
105              
106             sub _use_custom_class {
107 10     10   21098 my ($self) = @_;
108 10         369 my $class = $self->mb_class;
109 10 100       40 if ( $class eq 'Module::Build' ) {
110 6         45 return "";
111             }
112             else {
113 4         136 return sprintf "use lib qw{%s}; use $class;", join ' ', split ',', $self->mb_lib;
114             }
115             }
116              
117             sub _dump_as {
118 14     14   669 my ($self, $ref, $name) = @_;
119 14         85 require Data::Dumper;
120 14         114 my $dumper = Data::Dumper->new( [ $ref ], [ $name ] );
121 14         525 $dumper->Sortkeys( 1 );
122 14         165 $dumper->Indent( 1 );
123 14         212 $dumper->Useqq( 1 );
124 14         133 return $dumper->Dump;
125             }
126              
127             sub _add_build_elements {
128 8 100   8   507 my @elems = @{ shift->build_element } or return '';
  8         311  
129 2         19 return '$build->add_build_element($_) for qw(' . join(' ', @elems) . ');';
130             }
131              
132             sub register_prereqs {
133 7     7 0 34 my ($self) = @_;
134              
135 7         241 $self->zilla->register_prereqs(
136             { phase => 'configure' },
137             'Module::Build' => $self->mb_version,
138             );
139              
140 7         255 $self->zilla->register_prereqs(
141             { phase => 'build' },
142             'Module::Build' => $self->mb_version,
143             );
144             }
145              
146             sub module_build_args {
147 7     7 0 22 my ($self) = @_;
148              
149 1         4 my @exe_files = map { $_->name }
150 7         15 @{ $self->zilla->find_files(':ExecFiles') };
  7         214  
151              
152             $self->log_fatal("can't install files with whitespace in their names")
153 7 50       43 if grep { /\s/ } @exe_files;
  1         8  
154              
155 7         235 my $prereqs = $self->zilla->prereqs;
156 7         70 my %prereqs = (
157             configure_requires => $prereqs->requirements_for(qw(configure requires)),
158             build_requires => $prereqs->requirements_for(qw(build requires)),
159             test_requires => $prereqs->requirements_for(qw(test requires)),
160             requires => $prereqs->requirements_for(qw(runtime requires)),
161             recommends => $prereqs->requirements_for(qw(runtime recommends)),
162             );
163              
164 7         614 my $name = $self->zilla->name =~ s/-/::/gr;
165              
166             return {
167             module_name => $name,
168             license => $self->zilla->license->meta_yml_name,
169             dist_abstract => $self->zilla->abstract,
170             dist_name => $self->zilla->name,
171             dist_version => $self->zilla->version,
172 7         198 dist_author => [ @{ $self->zilla->authors } ],
173             @exe_files ? ( script_files => [ sort @exe_files ] ) : (),
174 7         201 ( keys %{$self->zilla->_share_dir_map} ? (share_dir => $self->zilla->_share_dir_map) : ()),
175              
176 7 100       205 (map {; my $modules = $prereqs{$_}->as_string_hash; keys %$modules ? ( $_ => $modules ) : () } keys %prereqs),
  35 100       103  
  35 100       1493  
177             recursive_test_files => 1,
178             };
179             }
180              
181             sub fallback_build_requires {
182 7     7 0 21 my $self = shift;
183 7         256 my $prereqs = $self->zilla->prereqs;
184 7         58 my $merged = CPAN::Meta::Requirements->new;
185 7         131 for my $phase ( qw/build test/ ) {
186 14         1072 my $req = $prereqs->requirements_for($phase, 'requires');
187 14         645 $merged->add_requirements( $req );
188             };
189 7         458 return $self->_dump_as( $merged->as_string_hash, '*fallback_build_requires' );
190             }
191              
192             sub gather_files {
193 7     7 0 29 my ($self) = @_;
194              
195 7         51 require Dist::Zilla::File::InMemory;
196              
197 7         323 my $file = Dist::Zilla::File::InMemory->new({
198             name => 'Build.PL',
199             content => $template, # template evaluated later
200             });
201              
202 7         53 $self->add_file($file);
203 7         45 return;
204             }
205              
206             sub setup_installer {
207 7     7 0 24 my ($self) = @_;
208              
209 7 50       246 $self->log_fatal("can't build Build.PL; license has no known META.yml value")
210             unless $self->zilla->license->meta_yml_name;
211              
212 7         99 my $module_build_args = $self->module_build_args;
213              
214 7         277 $self->__module_build_args($module_build_args);
215              
216 7         38 my $dumped_args = $self->_dump_as($module_build_args, '*module_build_args');
217              
218 7         827 my $fallback_build_requires = $self->fallback_build_requires;
219              
220 7     34   319 my $file = first { $_->name eq 'Build.PL' } @{$self->zilla->files};
  34         144  
  7         241  
221              
222 7         76 $self->log_debug([ 'updating contents of Build.PL in memory' ]);
223 7   50     246 my $content = $self->fill_in_string(
224             $file->content,
225             {
226             plugin => \$self,
227             module_build_args => \$dumped_args,
228             fallback_build_prereqs => \$fallback_build_requires,
229             generated_by => \sprintf("%s v%s",
230             ref($self), $self->VERSION || '(dev)'),
231             },
232             );
233              
234 7         46 $file->content($content);
235              
236 7         33 return;
237             }
238              
239             # XXX: Just here to facilitate testing. -- rjbs, 2010-03-20
240             has __module_build_args => (
241             is => 'rw',
242             isa => 'HashRef',
243             );
244              
245             __PACKAGE__->meta->make_immutable;
246             1;
247              
248             #pod =head1 SEE ALSO
249             #pod
250             #pod Core Dist::Zilla plugins:
251             #pod L<@Basic|Dist::Zilla::PluginBundle::Basic>,
252             #pod L<@Filter|Dist::Zilla::PluginBundle::Filter>,
253             #pod L<MakeMaker|Dist::Zilla::Plugin::MakeMaker>,
254             #pod L<Manifest|Dist::Zilla::Plugin::Manifest>.
255             #pod
256             #pod Dist::Zilla roles:
257             #pod L<BuildPL|Dist::Zilla::Role::BuildPL>.
258             #pod
259             #pod =cut
260              
261             __END__
262              
263             =pod
264              
265             =encoding UTF-8
266              
267             =head1 NAME
268              
269             Dist::Zilla::Plugin::ModuleBuild - build a Build.PL that uses Module::Build
270              
271             =head1 VERSION
272              
273             version 6.029
274              
275             =head1 DESCRIPTION
276              
277             This plugin will create a F<Build.PL> for installing the dist using
278             L<Module::Build>.
279              
280             =head1 PERL VERSION
281              
282             This module should work on any version of perl still receiving updates from
283             the Perl 5 Porters. This means it should work on any version of perl released
284             in the last two to three years. (That is, if the most recently released
285             version is v5.40, then this module should work on both v5.40 and v5.38.)
286              
287             Although it may work on older versions of perl, no guarantee is made that the
288             minimum required version will not be increased. The version may be increased
289             for any reason, and there is no promise that patches will be accepted to lower
290             the minimum required perl.
291              
292             =head1 ATTRIBUTES
293              
294             =head2 mb_version
295              
296             B<Optional:> Specify the minimum version of L<Module::Build> to depend on.
297              
298             Defaults to 0.3601 if a sharedir is being used, otherwise 0.28.
299              
300             =head2 mb_class
301              
302             B<Optional:> Specify the class to use to create the build object. Defaults
303             to C<Module::Build> itself. If another class is specified, then the value
304             of mb_lib will be used to generate a line like C<use lib 'inc'> to be added
305             to the generated Build.PL file.
306              
307             =head2 mb_lib
308              
309             B<Optional:> Specify the list of directories to be passed to lib when using
310             mb_class. Defaults to C<inc>.
311              
312             =head2 build_element
313              
314             Anything given in a C<build_element> option will be added as a build element
315             with Module::Build's L<add_build_element> method.
316              
317             =head1 SEE ALSO
318              
319             Core Dist::Zilla plugins:
320             L<@Basic|Dist::Zilla::PluginBundle::Basic>,
321             L<@Filter|Dist::Zilla::PluginBundle::Filter>,
322             L<MakeMaker|Dist::Zilla::Plugin::MakeMaker>,
323             L<Manifest|Dist::Zilla::Plugin::Manifest>.
324              
325             Dist::Zilla roles:
326             L<BuildPL|Dist::Zilla::Role::BuildPL>.
327              
328             =head1 AUTHOR
329              
330             Ricardo SIGNES 😏 <cpan@semiotic.systems>
331              
332             =head1 COPYRIGHT AND LICENSE
333              
334             This software is copyright (c) 2022 by Ricardo SIGNES.
335              
336             This is free software; you can redistribute it and/or modify it under
337             the same terms as the Perl 5 programming language system itself.
338              
339             =cut