File Coverage

lib/Dist/Zilla/Plugin/ModuleInstall.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1 1     1   3409 use 5.008; # utf8
  1         4  
  1         48  
2 1     1   7 use strict;
  1         2  
  1         37  
3 1     1   5 use warnings;
  1         1036  
  1         45  
4 1     1   980 use utf8;
  1         10  
  1         6  
5              
6             package Dist::Zilla::Plugin::ModuleInstall;
7              
8             our $VERSION = '1.001000';
9              
10             # ABSTRACT: Build Module::Install based Distributions with Dist::Zilla
11              
12             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
13              
14 1     1   1855 use Moose qw( has with around );
  0            
  0            
15             use Config;
16             use Carp qw( carp croak );
17             use Dist::Zilla::Plugin::MakeMaker::Runner;
18             use Dist::Zilla::File::FromCode;
19             use Dist::Zilla::Util::ConfigDumper qw( config_dumper );
20              
21             has 'make_path' => (
22             isa => 'Str',
23             is => 'ro',
24             default => $Config{make} || 'make',
25             );
26              
27             has '_runner' => (
28             is => 'ro',
29             lazy => 1,
30             handles => [qw(build test)],
31             default => sub {
32             my ($self) = @_;
33             Dist::Zilla::Plugin::MakeMaker::Runner->new(
34             {
35             zilla => $self->zilla,
36             plugin_name => $self->plugin_name . '::Runner',
37             make_path => $self->make_path,
38             },
39             );
40             },
41             );
42              
43             with 'Dist::Zilla::Role::BuildRunner';
44             with 'Dist::Zilla::Role::InstallTool';
45             with 'Dist::Zilla::Role::TextTemplate';
46              
47             # no broken tempdir, keepalive_fail helper
48             use Dist::Zilla::Role::Tempdir 1.001000;
49             with 'Dist::Zilla::Role::Tempdir';
50              
51             with 'Dist::Zilla::Role::PrereqSource';
52             with 'Dist::Zilla::Role::TestRunner';
53              
54             use Dist::Zilla::File::InMemory;
55              
56             use namespace::autoclean;
57              
58             require inc::Module::Install;
59              
60             sub _doc_template {
61             my ( $self, $args ) = @_;
62             my $package = __PACKAGE__;
63             my $version = ( __PACKAGE__->VERSION() || 'undefined ( self-build? )' );
64              
65             my $t = <<"EOF";
66             use strict;
67             use warnings;
68             # Warning: This code was generated by ${package} Version ${version}
69             # As part of Dist::Zilla's build generation.
70             # Do not modify this file, instead, modify the dist.ini that configures its generation.
71             use inc::Module::Install {{ \$miver }};
72             {{ \$headings }}
73             {{ \$requires }}
74             {{ \$feet }}
75             WriteAll();
76             EOF
77             return $self->fill_in_string( $t, $args );
78             }
79              
80             sub _label_value_template {
81             my ( $self, $args ) = @_;
82             my $t = <<"EOF";
83             {{ \$label }} '{{ \$value }}';
84             EOF
85             return $self->fill_in_string( $t, $args );
86             }
87              
88             sub _label_string_template {
89             my ( $self, $args ) = @_;
90             my $t = <<"EOF";
91             {{ \$label }} "{{ quotemeta( \$string ) }}";
92             EOF
93             return $self->fill_in_string( $t, $args );
94             }
95              
96             sub _label_string_string_template {
97             my ( $self, $args ) = @_;
98             my $t = <<"EOF";
99             {{ \$label }} "{{ quotemeta(\$stringa) }}" => "{{ quotemeta(\$stringb) }}";
100             EOF
101             return $self->fill_in_string( $t, $args );
102             }
103              
104             sub _generate_makefile_pl {
105             my ($self) = @_;
106             my ( @headings, @requires, @feet );
107              
108             push @headings, _label_value_template( $self, { label => 'name', value => $self->zilla->name } ),
109             _label_string_template( $self, { label => 'abstract', string => $self->zilla->abstract } ),
110             _label_string_template( $self, { label => 'author', string => $self->zilla->authors->[0] } ),
111             _label_string_template( $self, { label => 'version', string => $self->zilla->version } ),
112             _label_string_template( $self, { label => 'license', string => $self->zilla->license->meta_yml_name } );
113              
114             my $prereqs = $self->zilla->prereqs;
115              
116             my $doreq = sub {
117             my ( $key, $target ) = @_;
118             push @requires, qq{\n# @$key => $target};
119             my $hash = $prereqs->requirements_for( @{$key} )->as_string_hash;
120             for ( sort keys %{$hash} ) {
121             if ( 'perl' eq $_ ) {
122             push @requires, _label_string_template( $self, { label => 'perl_version', string => $hash->{$_} } );
123             next;
124             }
125             push @requires,
126             $self->_label_string_string_template(
127             {
128             label => $target,
129             stringa => $_,
130             stringb => $hash->{$_},
131             },
132             );
133             }
134             };
135              
136             $doreq->( [qw(configure requires)], 'configure_requires' );
137             $doreq->( [qw(build requires)], 'requires' );
138             $doreq->( [qw(runtime requires)], 'requires' );
139             $doreq->( [qw(runtime recommends)], 'recommends' );
140             $doreq->( [qw(test requires)], 'test_requires' );
141              
142             push @feet, qq{\n# :ExecFiles};
143             my @found_files = @{ $self->zilla->find_files(':ExecFiles') };
144             for my $execfile ( map { $_->name } @found_files ) {
145             push @feet, _label_string_template( $self, $execfile );
146             }
147             my $content = _doc_template(
148             $self,
149             {
150             miver => "$Module::Install::VERSION",
151             headings => join( qq{\n}, @headings ),
152             requires => join( qq{\n}, @requires ),
153             feet => join( qq{\n}, @feet ),
154             },
155             );
156             return $content;
157             }
158              
159              
160              
161              
162              
163              
164              
165             sub register_prereqs {
166             my ($self) = @_;
167             $self->zilla->register_prereqs( { phase => 'configure' }, 'ExtUtils::MakeMaker' => 6.42 );
168             $self->zilla->register_prereqs( { phase => 'build' }, 'ExtUtils::MakeMaker' => 6.42 );
169             return;
170             }
171              
172              
173              
174              
175              
176              
177              
178              
179             my $error_load = 'Error running Makefile.PL for Module::Install. ';
180             my $no_keepalive = $error_load . 'Set MI_KEEPALIVE=1 if you want to retain the directory for analysis';
181             my $keepalive = $error_load . 'Inspect the temporary directory to determine cause';
182              
183             sub setup_installer {
184             my ( $self, ) = @_;
185              
186             my $file = Dist::Zilla::File::FromCode->new( { name => 'Makefile.PL', code => sub { _generate_makefile_pl($self) }, } );
187              
188             $self->add_file($file);
189              
190             my $code = sub {
191             my ($dir) = @_;
192             system $^X, 'Makefile.PL' and do {
193              
194             croak($no_keepalive) unless $ENV{MI_KEEPALIVE};
195              
196             $dir->keepalive_fail($keepalive);
197             };
198             };
199              
200             my (@generated) = $self->capture_tempdir($code);
201              
202             for (@generated) {
203             if ( $_->is_new ) {
204             $self->log( 'ModuleInstall created: ' . $_->name );
205             if ( $_->name =~ /\Ainc\/Module\/Install/msx ) {
206             $self->log( 'ModuleInstall added : ' . $_->name );
207             $self->add_file( $_->file );
208             }
209             }
210             if ( $_->is_modified ) {
211             $self->log( 'ModuleInstall modified: ' . $_->name );
212             }
213             }
214             return;
215             }
216              
217             around dump_config => config_dumper( __PACKAGE__, { attrs => [qw( make_path )] } );
218              
219             __PACKAGE__->meta->make_immutable;
220             no Moose;
221              
222             1;
223              
224             __END__
225              
226             =pod
227              
228             =encoding UTF-8
229              
230             =head1 NAME
231              
232             Dist::Zilla::Plugin::ModuleInstall - Build Module::Install based Distributions with Dist::Zilla
233              
234             =head1 VERSION
235              
236             version 1.001000
237              
238             =head1 SYNOPSIS
239              
240             dist.ini
241              
242             [ModuleInstall]
243              
244             =head1 DESCRIPTION
245              
246             This module will create a F<Makefile.PL> for installing the dist using L<< C<Module::Install>|Module::Install >>.
247              
248             It is at present a very minimal feature set, but it works.
249              
250             =head1 METHODS
251              
252             =head2 register_prereqs
253              
254             Tells Dist::Zilla about our needs to have EU::MM larger than 6.42
255              
256             =head2 setup_installer
257              
258             Generates the Makefile.PL, and runs it in a tmpdir, and then harvests the output and stores
259             it in the dist selectively.
260              
261             =head1 AUTHOR
262              
263             Kent Fredric <kentnl@cpan.org>
264              
265             =head1 COPYRIGHT AND LICENSE
266              
267             This software is copyright (c) 2014 by Kent Fredric <kentfredric@gmail.com>.
268              
269             This is free software; you can redistribute it and/or modify it under
270             the same terms as the Perl 5 programming language system itself.
271              
272             =cut