File Coverage

blib/lib/Perl/Metrics/Simple.pm
Criterion Covered Total %
statement 86 88 97.7
branch 13 18 72.2
condition n/a
subroutine 21 21 100.0
pod 6 6 100.0
total 126 133 94.7


line stmt bran cond sub pod time code
1             package Perl::Metrics::Simple;
2 5     5   225262 use 5.006;
  5         49  
3 5     5   21 use strict;
  5         8  
  5         93  
4 5     5   19 use warnings;
  5         9  
  5         157  
5              
6 5     5   34 use Carp qw(cluck confess);
  5         15  
  5         289  
7 5     5   2191 use Data::Dumper;
  5         23313  
  5         328  
8 5     5   947 use English qw(-no_match_vars);
  5         7582  
  5         34  
9 5     5   1607 use File::Basename qw(fileparse);
  5         9  
  5         350  
10 5     5   29 use File::Find 1.01 qw(find);
  5         111  
  5         296  
11 5     5   2307 use IO::File 1.14;
  5         36176  
  5         660  
12 5     5   2846 use PPI 1.113;
  5         474642  
  5         188  
13 5     5   2394 use Perl::Metrics::Simple::Analysis;
  5         39  
  5         177  
14 5     5   2980 use Perl::Metrics::Simple::Analysis::File;
  5         13  
  5         218  
15 5     5   36 use Readonly 1.03;
  5         142  
  5         3887  
16              
17             our $VERSION = 'v1.0.1';
18              
19             Readonly::Scalar our $PERL_FILE_SUFFIXES => qr{ \. (:? pl | pm | t ) }sxmi;
20             Readonly::Scalar our $SKIP_LIST_REGEX => qr{ \.svn | \. git | _darcs | CVS }sxmi;
21             Readonly::Scalar my $PERL_SHEBANG_REGEX => qr/ \A [#] ! .* perl /sxm;
22             Readonly::Scalar my $DOT_FILE_REGEX => qr/ \A [.] /sxm;
23              
24             sub new {
25 7     7 1 4259 my ($class) = @_;
26 7         19 my $self = {};
27 7         17 bless $self, $class;
28 7         21 return $self;
29             }
30              
31             sub analyze_files {
32 6     6 1 2170 my ( $self, @dirs_and_files ) = @_;
33 6         17 my @results = ();
34 6         15 my @objects = grep { ref $_ } @dirs_and_files;
  6         19  
35 6         14 @dirs_and_files = grep { not ref $_ } @dirs_and_files;
  6         19  
36 6 50       23 foreach my $file ( (scalar(@dirs_and_files)?@{ $self->find_files(@dirs_and_files) }:()),@objects ) {
  6         24  
37 21         236 my $file_analysis =
38             Perl::Metrics::Simple::Analysis::File->new( path => $file );
39 21         87 push @results, $file_analysis;
40             }
41 6         106 my $analysis = Perl::Metrics::Simple::Analysis->new( \@results );
42 6         35 return $analysis;
43             }
44              
45             sub find_files {
46 8     8 1 774 my ($self, @directories_and_files) = @_;
47 8         22 foreach my $path (@directories_and_files) {
48 8 100       232 if ( !-r $path ) {
49 1         184 confess "Path '$path' is not readable!";
50             }
51             }
52 7         40 my @found = $self->list_perl_files(@directories_and_files);
53 7         31 return \@found;
54             }
55              
56             sub list_perl_files {
57 7     7 1 20 my ( $self, @paths ) = @_;
58 7         14 my @files;
59              
60             my $wanted = sub {
61 51 50   51   192 return if $self->should_be_skipped($File::Find::name);
62 51 100       111 if ( $self->is_perl_file($File::Find::name) )
63             {
64 27         332 push @files, $File::Find::name;
65             }
66 7         166 };
67              
68 7         787 File::Find::find( { wanted => $wanted, no_chdir => 1 }, @paths );
69              
70 7         49 my @sorted_list = sort @files;
71 7         43 return @sorted_list;
72             }
73              
74             sub should_be_skipped {
75 54     54 1 545 my ( $self, $fullpath ) = @_;
76 54         658 my ( $name, $path, $suffix ) = File::Basename::fileparse($fullpath);
77 54         427 return $path =~ $SKIP_LIST_REGEX;
78             }
79              
80             sub is_perl_file {
81 51     51 1 82 my ( $self, $path ) = @_;
82 51 100       2347 return if ( !-f $path );
83 31         741 my ( $name, $path_part, $suffix ) =
84             File::Basename::fileparse( $path, $PERL_FILE_SUFFIXES );
85 31 50       133 return if $name =~ $DOT_FILE_REGEX;
86 31 100       98 if ( length $suffix ) {
87 23         65 return 1;
88             }
89 8         22 return _has_perl_shebang($path);
90             }
91              
92             sub _has_perl_shebang {
93 8     8   15 my $path = shift;
94              
95 8         58 my $fh = IO::File->new( $path, '<' );
96 8 50       855 if ( !-r $fh ) {
97 0         0 cluck "Could not open '$path' for reading: $OS_ERROR";
98 0         0 return;
99             }
100 8         128 my $first_line = <$fh>;
101 8         54 $fh->close();
102 8 50       147 return if ( !$first_line );
103 8         158 return $first_line =~ $PERL_SHEBANG_REGEX;
104             }
105              
106             1;
107              
108             __END__