File Coverage

blib/lib/Dist/Zilla/Plugin/MakeMaker.pm
Criterion Covered Total %
statement 114 115 99.1
branch 30 34 88.2
condition 8 9 88.8
subroutine 20 20 100.0
pod 0 6 0.0
total 172 184 93.4


line stmt bran cond sub pod time code
1             # ABSTRACT: build a Makefile.PL that uses ExtUtils::MakeMaker
2              
3             use Moose;
4 13     13   9465  
  13         35  
  13         121  
5             use Dist::Zilla::Pragmas;
6 13     13   89958  
  13         33  
  13         121  
7             use namespace::autoclean;
8 13     13   110  
  13         52  
  13         335  
9             use Config;
10 13     13   1132 use CPAN::Meta::Requirements 2.121; # requirements_for_module
  13         45  
  13         747  
11 13     13   94 use List::Util 1.29 qw(first pairs pairgrep);
  13         374  
  13         597  
12 13     13   93 use version;
  13         230  
  13         1311  
13 13     13   113 use Dist::Zilla::File::InMemory;
  13         40  
  13         120  
14 13     13   2835 use Dist::Zilla::Plugin::MakeMaker::Runner;
  13         48  
  13         489  
15 13     13   6178  
  13         51  
  13         28310  
16             #pod =head1 DESCRIPTION
17             #pod
18             #pod This plugin will produce an L<ExtUtils::MakeMaker>-powered F<Makefile.PL> for
19             #pod the distribution. If loaded, the L<Manifest|Dist::Zilla::Plugin::Manifest>
20             #pod plugin should also be loaded.
21             #pod
22             #pod =cut
23              
24             #pod =attr eumm_version
25             #pod
26             #pod This option declares the version of ExtUtils::MakeMaker required to configure
27             #pod and build the distribution. There is no default, although one may be added if
28             #pod it can be determined that the generated F<Makefile.PL> requires some specific
29             #pod minimum. I<No testing has been done on this front.>
30             #pod
31             #pod =cut
32              
33             has eumm_version => (
34             isa => 'Str',
35             is => 'rw',
36             );
37              
38             #pod =attr make_path
39             #pod
40             #pod This option sets the path to F<make>, used to build your dist and run tests.
41             #pod It defaults to the value for C<make> in L<Config>, or to C<make> if that isn't
42             #pod set.
43             #pod
44             #pod You probably won't need to set this option.
45             #pod
46             #pod =cut
47              
48             has 'make_path' => (
49             isa => 'Str',
50             is => 'ro',
51             default => $Config{make} || 'make',
52             );
53              
54             #pod =attr static_attribution
55             #pod
56             #pod This option omits the version number in the "generated by"
57             #pod comment in the Makefile.PL. For setups that copy the Makefile.PL
58             #pod back to the repo, this avoids churn just from upgrading Dist::Zilla.
59             #pod
60             #pod =cut
61              
62             has 'static_attribution' => (
63             isa => 'Bool',
64             is => 'ro',
65             );
66              
67             has '_runner' => (
68             is => 'ro',
69             lazy => 1,
70             handles => [qw(build test)],
71             default => sub {
72             my ($self) = @_;
73             Dist::Zilla::Plugin::MakeMaker::Runner->new({
74             zilla => $self->zilla,
75             plugin_name => $self->plugin_name . '::Runner',
76             make_path => $self->make_path,
77             default_jobs => $self->default_jobs,
78             });
79             },
80             );
81              
82             # This is here, rather than at the top, so that the "build" and "test" methods
83             # will exist, as they are required by BuildRunner and TestRunner respectively.
84             # I had originally fixed this with stub methods, but stub methods do not behave
85             # properly with this use case until Moose 2.0300. -- rjbs, 2012-02-08
86             with qw(
87             Dist::Zilla::Role::BuildRunner
88             Dist::Zilla::Role::InstallTool
89             Dist::Zilla::Role::PrereqSource
90             Dist::Zilla::Role::FileGatherer
91             Dist::Zilla::Role::TestRunner
92             Dist::Zilla::Role::TextTemplate
93             );
94              
95             my $template = q!# This file was automatically generated by {{ $generated_by }}.
96             use strict;
97             use warnings;
98              
99             {{ $perl_prereq ? qq[use $perl_prereq;] : ''; }}
100              
101             use ExtUtils::MakeMaker{{ defined $eumm_version && 0+$eumm_version ? ' ' . $eumm_version : '' }};
102             {{ $share_dir_code{preamble} || '' }}
103             my {{ $WriteMakefileArgs }}
104              
105             my {{ $fallback_prereqs }}
106              
107             unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
108             delete $WriteMakefileArgs{TEST_REQUIRES};
109             delete $WriteMakefileArgs{BUILD_REQUIRES};
110             $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs;
111             }
112              
113             delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
114             unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
115              
116             WriteMakefile(%WriteMakefileArgs);
117             {{ $share_dir_code{postamble} || '' }}!;
118              
119             my ($self) = @_;
120              
121 28     28 0 95 $self->zilla->register_prereqs(
122             { phase => 'configure' },
123 28   100     934 'ExtUtils::MakeMaker' => $self->eumm_version || 0,
124             );
125              
126             return unless keys %{ $self->zilla->_share_dir_map };
127              
128 28 100       92 $self->zilla->register_prereqs(
  28         927  
129             { phase => 'configure' },
130 4         120 'File::ShareDir::Install' => 0.06,
131             );
132             }
133              
134             my ($self) = @_;
135              
136             require Dist::Zilla::File::InMemory;
137 28     28 0 103  
138             my $file = Dist::Zilla::File::InMemory->new({
139 28         207 name => 'Makefile.PL',
140             content => $template, # template evaluated later
141 28         1127 });
142              
143             $self->add_file($file);
144             return;
145             }
146 28         197  
147 28         181 my ($self) = @_;
148              
149             my $share_dir_code = {};
150              
151 27     27 0 104 my $share_dir_map = $self->zilla->_share_dir_map;
152             if ( keys %$share_dir_map ) {
153 27         68 my $preamble = <<'PREAMBLE';
154             use File::ShareDir::Install;
155 27         745 $File::ShareDir::Install::INCLUDE_DOTFILES = 1;
156 27 100       137 $File::ShareDir::Install::INCLUDE_DOTDIRS = 1;
157 4         17 PREAMBLE
158              
159             if ( my $dist_share_dir = $share_dir_map->{dist} ) {
160             $dist_share_dir = quotemeta $dist_share_dir;
161             $preamble .= qq{install_share dist => "$dist_share_dir";\n};
162             }
163 4 100       24  
164 2         7 if ( my $mod_map = $share_dir_map->{module} ) {
165 2         10 for my $mod ( keys %$mod_map ) {
166             my $mod_share_dir = quotemeta $mod_map->{$mod};
167             $preamble .= qq{install_share module => "$mod", "$mod_share_dir";\n};
168 4 100       17 }
169 3         16 }
170 5         18  
171 5         26 $share_dir_code->{preamble} = "\n" . $preamble . "\n";
172             $share_dir_code->{postamble}
173             = qq{\n\{\npackage\nMY;\nuse File::ShareDir::Install qw(postamble);\n\}\n};
174             }
175 4         24  
176             return $share_dir_code;
177 4         14 }
178              
179             my ($self) = @_;
180 27         153  
181             my $name = $self->zilla->name =~ s/-/::/gr;
182              
183             my @exe_files = map { $_->name }
184 28     28 0 82 @{ $self->zilla->find_files(':ExecFiles') };
185              
186 28         987 $self->log_fatal("can't install files with whitespace in their names")
187             if grep { /\s/ } @exe_files;
188 1         5  
189 28         96 my %test_dirs;
  28         785  
190             for my $file (@{ $self->zilla->files }) {
191             next unless $file->name =~ m{\At/.+\.t\z};
192 28 50       125 my $dir = $file->name =~ s{/[^/]+\.t\z}{/*.t}gr;
  1         6  
193              
194 28         65 $test_dirs{ $dir } = 1;
195 28         73 }
  28         890  
196 173 100       529  
197 36         174 my $prereqs = $self->zilla->prereqs;
198             my $perl_prereq = $prereqs->requirements_for(qw(runtime requires))
199 36         160 ->clone
200             ->add_requirements($prereqs->requirements_for(qw(configure requires)))
201             ->add_requirements($prereqs->requirements_for(qw(build requires)))
202 28         828 ->add_requirements($prereqs->requirements_for(qw(test requires)))
203             ->as_string_hash->{perl};
204              
205             $perl_prereq = version->parse($perl_prereq)->numify if $perl_prereq;
206              
207             my $prereqs_dump = sub {
208 28         167 $self->_normalize_eumm_versions(
209             $prereqs->requirements_for(@_)
210 28 100       5991 ->clone
211             ->clear_requirement('perl')
212             ->as_string_hash
213 112     112   379 );
214             };
215              
216             my %require_prereqs = map {
217             $_ => $prereqs_dump->($_, 'requires');
218             } qw(configure build test runtime);
219 28         208  
220             # EUMM may soon be able to support this, but until we decide to inject a
221             # higher configure-requires version, we should at least warn the user
222 28         103 # https://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker/issues/215
  112         260  
223             foreach my $phase (qw(configure build test runtime)) {
224             if (my @version_ranges = pairgrep { defined($b) && !version::is_lax($b) } %{ $require_prereqs{$phase} }
225             and ($self->eumm_version || 0) < '7.1101') {
226             $self->log_fatal([
227             'found version range in %s prerequisites, which ExtUtils::MakeMaker cannot parse (must specify eumm_version of at least 7.1101): %s %s',
228 28         123 $phase, $_->[0], $_->[1]
229 112 50 100 81   1363 ]) foreach pairs @version_ranges;
  81 100 100     408  
  112         575  
230             }
231             }
232              
233             my %write_makefile_args = (
234 1         22 DISTNAME => $self->zilla->name,
235             NAME => $name,
236             AUTHOR => join(q{, }, @{ $self->zilla->authors }),
237             ABSTRACT => $self->zilla->abstract,
238             VERSION => $self->zilla->version,
239             LICENSE => $self->zilla->license->meta_yml_name,
240             @exe_files ? ( EXE_FILES => [ sort @exe_files ] ) : (),
241 27         757  
242             CONFIGURE_REQUIRES => $require_prereqs{configure},
243             keys %{ $require_prereqs{build} } ? ( BUILD_REQUIRES => $require_prereqs{build} ) : (),
244             keys %{ $require_prereqs{test} } ? ( TEST_REQUIRES => $require_prereqs{test} ) : (),
245             PREREQ_PM => $require_prereqs{runtime},
246              
247             test => { TESTS => join q{ }, sort keys %test_dirs },
248 27         449 );
249 27         515  
250             $write_makefile_args{MIN_PERL_VERSION} = $perl_prereq if $perl_prereq;
251              
252 27 100       1105 return \%write_makefile_args;
    100          
    100          
253             }
254              
255 27 100       127 my ($self, $prereqs) = @_;
256             for my $v (values %$prereqs) {
257 27         238 if (version::is_strict($v)) {
258             my $version = version->parse($v);
259             if ($version->is_qv) {
260             if ((() = $v =~ /\./g) > 1) {
261 139     139   23869 $v =~ s/^v//;
262 139         417 }
263 129 100       402 else {
264 126         2735 $v = $version->numify;
265 126 100       647 }
266 4 50       22 }
267 4         19 }
268             }
269             return $prereqs;
270 0         0 }
271              
272             my ($self, $ref, $name) = @_;
273             require Data::Dumper;
274             my $dumper = Data::Dumper->new( [ $ref ], [ $name ] );
275 139         632 $dumper->Sortkeys( 1 );
276             $dumper->Indent( 1 );
277             $dumper->Useqq( 1 );
278             return $dumper->Dump;
279 54     54   164 }
280 54         7280  
281 54         69802 my $self = shift;
282 54         1925 my $fallback
283 54         500 = $self->_normalize_eumm_versions(
284 54         800 $self->zilla->prereqs->merged_requires
285 54         387 ->clone
286             ->clear_requirement('perl')
287             ->as_string_hash
288             );
289 27     27 0 69 return $self->_dump_as( $fallback, '*FallbackPrereqs' );
290 27         795 }
291              
292             my ($self) = @_;
293              
294             my $write_makefile_args = $self->write_makefile_args;
295              
296             $self->__write_makefile_args($write_makefile_args); # save for testing
297 27         166  
298             my $perl_prereq = $write_makefile_args->{MIN_PERL_VERSION};
299              
300             my $dumped_args = $self->_dump_as($write_makefile_args, '*WriteMakefileArgs');
301 28     28 0 103  
302             my $file = first { $_->name eq 'Makefile.PL' } @{$self->zilla->files};
303 28         160  
304             $self->log_debug([ 'updating contents of Makefile.PL in memory' ]);
305 27         1026  
306             my $attribution = $self->static_attribution
307 27         68 ? ref($self)
308             : sprintf("%s v%s", ref($self), $self->VERSION || '(dev)');
309 27         143  
310             my $content = $self->fill_in_string(
311 27     158   2533 $file->content,
  158         458  
  27         994  
312             {
313 27         313 eumm_version => \($self->eumm_version),
314             perl_prereq => \$perl_prereq,
315 27 50 50     2462 share_dir_code => $self->share_dir_code,
316             fallback_prereqs => \($self->fallback_prereq_pm),
317             WriteMakefileArgs => \$dumped_args,
318             generated_by => \$attribution,
319 27         214 },
320             );
321              
322             $file->content($content);
323              
324             return;
325             }
326              
327             # XXX: Just here to facilitate testing. -- rjbs, 2010-03-20
328             has __write_makefile_args => (
329             is => 'rw',
330             isa => 'HashRef',
331 27         207 );
332              
333 27         140 __PACKAGE__->meta->make_immutable;
334             1;
335              
336             #pod =head1 SEE ALSO
337             #pod
338             #pod Core Dist::Zilla plugins:
339             #pod L<@Basic|Dist::Zilla::PluginBundle::Basic>,
340             #pod L<ModuleBuild|Dist::Zilla::Plugin::ModuleBuild>,
341             #pod L<Manifest|Dist::Zilla::Plugin::Manifest>.
342             #pod
343             #pod Dist::Zilla roles:
344             #pod L<BuildRunner|Dist::Zilla::Role::FileGatherer>,
345             #pod L<InstallTool|Dist::Zilla::Role::InstallTool>,
346             #pod L<PrereqSource|Dist::Zilla::Role::PrereqSource>,
347             #pod L<TestRunner|Dist::Zilla::Role::TestRunner>.
348             #pod
349             #pod =cut
350              
351              
352             =pod
353              
354             =encoding UTF-8
355              
356             =head1 NAME
357              
358             Dist::Zilla::Plugin::MakeMaker - build a Makefile.PL that uses ExtUtils::MakeMaker
359              
360             =head1 VERSION
361              
362             version 6.028
363              
364             =head1 DESCRIPTION
365              
366             This plugin will produce an L<ExtUtils::MakeMaker>-powered F<Makefile.PL> for
367             the distribution. If loaded, the L<Manifest|Dist::Zilla::Plugin::Manifest>
368             plugin should also be loaded.
369              
370             =head1 PERL VERSION
371              
372             This module should work on any version of perl still receiving updates from
373             the Perl 5 Porters. This means it should work on any version of perl released
374             in the last two to three years. (That is, if the most recently released
375             version is v5.40, then this module should work on both v5.40 and v5.38.)
376              
377             Although it may work on older versions of perl, no guarantee is made that the
378             minimum required version will not be increased. The version may be increased
379             for any reason, and there is no promise that patches will be accepted to lower
380             the minimum required perl.
381              
382             =head1 ATTRIBUTES
383              
384             =head2 eumm_version
385              
386             This option declares the version of ExtUtils::MakeMaker required to configure
387             and build the distribution. There is no default, although one may be added if
388             it can be determined that the generated F<Makefile.PL> requires some specific
389             minimum. I<No testing has been done on this front.>
390              
391             =head2 make_path
392              
393             This option sets the path to F<make>, used to build your dist and run tests.
394             It defaults to the value for C<make> in L<Config>, or to C<make> if that isn't
395             set.
396              
397             You probably won't need to set this option.
398              
399             =head2 static_attribution
400              
401             This option omits the version number in the "generated by"
402             comment in the Makefile.PL. For setups that copy the Makefile.PL
403             back to the repo, this avoids churn just from upgrading Dist::Zilla.
404              
405             =head1 SEE ALSO
406              
407             Core Dist::Zilla plugins:
408             L<@Basic|Dist::Zilla::PluginBundle::Basic>,
409             L<ModuleBuild|Dist::Zilla::Plugin::ModuleBuild>,
410             L<Manifest|Dist::Zilla::Plugin::Manifest>.
411              
412             Dist::Zilla roles:
413             L<BuildRunner|Dist::Zilla::Role::FileGatherer>,
414             L<InstallTool|Dist::Zilla::Role::InstallTool>,
415             L<PrereqSource|Dist::Zilla::Role::PrereqSource>,
416             L<TestRunner|Dist::Zilla::Role::TestRunner>.
417              
418             =head1 AUTHOR
419              
420             Ricardo SIGNES 😏 <cpan@semiotic.systems>
421              
422             =head1 COPYRIGHT AND LICENSE
423              
424             This software is copyright (c) 2022 by Ricardo SIGNES.
425              
426             This is free software; you can redistribute it and/or modify it under
427             the same terms as the Perl 5 programming language system itself.
428              
429             =cut