File Coverage

blib/lib/Dist/Zilla/Plugin/MatchManifest.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             #---------------------------------------------------------------------
2             package Dist::Zilla::Plugin::MatchManifest;
3             #
4             # Copyright 2009 Christopher J. Madsen
5             #
6             # Author: Christopher J. Madsen <perl@cjmweb.net>
7             # Created: 17 Oct 2009
8             #
9             # This program is free software; you can redistribute it and/or modify
10             # it under the same terms as Perl itself.
11             #
12             # This program is distributed in the hope that it will be useful,
13             # but WITHOUT ANY WARRANTY; without even the implied warranty of
14             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the
15             # GNU General Public License or the Artistic License for more details.
16             #
17             # ABSTRACT: Ensure that MANIFEST is correct
18             #---------------------------------------------------------------------
19              
20             our $VERSION = '4.02';
21             # This file is part of Dist-Zilla-Plugin-MatchManifest 4.02 (July 19, 2014)
22              
23              
24 1     1   1083 use Moose 0.65; # attr fulfills requires
  0            
  0            
25             use Moose::Autobox 0.09; # flattten
26             with 'Dist::Zilla::Role::InstallTool';
27              
28             use autodie ':io';
29              
30              
31             has require_builder => (
32             is => 'ro',
33             isa => 'Bool',
34             default => 1,
35             );
36              
37             sub setup_installer {
38             my ($self, $arg) = @_;
39              
40             my $files = $self->zilla->files;
41              
42             # Find the existing MANIFEST:
43             my $manifestFile = $files->grep(sub{ $_->name eq 'MANIFEST' })->head;
44              
45             # No MANIFEST; create one:
46             unless ($manifestFile) {
47             $manifestFile = Dist::Zilla::File::InMemory->new({
48             name => 'MANIFEST',
49             content => '',
50             });
51              
52             $self->add_file($manifestFile);
53             } # end unless distribution already contained MANIFEST
54              
55             # List the files actually in the distribution:
56             my $builder_found;
57              
58             my $manifest = $files->map(sub {
59             my $name = $_->name;
60             ++$builder_found if $name eq 'Makefile.PL' or $name eq 'Build.PL';
61             return $name unless $name =~ /[ '\\]/;
62             $name =~ s/\\/\\\\/g;
63             $name =~ s/'/\\'/g;
64             return qq{'$name'};
65             })->sort->join("\n") . "\n";
66              
67             if (not $builder_found and $self->require_builder) {
68             $self->log_fatal(<<'END ERROR');
69             No Makefile.PL or Build.PL found!
70             [MatchManifest] must come after [MakeMaker] or [ModuleBuild].
71             Otherwise, the files they generate won't be listed in MANIFEST.
72             Set require_builder = 0 if you really want a dist with no Makefile.PL.
73             END ERROR
74             }
75              
76             return if $manifest eq $manifestFile->content;
77              
78             # We've got a mismatch. Report it:
79             require Text::Diff;
80              
81             my $onDisk = $self->zilla->root->file('MANIFEST');
82             my $stat = $onDisk->stat;
83              
84             my $diff = Text::Diff::diff(\$manifestFile->content, \$manifest, {
85             FILENAME_A => 'MANIFEST (on disk) ',
86             FILENAME_B => 'MANIFEST (auto-generated)',
87             CONTEXT => 0,
88             MTIME_A => $stat ? $stat->mtime : 0,
89             MTIME_B => time,
90             });
91              
92             $diff =~ s/^\@\@.*\n//mg; # Don't care about line numbers
93             chomp $diff;
94              
95             $self->log("MANIFEST does not match the collected files!");
96             $self->zilla->chrome->logger->log($diff); # No prefix
97              
98             # See if the author wants to accept the new MANIFEST:
99             $self->log_fatal("Aborted because of MANIFEST mismatch")
100             unless $self->zilla->chrome->prompt_yn("Update MANIFEST?",
101             { default => 0 });
102              
103             # Update the MANIFEST in the distribution:
104             $manifestFile->content($manifest);
105              
106             # And the original on disk:
107             open(my $out, '>:raw:utf8', $onDisk);
108             print $out $manifest;
109             close $out;
110              
111             $self->log_debug("Updated MANIFEST");
112             } # end setup_installer
113              
114             #---------------------------------------------------------------------
115             __PACKAGE__->meta->make_immutable;
116             no Moose;
117             1;
118              
119             __END__
120              
121             =head1 NAME
122              
123             Dist::Zilla::Plugin::MatchManifest - Ensure that MANIFEST is correct
124              
125             =head1 VERSION
126              
127             This document describes version 4.02 of
128             Dist::Zilla::Plugin::MatchManifest, released July 19, 2014.
129              
130             =head1 SYNOPSIS
131              
132             [MatchManifest]
133             require_builder = 1 ; this is the default and should seldom be changed
134              
135             =head1 DESCRIPTION
136              
137             If included, this plugin will ensure that the distribution contains a
138             F<MANIFEST> file and that its contents match the files collected by
139             Dist::Zilla. If not, it will display the differences and offer to
140             update the F<MANIFEST>.
141              
142             As I see it, there are 2 problems that a MANIFEST can protect against:
143              
144             =over
145              
146             =item 1.
147              
148             A file I don't want to distribute winds up in the tarball
149              
150             =item 2.
151              
152             A file I did want to distribute gets left out of the tarball
153              
154             =back
155              
156             Dist::Zilla protects against the second problem by using GatherDir
157             plugins that aren't restricted by a MANIFEST file. But the standard
158             L<Manifest|Dist::Zilla::Plugin::Manifest> plugin offers no protection
159             against the first problem.
160              
161             By keeping your MANIFEST under source control and using this plugin to
162             make sure it's kept up to date, you can protect yourself against both
163             problems.
164              
165             MatchManifest must come after your MakeMaker or ModuleBuild plugin, so
166             that it can see any F<Makefile.PL> or F<Build.PL> generated.
167              
168             =head1 ATTRIBUTES
169              
170             =head2 require_builder
171              
172             For safety, MatchManifest aborts if it doesn't see a F<Makefile.PL> or
173             F<Build.PL> in your dist. If C<[MatchManifest]> is listed before
174             C<[MakeMaker]> in your F<dist.ini>, then the manifest will be checked
175             before F<Makefile.PL> has been added, which is bad.
176              
177             If you really want to create a dist with no F<Makefile.PL> or
178             F<Build.PL>, you can set C<require_builder> to 0 to skip this check.
179              
180             =for Pod::Coverage
181             setup_installer
182              
183             =head1 CONFIGURATION AND ENVIRONMENT
184              
185             Dist::Zilla::Plugin::MatchManifest requires no configuration files or environment variables.
186              
187             =head1 INCOMPATIBILITIES
188              
189             None reported.
190              
191             =head1 BUGS AND LIMITATIONS
192              
193             No bugs have been reported.
194              
195             =head1 AUTHOR
196              
197             Christopher J. Madsen S<C<< <perl AT cjmweb.net> >>>
198              
199             Please report any bugs or feature requests
200             to S<C<< <bug-Dist-Zilla-Plugin-MatchManifest AT rt.cpan.org> >>>
201             or through the web interface at
202             L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Dist-Zilla-Plugin-MatchManifest >>.
203              
204             You can follow or contribute to Dist-Zilla-Plugin-MatchManifest's development at
205             L<< https://github.com/madsen/dist-zilla-plugin-matchmanifest >>.
206              
207             =head1 COPYRIGHT AND LICENSE
208              
209             This software is copyright (c) 2014 by Christopher J. Madsen.
210              
211             This is free software; you can redistribute it and/or modify it under
212             the same terms as the Perl 5 programming language system itself.
213              
214             =head1 DISCLAIMER OF WARRANTY
215              
216             BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
217             FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
218             OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
219             PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
220             EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
221             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
222             ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
223             YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
224             NECESSARY SERVICING, REPAIR, OR CORRECTION.
225              
226             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
227             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
228             REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE
229             LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
230             OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
231             THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
232             RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
233             FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
234             SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
235             SUCH DAMAGES.
236              
237             =cut