File Coverage

blib/lib/Path/Iter.pm
Criterion Covered Total %
statement 49 52 94.2
branch 24 30 80.0
condition 2 3 66.6
subroutine 5 5 100.0
pod 1 1 100.0
total 81 91 89.0


line stmt bran cond sub pod time code
1             package Path::Iter;
2              
3 1     1   31634 use strict;
  1         4  
  1         49  
4 1     1   6 use warnings;
  1         2  
  1         38  
5 1     1   5 use File::Spec ();
  1         8  
  1         641  
6              
7             $Path::Iter::VERSION = 0.2;
8              
9             sub get_iterator {
10 7     7 1 5407 my @queue = @_;
11              
12 7         14 my %args = ();
13 7 100       24 if (ref $queue[-1] eq 'HASH') {
14 4         8 %args = (%args, %{ pop @queue });
  4         16  
15             }
16              
17 7         12 @{ $args{'errors'} } = (); # empty an existing one
  7         19  
18 7         9 %{ $args{'initial'} } = (); # empty an existing one
  7         14  
19            
20 7         16 for my $queue_item (@queue) {
21 7         49 $queue_item = File::Spec->catdir($queue_item); # File::Spec version of =~ s{/+$}{};
22 7         29 $args{'initial'}{$queue_item} = 1;
23             }
24              
25             return sub {
26 42 100   42   729 return if !@queue;
27              
28 35         52 my $path = shift @queue;
29 35         189 $path = File::Spec->catdir($path); # File::Spec version of =~ s{/+$}{};
30              
31             # make it possible to handle symlinks how they want/need
32             # return $path if -l $path;
33 35 100       634 if (-l $path) {
34 5 100       19 if (ref $args{'symlink_handler'} eq 'CODE') {
35 3 50       9 my $is_initial = exists $args{'initial'}->{$path} ? 1 : 0;
36 3         16 my ($symlink_traverse) = $args{'symlink_handler'}->($path, $is_initial);
37            
38 3 100 66     23 if (defined $symlink_traverse && $symlink_traverse) {
39 2 100       8 if ($symlink_traverse == 2) {
40 1 50       8 delete $args{'initial'}->{$path} if $is_initial;
41 1         11 $path = readlink($path);
42 1         5 $path = File::Spec->catdir($path); # File::Spec version of =~ s{/+$}{};
43 1 50       7 $args{'initial'}->{$path}++ if $is_initial;
44             }
45             }
46             else {
47 1         5 return $path;
48             }
49             }
50             else {
51 2         10 return $path;
52             }
53             }
54              
55 32 100       424 if (-d $path) {
56 16 50       331 if (opendir DIR, $path) {
57 16 100       217 my @dir_contents = grep { $_ ne '.' && $_ ne '..' } readdir DIR;
  60         278  
58 16         168 closedir DIR;
59            
60 16 100       43 if (@dir_contents) {
61 8 100       21 if (ref $args{'readdir_handler'} eq 'CODE') {
62 2         5 push @queue, $args{'readdir_handler'}->( $path, map { File::Spec->catdir($path,$_) } @dir_contents);
  7         54  
63             }
64             else {
65 6         9 push @queue, map { File::Spec->catdir($path,$_) } @dir_contents;
  21         128  
66             }
67             }
68             }
69             else {
70 0         0 push @{$args{'errors'}}, {
  0         0  
71             'path' => $path,
72             'function' => 'opendir',
73             'args' => [\*DIR, $path],
74             'errno' => int($!),
75             'error' => int($!) . ": $!",
76             };
77 0 0       0 return if $args{'stop_when_opendir_fails'};
78             }
79             }
80            
81 32         132 return $path;
82             }
83 7         65 }
84              
85             1;