File Coverage

blib/lib/Dist/Zilla/Plugin/MakeMaker.pm
Criterion Covered Total %
statement 114 115 99.1
branch 30 34 88.2
condition 10 12 83.3
subroutine 20 20 100.0
pod 0 6 0.0
total 174 187 93.0


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