File Coverage

blib/lib/Dist/Zilla/Plugin/GenerateFile/ShareDir.pm
Criterion Covered Total %
statement 48 50 96.0
branch 6 10 60.0
condition n/a
subroutine 13 14 92.8
pod 0 4 0.0
total 67 78 85.9


line stmt bran cond sub pod time code
1 3     3   1998345 use strict;
  3         8  
  3         100  
2 3     3   16 use warnings;
  3         6  
  3         220  
3             package Dist::Zilla::Plugin::GenerateFile::ShareDir; # git description: v0.006-8-g7955ef5
4             # ABSTRACT: Create files in the repository or build, based on a template located in a dist sharedir
5             # KEYWORDS: plugin distribution generate create file sharedir template
6             # vim: set ts=8 sts=4 sw=4 tw=115 et :
7              
8             our $VERSION = '0.007';
9              
10 3     3   18 use Moose;
  3         7  
  3         26  
11             with (
12             'Dist::Zilla::Role::FileGatherer',
13             'Dist::Zilla::Role::FileMunger',
14             'Dist::Zilla::Role::TextTemplate',
15             'Dist::Zilla::Role::RepoFileInjector',
16             'Dist::Zilla::Role::AfterBuild',
17             'Dist::Zilla::Role::AfterRelease',
18             );
19              
20 3     3   23580 use MooseX::SlurpyConstructor 1.2;
  3         80162  
  3         21  
21 3     3   118862 use Moose::Util 'find_meta';
  3         9  
  3         24  
22 3     3   756 use File::ShareDir 'dist_file';
  3         7  
  3         249  
23 3     3   19 use Path::Tiny 0.04;
  3         96  
  3         146  
24 3     3   19 use Encode;
  3         6  
  3         300  
25 3     3   20 use Moose::Util::TypeConstraints 'enum';
  3         7  
  3         28  
26 3     3   1325 use namespace::autoclean;
  3         7  
  3         23  
27              
28             has dist => (
29             is => 'ro', isa => 'Str',
30             init_arg => '-dist',
31             lazy => 1,
32             default => sub { (my $dist = find_meta(shift)->name) =~ s/::/-/g; $dist },
33             );
34              
35             has filename => (
36             init_arg => '-destination_filename',
37             is => 'ro', isa => 'Str',
38             required => 1,
39             );
40              
41             has source_filename => (
42             init_arg => '-source_filename',
43             is => 'ro', isa => 'Str',
44             lazy => 1,
45             default => sub { shift->filename },
46             );
47              
48             has encoding => (
49             init_arg => '-encoding',
50             is => 'ro', isa => 'Str',
51             lazy => 1,
52             default => 'UTF-8',
53             );
54              
55             has location => (
56             is => 'ro', isa => enum([ qw(build root) ]),
57             lazy => 1,
58             default => 'build',
59             init_arg => '-location',
60             );
61              
62             has phase => (
63             is => 'ro', isa => enum([ qw(build release) ]),
64             lazy => 1,
65             default => 'release',
66             init_arg => '-phase',
67             );
68              
69             has _extra_args => (
70             isa => 'HashRef[Str]',
71             init_arg => undef,
72             lazy => 1,
73             default => sub { {} },
74             traits => ['Hash'],
75             handles => { _extra_args => 'elements' },
76             slurpy => 1,
77             );
78              
79             around BUILDARGS => sub
80             {
81             my $orig = shift;
82             my $class = shift;
83              
84             my $args = $class->$orig(@_);
85             $args->{'-destination_filename'} = delete $args->{'-filename'} if exists $args->{'-filename'};
86              
87             return $args;
88             };
89              
90             around dump_config => sub
91             {
92             my ($orig, $self) = @_;
93             my $config = $self->$orig;
94              
95             $config->{+__PACKAGE__} = {
96             # XXX FIXME - it seems META.* does not like the leading - in field
97             # names! something is wrong with the serialization process.
98             'dist' => $self->dist,
99             'encoding' => $self->encoding,
100             'source_filename' => $self->source_filename,
101             'destination_filename' => $self->filename,
102             'location' => $self->location,
103             $self->location eq 'root' ? ( 'phase' => $self->phase ) : (),
104             blessed($self) ne __PACKAGE__ ? ( version => $VERSION ) : (),
105             $self->_extra_args,
106             };
107             return $config;
108             };
109              
110             sub gather_files
111             {
112 3     3 0 192820 my $self = shift;
113              
114             # this should die if the file does not exist
115 3         171 my $file_path = dist_file($self->dist, $self->source_filename);
116              
117 3         581 my $content = path($file_path)->slurp_raw;
118 3         984 $content = Encode::decode($self->encoding, $content, Encode::FB_CROAK());
119              
120 3         3907 require Dist::Zilla::File::InMemory;
121 3         274132 my $file = Dist::Zilla::File::InMemory->new(
122             name => $self->filename,
123             encoding => $self->encoding, # only used in Dist::Zilla 5.000+
124             content => $content,
125             );
126              
127 3 100       1641 if ($self->location eq 'build')
128             {
129 2         15 $self->add_file($file);
130             }
131             else
132             {
133             # root eq $self->location
134 1         6 $self->add_repo_file($file);
135             }
136 3         3520 return;
137             }
138              
139             around munge_files => sub
140             {
141             my ($orig, $self, @args) = @_;
142              
143             return $self->$orig(@args) if $self->location eq 'build';
144              
145             for my $file ($self->_repo_files)
146             {
147             if ($file->can('is_bytes') and $file->is_bytes)
148             {
149             $self->log_debug([ '%s has \'bytes\' encoding, skipping...', $file->name ]);
150             next;
151             }
152             $self->munge_file($file);
153             }
154             };
155              
156             sub munge_file
157             {
158 3     3 0 296 my ($self, $file) = @_;
159              
160 3 50       14 return unless $file->name eq $self->filename;
161 3         16 $self->log_debug([ 'updating contents of %s in memory', $file->name ]);
162              
163 3         1267 my $content = $self->fill_in_string(
164             $file->content,
165             {
166             $self->_extra_args, # must be first
167             dist => \($self->zilla),
168             plugin => \$self,
169             },
170             );
171              
172             # older Dist::Zilla wrote out all files :raw, so we need to encode manually here.
173 3 50       867 $content = Encode::encode($self->encoding, $content, Encode::FB_CROAK()) if not $file->can('encoded_content');
174              
175 3         16 $file->content($content);
176             }
177              
178             sub after_build
179             {
180 3     3 0 124740 my $self = shift;
181 3 100       177 $self->write_repo_files if $self->phase eq 'build';
182             }
183              
184             sub after_release
185             {
186 0     0 0   my $self = shift;
187 0 0         $self->write_repo_files if $self->phase eq 'release';
188             }
189              
190             __PACKAGE__->meta->make_immutable;
191              
192             __END__
193              
194             =pod
195              
196             =encoding UTF-8
197              
198             =for stopwords sharedir
199              
200             =head1 NAME
201              
202             Dist::Zilla::Plugin::GenerateFile::ShareDir - Create files in the repository or build, based on a template located in a dist sharedir
203              
204             =head1 VERSION
205              
206             version 0.007
207              
208             =head1 SYNOPSIS
209              
210             In your F<dist.ini>:
211              
212             [GenerateFile::ShareDir]
213             -dist = Dist::Zilla::PluginBundle::Author::ME
214             -source_filename = my_data_template.txt
215             -destination_filename = examples/my_data.txt
216             key1 = value to pass to template
217             key2 = another value to pass to template
218              
219             =head1 DESCRIPTION
220              
221             Generates a file in your dist, indicated by C<-destination_file>, based on the
222             L<Text::Template> located in the C<-source_file> of C<-dist>'s
223             L<distribution sharedir|File::ShareDir>. Any extra config values are passed
224             along to the template, in addition to C<$zilla> and C<$plugin> objects.
225              
226             I expect that usually the C<-dist> that contains the template will be either a
227             plugin bundle, so you can generate a custom-tailored file in your dist, or a
228             plugin that subclasses this one. (Otherwise, you can just as easily use
229             L<[GatherDir::Template]|Dist::Zilla::Plugin::GatherDir::Template>
230             or L<[GenerateFile]|Dist::Zilla::Plugin::GenerateFile>
231             to generate the file directly, without needing a sharedir.)
232              
233             =for Pod::Coverage::TrustPod gather_files
234             munge_file
235             after_build
236             after_release
237              
238             =head1 OPTIONS
239              
240             All unrecognized keys/values will be passed to the template as is.
241             Recognized options are:
242              
243             =head2 C<-dist>
244              
245             The distribution name to use when finding the sharedir (see L<File::ShareDir>
246             and L<Dist::Zilla::Plugin::ShareDir>). Defaults to the dist corresponding to
247             the running plugin.
248              
249             =head2 C<-destination_filename> or C<-filename>
250              
251             The filename to generate in the distribution being built. Required.
252              
253             =head2 C<-source_filename>
254              
255             The filename in the sharedir to use to generate the new file. Defaults to the
256             same filename and path as C<-destination_file>.
257              
258             =head2 C<-encoding>
259              
260             The encoding of the source file; will also be used for the encoding of the
261             destination file. Defaults to UTF-8.
262              
263             =head2 C<-location>
264              
265             default: C<build>
266              
267             The target location of the generated file. When C<build>, the file is added to
268             the distribution in the normal file gathering phase. When C<root>, the file is
269             instead written to the source repository.
270              
271             =head2 C<-phase>
272              
273             Only relevant when C<-location = root>. When C<build> (the default), the file
274             is written on every build operation. When C<release>, it is only written after
275             the distribution is released.
276              
277             =head1 SEE ALSO
278              
279             =for stopwords templated
280              
281             =over 4
282              
283             =item *
284              
285             L<File::ShareDir>
286              
287             =item *
288              
289             L<Dist::Zilla::Plugin::ShareDir>
290              
291             =item *
292              
293             L<Text::Template>
294              
295             =item *
296              
297             L<[GatherDir::Template]|Dist::Zilla::Plugin::GatherDir::Template> - gather a file from the dist, and then pass it through a template
298              
299             =item *
300              
301             L<[GenerateFile]|Dist::Zilla::Plugin::GenerateFile> - generate a (possibly-templated) file purely based on data in F<dist.ini>
302              
303             =back
304              
305             =head1 SUPPORT
306              
307             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Zilla-Plugin-GenerateFile-ShareDir>
308             (or L<bug-Dist-Zilla-Plugin-GenerateFile-ShareDir@rt.cpan.org|mailto:bug-Dist-Zilla-Plugin-GenerateFile-ShareDir@rt.cpan.org>).
309              
310             There is also a mailing list available for users of this distribution, at
311             L<http://dzil.org/#mailing-list>.
312              
313             There is also an irc channel available for users of this distribution, at
314             irc://irc.perl.org/#distzilla.
315              
316             I am also usually active on irc, as 'ether' at C<irc.perl.org>.
317              
318             =head1 AUTHOR
319              
320             Karen Etheridge <ether@cpan.org>
321              
322             =head1 CONTRIBUTOR
323              
324             =for stopwords Kent Fredric
325              
326             Kent Fredric <kentfredric@gmail.com>
327              
328             =head1 COPYRIGHT AND LICENCE
329              
330             This software is copyright (c) 2013 by Karen Etheridge.
331              
332             This is free software; you can redistribute it and/or modify it under
333             the same terms as the Perl 5 programming language system itself.
334              
335             =cut