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.030;
2             # ABSTRACT: build a Makefile.PL that uses ExtUtils::MakeMaker
3              
4 13     13   9717 use Moose;
  13         41  
  13         115  
5              
6 13     13   92708 use Dist::Zilla::Pragmas;
  13         41  
  13         119  
7              
8 13     13   106 use namespace::autoclean;
  13         34  
  13         303  
9              
10 13     13   1266 use Config;
  13         44  
  13         880  
11 13     13   103 use CPAN::Meta::Requirements 2.121; # requirements_for_module
  13         395  
  13         637  
12 13     13   108 use List::Util 1.29 qw(first pairs pairgrep);
  13         293  
  13         1363  
13 13     13   164 use version;
  13         66  
  13         114  
14 13     13   3111 use Dist::Zilla::File::InMemory;
  13         56  
  13         542  
15 13     13   6707 use Dist::Zilla::Plugin::MakeMaker::Runner;
  13         52  
  13         30921  
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 113 my ($self) = @_;
139              
140 29   100     1000 $self->zilla->register_prereqs(
141             { phase => 'configure' },
142             'ExtUtils::MakeMaker' => $self->eumm_version || 0,
143             );
144              
145 29 100       100 return unless keys %{ $self->zilla->_share_dir_map };
  29         978  
146              
147 4         114 $self->zilla->register_prereqs(
148             { phase => 'configure' },
149             'File::ShareDir::Install' => 0.06,
150             );
151             }
152              
153             sub gather_files {
154 29     29 0 108 my ($self) = @_;
155              
156 29         229 require Dist::Zilla::File::InMemory;
157              
158 29         1210 my $file = Dist::Zilla::File::InMemory->new({
159             name => 'Makefile.PL',
160             content => $template, # template evaluated later
161             });
162              
163 29         223 $self->add_file($file);
164 29         189 return;
165             }
166              
167             sub share_dir_code {
168 28     28 0 97 my ($self) = @_;
169              
170 28         80 my $share_dir_code = {};
171              
172 28         772 my $share_dir_map = $self->zilla->_share_dir_map;
173 28 100       208 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       21 if ( my $dist_share_dir = $share_dir_map->{dist} ) {
181 2         6 $dist_share_dir = quotemeta $dist_share_dir;
182 2         12 $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         20 for my $mod ( keys %$mod_map ) {
187 5         19 my $mod_share_dir = quotemeta $mod_map->{$mod};
188 5         27 $preamble .= qq{install_share module => "$mod", "$mod_share_dir";\n};
189             }
190             }
191              
192 4         25 $share_dir_code->{preamble} = "\n" . $preamble . "\n";
193             $share_dir_code->{postamble}
194 4         14 = qq{\n\{\npackage\nMY;\nuse File::ShareDir::Install qw(postamble);\n\}\n};
195             }
196              
197 28         150 return $share_dir_code;
198             }
199              
200             sub write_makefile_args {
201 29     29 0 97 my ($self) = @_;
202              
203 29   66     1187 my $name = $self->main_module || ($self->zilla->name =~ s/-/::/gr);
204              
205 1         5 my @exe_files = map { $_->name }
206 29         101 @{ $self->zilla->find_files(':ExecFiles') };
  29         855  
207              
208             $self->log_fatal("can't install files with whitespace in their names")
209 29 50       154 if grep { /\s/ } @exe_files;
  1         6  
210              
211 29         91 my %test_dirs;
212 29         81 for my $file (@{ $self->zilla->files }) {
  29         1048  
213 177 100       535 next unless $file->name =~ m{\At/.+\.t\z};
214 37         157 my $dir = $file->name =~ s{/[^/]+\.t\z}{/*.t}gr;
215              
216 37         169 $test_dirs{ $dir } = 1;
217             }
218              
219 29         885 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         213 ->as_string_hash->{perl};
226              
227 29 100       6206 $perl_prereq = version->parse($perl_prereq)->numify if $perl_prereq;
228              
229             my $prereqs_dump = sub {
230 116     116   429 $self->_normalize_eumm_versions(
231             $prereqs->requirements_for(@_)
232             ->clone
233             ->clear_requirement('perl')
234             ->as_string_hash
235             );
236 29         251 };
237              
238             my %require_prereqs = map {
239 29         107 $_ => $prereqs_dump->($_, 'requires');
  116         318  
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         183 foreach my $phase (qw(configure build test runtime)) {
246 116 50 100 82   1512 if (my @version_ranges = pairgrep { defined($b) && !version::is_lax($b) } %{ $require_prereqs{$phase} }
  82 100 100     434  
  116         624  
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         34 ]) foreach pairs @version_ranges;
252             }
253             }
254              
255             my %write_makefile_args = (
256             DISTNAME => $self->zilla->name,
257             NAME => $name,
258 28         829 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         515 keys %{ $require_prereqs{build} } ? ( BUILD_REQUIRES => $require_prereqs{build} ) : (),
266 28         573 keys %{ $require_prereqs{test} } ? ( TEST_REQUIRES => $require_prereqs{test} ) : (),
267             PREREQ_PM => $require_prereqs{runtime},
268              
269 28 100       1121 test => { TESTS => join q{ }, sort keys %test_dirs },
    100          
    100          
270             );
271              
272 28 100       167 $write_makefile_args{MIN_PERL_VERSION} = $perl_prereq if $perl_prereq;
273              
274 28         233 return \%write_makefile_args;
275             }
276              
277             sub _normalize_eumm_versions {
278 144     144   24833 my ($self, $prereqs) = @_;
279 144         436 for my $v (values %$prereqs) {
280 130 100       418 if (version::is_strict($v)) {
281 127         2936 my $version = version->parse($v);
282 127 100       689 if ($version->is_qv) {
283 4 50       18 if ((() = $v =~ /\./g) > 1) {
284 4         21 $v =~ s/^v//;
285             }
286             else {
287 0         0 $v = $version->numify;
288             }
289             }
290             }
291             }
292 144         706 return $prereqs;
293             }
294              
295             sub _dump_as {
296 56     56   189 my ($self, $ref, $name) = @_;
297 56         8338 require Data::Dumper;
298 56         76094 my $dumper = Data::Dumper->new( [ $ref ], [ $name ] );
299 56         2131 $dumper->Sortkeys( 1 );
300 56         547 $dumper->Indent( 1 );
301 56         846 $dumper->Useqq( 1 );
302 56         393 return $dumper->Dump;
303             }
304              
305             sub fallback_prereq_pm {
306 28     28 0 83 my $self = shift;
307 28         812 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         183 return $self->_dump_as( $fallback, '*FallbackPrereqs' );
315             }
316              
317             sub setup_installer {
318 29     29 0 116 my ($self) = @_;
319              
320 29         174 my $write_makefile_args = $self->write_makefile_args;
321              
322 28         1106 $self->__write_makefile_args($write_makefile_args); # save for testing
323              
324 28         90 my $perl_prereq = $write_makefile_args->{MIN_PERL_VERSION};
325              
326 28         151 my $dumped_args = $self->_dump_as($write_makefile_args, '*WriteMakefileArgs');
327              
328 28     162   2893 my $file = first { $_->name eq 'Makefile.PL' } @{$self->zilla->files};
  162         507  
  28         1107  
329              
330 28         304 $self->log_debug([ 'updating contents of Makefile.PL in memory' ]);
331              
332 28 50 50     2609 my $attribution = $self->static_attribution
333             ? ref($self)
334             : sprintf("%s v%s", ref($self), $self->VERSION || '(dev)');
335              
336 28         215 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         224 $file->content($content);
349              
350 28         145 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.030
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) 2023 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