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.030;
2             # ABSTRACT: build a Build.PL that uses Module::Build
3              
4 3     3   2702 use Moose;
  3         18  
  3         28  
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   21845 use Dist::Zilla::Pragmas;
  3         10  
  3         31  
13              
14 3     3   37 use namespace::autoclean;
  3         10  
  3         29  
15              
16 3     3   315 use CPAN::Meta::Requirements 2.121; # requirements_for_module
  3         91  
  3         116  
17 3     3   466 use Dist::Zilla::File::InMemory;
  3         10  
  3         121  
18 3     3   30 use List::Util 'first';
  3         7  
  3         292  
19 3     3   1608 use Data::Dumper;
  3         14099  
  3         4846  
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 1818 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   22312 my ($self) = @_;
108 10         446 my $class = $self->mb_class;
109 10 100       37 if ( $class eq 'Module::Build' ) {
110 6         49 return "";
111             }
112             else {
113 4         139 return sprintf "use lib qw{%s}; use $class;", join ' ', split ',', $self->mb_lib;
114             }
115             }
116              
117             sub _dump_as {
118 14     14   672 my ($self, $ref, $name) = @_;
119 14         98 require Data::Dumper;
120 14         120 my $dumper = Data::Dumper->new( [ $ref ], [ $name ] );
121 14         538 $dumper->Sortkeys( 1 );
122 14         125 $dumper->Indent( 1 );
123 14         212 $dumper->Useqq( 1 );
124 14         94 return $dumper->Dump;
125             }
126              
127             sub _add_build_elements {
128 8 100   8   535 my @elems = @{ shift->build_element } or return '';
  8         310  
129 2         19 return '$build->add_build_element($_) for qw(' . join(' ', @elems) . ');';
130             }
131              
132             sub register_prereqs {
133 7     7 0 28 my ($self) = @_;
134              
135 7         239 $self->zilla->register_prereqs(
136             { phase => 'configure' },
137             'Module::Build' => $self->mb_version,
138             );
139              
140 7         266 $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 26 my ($self) = @_;
148              
149 1         5 my @exe_files = map { $_->name }
150 7         17 @{ $self->zilla->find_files(':ExecFiles') };
  7         199  
151              
152             $self->log_fatal("can't install files with whitespace in their names")
153 7 50       47 if grep { /\s/ } @exe_files;
  1         7  
154              
155 7         275 my $prereqs = $self->zilla->prereqs;
156 7         51 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         657 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         210 dist_author => [ @{ $self->zilla->authors } ],
173             @exe_files ? ( script_files => [ sort @exe_files ] ) : (),
174 7         194 ( keys %{$self->zilla->_share_dir_map} ? (share_dir => $self->zilla->_share_dir_map) : ()),
175              
176 7 100       211 (map {; my $modules = $prereqs{$_}->as_string_hash; keys %$modules ? ( $_ => $modules ) : () } keys %prereqs),
  35 100       91  
  35 100       1474  
177             recursive_test_files => 1,
178             };
179             }
180              
181             sub fallback_build_requires {
182 7     7 0 18 my $self = shift;
183 7         247 my $prereqs = $self->zilla->prereqs;
184 7         55 my $merged = CPAN::Meta::Requirements->new;
185 7         159 for my $phase ( qw/build test/ ) {
186 14         1076 my $req = $prereqs->requirements_for($phase, 'requires');
187 14         636 $merged->add_requirements( $req );
188             };
189 7         460 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         59 require Dist::Zilla::File::InMemory;
196              
197 7         389 my $file = Dist::Zilla::File::InMemory->new({
198             name => 'Build.PL',
199             content => $template, # template evaluated later
200             });
201              
202 7         54 $self->add_file($file);
203 7         38 return;
204             }
205              
206             sub setup_installer {
207 7     7 0 24 my ($self) = @_;
208              
209 7 50       254 $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         96 my $module_build_args = $self->module_build_args;
213              
214 7         299 $self->__module_build_args($module_build_args);
215              
216 7         41 my $dumped_args = $self->_dump_as($module_build_args, '*module_build_args');
217              
218 7         958 my $fallback_build_requires = $self->fallback_build_requires;
219              
220 7     34   290 my $file = first { $_->name eq 'Build.PL' } @{$self->zilla->files};
  34         108  
  7         256  
221              
222 7         67 $self->log_debug([ 'updating contents of Build.PL in memory' ]);
223 7   50     284 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         52 $file->content($content);
235              
236 7         36 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.030
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) 2023 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