File Coverage

blib/lib/Dist/Zilla/Plugin/FileFinder/ByName.pm
Criterion Covered Total %
statement 43 43 100.0
branch 7 8 87.5
condition 12 12 100.0
subroutine 10 10 100.0
pod 0 3 0.0
total 72 76 94.7


line stmt bran cond sub pod time code
1             # ABSTRACT: FileFinder matching on pathnames
2              
3             use Moose;
4 2     2   2046 with 'Dist::Zilla::Role::FileFinder';
  2         6  
  2         16  
5              
6             use Dist::Zilla::Pragmas;
7 2     2   14303  
  2         5  
  2         20  
8             use namespace::autoclean;
9 2     2   16  
  2         6  
  2         23  
10             #pod =head1 SYNOPSIS
11             #pod
12             #pod In your F<dist.ini>:
13             #pod
14             #pod [FileFinder::ByName / MyFiles]
15             #pod dir = bin ; look in the bin/ directory
16             #pod dir = lib ; and the lib/ directory
17             #pod file = *.pl ; for .pl files
18             #pod match = \.pm$ ; and for .pm files
19             #pod skip = ignore ; that don't have "ignore" in the path
20             #pod
21             #pod =head1 CREDITS
22             #pod
23             #pod This plugin was originally contributed by Christopher J. Madsen.
24             #pod
25             #pod =cut
26              
27             use Moose::Util::TypeConstraints;
28 2     2   178 use MooseX::Types::Moose qw(ArrayRef RegexpRef Str);
  2         7  
  2         17  
29 2     2   4648  
  2         5  
  2         33  
30             use Text::Glob 0.08 qw(glob_to_regex_string);
31 2     2   11467  
  2         932  
  2         1739  
32             #pod =attr dir
33             #pod
34             #pod The file must be located in one of the specified directories (relative
35             #pod to the root directory of the dist).
36             #pod
37             #pod =attr file
38             #pod
39             #pod The filename must match one of the specified patterns (which are
40             #pod converted to regexs using L<Text::Glob> and combined with any C<match>
41             #pod rules).
42             #pod
43             #pod =cut
44              
45             has dirs => (
46             is => 'ro',
47             isa => ArrayRef[Str],
48             default => sub { [] },
49             );
50              
51             has files => (
52             is => 'ro',
53             isa => ArrayRef[Str],
54             default => sub { [] },
55             );
56              
57             {
58             my $type = subtype as ArrayRef[RegexpRef];
59             coerce $type, from ArrayRef[Str], via { [map { qr/$_/ } @$_] };
60              
61             #pod =attr match
62             #pod
63             #pod The pathname must match one of these regular expressions.
64             #pod
65             #pod =attr skip
66             #pod
67             #pod The pathname must I<not> match any of these regular expressions.
68             #pod
69             #pod =cut
70              
71             has matches => (
72             is => 'ro',
73             isa => $type,
74             coerce => 1,
75             default => sub { [] },
76             );
77              
78             has skips => (
79             is => 'ro',
80             isa => $type,
81             coerce => 1,
82             default => sub { [] },
83             );
84             }
85              
86             dir dirs
87 7     7 0 1117 file files
88             match matches
89             matching matches
90             skip skips
91             except skips
92             ) } }
93              
94              
95             my $list = shift;
96 7     7 0 1978 return undef unless @$list;
97             # Special case to avoid stringify+compile
98             return $list->[0] if @$list == 1;
99 39     39   74 # Wrap each element to ensure that alternations are isolated
100 39 100       106 my $re = join('|', map { "(?:$_)" } @$list);
101             qr/$re/
102 22 100       62 }
103              
104 8         23 my $self = shift;
  16         67  
105 8         268  
106             my $skip = _join_re($self->skips);
107             my $dir = _join_re([ map { qr!^\Q$_/! } @{ $self->dirs } ]);
108             my $match = _join_re([
109 13     13 0 30 (map { my $re = glob_to_regex_string($_); qr!(?:\A|/)$re\z! }
110             @{ $self->files }),
111 13         482 @{ $self->matches }
112 13         8822 ]);
  10         195  
  13         452  
113              
114 8         44 my $files = $self->zilla->files;
  8         734  
115 13         444  
116 13         33 $files = [ grep {
  13         446  
117             my $name = $_->name;
118             (not defined $dir or $name =~ $dir) and
119 13         420 (not defined $match or $name =~ $match) and
120             (not defined $skip or $name !~ $skip)
121             } @$files ];
122 13         36  
  455         1176  
123 455 100 100     4506 $self->log_debug("No files found") unless @$files;
      100        
      100        
      100        
124             $self->log_debug("Found " . $_->name) for @$files;
125              
126             $files;
127             }
128 13 50       44  
129 13         50 __PACKAGE__->meta->make_immutable;
130             1;
131 13         332  
132             #pod =head1 DESCRIPTION
133             #pod
134             #pod FileFinder::ByName is a L<FileFinder|Dist::Zilla::Role::FileFinder> that
135             #pod selects files by matching the criteria you specify against the pathname.
136             #pod
137             #pod There are three types of criteria you can use. C<dir> limits the
138             #pod search to a particular directory. C<match> is a regular expression
139             #pod that must match the pathname. C<skip> is a regular expression that
140             #pod must not match the pathname.
141             #pod
142             #pod Each key can be specified multiple times. Multiple occurrences of the
143             #pod same key are ORed together. Different keys are ANDed together. That
144             #pod means that to be selected, a file must be located in one of the
145             #pod C<dir>s, must match one of the C<match> regexs, and must not match any
146             #pod of the C<skip> regexs.
147             #pod
148             #pod Note that C<file> and C<match> are considered to be the I<same> key.
149             #pod They're just different ways to write a regex that the pathname must match.
150             #pod
151             #pod Omitting a particular key means that criterion will not apply to the
152             #pod search. Omitting all keys will select every file in your dist.
153             #pod
154             #pod Note: If you need to OR different types of criteria, then use more
155             #pod than one instance of FileFinder::ByName. A
156             #pod L<FileFinderUser|Dist::Zilla::Role::FileFinderUser> should allow you
157             #pod to specify more than one FileFinder to use.
158             #pod
159             #pod =for Pod::Coverage
160             #pod mvp_aliases
161             #pod mvp_multivalue_args
162             #pod find_files
163              
164              
165             =pod
166              
167             =encoding UTF-8
168              
169             =head1 NAME
170              
171             Dist::Zilla::Plugin::FileFinder::ByName - FileFinder matching on pathnames
172              
173             =head1 VERSION
174              
175             version 6.028
176              
177             =head1 SYNOPSIS
178              
179             In your F<dist.ini>:
180              
181             [FileFinder::ByName / MyFiles]
182             dir = bin ; look in the bin/ directory
183             dir = lib ; and the lib/ directory
184             file = *.pl ; for .pl files
185             match = \.pm$ ; and for .pm files
186             skip = ignore ; that don't have "ignore" in the path
187              
188             =head1 DESCRIPTION
189              
190             FileFinder::ByName is a L<FileFinder|Dist::Zilla::Role::FileFinder> that
191             selects files by matching the criteria you specify against the pathname.
192              
193             There are three types of criteria you can use. C<dir> limits the
194             search to a particular directory. C<match> is a regular expression
195             that must match the pathname. C<skip> is a regular expression that
196             must not match the pathname.
197              
198             Each key can be specified multiple times. Multiple occurrences of the
199             same key are ORed together. Different keys are ANDed together. That
200             means that to be selected, a file must be located in one of the
201             C<dir>s, must match one of the C<match> regexs, and must not match any
202             of the C<skip> regexs.
203              
204             Note that C<file> and C<match> are considered to be the I<same> key.
205             They're just different ways to write a regex that the pathname must match.
206              
207             Omitting a particular key means that criterion will not apply to the
208             search. Omitting all keys will select every file in your dist.
209              
210             Note: If you need to OR different types of criteria, then use more
211             than one instance of FileFinder::ByName. A
212             L<FileFinderUser|Dist::Zilla::Role::FileFinderUser> should allow you
213             to specify more than one FileFinder to use.
214              
215             =head1 PERL VERSION
216              
217             This module should work on any version of perl still receiving updates from
218             the Perl 5 Porters. This means it should work on any version of perl released
219             in the last two to three years. (That is, if the most recently released
220             version is v5.40, then this module should work on both v5.40 and v5.38.)
221              
222             Although it may work on older versions of perl, no guarantee is made that the
223             minimum required version will not be increased. The version may be increased
224             for any reason, and there is no promise that patches will be accepted to lower
225             the minimum required perl.
226              
227             =head1 ATTRIBUTES
228              
229             =head2 dir
230              
231             The file must be located in one of the specified directories (relative
232             to the root directory of the dist).
233              
234             =head2 file
235              
236             The filename must match one of the specified patterns (which are
237             converted to regexs using L<Text::Glob> and combined with any C<match>
238             rules).
239              
240             =head2 match
241              
242             The pathname must match one of these regular expressions.
243              
244             =head2 skip
245              
246             The pathname must I<not> match any of these regular expressions.
247              
248             =head1 CREDITS
249              
250             This plugin was originally contributed by Christopher J. Madsen.
251              
252             =for Pod::Coverage mvp_aliases
253             mvp_multivalue_args
254             find_files
255              
256             =head1 AUTHOR
257              
258             Ricardo SIGNES 😏 <cpan@semiotic.systems>
259              
260             =head1 COPYRIGHT AND LICENSE
261              
262             This software is copyright (c) 2022 by Ricardo SIGNES.
263              
264             This is free software; you can redistribute it and/or modify it under
265             the same terms as the Perl 5 programming language system itself.
266              
267             =cut