File Coverage

blib/lib/Perl/Metrics/Simple.pm
Criterion Covered Total %
statement 86 88 97.7
branch 14 18 77.7
condition n/a
subroutine 21 21 100.0
pod 6 6 100.0
total 127 133 95.4


line stmt bran cond sub pod time code
1             package Perl::Metrics::Simple;
2 6     6   264150 use 5.006;
  6         61  
3 6     6   33 use strict;
  6         12  
  6         143  
4 6     6   30 use warnings;
  6         12  
  6         211  
5              
6 6     6   42 use Carp qw(cluck confess);
  6         15  
  6         426  
7 6     6   3282 use Data::Dumper;
  6         36440  
  6         386  
8 6     6   1141 use English qw(-no_match_vars);
  6         9124  
  6         43  
9 6     6   2292 use File::Basename qw(fileparse);
  6         13  
  6         459  
10 6     6   45 use File::Find 1.01 qw(find);
  6         157  
  6         521  
11 6     6   3097 use IO::File 1.14;
  6         53592  
  6         762  
12 6     6   3546 use PPI 1.113;
  6         676506  
  6         632  
13 6     6   3364 use Perl::Metrics::Simple::Analysis;
  6         51  
  6         209  
14 6     6   3698 use Perl::Metrics::Simple::Analysis::File;
  6         13  
  6         232  
15 6     6   49 use Readonly 1.03;
  6         101  
  6         5672  
16              
17             our $VERSION = 'v1.0.3';
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 12     12 1 7058 my ($class) = @_;
26 12         36 my $self = {};
27 12         31 bless $self, $class;
28 12         32 return $self;
29             }
30              
31             sub analyze_files {
32 11     11 1 2160 my ( $self, @dirs_and_files ) = @_;
33 11         29 my @results = ();
34 11         26 my @objects = grep { ref } @dirs_and_files;
  11         37  
35 11         31 @dirs_and_files = grep { not ref } @dirs_and_files;
  11         37  
36 11 100       39 foreach my $file ( (scalar(@dirs_and_files)?@{ $self->find_files(@dirs_and_files) }:()),@objects ) {
  6         22  
37 26         221 my $file_analysis =
38             Perl::Metrics::Simple::Analysis::File->new( path => $file );
39 26         100 push @results, $file_analysis;
40             }
41 11         121 my $analysis = Perl::Metrics::Simple::Analysis->new( \@results );
42 11         45 return $analysis;
43             }
44              
45             sub find_files {
46 8     8 1 1085 my ($self, @directories_and_files) = @_;
47 8         24 foreach my $path (@directories_and_files) {
48 8 100       280 if ( !-r $path ) {
49 1         236 confess "Path '$path' is not readable!";
50             }
51             }
52 7         68 my @found = $self->list_perl_files(@directories_and_files);
53 7         51 return \@found;
54             }
55              
56             sub list_perl_files {
57 7     7 1 27 my ( $self, @paths ) = @_;
58 7         15 my @files;
59              
60             my $wanted = sub {
61 51 50   51   215 return if $self->should_be_skipped($File::Find::name);
62 51 100       136 if ( $self->is_perl_file($File::Find::name) )
63             {
64 27         463 push @files, $File::Find::name;
65             }
66 7         43 };
67              
68 7         946 File::Find::find( { wanted => $wanted, no_chdir => 1 }, @paths );
69              
70 7         76 my @sorted_list = sort @files;
71 7         118 return @sorted_list;
72             }
73              
74             sub should_be_skipped {
75 54     54 1 692 my ( $self, $fullpath ) = @_;
76 54         773 my ( $name, $path, $suffix ) = File::Basename::fileparse($fullpath);
77 54         908 return $path =~ $SKIP_LIST_REGEX;
78             }
79              
80             sub is_perl_file {
81 51     51 1 104 my ( $self, $path ) = @_;
82 51 100       2925 return if ( !-f $path );
83 31         974 my ( $name, $path_part, $suffix ) =
84             File::Basename::fileparse( $path, $PERL_FILE_SUFFIXES );
85 31 50       170 return if $name =~ $DOT_FILE_REGEX;
86 31 100       80 if ( length $suffix ) {
87 23         75 return 1;
88             }
89 8         35 return _has_perl_shebang($path);
90             }
91              
92             sub _has_perl_shebang {
93 8     8   16 my $path = shift;
94              
95 8         65 my $fh = IO::File->new( $path, '<' );
96 8 50       1056 if ( !-r $fh ) {
97 0         0 cluck "Could not open '$path' for reading: $OS_ERROR";
98 0         0 return;
99             }
100 8         210 my $first_line = <$fh>;
101 8         69 $fh->close();
102 8 50       200 return if ( !$first_line );
103 8         214 return $first_line =~ $PERL_SHEBANG_REGEX;
104             }
105              
106             1;
107              
108             __END__