File Coverage

blib/lib/Dist/Zilla/Plugin/CopyFilesFromBuild.pm
Criterion Covered Total %
statement 71 89 79.7
branch 11 20 55.0
condition n/a
subroutine 16 18 88.8
pod 0 2 0.0
total 98 129 75.9


line stmt bran cond sub pod time code
1 1     1   126229 use strict;
  1         2  
  1         27  
2 1     1   6 use warnings;
  1         1  
  1         36  
3 1     1   453 use utf8;
  1         8  
  1         3  
4              
5             package Dist::Zilla::Plugin::CopyFilesFromBuild;
6             # ABSTRACT: Copy (or move) specific files after building (for SCM inclusion, etc.)
7             $Dist::Zilla::Plugin::CopyFilesFromBuild::VERSION = '0.170880';
8 1     1   466 use Moose;
  1         299806  
  1         6  
9 1     1   5320 use MooseX::Has::Sugar;
  1         483  
  1         3  
10             with qw/ Dist::Zilla::Role::AfterBuild /;
11              
12 1     1   529 use File::Copy ();
  1         1691  
  1         21  
13 1     1   482 use IO::File;
  1         6473  
  1         104  
14 1     1   6 use List::Util 1.33 qw( any );
  1         15  
  1         52  
15 1     1   636 use Path::Tiny;
  1         8716  
  1         53  
16 1     1   384 use Set::Scalar;
  1         7626  
  1         627  
17              
18             # accept some arguments multiple times.
19 1     1 0 1795502 sub mvp_multivalue_args { qw{ copy move } }
20              
21             has copy => (
22             ro, lazy,
23             isa => 'ArrayRef[Str]',
24             default => sub { [] },
25             );
26              
27             has move => (
28             ro, lazy,
29             isa => 'ArrayRef[Str]',
30             default => sub { [] },
31             );
32              
33             sub after_build {
34 1     1 0 326080 my $self = shift;
35 1         2 my $data = shift;
36              
37 1         2 my $build_root = $data->{build_root};
38 1         2 for my $path (@{$self->copy}) {
  1         30  
39 2 50       383 if ($path eq '') {
40 0         0 next;
41             }
42 2         6 my $src = path($build_root)->child( $path );
43 2         130 my $dest = path($self->zilla->root)->child( $path );
44 2 50       107 if (-e $src) {
45 2 50       40 File::Copy::copy "$src", "$dest"
46             or $self->log_fatal("Unable to copy $src to $dest: $!");
47 2         463 $self->log("Copied $src to $dest");
48             } else {
49 0         0 $self->log_fatal("Cannot copy $path from build: file does not exist");
50             }
51             }
52              
53 1         291 my $moved_something = 0;
54              
55 1         3 for my $path (@{$self->move}) {
  1         51  
56 1 50       4 if ($path eq '') {
57 0         0 next;
58             }
59 1         3 my $src = path($build_root)->child( $path );
60 1         77 my $dest = path($self->zilla->root)->child( $path );
61 1 50       65 if (-e $src) {
62 1 50       21 File::Copy::move "$src", "$dest"
63             or $self->log_fatal("Unable to move $src to $dest: $!");
64 1         112 $moved_something++;
65 1         4 $self->log("Moved $src to $dest");
66             } else {
67 0         0 $self->log_fatal("Cannot move $path from build: file does not exist");
68             }
69             }
70              
71 1 50       626 if ($moved_something) {
72             # These are probably horrible hacks. If so, please tell me a
73             # better way.
74 1         4 $self->_prune_moved_files();
75 1         73 $self->_filter_manifest($build_root);
76             }
77             }
78              
79             sub _prune_moved_files {
80 1     1   3 my ($self, ) = @_;
81 1         1 for my $file (@{ $self->zilla->files }) {
  1         38  
82 6 100   6   217 next unless any { $file->name eq $_ } @{$self->move};
  6         20  
  6         174  
83              
84 1         39 $self->log_debug([ 'pruning moved file %s', $file->name ]);
85              
86 1         102 $self->zilla->prune_file($file);
87             }
88             }
89              
90             sub _read_manifest {
91 0     0   0 my ($self, $manifest_filename) = @_;
92 0         0 my $input = IO::File->new($manifest_filename);
93 0         0 my @lines = $input->getlines;
94 0         0 chomp @lines;
95 0         0 return @lines;
96             }
97              
98             sub _write_manifest {
99 0     0   0 my ($self, $manifest_filename, @contents) = @_;
100 0         0 my $output = IO::File->new($manifest_filename, 'w');
101 0         0 $output->print(join("\n", (sort @contents)), "\n");
102             }
103              
104             sub _filter_manifest {
105 1     1   2 my ($self, $build_root) = @_;
106 1 50       1 if (@{$self->move}) {
  1         29  
107 1         4 my $manifest_file = path($build_root)->child( 'MANIFEST' );
108 1 50       40 return unless -e $manifest_file;
109 0           my $files = Set::Scalar->new($self->_read_manifest($manifest_file));
110 0           my $moved_files = Set::Scalar->new(@{$self->move});
  0            
111 0           my $filtered_files = $files->difference($moved_files);
112 0           $self->log_debug("Removing moved files from MANIFEST");
113 0           $self->_write_manifest($manifest_file, $filtered_files->members);
114             }
115             }
116              
117             __PACKAGE__->meta->make_immutable;
118 1     1   5 no Moose;
  1         2  
  1         5  
119             1; # Magic true value required at end of module
120              
121             __END__
122              
123             =pod
124              
125             =head1 NAME
126              
127             Dist::Zilla::Plugin::CopyFilesFromBuild - Copy (or move) specific files after building (for SCM inclusion, etc.)
128              
129             =head1 VERSION
130              
131             version 0.170880
132              
133             =head1 SYNOPSIS
134              
135             In your dist.ini:
136              
137             [CopyFilesFromBuild]
138             copy = README
139             move = README.pod
140             copy = Makefile.PL
141              
142             =head1 DESCRIPTION
143              
144             This plugin will automatically copy the files that you specify in
145             dist.ini from the build directory into the distribution directoory.
146             This is so you can commit them to version control.
147              
148             If you want to put a build-generated file in version control but you
149             I<don't> want it to I<remain> in the build dir, use C<move> instead of
150             C<copy>. When you use C<move>, the F<MANIFEST> file will be updated if
151             it exists, and the moved files will be pruned from their former
152             location.
153              
154             =head1 RATIONALE
155              
156             This plugin is based on CopyReadmeFromBuild. I wrote it because that
157             plugin was copying the wrong README file (F<README> instead of
158             F<README.mkdn> or F<README.pod>), and it could not be configured to do
159             otherwise. So I wrote my own module that copies exactly the files that
160             I specify.
161              
162             I added the C<move> functionality because I wanted to generate a
163             F<README.pod> file for Github, but MakeMaker wanted to also install
164             the README.pod file as part of the distribution. So I made it possible
165             to take a file generated during the build and move it I<out> of the
166             build directory, so that it would not be included in the distribution.
167              
168             =for Pod::Coverage after_build mvp_multivalue_args
169              
170             =head1 BUGS AND LIMITATIONS
171              
172             Please report any bugs or feature requests to
173             C<rct+perlbug@thompsonclan.org>.
174              
175             =head1 SEE ALSO
176              
177             =over 4
178              
179             =item *
180              
181             L<Dist::Zilla::Plugin::CopyReadmeFromBuild> - The basis for this module
182              
183             =back
184              
185             =head1 INSTALLATION
186              
187             See perlmodinstall for information and options on installing Perl modules.
188              
189             =head1 AUTHOR
190              
191             Ryan C. Thompson <rct@thompsonclan.org>
192              
193             =head1 COPYRIGHT AND LICENSE
194              
195             This software is copyright (c) 2010 by Ryan C. Thompson.
196              
197             This is free software; you can redistribute it and/or modify it under
198             the same terms as the Perl 5 programming language system itself.
199              
200             =head1 DISCLAIMER OF WARRANTY
201              
202             BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
203             FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
204             WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
205             PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
206             EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
207             IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
208             PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
209             SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME
210             THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.
211              
212             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
213             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
214             REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
215             TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
216             CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
217             SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
218             RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
219             FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
220             SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
221             DAMAGES.
222              
223             =cut