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.037;
2             # ABSTRACT: build a Build.PL that uses Module::Build
3              
4 3     3   3130 use Moose;
  3         8  
  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   21987 use Dist::Zilla::Pragmas;
  3         10  
  3         31  
13              
14 3     3   21 use namespace::autoclean;
  3         7  
  3         30  
15              
16 3     3   258 use CPAN::Meta::Requirements 2.121; # requirements_for_module
  3         655  
  3         99  
17 3     3   611 use Dist::Zilla::File::InMemory;
  3         45  
  3         140  
18 3     3   21 use List::Util 'first';
  3         7  
  3         256  
19 3     3   1441 use Data::Dumper;
  3         17488  
  3         4822  
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 2636 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   28562 my ($self) = @_;
108 10         545 my $class = $self->mb_class;
109 10 100       42 if ( $class eq 'Module::Build' ) {
110 6         51 return "";
111             }
112             else {
113 4         192 return sprintf "use lib qw{%s}; use $class;", join ' ', split ',', $self->mb_lib;
114             }
115             }
116              
117             sub _dump_as {
118 14     14   704 my ($self, $ref, $name) = @_;
119 14         101 require Data::Dumper;
120 14         154 my $dumper = Data::Dumper->new( [ $ref ], [ $name ] );
121 14         550 $dumper->Sortkeys( 1 );
122 14         124 $dumper->Indent( 1 );
123 14         201 $dumper->Useqq( 1 );
124 14         118 return $dumper->Dump;
125             }
126              
127             sub _add_build_elements {
128 8 100   8   534 my @elems = @{ shift->build_element } or return '';
  8         394  
129 2         76 return '$build->add_build_element($_) for qw(' . join(' ', @elems) . ');';
130             }
131              
132             sub register_prereqs {
133 7     7 0 24 my ($self) = @_;
134              
135 7         309 $self->zilla->register_prereqs(
136             { phase => 'configure' },
137             'Module::Build' => $self->mb_version,
138             );
139              
140 7         309 $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         3 my @exe_files = map { $_->name }
150 7         16 @{ $self->zilla->find_files(':ExecFiles') };
  7         277  
151              
152             $self->log_fatal("can't install files with whitespace in their names")
153 7 50       38 if grep { /\s/ } @exe_files;
  1         4  
154              
155 7         319 my $prereqs = $self->zilla->prereqs;
156 7         43 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         734 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         219 dist_author => [ @{ $self->zilla->authors } ],
173             @exe_files ? ( script_files => [ sort @exe_files ] ) : (),
174 7         228 ( keys %{$self->zilla->_share_dir_map} ? (share_dir => $self->zilla->_share_dir_map) : ()),
175              
176 7 100       268 (map {; my $modules = $prereqs{$_}->as_string_hash; keys %$modules ? ( $_ => $modules ) : () } keys %prereqs),
  35 100       103  
  35 100       1704  
177             recursive_test_files => 1,
178             };
179             }
180              
181             sub fallback_build_requires {
182 7     7 0 17 my $self = shift;
183 7         332 my $prereqs = $self->zilla->prereqs;
184 7         38 my $merged = CPAN::Meta::Requirements->new;
185 7         139 for my $phase ( qw/build test/ ) {
186 14         1243 my $req = $prereqs->requirements_for($phase, 'requires');
187 14         629 $merged->add_requirements( $req );
188             };
189 7         446 return $self->_dump_as( $merged->as_string_hash, '*fallback_build_requires' );
190             }
191              
192             sub gather_files {
193 7     7 0 25 my ($self) = @_;
194              
195 7         59 require Dist::Zilla::File::InMemory;
196              
197 7         353 my $file = Dist::Zilla::File::InMemory->new({
198             name => 'Build.PL',
199             content => $template, # template evaluated later
200             });
201              
202 7         46 $self->add_file($file);
203 7         29 return;
204             }
205              
206             sub setup_installer {
207 7     7 0 24 my ($self) = @_;
208              
209 7 50       319 $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         89 my $module_build_args = $self->module_build_args;
213              
214 7         403 $self->__module_build_args($module_build_args);
215              
216 7         36 my $dumped_args = $self->_dump_as($module_build_args, '*module_build_args');
217              
218 7         860 my $fallback_build_requires = $self->fallback_build_requires;
219              
220 7     34   305 my $file = first { $_->name eq 'Build.PL' } @{$self->zilla->files};
  34         128  
  7         315  
221              
222 7         74 $self->log_debug([ 'updating contents of Build.PL in memory' ]);
223 7   50     429 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         87 $file->content($content);
235              
236 7         38 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.037
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
284             released in the last two to three years. (That is, if the most recently
285             released version is v5.40, then this module should work on both v5.40 and
286             v5.38.)
287              
288             Although it may work on older versions of perl, no guarantee is made that the
289             minimum required version will not be increased. The version may be increased
290             for any reason, and there is no promise that patches will be accepted to
291             lower the minimum required perl.
292              
293             =head1 ATTRIBUTES
294              
295             =head2 mb_version
296              
297             B<Optional:> Specify the minimum version of L<Module::Build> to depend on.
298              
299             Defaults to 0.3601 if a sharedir is being used, otherwise 0.28.
300              
301             =head2 mb_class
302              
303             B<Optional:> Specify the class to use to create the build object. Defaults
304             to C<Module::Build> itself. If another class is specified, then the value
305             of mb_lib will be used to generate a line like C<use lib 'inc'> to be added
306             to the generated Build.PL file.
307              
308             =head2 mb_lib
309              
310             B<Optional:> Specify the list of directories to be passed to lib when using
311             mb_class. Defaults to C<inc>.
312              
313             =head2 build_element
314              
315             Anything given in a C<build_element> option will be added as a build element
316             with Module::Build's L<add_build_element> method.
317              
318             =head1 SEE ALSO
319              
320             Core Dist::Zilla plugins:
321             L<@Basic|Dist::Zilla::PluginBundle::Basic>,
322             L<@Filter|Dist::Zilla::PluginBundle::Filter>,
323             L<MakeMaker|Dist::Zilla::Plugin::MakeMaker>,
324             L<Manifest|Dist::Zilla::Plugin::Manifest>.
325              
326             Dist::Zilla roles:
327             L<BuildPL|Dist::Zilla::Role::BuildPL>.
328              
329             =head1 AUTHOR
330              
331             Ricardo SIGNES 😏 <cpan@semiotic.systems>
332              
333             =head1 COPYRIGHT AND LICENSE
334              
335             This software is copyright (c) 2026 by Ricardo SIGNES.
336              
337             This is free software; you can redistribute it and/or modify it under
338             the same terms as the Perl 5 programming language system itself.
339              
340             =cut