File Coverage

blib/lib/File/chmod/Recursive.pm
Criterion Covered Total %
statement 24 95 25.2
branch 0 54 0.0
condition 0 27 0.0
subroutine 8 12 66.6
pod 3 3 100.0
total 35 191 18.3


line stmt bran cond sub pod time code
1             package File::chmod::Recursive;
2              
3             #######################
4             # LOAD MODULES
5             #######################
6 1     1   634 use strict;
  1         2  
  1         56  
7 1     1   7 use warnings FATAL => 'all';
  1         1  
  1         56  
8 1     1   12 use Carp qw(croak carp);
  1         1  
  1         61  
9              
10 1     1   3 use Cwd qw(abs_path);
  1         2  
  1         33  
11 1     1   4 use File::Find qw(find);
  1         0  
  1         53  
12 1     1   454 use File::chmod qw(chmod);
  1         2482  
  1         107  
13              
14             #######################
15             # VERSION
16             #######################
17             our $VERSION = '1.0.1';
18              
19             #######################
20             # EXPORT
21             #######################
22 1     1   10 use base qw(Exporter);
  1         1  
  1         383  
23             our ( @EXPORT, @EXPORT_OK );
24              
25             @EXPORT = qw(chmod_recursive);
26             @EXPORT_OK = qw(chmod_recursive rchmod chmodr);
27              
28             #######################
29             # CHMOD RECURSIVE
30             #######################
31             sub chmod_recursive {
32              
33             # Read Input
34 0     0 1   my @in = @_;
35              
36             # Default mode
37 0           my $mode = {
38             files => q(),
39             dirs => q(),
40             match_dirs => {},
41             match_files => {},
42             match => {},
43             };
44              
45             # Default _find_ settings
46 0           my %find_settings = (
47             follow => 0, # Do not Follow symlinks
48             no_chdir => 1, # Do not chdir
49             );
50              
51             # Verbose mode
52 0           my $verbose = 0;
53              
54             # Check Input
55 0           my $dir;
56 0 0         if ( ref $in[0] eq 'HASH' ) {
57              
58             # Usage chmod_recursive({}, $dir);
59              
60             # Get modes
61 0   0       $mode->{files} = $in[0]->{files} || q();
62 0   0       $mode->{dirs} = $in[0]->{dirs} || q();
63 0   0       $mode->{match_files} = $in[0]->{match_files} || {};
64 0   0       $mode->{match_dirs} = $in[0]->{match_dirs} || {};
65 0   0       $mode->{match} = $in[0]->{match} || {};
66              
67             # Check for _find_ settings
68 0 0         if ( $in[0]->{follow_symlinks} ) {
69 0           $find_settings{follow} = 1; # Follow Symlinks
70 0           $find_settings{follow_skip} = 2; # Skip duplicates
71             } ## end if ( $in[0]->{follow_symlinks...})
72 0 0         if ( $in[0]->{depth_first} ) {
73 0           $find_settings{bydepth} = 1;
74             }
75              
76             # Verbose on/off
77 0   0       $verbose = $in[0]->{verbose} || 0;
78              
79             } ## end if ( ref $in[0] eq 'HASH')
80              
81             else {
82              
83             # Usage chmod_recursive($mode, $dir);
84              
85             # Set modes
86 0           $mode->{files} = $in[0];
87 0           $mode->{dirs} = $in[0];
88             } ## end else [ if ( ref $in[0] eq 'HASH')]
89              
90             # Get directory
91 0   0       $dir = $in[1] || croak "Directory not provided";
92 0           $dir = abs_path($dir);
93 0 0         croak "$dir is not a directory" unless -d $dir;
94              
95             # Run chmod
96 0           my @updated;
97             {
98              
99             # Turn off warnings for file find
100 1     1   7 no warnings 'File::Find';
  1         2  
  1         840  
  0            
101             find(
102             {
103             %find_settings,
104             wanted => sub {
105              
106             # The main stuff
107              
108             # Get full path
109 0     0     my $path = $File::Find::name;
110              
111 0 0         if ( not -l $path ) { # Do not set permissions on symlinks
112              
113             # Process files
114 0 0         if ( -f $path ) {
    0          
115              
116 0           my $file_isa_match = 0;
117              
118             # Process file Matches
119 0           foreach
120 0           my $match_re ( keys %{ $mode->{match_files} } )
121             {
122 0 0         next if $file_isa_match;
123 0 0         next unless ( $path =~ m{$match_re} );
124 0           $file_isa_match = 1; # Done matching
125 0 0         if (
126             chmod(
127             $mode->{match_files}->{$match_re},
128             $path
129             )
130             )
131             {
132 0           push @updated, $path;
133 0 0         warn
134             "chmod_recursive: $path -> $mode->{match_files}->{$match_re}\n"
135             if $verbose;
136             } ## end if ( chmod( $mode->{match_files...}))
137             } ## end foreach my $match_re ( keys...)
138              
139             # Process generic matches
140 0           foreach my $match_re ( keys %{ $mode->{match} } )
  0            
141             {
142 0 0         next if $file_isa_match;
143 0 0         next unless ( $path =~ m{$match_re} );
144 0           $file_isa_match = 1;
145 0 0         if (
146             chmod(
147             $mode->{match}->{$match_re},
148             $path
149             )
150             )
151             {
152 0           push @updated, $path;
153 0 0         warn
154             "chmod_recursive: $path -> $mode->{match}->{$match_re}\n"
155             if $verbose;
156             } ## end if ( chmod( $mode->{match...}))
157             } ## end foreach my $match_re ( keys...)
158              
159             # Process non-matches
160 0 0 0       if (
      0        
161              
162             # Skip processed
163             ( not $file_isa_match )
164              
165             # And we're updating files
166             and ( $mode->{files} )
167              
168             # And succesfully updated
169             and ( chmod( $mode->{files}, $path ) )
170             )
171             {
172 0           push @updated, $path;
173 0 0         warn
174             "chmod_recursive: $path -> $mode->{files}\n"
175             if $verbose;
176             } ## end if ( ( not $file_isa_match...))
177             } ## end if ( -f $path )
178              
179             # Process Dirs
180             elsif ( -d $path ) {
181              
182 0           my $dir_isa_match = 0;
183              
184             # Process Matches
185 0           foreach
186 0           my $match_re ( keys %{ $mode->{match_dirs} } )
187             {
188 0 0         next if $dir_isa_match;
189 0 0         next unless ( $path =~ m{$match_re} );
190 0           $dir_isa_match = 1; # Done matching
191 0 0         if (
192             chmod(
193             $mode->{match_dirs}->{$match_re},
194             $path
195             )
196             )
197             {
198 0           push @updated, $path;
199 0 0         warn
200             "chmod_recursive: $path -> $mode->{match_dirs}->{$match_re}\n"
201             if $verbose;
202             } ## end if ( chmod( $mode->{match_dirs...}))
203             } ## end foreach my $match_re ( keys...)
204              
205             # Process generic matches
206 0           foreach my $match_re ( keys %{ $mode->{match} } )
  0            
207             {
208 0 0         next if $dir_isa_match;
209 0 0         next unless ( $path =~ m{$match_re} );
210 0           $dir_isa_match = 1; # Done matching
211 0 0         if (
212             chmod(
213             $mode->{match}->{$match_re},
214             $path
215             )
216             )
217             {
218 0           push @updated, $path;
219 0 0         warn
220             "chmod_recursive: $path -> $mode->{match}->{$match_re}\n"
221             if $verbose;
222             } ## end if ( chmod( $mode->{match...}))
223             } ## end foreach my $match_re ( keys...)
224              
225             # Process non-matches
226 0 0 0       if (
      0        
227              
228             # Skip processed
229             ( not $dir_isa_match )
230              
231             # And we're updating files
232             and ( $mode->{dirs} )
233              
234             # And succesfully updated
235             and ( chmod( $mode->{dirs}, $path ) )
236             )
237             {
238 0           push @updated, $path;
239 0 0         warn
240             "chmod_recursive: $path -> $mode->{dirs}\n"
241             if $verbose;
242             } ## end if ( ( not $dir_isa_match...))
243             } ## end elsif ( -d $path )
244              
245             } ## end if ( not -l $path )
246              
247             },
248             },
249 0           $dir
250             );
251             }
252              
253             # Done
254 0           return scalar @updated;
255             } ## end sub chmod_recursive
256              
257             #######################
258             # ALIASES
259             #######################
260 0     0 1   sub rchmod { return chmod_recursive(@_); }
261 0     0 1   sub chmodr { return chmod_recursive(@_); }
262              
263             #######################
264             1;
265              
266             __END__