File Coverage

blib/lib/Perl/Metrics2/Parse.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Perl::Metrics2::Parse;
2              
3             # Delegatable PPI caching parser.
4             # Takes a PPI::Cache directory and a list of files to parse.
5              
6 1     1   2304 use strict;
  1         2  
  1         46  
7 1     1   7 use warnings;
  1         3  
  1         35  
8 1     1   5 use Process ();
  1         2  
  1         14  
9 1     1   5 use Process::Storable ();
  1         2  
  1         15  
10 1     1   6 use Process::Delegatable ();
  1         2  
  1         14  
11 1     1   418 use PPI::Util ();
  0            
  0            
12             use PPI::Cache ();
13             use PPI::Document ();
14             use Params::Util '_ARRAY';
15              
16             our $VERSION = '0.06';
17             our @ISA = qw{
18             Process::Delegatable
19             Process::Storable
20             Process
21             };
22              
23             sub new {
24             my $class = shift;
25             my $self = bless { @_ }, $class;
26              
27             # Check params
28             unless ( -d $self->cache ) {
29             die "Missing or invalid cache directory";
30             }
31             unless ( _ARRAY($self->files) ) {
32             die "Missing or invalid file list";
33             }
34              
35             return $self;
36             }
37              
38             sub cache {
39             $_[0]->{cache};
40             }
41              
42             sub files {
43             $_[0]->{files};
44             }
45              
46             sub ok {
47             $_[0]->{ok};
48             }
49              
50             sub prepare {
51             my $self = shift;
52              
53             # Set the default PPI document cache
54             $self->{ppi_cache} = PPI::Cache->new(
55             path => $self->cache,
56             );
57             unless ( PPI::Document->set_cache( $self->{ppi_cache} ) ) {
58             die "Failed to set PPI parser cache";
59             }
60              
61             return 1;
62             }
63              
64             sub run {
65             my $self = shift;
66             my @files = @{$self->files};
67              
68             # Prepare the accounting
69             $self->{stats}->{files} = scalar @files;
70             $self->{stats}->{parsed} = 0;
71             $self->{stats}->{error} = 0;
72             $self->{messages} = [];
73              
74             # Process the files
75             foreach my $file ( @files ) {
76             # Skip if already cached
77             my $md5 = PPI::Util::md5hex_file($file);
78             my (undef, $path) = $self->{ppi_cache}->_paths($md5);
79             next if -f $path;
80              
81             # Parse and cache the file, ignoring errors
82             my $document = eval {
83             PPI::Document->new($file)
84             };
85             if ( $@ ) {
86             push @{$self->{messages}}, "CRASHED while parsing $file";
87             $self->{stats}->{error}++;
88             } elsif ( ! $document ) {
89             my $errstr = PPI::Document->errstr;
90             push @{$self->{messages}}, "Failed to parse $file";
91             $self->{stats}->{error}++;
92             } else {
93             push @{$self->{messages}}, "Parsed $file";
94             $self->{stats}->{parsed}++;
95             }
96             }
97              
98             # Success means we ran without errors, EVEN if we
99             # didn't actually need to parse anything.
100             if ( $self->{stats}->{error} ) {
101             $self->{ok} = 0;
102             } else {
103             $self->{ok} = 1;
104             }
105              
106             return 1;
107             }
108              
109             1;