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   259897 use 5.006;
  6         67  
3 6     6   34 use strict;
  6         11  
  6         142  
4 6     6   34 use warnings;
  6         9  
  6         208  
5              
6 6     6   38 use Carp qw(cluck confess);
  6         11  
  6         398  
7 6     6   3175 use Data::Dumper;
  6         35661  
  6         389  
8 6     6   1006 use English qw(-no_match_vars);
  6         9067  
  6         50  
9 6     6   2288 use File::Basename qw(fileparse);
  6         13  
  6         489  
10 6     6   55 use File::Find 1.01 qw(find);
  6         159  
  6         443  
11 6     6   3168 use IO::File 1.14;
  6         52627  
  6         729  
12 6     6   3403 use PPI 1.113;
  6         661047  
  6         274  
13 6     6   3158 use Perl::Metrics::Simple::Analysis;
  6         68  
  6         224  
14 6     6   3271 use Perl::Metrics::Simple::Analysis::File;
  6         16  
  6         233  
15 6     6   39 use Readonly 1.03;
  6         99  
  6         5885  
16              
17             our $VERSION = 'v1.0.2';
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 6766 my ($class) = @_;
26 12         32 my $self = {};
27 12         30 bless $self, $class;
28 12         34 return $self;
29             }
30              
31             sub analyze_files {
32 11     11 1 2511 my ( $self, @dirs_and_files ) = @_;
33 11         29 my @results = ();
34 11         28 my @objects = grep { ref $_ } @dirs_and_files;
  11         50  
35 11         25 @dirs_and_files = grep { not ref $_ } @dirs_and_files;
  11         37  
36 11 100       41 foreach my $file ( (scalar(@dirs_and_files)?@{ $self->find_files(@dirs_and_files) }:()),@objects ) {
  6         24  
37 26         191 my $file_analysis =
38             Perl::Metrics::Simple::Analysis::File->new( path => $file );
39 26         89 push @results, $file_analysis;
40             }
41 11         95 my $analysis = Perl::Metrics::Simple::Analysis->new( \@results );
42 11         53 return $analysis;
43             }
44              
45             sub find_files {
46 8     8 1 948 my ($self, @directories_and_files) = @_;
47 8         24 foreach my $path (@directories_and_files) {
48 8 100       239 if ( !-r $path ) {
49 1         247 confess "Path '$path' is not readable!";
50             }
51             }
52 7         56 my @found = $self->list_perl_files(@directories_and_files);
53 7         39 return \@found;
54             }
55              
56             sub list_perl_files {
57 7     7 1 26 my ( $self, @paths ) = @_;
58 7         14 my @files;
59              
60             my $wanted = sub {
61 51 50   51   221 return if $self->should_be_skipped($File::Find::name);
62 51 100       138 if ( $self->is_perl_file($File::Find::name) )
63             {
64 27         416 push @files, $File::Find::name;
65             }
66 7         143 };
67              
68 7         852 File::Find::find( { wanted => $wanted, no_chdir => 1 }, @paths );
69              
70 7         53 my @sorted_list = sort @files;
71 7         56 return @sorted_list;
72             }
73              
74             sub should_be_skipped {
75 54     54 1 703 my ( $self, $fullpath ) = @_;
76 54         758 my ( $name, $path, $suffix ) = File::Basename::fileparse($fullpath);
77 54         541 return $path =~ $SKIP_LIST_REGEX;
78             }
79              
80             sub is_perl_file {
81 51     51 1 100 my ( $self, $path ) = @_;
82 51 100       2767 return if ( !-f $path );
83 31         915 my ( $name, $path_part, $suffix ) =
84             File::Basename::fileparse( $path, $PERL_FILE_SUFFIXES );
85 31 50       175 return if $name =~ $DOT_FILE_REGEX;
86 31 100       84 if ( length $suffix ) {
87 23         69 return 1;
88             }
89 8         36 return _has_perl_shebang($path);
90             }
91              
92             sub _has_perl_shebang {
93 8     8   16 my $path = shift;
94              
95 8         62 my $fh = IO::File->new( $path, '<' );
96 8 50       1016 if ( !-r $fh ) {
97 0         0 cluck "Could not open '$path' for reading: $OS_ERROR";
98 0         0 return;
99             }
100 8         179 my $first_line = <$fh>;
101 8         114 $fh->close();
102 8 50       208 return if ( !$first_line );
103 8         221 return $first_line =~ $PERL_SHEBANG_REGEX;
104             }
105              
106             1;
107              
108             __END__