File Coverage

blib/lib/Dist/Zilla/Role/Git/DirtyFiles.pm
Criterion Covered Total %
statement 44 44 100.0
branch 5 6 83.3
condition n/a
subroutine 13 13 100.0
pod 1 1 100.0
total 63 64 98.4


line stmt bran cond sub pod time code
1             #
2             # This file is part of Dist-Zilla-Plugin-Git
3             #
4             # This software is copyright (c) 2009 by Jerome Quelin.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9 11     11   9170 use 5.008;
  11         60  
10 11     11   90 use strict;
  11         24  
  11         403  
11 11     11   71 use warnings;
  11         41  
  11         940  
12              
13             package Dist::Zilla::Role::Git::DirtyFiles;
14             # ABSTRACT: Provide the allow_dirty & changelog attributes
15              
16             our $VERSION = '2.048';
17              
18 11     11   85 use Moose::Role;
  11         26  
  11         117  
19 11     11   61962 use Types::Standard qw{ Any ArrayRef Str RegexpRef };
  11         31  
  11         134  
20 11     11   11700 use Type::Utils qw(coerce from as via subtype);
  11         5235  
  11         84  
21 11     11   9966 use Types::Path::Tiny 'Path';
  11         19652  
  11         97  
22              
23 11     11   4302 use namespace::autoclean;
  11         28  
  11         127  
24 11     11   1006 use Path::Tiny 0.048 qw(); # subsumes
  11         308  
  11         224  
25 11     11   55 use Try::Tiny;
  11         30  
  11         9703  
26              
27             requires qw(log_fatal repo_root zilla);
28              
29             # -- attributes
30              
31             #pod =attr allow_dirty
32             #pod
33             #pod A list of paths that are allowed to be dirty in the git checkout.
34             #pod Defaults to C<dist.ini> and the changelog (as defined per the
35             #pod C<changelog> attribute.
36             #pod
37             #pod If your C<repo_root> is not the default (C<.>), then these pathnames
38             #pod are relative to Dist::Zilla's root directory, not the Git root directory.
39             #pod
40             #pod =attr allow_dirty_match
41             #pod
42             #pod A list of regular expressions that match paths allowed to be dirty in
43             #pod the git checkout. This is combined with C<allow_dirty>. Defaults to
44             #pod the empty list.
45             #pod
46             #pod The paths being matched are relative to the Git root directory, even
47             #pod if your C<repo_root> is not the default (C<.>).
48             #pod
49             #pod =attr changelog
50             #pod
51             #pod The name of the changelog. Defaults to C<Changes>.
52             #pod
53             #pod =cut
54              
55             {
56             # We specifically allow the empty string to represent the empty list.
57             # Otherwise, there'd be no way to specify an empty list in an INI file.
58             my $type = subtype as ArrayRef[Path];
59             coerce $type,
60             from ArrayRef, via { (ArrayRef[Path])->coerce( [ grep length, @$_ ] ) },
61             from Any, via { length($_) ? (ArrayRef[Path])->coerce($_) : [] };
62              
63             has allow_dirty => (
64             is => 'ro', lazy => 1,
65             isa => $type,
66             coerce => 1,
67             builder => '_build_allow_dirty',
68             );
69             }
70              
71             has changelog => ( is => 'ro', isa=>Str, default => 'Changes' );
72              
73             {
74             my $type = subtype as ArrayRef[RegexpRef];
75             coerce $type, from ArrayRef[Str], via { [map qr/$_/, @$_] };
76             has allow_dirty_match => (
77             is => 'ro',
78             lazy => 1,
79             coerce => 1,
80             isa => $type,
81             default => sub { [] },
82             );
83             }
84              
85             around mvp_multivalue_args => sub {
86             my ($orig, $self) = @_;
87              
88             my @start = $self->$orig;
89             return (@start, 'allow_dirty', 'allow_dirty_match');
90             };
91              
92             # -- builders & initializers
93              
94 12     12   729 sub _build_allow_dirty { [ 'dist.ini', shift->changelog ] }
95              
96             around dump_config => sub
97             {
98             my $orig = shift;
99             my $self = shift;
100              
101             my $config = $self->$orig;
102              
103             $config->{+__PACKAGE__} = {
104             (map +($_ => [ sort @{ $self->$_ } ]), qw(allow_dirty allow_dirty_match)),
105             changelog => $self->changelog,
106             };
107              
108             return $config;
109             };
110              
111             #pod =method list_dirty_files
112             #pod
113             #pod my @dirty = $plugin->list_dirty_files($git, $listAllowed);
114             #pod
115             #pod This returns a list of the modified or deleted files in C<$git>,
116             #pod filtered against the C<allow_dirty> attribute. If C<$listAllowed> is
117             #pod true, only allowed files are listed. If it's false, only files that
118             #pod are not allowed to be dirty are listed.
119             #pod
120             #pod In scalar context, returns the number of dirty files.
121             #pod
122             #pod =cut
123              
124             sub list_dirty_files
125             {
126 29     29 1 262 my ($self, $git, $listAllowed) = @_;
127              
128 29         3744 my $git_root = $self->repo_root;
129 29         288 my @filenames = @{ $self->allow_dirty };
  29         1819  
130              
131             # Interpret allow_dirty relative to the dzil root, not git root nor cwd
132 29         1718 my $dzil_root = Path::Tiny::path($self->zilla->root)->absolute->realpath;
133 29         21714 $git_root = Path::Tiny::path($git_root)
134             ->absolute($dzil_root)
135             ->realpath;
136              
137 29 50       8339 $self->log_fatal("Dzil root $dzil_root is not inside Git root $git_root")
138             unless $git_root->subsumes($dzil_root);
139              
140 29         4936 for my $fn (@filenames) {
141             try {
142 42     42   2691 $fn = Path::Tiny::path($fn)
143             ->absolute($dzil_root)
144             ->realpath # process ..
145             ->relative($git_root)
146             ->stringify;
147 42         14348 };
148             }
149              
150 29         11364 my $allowed = join '|', @{ $self->allow_dirty_match }, map qr{^\Q$_\E$}, @filenames;
  29         1894  
151              
152 29 100       432 $allowed = qr/(?!X)X/ if $allowed eq ''; # this cannot match anything
153              
154 29 100       1541 return grep /$allowed/ ? $listAllowed : !$listAllowed,
155             $git->ls_files( { modified=>1, deleted=>1 } );
156             } # end list_dirty_files
157              
158              
159             1;
160              
161             __END__
162              
163             =pod
164              
165             =encoding UTF-8
166              
167             =head1 NAME
168              
169             Dist::Zilla::Role::Git::DirtyFiles - Provide the allow_dirty & changelog attributes
170              
171             =head1 VERSION
172              
173             version 2.048
174              
175             =head1 DESCRIPTION
176              
177             This role is used within the git plugin to work with files that are
178             dirty in the local git checkout.
179              
180             =head1 ATTRIBUTES
181              
182             =head2 allow_dirty
183              
184             A list of paths that are allowed to be dirty in the git checkout.
185             Defaults to C<dist.ini> and the changelog (as defined per the
186             C<changelog> attribute.
187              
188             If your C<repo_root> is not the default (C<.>), then these pathnames
189             are relative to Dist::Zilla's root directory, not the Git root directory.
190              
191             =head2 allow_dirty_match
192              
193             A list of regular expressions that match paths allowed to be dirty in
194             the git checkout. This is combined with C<allow_dirty>. Defaults to
195             the empty list.
196              
197             The paths being matched are relative to the Git root directory, even
198             if your C<repo_root> is not the default (C<.>).
199              
200             =head2 changelog
201              
202             The name of the changelog. Defaults to C<Changes>.
203              
204             =head1 METHODS
205              
206             =head2 list_dirty_files
207              
208             my @dirty = $plugin->list_dirty_files($git, $listAllowed);
209              
210             This returns a list of the modified or deleted files in C<$git>,
211             filtered against the C<allow_dirty> attribute. If C<$listAllowed> is
212             true, only allowed files are listed. If it's false, only files that
213             are not allowed to be dirty are listed.
214              
215             In scalar context, returns the number of dirty files.
216              
217             =for Pod::Coverage mvp_multivalue_args
218              
219             =head1 SUPPORT
220              
221             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Zilla-Plugin-Git>
222             (or L<bug-Dist-Zilla-Plugin-Git@rt.cpan.org|mailto:bug-Dist-Zilla-Plugin-Git@rt.cpan.org>).
223              
224             There is also a mailing list available for users of this distribution, at
225             L<http://dzil.org/#mailing-list>.
226              
227             There is also an irc channel available for users of this distribution, at
228             L<C<#distzilla> on C<irc.perl.org>|irc://irc.perl.org/#distzilla>.
229              
230             =head1 AUTHOR
231              
232             Jerome Quelin
233              
234             =head1 COPYRIGHT AND LICENCE
235              
236             This software is copyright (c) 2009 by Jerome Quelin.
237              
238             This is free software; you can redistribute it and/or modify it under
239             the same terms as the Perl 5 programming language system itself.
240              
241             =cut