File Coverage

lib/Code/Statistics/Collector.pm
Criterion Covered Total %
statement 98 99 98.9
branch 2 2 100.0
condition n/a
subroutine 25 25 100.0
pod 1 1 100.0
total 126 127 99.2


line stmt bran cond sub pod time code
1 1     1   6 use strict;
  1         2  
  1         33  
2 1     1   5 use warnings;
  1         2  
  1         62  
3              
4             package Code::Statistics::Collector;
5             $Code::Statistics::Collector::VERSION = '1.190680';
6             # ABSTRACT: collects statistics and dumps them to json
7              
8 1     1   24 use 5.006_003;
  1         4  
9              
10 1     1   4 use Moose;
  1         1  
  1         7  
11 1     1   6112 use MooseX::HasDefaults::RO;
  1         2  
  1         9  
12 1     1   5407 use Code::Statistics::MooseTypes;
  1         3  
  1         43  
13 1     1   530 use MooseX::SlurpyConstructor 1.1;
  1         30199  
  1         5  
14 1     1   40342 use Code::Statistics::Metric;
  1         3  
  1         5  
15 1     1   361 use Code::Statistics::Target;
  1         3  
  1         33  
16              
17 1     1   432 use File::Find::Rule::Perl;
  1         10791  
  1         12  
18 1     1   400 use Code::Statistics::File;
  1         3  
  1         46  
19 1     1   719 use JSON 'to_json';
  1         7203  
  1         7  
20 1     1   155 use File::Slurp 'write_file';
  1         2  
  1         52  
21 1     1   400 use Term::ProgressBar::Simple;
  1         60662  
  1         32  
22 1     1   7 use File::Find::Rule;
  1         2  
  1         12  
23              
24             has no_dump => ( isa => 'Bool' );
25              
26             has dirs => (
27             isa => 'CS::InputList',
28             coerce => 1,
29             default => sub { ['.'] },
30             );
31              
32             has files => (
33             isa => 'ArrayRef',
34             lazy => 1,
35             default => sub {
36             return $_[0]->_prepare_files;
37             },
38             );
39              
40             has targets => (
41             isa => 'CS::InputList',
42             coerce => 1,
43             default => sub { $_[0]->_get_all_submodules_for('Target') },
44             );
45              
46             has metrics => (
47             isa => 'CS::InputList',
48             coerce => 1,
49             default => sub { $_[0]->_get_all_submodules_for('Metric') },
50             );
51              
52             has progress_bar => (
53             isa => 'Term::ProgressBar::Simple',
54             lazy => 1,
55             default => sub {
56             my $params = { name => 'Files', ETA => 'linear', max_update_rate => '0.1' };
57             $params->{count} = @{ $_[0]->files };
58             return Term::ProgressBar::Simple->new( $params );
59             },
60             );
61              
62             has command_args => (
63             is => 'ro',
64             slurpy => 1,
65             default => sub { {} },
66             );
67              
68              
69             sub collect {
70 2     2 1 2116 my ( $self ) = @_;
71              
72 2         4 $_->analyze for @{ $self->files };
  2         90  
73              
74 2         7 my $json = $self->_measurements_as_json;
75 2         9 $self->_dump_file_measurements( $json );
76              
77 2         39 return $json;
78             }
79              
80             sub _find_files {
81 2     2   4 my ( $self ) = @_;
82             my @files = (
83 2         1470 File::Find::Rule::Perl->perl_file->in( @{ $self->dirs } ),
84 2         26 File::Find::Rule->file->name( '*.cgi' )->in( @{ $self->dirs } ),
  2         2128  
85             );
86 2         1257 @files = sort { lc $a cmp lc $b } @files;
  10         21  
87 2         6 return @files;
88             }
89              
90             sub _prepare_files {
91 2     2   4 my ( $self ) = @_;
92 2         7 my @files = $self->_find_files;
93 2         8 @files = map $self->_prepare_file( $_ ), @files;
94 2         4926 return \@files;
95             }
96              
97             sub _prepare_file {
98 8     8   15063 my ( $self, $path ) = @_;
99              
100             my %params = (
101             path => $path,
102             original_path => $path,
103             targets => $self->targets,
104             metrics => $self->metrics,
105 8     8   175 progress => sub { $self->progress_bar->increment },
106 8         164 );
107              
108 8         19 return Code::Statistics::File->new( %params, %{$self->command_args} );
  8         171  
109             }
110              
111             sub _dump_file_measurements {
112 2     2   4 my ( $self, $text ) = @_;
113 2 100       51 return if $self->no_dump;
114              
115 1         7 write_file( 'codestat.out', $text );
116              
117 1         289 return $self;
118             }
119              
120             sub _measurements_as_json {
121 2     2   22 my ( $self ) = @_;
122              
123 2         4 my @files = map $self->_strip_file( $_ ), @{ $self->files };
  2         48  
124 2         4 my @ignored_files = $self->_find_ignored_files( @{ $self->files } );
  2         37  
125              
126 2         56 my $measurements = {
127             files => \@files,
128             targets => $self->targets,
129             metrics => $self->metrics,
130             ignored_files => \@ignored_files
131             };
132              
133 2         16 my $json = to_json( $measurements, { pretty => 1, canonical => 1 } );
134              
135 2         281 return $json;
136             }
137              
138             sub _find_ignored_files {
139 2     2   8 my ( $self, @files ) = @_;
140              
141 2         5 my %present_files = map { $_->{original_path} => 1 } @files;
  8         20  
142              
143 2         46 my @all_files = File::Find::Rule->file->in( @{ $self->dirs } );
  2         122  
144 2         1655 @all_files = grep { !$present_files{$_} } @all_files;
  8         16  
145 2         12 my $useless_stuff = qr{
146             (^|/)
147             (
148             [.]git | [.]svn | cover_db | [.]build | nytprof |
149             blib
150             )
151             /
152             }x;
153 2         5 @all_files = grep { $_ !~ $useless_stuff } @all_files; # filter out files we most certainly do not care about
  0         0  
154              
155 2         7 return @all_files;
156             }
157              
158              
159             sub _strip_file {
160 8     8   15 my ( $self, $file ) = @_;
161 8         7 my %stripped_file = map { $_ => $file->{$_} } qw( path measurements );
  16         38  
162 8         16 return \%stripped_file;
163             }
164              
165             sub _get_all_submodules_for {
166 4     4   11 my ( $self, $type ) = @_;
167 4         11 my $class = "Code::Statistics::$type";
168 4         36 my @list = sort $class->all;
169              
170 4         43227 $_ =~ s/$class\::// for @list;
171              
172 4         18 my $all = join ';', @list;
173              
174 4         32 return $all;
175             }
176              
177             1;
178              
179             __END__
180              
181             =pod
182              
183             =encoding UTF-8
184              
185             =head1 NAME
186              
187             Code::Statistics::Collector - collects statistics and dumps them to json
188              
189             =head1 VERSION
190              
191             version 1.190680
192              
193             =head2 collect
194             Locates files to collect statistics on, collects them and dumps them to
195             JSON.
196              
197             =head2 _strip_file
198             Cuts down a file hash to have only the keys we actually want to dump to the
199             json file.
200              
201             =head1 AUTHOR
202              
203             Christian Walde <mithaldu@yahoo.de>
204              
205             =head1 COPYRIGHT AND LICENSE
206              
207              
208             Christian Walde has dedicated the work to the Commons by waiving all of his
209             or her rights to the work worldwide under copyright law and all related or
210             neighboring legal rights he or she had in the work, to the extent allowable by
211             law.
212              
213             Works under CC0 do not require attribution. When citing the work, you should
214             not imply endorsement by the author.
215              
216             =cut