File Coverage

lib/Perlmazing/Perlmazing/rmdir.pm
Criterion Covered Total %
statement 32 37 86.4
branch 8 18 44.4
condition 4 12 33.3
subroutine 4 4 100.0
pod 0 1 0.0
total 48 72 66.6


line stmt bran cond sub pod time code
1 1     1   11 use Perlmazing qw(croak dir devnull);
  1         3  
  1         9  
2 1     1   9 use File::Path qw();
  1         3  
  1         24  
3 1     1   10738 use IPC::Cmd qw();
  1         65020  
  1         699  
4              
5             my $checked;
6             my $can_run_rm;
7             my $on_win32;
8              
9             sub main {
10 2 100   2 0 15 if (not $checked) {
11 1   33     9 $on_win32 = ($^O eq 'MSWin32' or $^O eq 'WinNT');
12 1         4 $can_run_rm = IPC::Cmd::can_run('rm');
13 1         121238 $checked++;
14             }
15 2   33     15 my $path = shift || $_;
16            
17             # Let's have it behave as expected when the directory doesn't exist
18 2 50       46 return CORE::rmdir($path) unless -d $path;
19            
20             # Why am I doing this? After using a previous implementation for a while
21             # and trying many others from CPAN, all of them had a common problem:
22             # it takes them 20 or more times to delete a big directory, compared to
23             # the native OS tools to remove a dir. So, we try that first.
24 2         7 my $count = 0;
25             # Hide messages printed out to console from commands. Errors should stay in $! only.
26 2         15 my $devnull = devnull;
27 2         6 my $stderr = '';
28 2         8 my $stdout = '';
29             {
30 2         4 local *STDERR;
  2         10  
31 2         5 local *STDOUT;
32 2         24 open STDERR, '>>', \$stderr;
33 2         11 open STDOUT, '>>', \$stdout;
34 2 50 33     23 if ($on_win32 or $can_run_rm) {
35             # We can't return the actual number of deleted items (without verifying and taking time) this way. Just 1 for the directory.
36 2 50       6 if ($on_win32) {
37 0 0       0 unless (system qq[rmdir /S /Q "$path" >$devnull 2>&1]) {
38 0         0 $count = 1;
39             }
40             }
41             # Not win32, but can rm:
42             # Also, some times, rm is present on win32, and some times, it succeeds to delete files that for some reason rmdir fails to delete.
43             # In such case, this won't take a noticeable extra time to try:
44 2 50       7 if (!$count) {
45 2 50       14856 unless (system qq[$can_run_rm -rf "$path" >$devnull 2>&1]) {
46 2         24 $count = 1;
47             }
48             }
49             }
50             # If the previous steps didn't seem to work, we try the portable but slow Perl solution:
51 2 50       113 unless ($count) {
52 0         0 $count += eval {
53 0         0 File::Path::remove_tree($path);
54             };
55             }
56             }
57             # If the directory is gone, $count should never be 0
58 2 0 33     37 if (!$count and not -d $path) {
59 0         0 $count++;
60             }
61 2         402 $count;
62             }
63              
64             1;