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.029;
2             # ABSTRACT: build a Makefile.PL that uses ExtUtils::MakeMaker
3              
4 13     13   9775 use Moose;
  13         40  
  13         126  
5              
6 13     13   92788 use Dist::Zilla::Pragmas;
  13         44  
  13         115  
7              
8 13     13   120 use namespace::autoclean;
  13         35  
  13         304  
9              
10 13     13   1237 use Config;
  13         45  
  13         855  
11 13     13   100 use CPAN::Meta::Requirements 2.121; # requirements_for_module
  13         400  
  13         625  
12 13     13   151 use List::Util 1.29 qw(first pairs pairgrep);
  13         267  
  13         1361  
13 13     13   100 use version;
  13         32  
  13         117  
14 13     13   3140 use Dist::Zilla::File::InMemory;
  13         43  
  13         525  
15 13     13   6546 use Dist::Zilla::Plugin::MakeMaker::Runner;
  13         55  
  13         31166  
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 106 my ($self) = @_;
139              
140 29   100     997 $self->zilla->register_prereqs(
141             { phase => 'configure' },
142             'ExtUtils::MakeMaker' => $self->eumm_version || 0,
143             );
144              
145 29 100       88 return unless keys %{ $self->zilla->_share_dir_map };
  29         1015  
146              
147 4         116 $self->zilla->register_prereqs(
148             { phase => 'configure' },
149             'File::ShareDir::Install' => 0.06,
150             );
151             }
152              
153             sub gather_files {
154 29     29 0 131 my ($self) = @_;
155              
156 29         214 require Dist::Zilla::File::InMemory;
157              
158 29         1234 my $file = Dist::Zilla::File::InMemory->new({
159             name => 'Makefile.PL',
160             content => $template, # template evaluated later
161             });
162              
163 29         234 $self->add_file($file);
164 29         205 return;
165             }
166              
167             sub share_dir_code {
168 28     28 0 109 my ($self) = @_;
169              
170 28         95 my $share_dir_code = {};
171              
172 28         808 my $share_dir_map = $self->zilla->_share_dir_map;
173 28 100       182 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       20 if ( my $dist_share_dir = $share_dir_map->{dist} ) {
181 2         8 $dist_share_dir = quotemeta $dist_share_dir;
182 2         9 $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         14 for my $mod ( keys %$mod_map ) {
187 5         14 my $mod_share_dir = quotemeta $mod_map->{$mod};
188 5         22 $preamble .= qq{install_share module => "$mod", "$mod_share_dir";\n};
189             }
190             }
191              
192 4         26 $share_dir_code->{preamble} = "\n" . $preamble . "\n";
193             $share_dir_code->{postamble}
194 4         17 = qq{\n\{\npackage\nMY;\nuse File::ShareDir::Install qw(postamble);\n\}\n};
195             }
196              
197 28         160 return $share_dir_code;
198             }
199              
200             sub write_makefile_args {
201 29     29 0 96 my ($self) = @_;
202              
203 29   66     1183 my $name = $self->main_module || ($self->zilla->name =~ s/-/::/gr);
204              
205 1         5 my @exe_files = map { $_->name }
206 29         104 @{ $self->zilla->find_files(':ExecFiles') };
  29         866  
207              
208             $self->log_fatal("can't install files with whitespace in their names")
209 29 50       139 if grep { /\s/ } @exe_files;
  1         9  
210              
211 29         72 my %test_dirs;
212 29         60 for my $file (@{ $self->zilla->files }) {
  29         945  
213 177 100       532 next unless $file->name =~ m{\At/.+\.t\z};
214 37         166 my $dir = $file->name =~ s{/[^/]+\.t\z}{/*.t}gr;
215              
216 37         161 $test_dirs{ $dir } = 1;
217             }
218              
219 29         879 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         199 ->as_string_hash->{perl};
226              
227 29 100       6114 $perl_prereq = version->parse($perl_prereq)->numify if $perl_prereq;
228              
229             my $prereqs_dump = sub {
230 116     116   474 $self->_normalize_eumm_versions(
231             $prereqs->requirements_for(@_)
232             ->clone
233             ->clear_requirement('perl')
234             ->as_string_hash
235             );
236 29         227 };
237              
238             my %require_prereqs = map {
239 29         144 $_ => $prereqs_dump->($_, 'requires');
  116         289  
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         213 foreach my $phase (qw(configure build test runtime)) {
246 116 50 100 82   1469 if (my @version_ranges = pairgrep { defined($b) && !version::is_lax($b) } %{ $require_prereqs{$phase} }
  82 100 100     410  
  116         623  
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         25 ]) foreach pairs @version_ranges;
252             }
253             }
254              
255             my %write_makefile_args = (
256             DISTNAME => $self->zilla->name,
257             NAME => $name,
258 28         844 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         504 keys %{ $require_prereqs{build} } ? ( BUILD_REQUIRES => $require_prereqs{build} ) : (),
266 28         577 keys %{ $require_prereqs{test} } ? ( TEST_REQUIRES => $require_prereqs{test} ) : (),
267             PREREQ_PM => $require_prereqs{runtime},
268              
269 28 100       1202 test => { TESTS => join q{ }, sort keys %test_dirs },
    100          
    100          
270             );
271              
272 28 100       147 $write_makefile_args{MIN_PERL_VERSION} = $perl_prereq if $perl_prereq;
273              
274 28         236 return \%write_makefile_args;
275             }
276              
277             sub _normalize_eumm_versions {
278 144     144   24721 my ($self, $prereqs) = @_;
279 144         411 for my $v (values %$prereqs) {
280 130 100       425 if (version::is_strict($v)) {
281 127         2854 my $version = version->parse($v);
282 127 100       667 if ($version->is_qv) {
283 4 50       22 if ((() = $v =~ /\./g) > 1) {
284 4         20 $v =~ s/^v//;
285             }
286             else {
287 0         0 $v = $version->numify;
288             }
289             }
290             }
291             }
292 144         686 return $prereqs;
293             }
294              
295             sub _dump_as {
296 56     56   181 my ($self, $ref, $name) = @_;
297 56         8191 require Data::Dumper;
298 56         74975 my $dumper = Data::Dumper->new( [ $ref ], [ $name ] );
299 56         2094 $dumper->Sortkeys( 1 );
300 56         525 $dumper->Indent( 1 );
301 56         932 $dumper->Useqq( 1 );
302 56         408 return $dumper->Dump;
303             }
304              
305             sub fallback_prereq_pm {
306 28     28 0 74 my $self = shift;
307 28         803 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         215 return $self->_dump_as( $fallback, '*FallbackPrereqs' );
315             }
316              
317             sub setup_installer {
318 29     29 0 126 my ($self) = @_;
319              
320 29         195 my $write_makefile_args = $self->write_makefile_args;
321              
322 28         1159 $self->__write_makefile_args($write_makefile_args); # save for testing
323              
324 28         104 my $perl_prereq = $write_makefile_args->{MIN_PERL_VERSION};
325              
326 28         142 my $dumped_args = $self->_dump_as($write_makefile_args, '*WriteMakefileArgs');
327              
328 28     162   2857 my $file = first { $_->name eq 'Makefile.PL' } @{$self->zilla->files};
  162         498  
  28         1065  
329              
330 28         340 $self->log_debug([ 'updating contents of Makefile.PL in memory' ]);
331              
332 28 50 50     2712 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         233 $file->content($content);
349              
350 28         146 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.029
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 released
401             in the last two to three years. (That is, if the most recently released
402             version is v5.40, then this module should work on both v5.40 and v5.38.)
403              
404             Although it may work on older versions of perl, no guarantee is made that the
405             minimum required version will not be increased. The version may be increased
406             for any reason, and there is no promise that patches will be accepted to lower
407             the minimum required perl.
408              
409             =head1 ATTRIBUTES
410              
411             =head2 eumm_version
412              
413             This option declares the version of ExtUtils::MakeMaker required to configure
414             and build the distribution. There is no default, although one may be added if
415             it can be determined that the generated F<Makefile.PL> requires some specific
416             minimum. I<No testing has been done on this front.>
417              
418             =head2 make_path
419              
420             This option sets the path to F<make>, used to build your dist and run tests.
421             It defaults to the value for C<make> in L<Config>, or to C<make> if that isn't
422             set.
423              
424             You probably won't need to set this option.
425              
426             =head2 main_module
427              
428             This option sets the name of the main module in your dist. It defaults to the
429             name derived from the distribution's name after replacing C<-> with C<::>, (e.g.
430             C<Foo::Bar> for distribution C<Foo-Bar>). The value is set as a C<NAME> argument
431             for C<WriteMakefile>.
432              
433             You want to use this option when the name of distribution doesn't reflect any
434             module names contained in your distribution e.g. C<LWP> vs C<libwww-perl>.
435              
436             =head2 static_attribution
437              
438             This option omits the version number in the "generated by"
439             comment in the Makefile.PL. For setups that copy the Makefile.PL
440             back to the repo, this avoids churn just from upgrading Dist::Zilla.
441              
442             =head1 SEE ALSO
443              
444             Core Dist::Zilla plugins:
445             L<@Basic|Dist::Zilla::PluginBundle::Basic>,
446             L<ModuleBuild|Dist::Zilla::Plugin::ModuleBuild>,
447             L<Manifest|Dist::Zilla::Plugin::Manifest>.
448              
449             Dist::Zilla roles:
450             L<BuildRunner|Dist::Zilla::Role::FileGatherer>,
451             L<InstallTool|Dist::Zilla::Role::InstallTool>,
452             L<PrereqSource|Dist::Zilla::Role::PrereqSource>,
453             L<TestRunner|Dist::Zilla::Role::TestRunner>.
454              
455             =head1 AUTHOR
456              
457             Ricardo SIGNES 😏 <cpan@semiotic.systems>
458              
459             =head1 COPYRIGHT AND LICENSE
460              
461             This software is copyright (c) 2022 by Ricardo SIGNES.
462              
463             This is free software; you can redistribute it and/or modify it under
464             the same terms as the Perl 5 programming language system itself.
465              
466             =cut