File Coverage

blib/lib/Dist/Zilla/Role/RepoFileInjector.pm
Criterion Covered Total %
statement 44 45 97.7
branch 10 16 62.5
condition 3 3 100.0
subroutine 10 10 100.0
pod 2 2 100.0
total 69 76 90.7


line stmt bran cond sub pod time code
1 2     2   1063 use strict;
  2         3  
  2         56  
2 2     2   6 use warnings;
  2         1  
  2         95  
3             package Dist::Zilla::Role::RepoFileInjector; # git description: v0.006-2-gaf009ca
4             # ABSTRACT: Create files outside the build directory
5             # KEYWORDS: plugin distribution generate create file repository
6             # vim: set ts=8 sts=4 sw=4 tw=115 et :
7              
8             our $VERSION = '0.007';
9              
10 2     2   710 use Moose::Role;
  2         6134  
  2         7  
11              
12 2     2   8369 use MooseX::Types qw(enum role_type);
  2         48995  
  2         8  
13 2     2   6133 use MooseX::Types::Moose qw(ArrayRef Str Bool);
  2         19354  
  2         15  
14 2     2   6841 use Path::Tiny 0.022;
  2         53  
  2         92  
15 2     2   9 use Cwd ();
  2         2  
  2         29  
16 2     2   8 use namespace::clean;
  2         2  
  2         9  
17              
18             has repo_root => (
19             is => 'ro', isa => Str,
20             predicate => '_has_repo_root',
21             lazy => 1,
22             default => sub { path(Cwd::getcwd())->stringify },
23             );
24              
25             has allow_overwrite => (
26             is => 'ro', isa => Bool,
27             default => 1,
28             );
29              
30             has _repo_files => (
31             isa => ArrayRef[role_type('Dist::Zilla::Role::File')],
32             lazy => 1,
33             default => sub { [] },
34             traits => ['Array'],
35             handles => {
36             __push_repo_file => 'push',
37             _repo_files => 'elements',
38             },
39             );
40              
41             around dump_config => sub
42             {
43             my ($orig, $self) = @_;
44             my $config = $self->$orig;
45              
46             $config->{+__PACKAGE__} = {
47             version => $VERSION,
48             allow_overwrite => ( $self->allow_overwrite ? 1 : 0 ),
49             repo_root => ( $self->_has_repo_root ? $self->repo_root : '.' ),
50             };
51             return $config;
52             };
53              
54             sub add_repo_file
55             {
56 3     3 1 2892822 my ($self, $file) = @_;
57              
58 3         12 my ($pkg, undef, $line) = caller;
59 3 50       20 if ($file->can('_set_added_by'))
60             {
61 3         82 $file->_set_added_by(sprintf("%s (%s line %s)", $self->plugin_name, $pkg, $line));
62             }
63             else
64             {
65             # as done in Dist::Zilla::Role::FileInjector 4.300039
66 0         0 $file->meta->get_attribute('added_by')->set_value(
67             $file,
68             sprintf("%s (%s line %s)", $self->plugin_name, $pkg, $line),
69             );
70             }
71              
72 3         446 $self->log_debug([ 'adding file %s', $file->name ]);
73              
74 3         904 $self->__push_repo_file($file);
75             }
76              
77             sub write_repo_files
78             {
79 3     3 1 56507 my $self = shift;
80              
81 3         115 foreach my $file ($self->_repo_files)
82             {
83 3         13 my $filename = path($file->name);
84 3 50       207 my $abs_filename = $filename->is_relative
85             ? path($self->repo_root)->child($file->name)->stringify
86             : $file->name;
87              
88 3 100 100     355 if (-e $abs_filename and $self->allow_overwrite)
89             {
90 1         5 $self->log_debug([ 'removing pre-existing %s', $abs_filename ]);
91 1         323 unlink $abs_filename ;
92             }
93 3 100       45 $self->log_fatal([ '%s already exists (allow_overwrite = 0)', $abs_filename ]) if -e $abs_filename;
94              
95 2 50       10 $self->log_debug([ 'writing out %s%s', $file->name,
96             $filename->is_relative ? ' to ' . $self->repo_root : '' ]);
97              
98 2 50       518 Carp::croak("attempted to write $filename multiple times") if -e $filename;
99 2         28 $filename->touchpath;
100              
101             # handle dzil v4 files by assuming no (or latin1) encoding
102 2 50       661 my $encoded_content = $file->can('encoded_content') ? $file->encoded_content : $file->content;
103              
104 2         912 $filename->spew_raw($encoded_content);
105 2 50       663 chmod $file->mode, "$filename" or die "couldn't chmod $filename: $!";
106             }
107             }
108              
109             1;
110              
111             __END__
112              
113             =pod
114              
115             =encoding UTF-8
116              
117             =head1 NAME
118              
119             Dist::Zilla::Role::RepoFileInjector - Create files outside the build directory
120              
121             =head1 VERSION
122              
123             version 0.007
124              
125             =head1 SYNOPSIS
126              
127             In your F<dist.ini>:
128              
129             [MyPlugin]
130              
131             And in your plugin:
132              
133             package Dist::Zilla::Plugin::MyPlugin;
134             use Moose;
135             with 'Dist::Zilla::Role::RepoFileInjector';
136              
137             sub some_method {
138             ...
139             $self->add_repo_file(Dist::Zilla::File::InMemory->new(...));
140             }
141              
142             sub some_other_method {
143             ...
144             $self->write_repo_files;
145             }
146              
147             =head1 DESCRIPTION
148              
149             This role is to be consumed by any plugin that plans to create files outside
150             the distribution.
151              
152             =head1 ATTRIBUTES
153              
154             =head2 repo_root
155              
156             A string indicating the base directory where the file(s) are written, when
157             relative paths are provided. Defaults to the current working directory.
158              
159             This attribute is available as an option of your plugin in F<dist.ini>.
160              
161             =head2 allow_overwrite
162              
163             A boolean indicating whether it is permissible for the file to already exist
164             (whereupon it is overwritten). When false, a fatal exception is thrown when
165             the file already exists.
166              
167             Defaults to true.
168              
169             This attribute is available as an option of your plugin in F<dist.ini>.
170              
171             =head1 METHODS
172              
173             =head2 add_repo_file
174              
175             $plugin->add_repo_file($dzil_file);
176              
177             Registers a file object to be written to disk.
178             If the path is not absolute, it is treated as relative to C<repo_root>.
179             The file should consume the L<Dist::Zilla::Role::File> role.
180             Normally the consuming plugin would call this in the C<FileGatherer> phase.
181              
182             =head2 write_repo_files
183              
184             $plugin->write_repo_files;
185              
186             Writes out all files registered previously with C<add_repo_file>. Your plugin
187             should normally do this during either the C<AfterBuild> or C<AfterRelease>
188             phase, e.g.:
189              
190             sub after_build
191             {
192             my $self = shift;
193             $self->write_repo_files;
194             }
195              
196             =head2 _repo_files
197              
198             Returns the list of files added via C<add_repo_file>.
199             Normally the consuming plugin would call this in the C<FileMunger> phase.
200              
201             =head1 SEE ALSO
202              
203             =over 4
204              
205             =item *
206              
207             L<Dist::Zilla::Role::FileInjector>
208              
209             =back
210              
211             =head1 SUPPORT
212              
213             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Zilla-Role-RepoFileInjector>
214             (or L<bug-Dist-Zilla-Role-RepoFileInjector@rt.cpan.org|mailto:bug-Dist-Zilla-Role-RepoFileInjector@rt.cpan.org>).
215              
216             There is also a mailing list available for users of this distribution, at
217             L<http://dzil.org/#mailing-list>.
218              
219             There is also an irc channel available for users of this distribution, at
220             L<C<#distzilla> on C<irc.perl.org>|irc://irc.perl.org/#distzilla>.
221              
222             I am also usually active on irc, as 'ether' at C<irc.perl.org>.
223              
224             =head1 AUTHOR
225              
226             Karen Etheridge <ether@cpan.org>
227              
228             =head1 COPYRIGHT AND LICENCE
229              
230             This software is copyright (c) 2015 by Karen Etheridge.
231              
232             This is free software; you can redistribute it and/or modify it under
233             the same terms as the Perl 5 programming language system itself.
234              
235             =cut