File Coverage

blib/lib/File/MoreUtil.pm
Criterion Covered Total %
statement 246 248 99.1
branch 184 216 85.1
condition 114 124 91.9
subroutine 34 34 100.0
pod 29 29 100.0
total 607 651 93.2


line stmt bran cond sub pod time code
1             ## no critic: Subroutines::ProhibitExplicitReturnUndef
2             package File::MoreUtil;
3              
4 2     2   560471 use 5.010001;
  2         11  
5 2     2   14 use strict;
  2         4  
  2         67  
6 2     2   10 use warnings;
  2         4  
  2         164  
7              
8 2     2   14 use Cwd ();
  2         5  
  2         72  
9 2     2   11 use Exporter 'import';
  2         3  
  2         11617  
10              
11             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
12             our $DATE = '2023-11-02'; # DATE
13             our $DIST = 'File-MoreUtil'; # DIST
14             our $VERSION = '0.628'; # 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             );
48              
49             our %SPEC;
50              
51             sub file_exists {
52 4     4 1 482470 my $path = shift;
53              
54 4 100 100     165 !(-l $path) && (-e _) || (-l _);
55             }
56              
57             sub l_abs_path {
58 5     5 1 7341 my $path = shift;
59 5 100       168 return Cwd::abs_path($path) unless (-l $path);
60              
61 4         22 $path =~ s!/\z!!;
62 4         10 my ($parent, $leaf);
63 4 50       46 if ($path =~ m!(.+)/(.+)!s) {
64 4         132 $parent = Cwd::abs_path($1);
65 4 50       19 return undef unless defined($path);
66 4         14 $leaf = $2;
67             } else {
68 0         0 $parent = Cwd::getcwd();
69 0         0 $leaf = $path;
70             }
71 4         37 "$parent/$leaf";
72             }
73              
74             sub dir_empty {
75 8     8 1 19792 my ($dir) = @_;
76 8 100       219 return undef unless (-d $dir);
77 7 50       1455 return undef unless opendir my($dh), $dir;
78 7         213 while (defined(my $e = readdir $dh)) {
79 20 100 100     143 next if $e eq '.' || $e eq '..';
80 6         136 return 0;
81             }
82 1         25 1;
83             }
84              
85             sub dir_not_empty {
86 10     10 1 31 my ($dir) = @_;
87 10 100       215 return undef unless (-d $dir);
88 8 50       363 return undef unless opendir my($dh), $dir;
89 8         161 while (defined(my $e = readdir $dh)) {
90 22 100 100     158 next if $e eq '.' || $e eq '..';
91 6         102 return 1;
92             }
93 2         36 0;
94             }
95              
96 5     5 1 53 sub dir_has_entries { goto \&dir_not_empty }
97              
98             sub dir_has_files {
99 11     11 1 38 my ($dir) = @_;
100 11 100       288 return undef unless (-d $dir);
101 10 50       370 return undef unless opendir my($dh), $dir;
102 10         237 while (defined(my $e = readdir $dh)) {
103 29 100 100     179 next if $e eq '.' || $e eq '..';
104 9 100       450 next unless -f "$dir/$e";
105 5         130 return 1;
106             }
107 5         155 0;
108             }
109              
110             sub dir_only_has_files {
111 8     8 1 26 my ($dir) = @_;
112 8 100       212 return undef unless (-d $dir);
113 7 50       265 return undef unless opendir my($dh), $dir;
114 7         15 my $has_files;
115 7         154 while (defined(my $e = readdir $dh)) {
116 22 100 100     120 next if $e eq '.' || $e eq '..';
117 8 100       193 return 0 unless -f "$dir/$e";
118 5         43 $has_files++;
119             }
120 4 100       78 $has_files ? 1:0;
121             }
122              
123             sub dir_has_dot_files {
124 11     11 1 22 my ($dir) = @_;
125 11 100       179 return undef unless (-d $dir);
126 10 50       283 return undef unless opendir my($dh), $dir;
127 10         152 while (defined(my $e = readdir $dh)) {
128 29 100 100     106 next if $e eq '.' || $e eq '..';
129 9 100       70 next unless $e =~ /\A\./;
130 4 100       49 next unless -f "$dir/$e";
131 3         34 return 1;
132             }
133 7         106 0;
134             }
135              
136             sub dir_only_has_dot_files {
137 7     7 1 13 my ($dir) = @_;
138 7 100       104 return undef unless (-d $dir);
139 6 50       154 return undef unless opendir my($dh), $dir;
140 6         10 my $has_dot_files;
141 6         102 while (defined(my $e = readdir $dh)) {
142 18 100 100     64 next if $e eq '.' || $e eq '..';
143 6 100       98 return 0 unless $e =~ /\A\./;
144 3 100       47 return 0 unless -f "$dir/$e";
145 2         10 $has_dot_files++;
146             }
147 2 100       23 $has_dot_files ? 1:0;
148             }
149              
150             sub dir_has_non_dot_files {
151 11     11 1 23 my ($dir) = @_;
152 11 100       178 return undef unless (-d $dir);
153 10 50       217 return undef unless opendir my($dh), $dir;
154 10         132 while (defined(my $e = readdir $dh)) {
155 30 100 100     92 next if $e eq '.' || $e eq '..';
156 10 100       49 next if $e =~ /\A\./;
157 6 100       78 next unless -f "$dir/$e";
158 3         33 return 1;
159             }
160 7         80 0;
161             }
162              
163             sub dir_only_has_non_dot_files {
164 7     7 1 17 my ($dir) = @_;
165 7 100       108 return undef unless (-d $dir);
166 6 50       169 return undef unless opendir my($dh), $dir;
167 6         12 my $has_nondot_files;
168 6         89 while (defined(my $e = readdir $dh)) {
169 17 100 100     67 next if $e eq '.' || $e eq '..';
170 5 100       53 return 0 if $e =~ /\A\./;
171 2 100       34 return 0 unless -f "$dir/$e";
172 1         8 $has_nondot_files++;
173             }
174 2 100       26 $has_nondot_files ? 1:0;
175             }
176              
177             sub dir_has_subdirs {
178 12     12 1 54 my ($dir) = @_;
179 12 100       226 return undef unless (-d $dir);
180 11 50       312 return undef unless opendir my($dh), $dir;
181 11         173 while (defined(my $e = readdir $dh)) {
182 32 100 100     115 next if $e eq '.' || $e eq '..';
183 10 100       162 next if -l "$dir/$e";
184 4 100       17 next unless -d _;
185 2         22 return 1;
186             }
187 9         146 0;
188             }
189              
190             sub dir_only_has_subdirs {
191 9     9 1 14 my ($dir) = @_;
192 9 100       137 return undef unless (-d $dir);
193 8 50       184 return undef unless opendir my($dh), $dir;
194 8         12 my $has_subdirs;
195 8         110 while (defined(my $e = readdir $dh)) {
196 24 100 100     72 next if $e eq '.' || $e eq '..';
197 8 100       128 return 0 unless -d "$dir/$e";
198 4         21 $has_subdirs++;
199             }
200 4 100       46 $has_subdirs ? 1:0;
201             }
202              
203             sub dir_has_non_subdirs {
204 9     9 1 21 my ($dir) = @_;
205 9 100       144 return undef unless (-d $dir);
206 8 50       193 return undef unless opendir my($dh), $dir;
207 8         122 while (defined(my $e = readdir $dh)) {
208 23 100 100     80 next if $e eq '.' || $e eq '..';
209 7 100       99 return 1 if -l "$dir/$e";
210 4 100       50 return 1 if !(-d _);
211             }
212 3         41 0;
213             }
214              
215             sub dir_has_dot_subdirs {
216 6     6 1 14 my ($dir) = @_;
217 6 100       106 return undef unless (-d $dir);
218 5 50       137 return undef unless opendir my($dh), $dir;
219 5         77 while (defined(my $e = readdir $dh)) {
220 14 100 100     55 next if $e eq '.' || $e eq '..';
221 4 100       32 next unless $e =~ /\A\./;
222 2 50       21 next if -l "$dir/$e";
223 2 100       11 next unless -d _;
224 1         12 return 1;
225             }
226 4         53 0;
227             }
228              
229             sub dir_only_has_dot_subdirs {
230 9     9 1 19 my ($dir) = @_;
231 9 100       174 return undef unless (-d $dir);
232 8 50       244 return undef unless opendir my($dh), $dir;
233 8         11 my $has_dot_subdirs;
234 8         138 while (defined(my $e = readdir $dh)) {
235 24 100 100     83 next if $e eq '.' || $e eq '..';
236 8 100       93 return 0 unless $e =~ /\A\./;
237 4 100       113 return 0 unless -d "$dir/$e";
238 2         10 $has_dot_subdirs++;
239             }
240 2 100       40 $has_dot_subdirs ? 1:0;
241             }
242              
243             sub dir_has_non_dot_subdirs {
244 6     6 1 13 my ($dir) = @_;
245 6 100       97 return undef unless (-d $dir);
246 5 50       122 return undef unless opendir my($dh), $dir;
247 5         81 while (defined(my $e = readdir $dh)) {
248 14 100 100     64 next if $e eq '.' || $e eq '..';
249 4 100       24 next if $e =~ /\A\./;
250 2 50       19 next if -l "$dir/$e";
251 2 100       11 next unless -d _;
252 1         13 return 1;
253             }
254 4         53 0;
255             }
256              
257             sub dir_only_has_non_dot_subdirs {
258 9     9 1 17 my ($dir) = @_;
259 9 100       149 return undef unless (-d $dir);
260 8 50       230 return undef unless opendir my($dh), $dir;
261 8         15 my $has_nondot_subdirs;
262 8         101 while (defined(my $e = readdir $dh)) {
263 23 100 100     75 next if $e eq '.' || $e eq '..';
264 7 100       94 return 0 if $e =~ /\A\./;
265 3 100       50 return 0 unless -d "$dir/$e";
266 1         9 $has_nondot_subdirs++;
267             }
268 2 100       38 $has_nondot_subdirs ? 1:0;
269             }
270              
271             sub get_dir_entries {
272 2     2 1 10326 my ($dir) = @_;
273 2   100     16 $dir //= ".";
274 2 50       329 opendir my($dh), $dir or die "Can't opendir $dir: $!";
275 2 100       50 my @res = grep { $_ ne '.' && $_ ne '..' } readdir $dh;
  9         31  
276 2         45 closedir $dh; # we're so nice
277 2         36 @res;
278             }
279              
280             sub get_dir_dot_entries {
281 1     1 1 5 my ($dir) = @_;
282 1   50     9 $dir //= ".";
283 1 50       59 opendir my($dh), $dir or die "Can't opendir $dir: $!";
284 1 100 100     37 my @res = grep { $_ ne '.' && $_ ne '..' && /\A\./ } readdir $dh;
  6         41  
285 1         12 closedir $dh; # we're so nice
286 1         15 @res;
287             }
288              
289             sub get_dir_files {
290 1     1 1 5 my ($dir) = @_;
291 1   50     9 $dir //= ".";
292 1 50       47 opendir my($dh), $dir or die "Can't opendir $dir: $!";
293 1 100 100     36 my @res = grep { $_ ne '.' && $_ ne '..' && (-f "$dir/$_")} readdir $dh;
  6         87  
294 1         15 closedir $dh; # we're so nice
295 1         15 @res;
296             }
297              
298             sub get_dir_dot_files {
299 1     1 1 5 my ($dir) = @_;
300 1   50     8 $dir //= ".";
301 1 50       46 opendir my($dh), $dir or die "Can't opendir $dir: $!";
302 1 100 100     31 my @res = grep { $_ ne '.' && $_ ne '..' && /\A\./ && (-f "$dir/$_")} readdir $dh;
  6   100     81  
303 1         17 closedir $dh; # we're so nice
304 1         14 @res;
305             }
306              
307             sub get_dir_non_dot_files {
308 1     1 1 5 my ($dir) = @_;
309 1   50     9 $dir //= ".";
310 1 50       66 opendir my($dh), $dir or die "Can't opendir $dir: $!";
311 1 100 100     33 my @res = grep { $_ ne '.' && $_ ne '..' && !/\A\./ && (-f "$dir/$_")} readdir $dh;
  6   100     81  
312 1         17 closedir $dh; # we're so nice
313 1         14 @res;
314             }
315              
316             sub get_dir_subdirs {
317 2     2 1 10 my ($dir) = @_;
318 2   100     15 $dir //= ".";
319 2 50       117 opendir my($dh), $dir or die "Can't opendir $dir: $!";
320 2 100 100     52 my @res = grep { $_ ne '.' && $_ ne '..' && !(-l "$dir/$_") && (-d _) } readdir $dh;
  9   100     114  
321 2         27 closedir $dh; # we're so nice
322 2         26 @res;
323             }
324              
325             sub get_dir_non_subdirs {
326 2     2 1 88 my ($dir) = @_;
327 2   100     18 $dir //= ".";
328 2 50       127 opendir my($dh), $dir or die "Can't opendir $dir: $!";
329 2 100 100     53 my @res = grep { $_ ne '.' && $_ ne '..' && ((-l "$dir/$_") || !(-d _)) } readdir $dh;
  9   100     97  
330 2         23 closedir $dh; # we're so nice
331 2         27 @res;
332             }
333              
334             sub get_dir_dot_subdirs {
335 1     1 1 21 my ($dir) = @_;
336 1   50     13 $dir //= ".";
337 1 50       47 opendir my($dh), $dir or die "Can't opendir $dir: $!";
338 1 100 100     32 my @res = grep { $_ ne '.' && $_ ne '..' && /\A\./ && !(-l "$dir/$_") && (-d _) } readdir $dh;
  6   100     87  
      66        
339 1         10 closedir $dh; # we're so nice
340 1         11 @res;
341             }
342              
343             sub get_dir_non_dot_subdirs {
344 1     1 1 6 my ($dir) = @_;
345 1   50     10 $dir //= ".";
346 1 50       45 opendir my($dh), $dir or die "Can't opendir $dir: $!";
347 1 100 100     33 my @res = grep { $_ ne '.' && $_ ne '..' && !/\A\./ && !(-l "$dir/$_") && (-d _) } readdir $dh;
  6   100     96  
      66        
348 1         15 closedir $dh; # we're so nice
349 1         11 @res;
350             }
351              
352             sub get_dir_only_file {
353 3     3 1 441 my ($dir) = @_;
354 3   50     20 $dir //= ".";
355 3 50       80 opendir my($dh), $dir or die "Can't opendir $dir: $!";
356 3         4 my $res;
357 3         46 while (defined(my $e = readdir $dh)) {
358 9 100 100     42 next if $e eq '.' || $e eq '..';
359 3 50       35 return unless -f "$dir/$e";
360 3 100       23 return if defined $res;
361 2         11 $res = $e;
362             }
363 2 100       18 return unless defined $res;
364 1         11 $res;
365             }
366              
367             sub get_dir_only_subdir {
368 3     3 1 627 my ($dir) = @_;
369 3   50     16 $dir //= ".";
370 3 50       86 opendir my($dh), $dir or die "Can't opendir $dir: $!";
371 3         4 my $res;
372 3         51 while (defined(my $e = readdir $dh)) {
373 9 100 100     39 next if $e eq '.' || $e eq '..';
374 3 50       27 return unless -d "$dir/$e";
375 3 100       19 return if defined $res;
376 2         10 $res = $e;
377             }
378 2 100       16 return unless defined $res;
379 1         13 $res;
380             }
381              
382             1;
383             # ABSTRACT: File-related utilities
384              
385             __END__