File Coverage

blib/lib/MyCPAN/BackPANstats.pm
Criterion Covered Total %
statement 18 18 100.0
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 24 24 100.0


line stmt bran cond sub pod time code
1             package MyCPAN::Indexer::BackPANstats;
2 1     1   2655 use strict;
  1         2  
  1         38  
3              
4 1     1   6 use warnings;
  1         2  
  1         31  
5 1     1   5 no warnings;
  1         3  
  1         38  
6              
7 1     1   5 use subs qw(get_caller_info);
  1         105  
  1         11  
8 1     1   44 use vars qw($VERSION $logger);
  1         2  
  1         59  
9 1     1   6 use parent qw(MyCPAN::Indexer MyCPAN::Indexer::Component MyCPAN::Indexer::Reporter::Base);
  1         2  
  1         8  
10              
11             $VERSION = '1.28_12';
12              
13             =head1 NAME
14              
15             MyCPAN::Indexer::BackPANstats - Collect various stats about BackPAN activity
16              
17             =head1 SYNOPSIS
18              
19             use MyCPAN::Indexer;
20              
21             =head1 DESCRIPTION
22              
23             This module implements the indexer_class and reporter_class components
24             to allow C to collect stats on BackPAN.
25              
26             It runs through the indexing and prints a report at the end of the run.
27              
28             =cut
29              
30             use Carp qw(croak);
31             use Cwd qw(cwd);
32              
33             use Log::Log4perl;
34              
35             BEGIN {
36             $logger = Log::Log4perl->get_logger( __PACKAGE__ );
37             }
38              
39             __PACKAGE__->run( @ARGV ) unless caller;
40              
41             =head2 Indexer class
42              
43             =over 4
44              
45             =item get_indexer()
46              
47             A stand in for run_components later on.
48              
49             =cut
50              
51             sub get_indexer
52             {
53             my( $self ) = @_;
54              
55             1;
56             }
57              
58             sub class { __PACKAGE__ }
59              
60             =item setup_run_info
61              
62             Like C in C, but it remembers fewer
63             things. The test census really just cares about statements in the test
64             files, so the details about the run aren't as interesting.
65              
66             =cut
67              
68             sub setup_run_info { 1 }
69              
70             =item examine_dist_steps
71              
72             Given a distribution, unpack it, look at it, and report the findings.
73             It does everything except the looking right now, so it merely croaks.
74             Most of this needs to move out of run and into this method.
75              
76             =cut
77              
78             sub examine_dist_steps
79             {
80             my @methods = (
81             # method error message fatal
82             [ 'collect_info', "Could not get info!", 1 ],
83             );
84             }
85              
86             =item check_dist_size
87              
88             We don't care about 0 byte dists, so we always return true so setup_dist_info
89             doesn't bail out.
90              
91             =cut
92              
93             sub check_dist_size { 1 }
94              
95             =item collect_info
96              
97             Given a distribution, unpack it, look at it, and report the findings.
98             It does everything except the looking right now, so it merely croaks.
99             Most of this needs to move out of run and into this method.
100              
101             =cut
102              
103             use CPAN::DistnameInfo;
104             sub collect_info {
105             my $self = shift;
106             my $d = CPAN::DistnameInfo->new( $self->{dist_info}{dist_file} );
107             $self->set_dist_info( 'dist_name', $d->dist );
108             $self->set_dist_info( 'dist_version', $d->version );
109             $self->set_dist_info( 'maturity', $d->maturity );
110              
111             my @gmtime = gmtime( $self->dist_info( 'dist_date' ) );
112             my( $year, $month, $day ) = @gmtime[ 5,4,3 ];
113             $year += 1900;
114             $month += 1;
115              
116             $self->set_dist_info(
117             'yyyymmdd_gmt',
118             sprintf '%4d%02d%02d', $year, $month, $day
119             );
120              
121             $self->set_dist_info(
122             'calendar_quarter',
123             sprintf "%4dQ%d", $year, int( ($month - 1 ) / 3 ) + 1
124             );
125              
126             1;
127             }
128              
129              
130             =back
131              
132             =head2 Reporter class
133              
134             =over 4
135              
136             =item get_reporter( $Notes )
137              
138             C sets the C key in the C<$Notes> hash
139             reference. The value is a code reference that takes the information
140             collected about a distribution and counts the modules used in the test
141             files.
142              
143             See L for details about what
144             C expects and should do.
145              
146             $VAR1 = {
147             'dist_date' => 1207928766,
148             'dist_basename' => 'cpan-script-1.54.tar.gz',
149             'maturity' => 'released',
150             'dist_file' => '/Volumes/iPod/BackPAN/authors/id/B/BD/BDFOY/cpan-script-1.54.tar.gz',
151             'dist_size' => 6281,
152             'dist_author' => 'BDFOY',
153             'dist_name' => 'cpan-script',
154             'dist_md5' => '8053fa43edcdce9a90f78f878cbf6caf',
155             'dist_version' => '1.54'
156             };
157             =cut
158              
159             sub check_for_previous_successful_result { 1 }
160             sub check_for_previous_error_result { 0 }
161             sub final_words { sub { 1 } }
162              
163             sub get_reporter {
164             my $self = shift;
165             require JSON::XS;
166             use File::Basename qw(dirname);
167             use File::Path qw(make_path);
168             use Clone qw(clone);
169             use Data::Structure::Util qw(unbless);
170              
171             my $jsonner = JSON::XS->new->pretty;
172              
173             my $reporter = sub {
174             my( $info ) = @_;
175              
176             unless( defined $info ) {
177             $logger->error( "info is undefined!" );
178             return;
179             }
180              
181             my $out_path = $self->get_report_path( $info );
182             my $dir = dirname( $out_path );
183             unless( -d $dir ) {
184             make_path( $dir ) or
185             $logger->fatal( "Could not create directory $dir: $!" );
186             }
187              
188             open my($fh), ">:utf8", $out_path or
189             $logger->fatal( "Could not open $out_path: $!" );
190              
191             {
192             # now that indexer is a component, it has references to all the other
193             # objects, making for a big dump. We don't want the keys starting
194             # with _
195             # Storable doesn't work because it can't handle the CODE refs
196             my $clone = clone( $info ); # hack until we get an info class
197             unbless( $clone );
198             delete $clone->{run_info};
199             my $dist = $clone->{dist_info}{dist_basename};
200              
201             local $SIG{__WARN__} = sub {
202             $logger->warn( "Error writing to YAML output for $dist: @_" );
203             };
204              
205             foreach my $key ( keys %$clone ) {
206             delete $clone->{$key} if $key =~ /^_/;
207             }
208              
209             print { $fh } $jsonner->encode( $clone );
210             }
211              
212             $logger->error( "$out_path is missing!" ) unless -e $out_path;
213              
214             1;
215             };
216              
217             $self->set_note( 'reporter', $reporter );
218             }
219              
220             sub get_report_file_extension { 'json' }
221              
222             =back
223              
224             =head1 TO DO
225              
226             =over 4
227              
228             =item Count the lines in the files
229              
230             =item Code stats? Lines of code, lines of pod, lines of comments
231              
232             =back
233              
234             =head1 SOURCE AVAILABILITY
235              
236             This code is in Github:
237              
238             git://github.com/briandfoy/mycpan-indexer.git
239              
240             =head1 AUTHOR
241              
242             brian d foy, C<< >>
243              
244             =head1 COPYRIGHT AND LICENSE
245              
246             Copyright (c) 2010-2013, brian d foy, All Rights Reserved.
247              
248             You may redistribute this under the same terms as Perl itself.
249              
250             =cut
251              
252             1;