File Coverage

blib/lib/Dist/Zilla/Role/Git/DirtyFiles.pm
Criterion Covered Total %
statement 46 46 100.0
branch 5 6 83.3
condition n/a
subroutine 13 13 100.0
pod 1 1 100.0
total 65 66 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 10     10   6975 use 5.008;
  10         39  
10 10     10   63 use strict;
  10         25  
  10         334  
11 10     10   69 use warnings;
  10         32  
  10         750  
12              
13             package Dist::Zilla::Role::Git::DirtyFiles;
14             # ABSTRACT: Provide the allow_dirty & changelog attributes
15              
16             our $VERSION = '2.046';
17              
18 10     10   74 use Moose::Role;
  10         20  
  10         104  
19 10     10   55191 use Types::Standard qw{ Any ArrayRef Str RegexpRef };
  10         25  
  10         112  
20 10     10   10240 use Type::Utils qw(coerce from as via subtype);
  10         5057  
  10         78  
21 10     10   8683 use Types::Path::Tiny 'Path';
  10         19613  
  10         80  
22              
23 10     10   3728 use namespace::autoclean;
  10         28  
  10         155  
24 10     10   950 use Path::Tiny 0.048 qw(); # subsumes
  10         228  
  10         204  
25 10     10   57 use Try::Tiny;
  10         21  
  10         8660  
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 11     11   653 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 28     28 1 264 my ($self, $git, $listAllowed) = @_;
127              
128 28         3033 my $git_root = $self->repo_root;
129 28         205 my @filenames = @{ $self->allow_dirty };
  28         1649  
130              
131             # Interpret allow_dirty relative to the dzil root, not git root nor cwd
132 28         1385 my $dzil_root = Path::Tiny::path($self->zilla->root)->absolute->realpath;
133 28         18868 $git_root = Path::Tiny::path($git_root)
134             ->absolute($dzil_root)
135             ->realpath;
136              
137 28 50       8040 $self->log_fatal("Dzil root $dzil_root is not inside Git root $git_root")
138             unless $git_root->subsumes($dzil_root);
139              
140 28         4545 for my $fn (@filenames) {
141             try {
142 40     40   2166 $fn = Path::Tiny::path($fn)
143             ->absolute($dzil_root)
144             ->realpath # process ..
145             ->relative($git_root)
146             ->stringify;
147 40         13648 };
148             }
149              
150 28         10531 my $allowed = join '|', @{ $self->allow_dirty_match }, map { qr{^\Q$_\E$} } @filenames;
  28         1671  
  40         1800  
151              
152 28 100       352 $allowed = qr/(?!X)X/ if $allowed eq ''; # this cannot match anything
153              
154 28 100       1080 return grep { /$allowed/ ? $listAllowed : !$listAllowed }
  42         179264  
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.046
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