File Coverage

blib/lib/Dist/Zilla/Plugin/CopyFilesFromBuild.pm
Criterion Covered Total %
statement 68 86 79.0
branch 11 20 55.0
condition n/a
subroutine 15 17 88.2
pod 0 2 0.0
total 94 125 75.2


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