File Coverage

blib/lib/MyCPAN/App/DPAN.pm
Criterion Covered Total %
statement 30 89 33.7
branch 1 24 4.1
condition 0 3 0.0
subroutine 9 18 50.0
pod 7 7 100.0
total 47 141 33.3


line stmt bran cond sub pod time code
1             package MyCPAN::App::DPAN;
2 1     1   1085 use strict;
  1         2  
  1         48  
3 1     1   6 use warnings;
  1         2  
  1         41  
4              
5 1     1   5 use base qw(MyCPAN::App::BackPAN::Indexer);
  1         2  
  1         1115  
6 1     1   166723 use vars qw($VERSION $logger);
  1         6  
  1         65  
7              
8 1     1   7 use Cwd qw(cwd);
  1         5  
  1         74  
9 1     1   7 use File::Spec::Functions;
  1         1  
  1         152  
10 1     1   6 use Log::Log4perl;
  1         3  
  1         15  
11              
12             $VERSION = '1.28_11';
13              
14             =head1 NAME
15              
16             MyCPAN::App::DPAN - Create a CPAN-like structure out of some dists
17              
18             =head1 SYNOPSIS
19              
20             use MyCPAN::App::DPAN;
21              
22             my $application = MyCPAN::App::DPAN->activate( @ARGV );
23              
24             # do some other stuff, anything that you like
25              
26             $application->activate_end;
27              
28             =head1 DESCRIPTION
29              
30             This module ties together all the bits to let the C do its work. It
31             overrides the defaults in C to provide the
32             right components.
33              
34             The work happens in two steps. When you call C, the program goes
35             through all of the steps to examin each of the module distributions. It creates
36             a report for each distribution, then stops. This pause right after the
37             examination gives you the chance to do something right before the program
38             creates the PAUSE index files. The examination might take several minutes
39             (or even hours depending on how much you want to index), so you have a chance
40             to check the state of the world before the next step.
41              
42             When you call C, the program takes the results from the
43             previous step and creates the PAUSE index files in the F directory.
44             This step should be very quick since all of the information is ready-to-go.
45              
46             =cut
47              
48             =head1 METHODS
49              
50             =over 4
51              
52             =cut
53              
54             BEGIN {
55 1     1   87 use vars qw( $Starting_dir );
  1         2  
  1         405  
56 1     1   8013 $Starting_dir = cwd();
57              
58 1         56 $SIG{INT} = sub { print "Caught SIGINT\n"; chdir $Starting_dir; exit() };
  0         0  
  0         0  
  0         0  
59              
60 1         7138 my $cwd = cwd();
61              
62 1         39 my $report_dir = catfile( $cwd, 'indexer_reports' );
63              
64 1 50       82 my %Defaults = (
65             author_map => undef,
66             dpan_dir => $cwd,
67             collator_class => 'MyCPAN::App::DPAN::Reporter::Minimal',
68             dispatcher_class => 'MyCPAN::Indexer::Dispatcher::Serial',
69             extra_reports_dir => undef,
70             fresh_start => defined $ENV{DPAN_FRESH_START} ? $ENV{DPAN_FRESH_START} : 0,
71             i_ignore_errors_at_my_peril => 0,
72             ignore_missing_dists => 0,
73             ignore_packages => 'main MY MM DB bytes DynaLoader',
74             indexer_class => 'MyCPAN::App::DPAN::Indexer',
75             organize_dists => 1,
76             parallel_jobs => 1,
77             pause_id => 'DPAN',
78             pause_full_name => "DPAN user ",
79             queue_class => 'MyCPAN::App::DPAN::SkipQueue',
80             relative_paths_in_report => 1,
81             reporter_class => 'MyCPAN::App::DPAN::Reporter::Minimal',
82             skip_perl => 0,
83             use_real_whois => 0,
84             );
85              
86             =item default_keys
87              
88             Returns the list of default configuration directive.
89              
90             =cut
91              
92             sub default_keys
93             {
94 0     0 1   my %Seen;
95 0           grep { ! $Seen{$_}++ } keys %Defaults, $_[0]->SUPER::default_keys;
  0            
96             }
97              
98             =item default( DIRECTIVE )
99              
100             Returns the configuration value for DIRECTIVE.
101              
102             =cut
103              
104             sub default
105             {
106 0 0   0 1   exists $Defaults{ $_[1] }
107             ?
108             $Defaults{ $_[1] }
109             :
110             $_[0]->SUPER::default( $_[1] );
111             }
112              
113             =item adjust_config
114              
115             Adjusts the configuration to set various internal values. You don't need
116             to call this yourself.
117              
118             =cut
119              
120             sub adjust_config
121             {
122 0     0 1   my( $application ) = @_;
123              
124 0           my $coordinator = $application->get_coordinator;
125 0           my $config = $coordinator->get_config;
126              
127             # the Indexer stuff expects the directory in backpan_dir
128 0 0         if( $config->exists( 'dpan_dir') )
129             {
130 0           $config->set(
131             'backpan_dir',
132             $config->get( 'dpan_dir' )
133             );
134             }
135              
136 0           $application->SUPER::adjust_config;
137             }
138              
139 1         45 $logger = Log::Log4perl->get_logger( 'backpan_indexer' );
140             }
141              
142             =item activate_steps
143              
144             Returns the list of methods to invoke from C. By overriding this
145             method you can change the DPAN process.
146              
147             =cut
148              
149             sub activate_steps
150             {
151 0     0 1   qw(
152             process_options
153             setup_coordinator
154             setup_environment
155             handle_config
156             setup_logging
157             fresh_start
158             setup_dirs
159             run_components
160             );
161             }
162              
163             =item activate_end
164              
165             Runs right before C is about to exit. It calls the postflight
166             handler if one if configured. It prints a short summary message to
167             standard output.
168              
169             =cut
170              
171             sub activate_end
172             {
173 0     0 1   my( $application ) = @_;
174              
175 0           my $coordinator = $application->get_coordinator;
176 0           $application->cleanup;
177              
178 0           $application->_handle_postflight;
179              
180 0 0 0       print <<"HERE" unless( $coordinator->get_note( 'epic_fail' ) || $coordinator->get_note( 'postflight_failure' ) );
181             =================================================
182             Ensure you reload your indices in your CPAN tool!
183              
184             For CPAN.pm, use:
185              
186             cpan> reload index
187              
188             For CPANPLUS, use
189              
190             CPAN Terminal> x
191             =================================================
192             HERE
193              
194 0 0         print <<"HERE" if $coordinator->get_note( 'epic_fail' );
195             =================================================
196             Something really bad happened and I couldn't
197             finish creating the index files. The DPAN is
198             incomplete.
199             =================================================
200             HERE
201              
202 0 0         print <<"HERE" if $coordinator->get_note( 'postflight_failure' );
203             =================================================
204             I wasn't able to complete the postflight step.
205             DPAN might be okay, but your post processing
206             may have failed.
207             =================================================
208             HERE
209              
210 0           $application->_exit;
211             }
212              
213             sub _handle_postflight
214             {
215 0     0     my( $application ) = @_;
216              
217 0           $logger->info( "Handling cleanup" );
218              
219 0           my $config = $application->get_coordinator->get_config;
220              
221             # if it's not in the config then we're done already.
222 0 0         return 1 unless $config->exists( 'postflight_class' );
223              
224 0           my $class = $config->get( 'postflight_class' );
225              
226 0 0         if( $application->_check_postflight_class( $class ) )
227             {
228 0 0         eval { $class->run( $application ) } or do {
  0            
229 0           my $at = $@;
230 0           $logger->error( "postflight class [$class] complained: $at" );
231 0           $application->get_coordinator->set_note( 'postflight_failure', $at );
232 0           return;
233             };
234             }
235              
236 0           return 1;
237             }
238              
239             sub _check_postflight_class
240             {
241 0     0     my( $application, $class ) = @_;
242              
243 0 0         if( eval( "require $class; 1" ) )
244             {
245 0 0         unless( eval { $class->can('run') } )
  0            
246             {
247 0           my $error = "Class [$class] does not claim to have a run() method";
248 0           $logger->error( $error );
249 0           $application->get_coordinator->set_note( 'postflight_class_failure', $error );
250 0           return;
251             }
252             }
253             else
254             {
255 0           my $at = $@;
256 0           $logger->error( "Could not load postflight class [$class]: $at" );
257 0           $application->get_coordinator->set_note( 'postflight_class_failure', $at );
258 0           return;
259             }
260              
261 0           return 1;
262             }
263              
264             =item components
265              
266             Returns the list of components to load and the implementing classes.
267              
268             =cut
269              
270             sub components
271             {
272             (
273 0     0 1   [ qw( queue MyCPAN::Indexer::Queue get_queue ) ],
274             [ qw( dispatcher MyCPAN::Indexer::Dispatcher::Serial get_dispatcher ) ],
275             [ qw( reporter MyCPAN::App::DPAN::Reporter::Minimal get_reporter ) ],
276             [ qw( worker MyCPAN::Indexer::Worker get_task ) ],
277             [ qw( collator MyCPAN::App::DPAN::Reporter::Minimal get_collator ) ],
278             # this has to be last because it kicks off everything
279             [ qw( interface MyCPAN::Indexer::Interface::Text do_interface ) ],
280             )
281             }
282              
283             =item fresh_start
284              
285             If C is set, this method deletes the reports in the
286             report directory, leaving the directories in place.
287              
288             =cut
289              
290             sub fresh_start
291             {
292 0     0 1   my( $application ) = @_;
293              
294 0           my $config = $application->get_coordinator->get_config;
295            
296 0 0         return unless $config->get( 'fresh_start' );
297            
298 0           require File::Path;
299 0           foreach my $dir ( map { my $m = "${_}_report_subdir"; $config->$m() } qw(error success) )
  0            
  0            
300             {
301 0           $logger->info( "Cleaning report directory [$dir]" );
302 0           unlink glob( catfile( $dir, '*' ) );
303             }
304              
305 0           return 1;
306             }
307              
308             1;
309              
310             =back
311              
312             =head1 SOURCE AVAILABILITY
313              
314             This code is in Github:
315              
316             git://github.com/briandfoy/mycpan-indexer.git
317             git://github.com/briandfoy/mycpan--app--dpan.git
318              
319             =head1 AUTHOR
320              
321             brian d foy, C<< >>
322              
323             =head1 COPYRIGHT AND LICENSE
324              
325             Copyright (c) 2008-2010, brian d foy, All Rights Reserved.
326              
327             You may redistribute this under the same terms as Perl itself.
328              
329             =cut