File Coverage

blib/lib/App/rshasum.pm
Criterion Covered Total %
statement 58 64 90.6
branch 12 16 75.0
condition 2 2 100.0
subroutine 11 12 91.6
pod 1 1 100.0
total 84 95 88.4


line stmt bran cond sub pod time code
1             package App::rshasum;
2             $App::rshasum::VERSION = '0.10.0';
3 2     2   172042 use 5.016;
  2         30  
4 2     2   12 use strict;
  2         4  
  2         41  
5 2     2   9 use warnings;
  2         4  
  2         48  
6              
7 2     2   1071 use File::Find::Object ();
  2         25108  
  2         47  
8 2     2   978 use Digest ();
  2         1190  
  2         51  
9              
10 2     2   1557 use Getopt::Long qw/ GetOptions /;
  2         22008  
  2         9  
11 2     2   352 use List::Util 1.33 qw/ any /;
  2         39  
  2         1211  
12              
13             sub _line
14             {
15 13     13   31 my ( $d, $path ) = @_;
16              
17 13         178 return $d->hexdigest . ' ' . $path . "\n";
18             }
19              
20             sub _worker
21             {
22 3     3   1914 my ( $self, $args ) = @_;
23              
24 3         6 my $digest = $args->{digest};
25 3         8 my $output_cb = $args->{output_cb};
26 3 100       5 my @prunes = ( map { qr/$_/ } @{ $args->{prune_re} || [] } );
  2         11  
  3         16  
27 3   100     14 my $start_path = ( $args->{start_path} // "." );
28              
29 3         47 my $t = Digest->new($digest);
30              
31 3         3335 my $ff = File::Find::Object->new( {}, $start_path );
32             FILES:
33 3         691 while ( my $r = $ff->next_obj )
34             {
35 18         4749 my $path = join '/', @{ $r->full_components };
  18         48  
36 18 100       172 if (@prunes)
37             {
38 12 100   12   64 if ( any { $path =~ $_ } @prunes )
  12         88  
39             {
40 2         8 $ff->prune;
41 2         178 next FILES;
42             }
43             }
44 16 100       62 if ( $r->is_file )
45             {
46 10         14 my $fh;
47 10 50       384 if ( not( open $fh, '<', $r->path ) )
48             {
49 0         0 warn "Could not open @{[$r->path]} ; skipping";
  0         0  
50 0         0 next FILES;
51             }
52 10         37 binmode $fh;
53 10         56 my $d = Digest->new($digest);
54 10         365 $d->addfile($fh);
55 10         486 close $fh;
56 10         34 my $s = _line( $d, $path, );
57 10         45 $output_cb->( { str => $s } );
58 10         126 $t->add($s);
59             }
60             }
61 3         410 my $s = _line( $t, '-', );
62 3         14 $output_cb->( { str => $s } );
63              
64 3         70 return;
65             }
66              
67             sub run
68             {
69 1     1 1 109 my $digest;
70             my @skips;
71 1         3 my $start_path = '.';
72 1 50       8 GetOptions(
73             'digest=s' => \$digest,
74             'skip=s' => \@skips,
75             'start-path=s' => \$start_path,
76             ) or die "Unknown flags $!";
77 1 50       580 if ( not defined($digest) )
78             {
79 0         0 die "Please give a --digest=[digest] argument.";
80             }
81 1 50       4 if (@ARGV)
82             {
83 1         14 die
84             qq#Leftover arguments "@ARGV" in the command line. (Did you intend to use --start-path ?)#;
85             }
86             return shift()->_worker(
87             {
88             digest => $digest,
89 0     0     output_cb => sub { print shift()->{str}; },
90 0           prune_re => ( \@skips ),
91             start_path => $start_path,
92             }
93             );
94             }
95              
96             1;
97              
98             __END__