File Coverage

blib/lib/File/chdir/WalkDir.pm
Criterion Covered Total %
statement 37 46 80.4
branch 17 26 65.3
condition 1 2 50.0
subroutine 6 6 100.0
pod 1 1 100.0
total 62 81 76.5


line stmt bran cond sub pod time code
1             package File::chdir::WalkDir;
2             {
3             $File::chdir::WalkDir::VERSION = '0.040';
4             }
5              
6 1     1   30204 use strict;
  1         3  
  1         46  
7 1     1   6 use warnings;
  1         2  
  1         35  
8              
9 1     1   1206 use parent 'Exporter';
  1         301  
  1         4  
10             our @EXPORT = ( qw/walkdir/ );
11              
12 1     1   938 use File::Spec::Functions 'no_upwards';
  1         913  
  1         91  
13 1     1   1037 use File::chdir;
  1         1794  
  1         472  
14              
15             sub walkdir {
16 8 100   8 1 1570 my $opts = ( ref $_[-1] eq 'HASH' ) ? pop : {};
17              
18 8         16 my ($dir, $code_ref, @excluded_patterns) = @_;
19             #old api support
20 8 50       22 if (ref $opts->{'exclude'} eq 'Regexp') {
21 0         0 push @excluded_patterns, $opts->{'exclude'};
22             }
23 8 100       18 push @{ $opts->{'exclude'} }, @excluded_patterns if @excluded_patterns;
  2         5  
24              
25 8         29 local $CWD = $dir;
26 8         300 opendir( my $dh, $CWD);
27             #print "In: $CWD\n";
28              
29             #holder for files/dirs that will be acted on after full dir is read,
30             #use if worried about confusing readdir, say by renaming files
31 8         282 my @deferred;
32              
33 8         70 FILE: while ( my $entry = readdir $dh ) {
34            
35             # next if the $entry refers to a '.' or '..' like construct
36 32 100       260 next unless no_upwards( $entry );
37            
38 16   50     134 my $include = $opts->{'include'} || [];
39 16 50       32 if (@$include) {
40 0         0 my $allow = 0;
41              
42 0         0 foreach my $pattern (@$include) {
43 0 0       0 if ($entry =~ $pattern) {
44 0         0 $allow = 1;
45 0         0 last;
46             }
47             }
48              
49 0 0       0 next unless $allow;
50             }
51              
52 16 100       17 foreach my $pattern (@{ $opts->{'exclude'} || [] }) {
  16         48  
53 10 100       52 next FILE if ($entry =~ $pattern);
54             }
55              
56 14 100       148 if (-d $entry) {
57 5 50       47 next if (-l $entry); # skip linked directories
58 5         23 walkdir($entry, $code_ref, $opts);
59              
60             #all directory actions are deferred
61 5 50       117 push @deferred, $entry if $opts->{'act_on_directories'};
62             } else {
63 9 50       17 if ($opts->{'defer'}) {
64 0         0 push @deferred, $entry;
65             } else {
66 9         19 $code_ref->($entry, $CWD);
67             }
68             }
69              
70             }
71              
72             #process files/dirs that were deferred
73 8         161 foreach my $entry (@deferred) {
74 0           $code_ref->($entry, $CWD);
75             }
76              
77             }
78              
79             1;
80              
81             __END__