File Coverage

blib/lib/File/Util/Test.pm
Criterion Covered Total %
statement 290 302 96.0
branch 224 278 80.5
condition 124 135 91.8
subroutine 35 35 100.0
pod 30 30 100.0
total 703 780 90.1


line stmt bran cond sub pod time code
1             ## no critic: Subroutines::ProhibitExplicitReturnUndef
2             package File::Util::Test;
3              
4 2     2   510575 use 5.010001;
  2         9  
5 2     2   14 use strict;
  2         4  
  2         68  
6 2     2   10 use warnings;
  2         4  
  2         141  
7              
8 2     2   16 use Cwd ();
  2         18  
  2         56  
9 2     2   10 use Exporter 'import';
  2         5  
  2         13558  
10              
11             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
12             our $DATE = '2024-07-17'; # DATE
13             our $DIST = 'File-Util-Test'; # DIST
14             our $VERSION = '0.632'; # VERSION
15              
16             our @EXPORT_OK = qw(
17             file_exists
18             l_abs_path
19             dir_empty
20             dir_not_empty
21             dir_has_entries
22             dir_has_files
23             dir_has_dot_files
24             dir_has_non_dot_files
25             dir_has_subdirs
26             dir_has_non_subdirs
27             dir_has_dot_subdirs
28             dir_has_non_dot_subdirs
29             dir_only_has_files
30             dir_only_has_dot_files
31             dir_only_has_non_dot_files
32             dir_only_has_subdirs
33             dir_only_has_dot_subdirs
34             dir_only_has_non_dot_subdirs
35              
36             get_dir_entries
37             get_dir_dot_entries
38             get_dir_subdirs
39             get_dir_non_subdirs
40             get_dir_dot_subdirs
41             get_dir_non_dot_subdirs
42             get_dir_files
43             get_dir_dot_files
44             get_dir_non_dot_files
45             get_dir_only_file
46             get_dir_only_subdir
47             get_dir_only_symlink
48             );
49              
50             our %SPEC;
51              
52             sub file_exists {
53 4     4 1 491079 my $path = shift;
54              
55 4 100 100     135 !(-l $path) && (-e _) || (-l _);
56             }
57              
58             sub l_abs_path {
59 5     5 1 7084 my $path = shift;
60 5 100       155 return Cwd::abs_path($path) unless (-l $path);
61              
62 4         16 $path =~ s!/\z!!;
63 4         9 my ($parent, $leaf);
64 4 50       36 if ($path =~ m!(.+)/(.+)!s) {
65 4         80 $parent = Cwd::abs_path($1);
66 4 50       14 return undef unless defined($path);
67 4         13 $leaf = $2;
68             } else {
69 0         0 $parent = Cwd::getcwd();
70 0         0 $leaf = $path;
71             }
72 4         30 "$parent/$leaf";
73             }
74              
75             sub dir_empty {
76 8     8 1 41287 my ($dir) = @_;
77 8 100       259 return undef unless (-d $dir);
78 7 50       339 return undef unless opendir my($dh), $dir;
79 7         3381 while (defined(my $e = readdir $dh)) {
80 20 100 100     142 next if $e eq '.' || $e eq '..';
81 6         110 return 0;
82             }
83 1         19 1;
84             }
85              
86             sub dir_not_empty {
87 10     10 1 28 my ($dir) = @_;
88 10 100       217 return undef unless (-d $dir);
89 8 50       272 return undef unless opendir my($dh), $dir;
90 8         168 while (defined(my $e = readdir $dh)) {
91 22 100 100     128 next if $e eq '.' || $e eq '..';
92 6         136 return 1;
93             }
94 2         33 0;
95             }
96              
97 5     5 1 20 sub dir_has_entries { goto \&dir_not_empty }
98              
99             sub dir_has_files {
100 11     11 1 36 my ($dir) = @_;
101 11 100       249 return undef unless (-d $dir);
102 10 50       396 return undef unless opendir my($dh), $dir;
103 10         246 while (defined(my $e = readdir $dh)) {
104 29 100 100     182 next if $e eq '.' || $e eq '..';
105 9 100       357 next unless -f "$dir/$e";
106 5         87 return 1;
107             }
108 5         87 0;
109             }
110              
111             sub dir_only_has_files {
112 8     8 1 25 my ($dir) = @_;
113 8 100       165 return undef unless (-d $dir);
114 7 50       259 return undef unless opendir my($dh), $dir;
115 7         18 my $has_files;
116 7         140 while (defined(my $e = readdir $dh)) {
117 22 100 100     117 next if $e eq '.' || $e eq '..';
118 8 100       143 return 0 unless -f "$dir/$e";
119 5         44 $has_files++;
120             }
121 4 100       105 $has_files ? 1:0;
122             }
123              
124             sub dir_has_dot_files {
125 11     11 1 36 my ($dir) = @_;
126 11 100       231 return undef unless (-d $dir);
127 10 50       351 return undef unless opendir my($dh), $dir;
128 10         195 while (defined(my $e = readdir $dh)) {
129 29 100 100     193 next if $e eq '.' || $e eq '..';
130 9 100       86 next unless $e =~ /\A\./;
131 4 100       96 next unless -f "$dir/$e";
132 3         57 return 1;
133             }
134 7         136 0;
135             }
136              
137             sub dir_only_has_dot_files {
138 7     7 1 24 my ($dir) = @_;
139 7 100       157 return undef unless (-d $dir);
140 6 50       285 return undef unless opendir my($dh), $dir;
141 6         39 my $has_dot_files;
142 6         134 while (defined(my $e = readdir $dh)) {
143 18 100 100     121 next if $e eq '.' || $e eq '..';
144 6 100       81 return 0 unless $e =~ /\A\./;
145 3 100       88 return 0 unless -f "$dir/$e";
146 2         22 $has_dot_files++;
147             }
148 2 100       40 $has_dot_files ? 1:0;
149             }
150              
151             sub dir_has_non_dot_files {
152 11     11 1 35 my ($dir) = @_;
153 11 100       4265 return undef unless (-d $dir);
154 10 50       383 return undef unless opendir my($dh), $dir;
155 10         249 while (defined(my $e = readdir $dh)) {
156 30 100 100     160 next if $e eq '.' || $e eq '..';
157 10 100       77 next if $e =~ /\A\./;
158 6 100       129 next unless -f "$dir/$e";
159 3         55 return 1;
160             }
161 7         108 0;
162             }
163              
164             sub dir_only_has_non_dot_files {
165 7     7 1 23 my ($dir) = @_;
166 7 100       164 return undef unless (-d $dir);
167 6 50       219 return undef unless opendir my($dh), $dir;
168 6         15 my $has_nondot_files;
169 6         120 while (defined(my $e = readdir $dh)) {
170 17 100 100     94 next if $e eq '.' || $e eq '..';
171 5 100       111 return 0 if $e =~ /\A\./;
172 2 100       85 return 0 unless -f "$dir/$e";
173 1         51 $has_nondot_files++;
174             }
175 2 100       42 $has_nondot_files ? 1:0;
176             }
177              
178             sub dir_has_subdirs {
179 12     12 1 38 my ($dir) = @_;
180 12 100       278 return undef unless (-d $dir);
181 11 50       372 return undef unless opendir my($dh), $dir;
182 11         230 while (defined(my $e = readdir $dh)) {
183 32 100 100     194 next if $e eq '.' || $e eq '..';
184 10 100       176 next if -l "$dir/$e";
185 4 100       33 next unless -d _;
186 2         37 return 1;
187             }
188 9         140 0;
189             }
190              
191             sub dir_only_has_subdirs {
192 9     9 1 26 my ($dir) = @_;
193 9 100       220 return undef unless (-d $dir);
194 8 50       277 return undef unless opendir my($dh), $dir;
195 8         17 my $has_subdirs;
196 8         175 while (defined(my $e = readdir $dh)) {
197 24 100 100     111 next if $e eq '.' || $e eq '..';
198 8 100       191 return 0 unless -d "$dir/$e";
199 4         32 $has_subdirs++;
200             }
201 4 100       64 $has_subdirs ? 1:0;
202             }
203              
204             sub dir_has_non_subdirs {
205 9     9 1 23 my ($dir) = @_;
206 9 100       151 return undef unless (-d $dir);
207 8 50       234 return undef unless opendir my($dh), $dir;
208 8         128 while (defined(my $e = readdir $dh)) {
209 23 100 100     125 next if $e eq '.' || $e eq '..';
210 7 100       127 return 1 if -l "$dir/$e";
211 4 100       40 return 1 if !(-d _);
212             }
213 3         39 0;
214             }
215              
216             sub dir_has_dot_subdirs {
217 6     6 1 19 my ($dir) = @_;
218 6 100       135 return undef unless (-d $dir);
219 5 50       178 return undef unless opendir my($dh), $dir;
220 5         136 while (defined(my $e = readdir $dh)) {
221 14 100 100     85 next if $e eq '.' || $e eq '..';
222 4 100       46 next unless $e =~ /\A\./;
223 2 50       37 next if -l "$dir/$e";
224 2 100       18 next unless -d _;
225 1         22 return 1;
226             }
227 4         109 0;
228             }
229              
230             sub dir_only_has_dot_subdirs {
231 9     9 1 25 my ($dir) = @_;
232 9 100       198 return undef unless (-d $dir);
233 8 50       300 return undef unless opendir my($dh), $dir;
234 8         18 my $has_dot_subdirs;
235 8         171 while (defined(my $e = readdir $dh)) {
236 24 100 100     131 next if $e eq '.' || $e eq '..';
237 8 100       123 return 0 unless $e =~ /\A\./;
238 4 100       111 return 0 unless -d "$dir/$e";
239 2         15 $has_dot_subdirs++;
240             }
241 2 100       32 $has_dot_subdirs ? 1:0;
242             }
243              
244             sub dir_has_non_dot_subdirs {
245 6     6 1 16 my ($dir) = @_;
246 6 100       126 return undef unless (-d $dir);
247 5 50       152 return undef unless opendir my($dh), $dir;
248 5         108 while (defined(my $e = readdir $dh)) {
249 14 100 100     91 next if $e eq '.' || $e eq '..';
250 4 100       42 next if $e =~ /\A\./;
251 2 50       26 next if -l "$dir/$e";
252 2 100       13 next unless -d _;
253 1         17 return 1;
254             }
255 4         71 0;
256             }
257              
258             sub dir_only_has_non_dot_subdirs {
259 9     9 1 32 my ($dir) = @_;
260 9 100       203 return undef unless (-d $dir);
261 8 50       309 return undef unless opendir my($dh), $dir;
262 8         19 my $has_nondot_subdirs;
263 8         160 while (defined(my $e = readdir $dh)) {
264 23 100 100     120 next if $e eq '.' || $e eq '..';
265 7 100       149 return 0 if $e =~ /\A\./;
266 3 100       77 return 0 unless -d "$dir/$e";
267 1         13 $has_nondot_subdirs++;
268             }
269 2 100       39 $has_nondot_subdirs ? 1:0;
270             }
271              
272             sub get_dir_entries {
273 2 50   2 1 13058 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
274 2 50       14 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
275              
276 2         7 my ($dir) = @_;
277 2   100     14 $dir //= ".";
278              
279 2 50       223 opendir my($dh), $dir or die "Can't opendir $dir: $!";
280 2 100       66 my @res = grep { $_ ne '.' && $_ ne '..' } readdir $dh;
  9         44  
281 2         47 closedir $dh; # we're so nice
282 2         79 @res;
283             }
284              
285             sub get_dir_dot_entries {
286 1 50   1 1 6 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
287 1 50       7 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
288              
289 1         3 my ($dir) = @_;
290 1   50     29 $dir //= ".";
291              
292 1 50       61 opendir my($dh), $dir or die "Can't opendir $dir: $!";
293 1 100 100     41 my @res = grep { $_ ne '.' && $_ ne '..' && /\A\./ } readdir $dh;
  6         46  
294 1         17 closedir $dh; # we're so nice
295 1         16 @res;
296             }
297              
298             sub get_dir_files {
299 1 50   1 1 7 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
300 1 50       5 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
301              
302 1         3 my ($dir) = @_;
303 1   50     10 $dir //= ".";
304              
305 1 50       47 opendir my($dh), $dir or die "Can't opendir $dir: $!";
306 1 100 100     34 my @res = grep { $_ ne '.' && $_ ne '..' && (-f "$dir/$_")} readdir $dh;
  6         75  
307 1         14 closedir $dh; # we're so nice
308 1         16 @res;
309             }
310              
311             sub get_dir_dot_files {
312 1 50   1 1 9 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
313 1 50       13 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
314              
315 1         5 my ($dir) = @_;
316 1   50     9 $dir //= ".";
317              
318 1 50       78 opendir my($dh), $dir or die "Can't opendir $dir: $!";
319 1 100 100     68 my @res = grep { $_ ne '.' && $_ ne '..' && /\A\./ && (-f "$dir/$_")} readdir $dh;
  6   100     110  
320 1         23 closedir $dh; # we're so nice
321 1         16 @res;
322             }
323              
324             sub get_dir_non_dot_files {
325 1 50   1 1 7 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
326 1 50       6 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
327              
328 1         3 my ($dir) = @_;
329 1   50     9 $dir //= ".";
330              
331 1 50       45 opendir my($dh), $dir or die "Can't opendir $dir: $!";
332 1 100 100     34 my @res = grep { $_ ne '.' && $_ ne '..' && !/\A\./ && (-f "$dir/$_")} readdir $dh;
  6   100     79  
333 1         75 closedir $dh; # we're so nice
334 1         44 @res;
335             }
336              
337             sub get_dir_subdirs {
338 2 50   2 1 13 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
339 2 50       11 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
340              
341 2         7 my ($dir) = @_;
342 2   100     12 $dir //= ".";
343              
344 2 50       118 opendir my($dh), $dir or die "Can't opendir $dir: $!";
345 2 100 100     58 my @res = grep { $_ ne '.' && $_ ne '..' && !(-l "$dir/$_") && (-d _) } readdir $dh;
  9   100     143  
346 2         26 closedir $dh; # we're so nice
347 2         25 @res;
348             }
349              
350             sub get_dir_non_subdirs {
351 2 50   2 1 16 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
352 2 50       10 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
353              
354 2         8 my ($dir) = @_;
355 2   100     12 $dir //= ".";
356              
357 2 50       88 opendir my($dh), $dir or die "Can't opendir $dir: $!";
358 2 100 100     58 my @res = grep { $_ ne '.' && $_ ne '..' && ((-l "$dir/$_") || !(-d _)) } readdir $dh;
  9   100     116  
359 2         25 closedir $dh; # we're so nice
360 2         27 @res;
361             }
362              
363             sub get_dir_dot_subdirs {
364 1 50   1 1 7 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
365 1 50       6 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
366              
367 1         3 my ($dir) = @_;
368 1   50     9 $dir //= ".";
369              
370 1 50       43 opendir my($dh), $dir or die "Can't opendir $dir: $!";
371 1 100 100     32 my @res = grep { $_ ne '.' && $_ ne '..' && /\A\./ && !(-l "$dir/$_") && (-d _) } readdir $dh;
  6   100     89  
      66        
372 1         14 closedir $dh; # we're so nice
373 1         14 @res;
374             }
375              
376             sub get_dir_non_dot_subdirs {
377 1 50   1 1 6 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
378 1 50       6 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
379              
380 1         4 my ($dir) = @_;
381 1   50     7 $dir //= ".";
382              
383 1 50       43 opendir my($dh), $dir or die "Can't opendir $dir: $!";
384 1 100 100     33 my @res = grep { $_ ne '.' && $_ ne '..' && !/\A\./ && !(-l "$dir/$_") && (-d _) } readdir $dh;
  6   100     82  
      66        
385 1         15 closedir $dh; # we're so nice
386 1         14 @res;
387             }
388              
389             sub get_dir_only_file {
390 8 100   8 1 455 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  4         16  
391 8         23 my $opt_ignore_dir = delete $opts->{ignore_dir};
392 8 50       31 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
393              
394 8         20 my ($dir) = @_;
395 8   50     70 $dir //= ".";
396              
397 8 50       347 opendir my($dh), $dir or die "Can't opendir $dir: $!";
398 8         18 my $res;
399 8         223 while (defined(my $e = readdir $dh)) {
400 26 100 100     149 next if $e eq '.' || $e eq '..';
401 10         143 my @st = stat "$dir/$e";
402 10 100 100     58 next if -d _ && $opt_ignore_dir;
403 9 100       45 return unless -f _;
404 8 100       54 return if defined $res;
405 6         47 $res = $e;
406             }
407 5 100       55 return unless defined $res;
408 3         68 $res;
409             }
410              
411             sub get_dir_only_subdir {
412 8 100   8 1 14281 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  4         11  
413 8         26 my $opt_ignore_file = delete $opts->{ignore_file};
414 8 50       51 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
415              
416 8         19 my ($dir) = @_;
417 8   50     39 $dir //= ".";
418              
419 8 50       263 opendir my($dh), $dir or die "Can't opendir $dir: $!";
420 8         18 my $res;
421 8         175 while (defined(my $e = readdir $dh)) {
422 26 100 100     115 next if $e eq '.' || $e eq '..';
423 10         97 my @st = stat "$dir/$e";
424 10 100 100     44 next if -f _ && $opt_ignore_file;
425 9 100       30 return unless -d _;
426 8 100       46 return if defined $res;
427 6         32 $res = $e;
428             }
429 5 100       41 return unless defined $res;
430 3         46 $res;
431             }
432              
433             sub get_dir_only_symlink {
434 3 50   3 1 4362 my $opts = ref $_[0] eq 'HASH' ? {%{shift()}} : {};
  0         0  
435 3 50       12 die "Unknown option(s): ".join(", ", keys %$opts) if keys %$opts;
436              
437 3         7 my ($dir) = @_;
438 3   50     18 $dir //= ".";
439              
440 3 50       93 opendir my($dh), $dir or die "Can't opendir $dir: $!";
441 3         7 my $res;
442 3         50 while (defined(my $e = readdir $dh)) {
443 9 100 100     47 next if $e eq '.' || $e eq '..';
444 3         32 my @st = lstat "$dir/$e";
445 3 50       11 return unless -l _;
446 3 100       20 return if defined $res;
447 2         15 $res = $e;
448             }
449 2 100       22 return unless defined $res;
450 1         17 $res;
451             }
452              
453             1;
454             # ABSTRACT: Utilities related mostly to testing/checking for files in directories
455              
456             __END__