File Coverage

lib/CPANPLUS/Dist/MM.pm
Criterion Covered Total %
statement 226 318 71.1
branch 67 134 50.0
condition 25 54 46.3
subroutine 19 20 95.0
pod 4 7 57.1
total 341 533 64.0


line stmt bran cond sub pod time code
1             package CPANPLUS::Dist::MM;
2              
3 2     2   37 use strict;
  2         25  
  2         33  
4 2     2   65 use vars qw[@ISA $STATUS];
  2         20  
  2         114  
5             @ISA = qw[CPANPLUS::Dist];
6              
7              
8 2     2   38 use CPANPLUS::Internals::Constants;
  2         19  
  2         157  
9 2     2   67 use CPANPLUS::Internals::Constants::Report;
  2         19  
  2         137  
10 2     2   35 use CPANPLUS::Error;
  2         52  
  2         82  
11 2     2   30 use FileHandle;
  2         18  
  2         65  
12 2     2   41 use Cwd;
  2         19  
  2         139  
13              
14 2     2   33 use IPC::Cmd qw[run];
  2         19  
  2         126  
15 2     2   33 use Params::Check qw[check];
  2         18  
  2         107  
16 2     2   34 use File::Basename qw[dirname];
  2         20  
  2         100  
17 2     2   30 use Module::Load::Conditional qw[can_load check_install];
  2         18  
  2         54  
18 2     2   33 use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
  2         19  
  2         70  
19              
20             local $Params::Check::VERBOSE = 1;
21              
22             =pod
23            
24             =head1 NAME
25            
26             CPANPLUS::Dist::MM
27            
28             =head1 SYNOPSIS
29            
30             my $mm = CPANPLUS::Dist->new(
31             format => 'makemaker',
32             module => $modobj,
33             );
34             $mm->create; # runs make && make test
35             $mm->install; # runs make install
36            
37            
38             =head1 DESCRIPTION
39            
40             C<CPANPLUS::Dist::MM> is a distribution class for MakeMaker related
41             modules.
42             Using this package, you can create, install and uninstall perl
43             modules. It inherits from C<CPANPLUS::Dist>.
44            
45             =head1 ACCESSORS
46            
47             =over 4
48            
49             =item parent()
50            
51             Returns the C<CPANPLUS::Module> object that parented this object.
52            
53             =item status()
54            
55             Returns the C<Object::Accessor> object that keeps the status for
56             this module.
57            
58             =back
59            
60             =head1 STATUS ACCESSORS
61            
62             All accessors can be accessed as follows:
63             $mm->status->ACCESSOR
64            
65             =over 4
66            
67             =item makefile ()
68            
69             Location of the Makefile (or Build file).
70             Set to 0 explicitly if something went wrong.
71            
72             =item make ()
73            
74             BOOL indicating if the C<make> (or C<Build>) command was successful.
75            
76             =item test ()
77            
78             BOOL indicating if the C<make test> (or C<Build test>) command was
79             successful.
80            
81             =item prepared ()
82            
83             BOOL indicating if the C<prepare> call exited succesfully
84             This gets set after C<perl Makefile.PL>
85            
86             =item distdir ()
87            
88             Full path to the directory in which the C<prepare> call took place,
89             set after a call to C<prepare>.
90            
91             =item created ()
92            
93             BOOL indicating if the C<create> call exited succesfully. This gets
94             set after C<make> and C<make test>.
95            
96             =item installed ()
97            
98             BOOL indicating if the module was installed. This gets set after
99             C<make install> (or C<Build install>) exits successfully.
100            
101             =item uninstalled ()
102            
103             BOOL indicating if the module was uninstalled properly.
104            
105             =item _create_args ()
106            
107             Storage of the arguments passed to C<create> for this object. Used
108             for recursive calls when satisfying prerequisites.
109            
110             =item _install_args ()
111            
112             Storage of the arguments passed to C<install> for this object. Used
113             for recursive calls when satisfying prerequisites.
114            
115             =back
116            
117             =cut
118              
119             =head1 METHODS
120            
121             =head2 $bool = $dist->format_available();
122            
123             Returns a boolean indicating whether or not you can use this package
124             to create and install modules in your environment.
125            
126             =cut
127              
128             ### check if the format is available ###
129             sub format_available {
130 17     17 1 316     my $dist = shift;
131               
132             ### we might be called as $class->format_available =/
133 17         957     require CPANPLUS::Internals;
134 17         713     my $cb = CPANPLUS::Internals->_retrieve_id(
135                                 CPANPLUS::Internals->_last_id );
136 17         441     my $conf = $cb->configure_object;
137               
138 17         290     my $mod = "ExtUtils::MakeMaker";
139 17 100       794     unless( can_load( modules => { $mod => 0.0 } ) ) {
140 1         22         error( loc( "You do not have '%1' -- '%2' not available",
141                                 $mod, __PACKAGE__ ) );
142 1         36         return;
143                 }
144                 
145 16         3843     for my $pgm ( qw[make perlwrapper] ) {
146 32 50       815         unless( $conf->get_program( $pgm ) ) {
147 0         0             error(loc("You do not have '%1'in your path -- '%2' not available",
148                                     $pgm, __PACKAGE__ ));
149 0         0             return;
150                     }
151                 }
152              
153 16         304     return 1;
154             }
155              
156             =pod $bool = $dist->init();
157            
158             Sets up the C<CPANPLUS::Dist::MM> object for use.
159             Effectively creates all the needed status accessors.
160            
161             Called automatically whenever you create a new C<CPANPLUS::Dist> object.
162            
163             =cut
164              
165             sub init {
166 15     15 0 143     my $dist = shift;
167 15         176     my $status = $dist->status;
168                
169 15         245     $status->mk_accessors(qw[makefile make test created installed uninstalled
170             bin_make _prepare_args _create_args _install_args]
171                                     );
172                 
173 15         202     return 1;
174             }    
175              
176             =pod $bool = $dist->prepare(....)
177            
178             =cut
179              
180             sub prepare {
181             ### just in case you already did a create call for this module object
182             ### just via a different dist object
183 10     10 0 3393     my $dist = shift;
184 10         379     my $self = $dist->parent;
185                 
186             ### we're also the cpan_dist, since we don't need to have anything
187             ### prepared
188 10 100       186     $dist = $self->status->dist_cpan if $self->status->dist_cpan;
189 10 100       332     $self->status->dist_cpan( $dist ) unless $self->status->dist_cpan;
190              
191 10         208     my $cb = $self->parent;
192 10         190     my $conf = $cb->configure_object;
193 10         302     my %hash = @_;
194              
195 10         92     my $dir;
196 10 100       190     unless( $dir = $self->status->extract ) {
197 1         156         error( loc( "No dir found to operate on!" ) );
198 1         81         return;
199                 }
200                 
201 9         91     my $args;
202 9         79     my( $force, $verbose, $perl, $mmflags );
203 9         77     { local $Params::Check::ALLOW_UNKNOWN = 1;
  9         83  
204 9         294         my $tmpl = {
205                         perl => { default => $^X, store => \$perl },
206                         makemakerflags => { default =>
207                                                     $conf->get_conf('makemakerflags'),
208                                                 store => \$mmflags },
209                         force => { default => $conf->get_conf('force'),
210                                                 store => \$force },
211                         verbose => { default => $conf->get_conf('verbose'),
212                                                 store => \$verbose },
213                     };
214              
215 9 50       145         $args = check( $tmpl, \%hash ) or return;
216                 }
217                 
218             ### maybe we already ran a create on this object? ###
219 9 50 33     147     return 1 if $dist->status->prepared && !$force;
220                     
221             ### store the arguments, so ->install can use them in recursive loops ###
222 9         151     $dist->status->_prepare_args( $args );
223                 
224             ### chdir to work directory ###
225 9         314     my $orig = cwd();
226 9 50       296537     unless( $cb->_chdir( dir => $dir ) ) {
227 0         0         error( loc( "Could not chdir to build directory '%1'", $dir ) );
228 0         0         return;
229                 }
230                 
231 9         272     my $fail;
232                 RUN: {
233             ### don't run 'perl makefile.pl' again if there's a makefile already
234 9 100 100     142         if( -e MAKEFILE->() && (-M MAKEFILE->() < -M $dir) && !$force ) {
  9   66     342  
235 1         197             msg(loc("'%1' already exists, not running '%2 %3' again ".
236                                 " unless you force",
237                                 MAKEFILE->(), $perl, MAKEFILE_PL->() ), $verbose );
238                         
239                     } else {
240 8 100       145             unless( -e MAKEFILE_PL->() ) {
241 3         2475                 msg(loc("No '%1' found - attempting to generate one",
242                                     MAKEFILE_PL->() ), $verbose );
243                                     
244 3         425                 $dist->write_makefile_pl(
245                                         verbose => $verbose,
246                                         force => $force
247                                     );
248                             
249             ### bail out if there's no makefile.pl ###
250 3 100       197                 unless( -e MAKEFILE_PL->() ) {
251 1         120                     error( loc( "Could not find '%1' - cannot continue",
252                                             MAKEFILE_PL->() ) );
253                     
254             ### mark that we screwed up ###
255 1         207                     $dist->status->makefile(0);
256 1         10                     $fail++; last RUN;
  1         162  
257                             }
258                         }
259                 
260             ### you can turn off running this verbose by changing
261             ### the config setting below, although it is really not
262             ### recommended
263 7   33     1557             my $run_verbose = $verbose ||
      50        
264                                           $conf->get_conf('allow_build_interactivity') ||
265                                           0;
266                 
267             ### this makes MakeMaker use defaults if possible, according
268             ### to schwern. See ticket 8047 for details.
269 7 50       526             local $ENV{PERL_MM_USE_DEFAULT} = 1 unless $run_verbose;
270                 
271             ### turn off our PERL5OPT so no modules from CPANPLUS::inc get
272             ### included in the makefile.pl -- it should build without
273             ### also, modules that run in taint mode break if we leave
274             ### our code ref in perl5opt
275             ### XXX we've removed the ENV settings from cp::inc, so only need
276             ### to reset the @INC
277             #local $ENV{PERL5OPT} = CPANPLUS::inc->original_perl5opt || '';
278                 
279             ### make sure it's a string, so that mmflags that have more than
280             ### one key value pair are passed as is, rather than as:
281             ### perl Makefile.PL "key=val key=>val"
282 7         81             my $captured; my $makefile_pl = MAKEFILE_PL->();
  7         144  
283                         
284             ### setting autoflush to true fixes issue from rt #8047
285             ### XXX this means that we need to keep the path to CPANPLUS
286             ### in @INC, stopping us from resolving dependencies on CPANPLUS
287             ### at bootstrap time properly.
288              
289             ### XXX this fails under ipc::run due to the extra quotes,
290             ### but it works in ipc::open3. however, ipc::open3 doesn't work
291             ### on win32/cygwin. XXX TODO get a windows box and sort this out
292             # my $cmd = qq[$perl -MEnglish -le ] .
293             # QUOTE_PERL_ONE_LINER->(
294             # qq[\$OUTPUT_AUTOFLUSH++,do(q($makefile_pl))]
295             # )
296             # . $mmflags;
297              
298             # my $flush = OPT_AUTOFLUSH;
299             # my $cmd = "$perl $flush $makefile_pl $mmflags";
300              
301 7         212             my $run_perl = $conf->get_program('perlwrapper');
302 7         213             my $cmd = "$perl $run_perl $makefile_pl $mmflags";
303              
304 7 100       568             unless( scalar run( command => $cmd,
305                                             buffer => \$captured,
306                                             verbose => $run_verbose, # may be interactive
307                         ) ) {
308 1         3335                 error( loc( "Could not run '%1 %2': %3 -- cannot continue",
309                                         $perl, MAKEFILE_PL->(), $captured ) );
310                             
311 1         365                 $dist->status->makefile(0);
312 1         10                 $fail++; last RUN;
  1         231  
313                         }
314              
315             ### put the output on the stack, don't print it
316 6         4201             msg( $captured, 0 );
317                     }
318                     
319             ### so, nasty feature in Module::Build, that when a Makefile.PL
320             ### is a disguised Build.PL, it generates a Build file, not a
321             ### Makefile. this breaks everything :( see rt bug #19741
322 7 50 33     1707         if( not -e MAKEFILE->( $dir ) and -e BUILD_PL->( $dir ) ) {
323 0         0             error(loc(
324                                 "We just ran '%1' without errors, but no '%2' is ".
325                                 "present. However, there is a '%3' file, so this may ".
326                                 "be related to bug #19741 in %4, which describes a ".
327                                 "fake '%5' which generates a '%6' file instead of a '%7'. ".
328                                 "You could try to work around this issue by setting '%8' ".
329                                 "to false and trying again. This will attempt to use the ".
330                                 "'%9' instead.",
331                                 "$^X ".MAKEFILE_PL->(), MAKEFILE->(), BUILD_PL->(),
332                                 'Module::Build', MAKEFILE_PL->(), 'Build', MAKEFILE->(),
333                                 'prefer_makefile', BUILD_PL->()
334                         ));
335                         
336 0         0             $fail++, last RUN;
337                     }
338                     
339             ### if we got here, we managed to make a 'makefile' ###
340 7         901         $dist->status->makefile( MAKEFILE->($dir) );
341                     
342             ### start resolving prereqs ###
343 7         489         my $prereqs = $self->status->prereqs;
344                     
345             ### a hashref of prereqs on success, undef on failure ###
346 7   66     267         $prereqs ||= $dist->_find_prereqs(
347                                                 verbose => $verbose,
348                                                 file => $dist->status->makefile
349                                             );
350                     
351 7 50       369         unless( $prereqs ) {
352 0         0             error( loc( "Unable to scan '%1' for prereqs",
353                                     $dist->status->makefile ) );
354              
355 0         0             $fail++; last RUN;
  0         0  
356                     }
357                 }
358                
359 9 50       1252 unless( $cb->_chdir( dir => $orig ) ) {
360 0         0         error( loc( "Could not chdir back to start dir '%1'", $orig ) );
361                 }
362                
363             ### save where we wrote this stuff -- same as extract dir in normal
364             ### installer circumstances
365 9         184     $dist->status->distdir( $self->status->extract );
366                
367 9 100       136     return $dist->status->prepared( $fail ? 0 : 1);
368             }
369              
370             =pod
371            
372             =head2 $href = $dist->_find_prereqs( file => '/path/to/Makefile', [verbose => BOOL])
373            
374             Parses a C<Makefile> for C<PREREQ_PM> entries and distills from that
375             any prerequisites mentioned in the C<Makefile>
376            
377             Returns a hash with module-version pairs on success and false on
378             failure.
379            
380             =cut
381              
382             sub _find_prereqs {
383 1     1   42     my $dist = shift;
384 1         113     my $self = $dist->parent;
385 1         33     my $cb = $self->parent;
386 1         142     my $conf = $cb->configure_object;
387 1         34     my %hash = @_;
388              
389 1         11     my ($verbose, $file);
390 1         149     my $tmpl = {
391                     verbose => { default => $conf->get_conf('verbose'), store => \$verbose },
392                     file => { required => 1, allow => FILE_READABLE, store => \$file },
393                 };
394                 
395 1 50       16     my $args = check( $tmpl, \%hash ) or return;
396                 
397 1         127     my $fh = FileHandle->new();
398 1 50       392     unless( $fh->open( $file ) ) {
399 0         0         error( loc( "Cannot open '%1': %2", $file, $! ) );
400 0         0         return;
401                 }
402                 
403 1         268     my %p;
404 1         230     while( <$fh> ) {
405 791         7193         my ($found) = m|^[\#]\s+PREREQ_PM\s+=>\s+(.+)|;
406                     
407 791 50       11382         next unless $found;
408                     
409 0         0         while( $found =~ m/(?:\s)([\w\:]+)=>(?:q\[(.*?)\],?|undef)/g ) {
410 0 0       0             if( defined $p{$1} ) {
411 0         0                 msg(loc("Warning: PREREQ_PM mentions '%1' more than once. " .
412                                     "Last mention wins.", $1 ), $verbose );
413                         }
414                         
415 0         0             $p{$1} = $cb->_version_to_number(version => $2);
416                     }
417 0         0         last;
418                 }
419              
420 1         86     my $href = $cb->_callbacks->filter_prereqs->( $cb, \%p );
421              
422 1         18     $self->status->prereqs( $href );
423                 
424             ### just to make sure it's not the same reference ###
425 1         15     return { %$href };
426             }     
427              
428             =pod
429            
430             =head2 $bool = $dist->create([perl => '/path/to/perl', make => '/path/to/make', makeflags => 'EXTRA=FLAGS', prereq_target => TARGET, skiptest => BOOL, force => BOOL, verbose => BOOL])
431            
432             C<create> preps a distribution for installation. This means it will
433             run C<perl Makefile.PL>, C<make> and C<make test>.
434             This will also scan for and attempt to satisfy any prerequisites the
435             module may have.
436            
437             If you set C<skiptest> to true, it will skip the C<make test> stage.
438             If you set C<force> to true, it will go over all the stages of the
439             C<make> process again, ignoring any previously cached results. It
440             will also ignore a bad return value from C<make test> and still allow
441             the operation to return true.
442            
443             Returns true on success and false on failure.
444            
445             You may then call C<< $dist->install >> on the object to actually
446             install it.
447            
448             =cut
449              
450             sub create {
451             ### just in case you already did a create call for this module object
452             ### just via a different dist object
453 8     8 1 102     my $dist = shift;
454 8         234     my $self = $dist->parent;
455                 
456             ### we're also the cpan_dist, since we don't need to have anything
457             ### prepared
458 8 50       103     $dist = $self->status->dist_cpan if $self->status->dist_cpan;
459 8 50       209     $self->status->dist_cpan( $dist ) unless $self->status->dist_cpan;
460              
461 8         297     my $cb = $self->parent;
462 8         1158     my $conf = $cb->configure_object;
463 8         194     my %hash = @_;
464              
465 8         71     my $dir;
466 8 50       102     unless( $dir = $self->status->extract ) {
467 0         0         error( loc( "No dir found to operate on!" ) );
468 0         0         return;
469                 }
470                 
471 8         96     my $args;
472 8         74     my( $force, $verbose, $make, $makeflags, $skiptest, $prereq_target, $perl,
473                     $mmflags, $prereq_format, $prereq_build);
474 8         71     { local $Params::Check::ALLOW_UNKNOWN = 1;
  8         72  
475 8         758         my $tmpl = {
476                         perl => { default => $^X, store => \$perl },
477                         force => { default => $conf->get_conf('force'),
478                                                 store => \$force },
479                         verbose => { default => $conf->get_conf('verbose'),
480                                                 store => \$verbose },
481                         make => { default => $conf->get_program('make'),
482                                                 store => \$make },
483                         makeflags => { default => $conf->get_conf('makeflags'),
484                                                 store => \$makeflags },
485                         skiptest => { default => $conf->get_conf('skiptest'),
486                                                 store => \$skiptest },
487                         prereq_target => { default => '', store => \$prereq_target },
488             ### don't set the default prereq format to 'makemaker' -- wrong!
489                         prereq_format => { #default => $self->status->installer_type,
490                                                 default => '',
491                                                 store => \$prereq_format },
492                         prereq_build => { default => 0, store => \$prereq_build },
493                     };
494              
495 8 50       208         $args = check( $tmpl, \%hash ) or return;
496                 }
497                 
498             ### maybe we already ran a create on this object? ###
499 8 50 33     137     return 1 if $dist->status->created && !$force;
500                     
501             ### store the arguments, so ->install can use them in recursive loops ###
502 8         102     $dist->status->_create_args( $args );
503                 
504 8 100       118     unless( $dist->status->prepared ) {
505 1         98         error( loc( "You have not successfully prepared a '%2' distribution ".
506                                 "yet -- cannot create yet", __PACKAGE__ ) );
507 1         104         return;
508                 }
509                 
510                 
511             ### chdir to work directory ###
512 7         489     my $orig = cwd();
513 7 100       215687     unless( $cb->_chdir( dir => $dir ) ) {
514 1         243         error( loc( "Could not chdir to build directory '%1'", $dir ) );
515 1         306         return;
516                 }
517                 
518 6         111     my $fail; my $prereq_fail; my $test_fail;
  6         98  
  6         66  
519 6         2697     RUN: {
520             ### this will set the directory back to the start
521             ### dir, so we must chdir /again/
522 6         129         my $ok = $dist->_resolve_prereqs(
523                                         format => $prereq_format,
524                                         verbose => $verbose,
525                                         prereqs => $self->status->prereqs,
526                                         target => $prereq_target,
527                                         force => $force,
528                                         prereq_build => $prereq_build,
529                                 );
530                     
531 6 50       207         unless( $cb->_chdir( dir => $dir ) ) {
532 0         0             error( loc( "Could not chdir to build directory '%1'", $dir ) );
533 0         0             return;
534                     }
535                               
536 6 50       138         unless( $ok ) {
537                    
538             #### use $dist->flush to reset the cache ###
539 0         0             error( loc( "Unable to satisfy prerequisites for '%1' " .
540                                     "-- aborting install", $self->module ) );
541 0         0             $dist->status->make(0);
542 0         0             $fail++; $prereq_fail++;
  0         0  
543 0         0             last RUN;
544                     }
545             ### end of prereq resolving ###
546                     
547 6         54         my $captured;
548                     
549             ### 'make' section ###
550 6 100 66     698         if( -d BLIB->($dir) && (-M BLIB->($dir) < -M $dir) && !$force ) {
      66        
551 1         121             msg(loc("Already ran '%1' for this module [%2] -- " .
552                                 "not running again unless you force",
553                                 $make, $self->module ), $verbose );
554                     } else {
555 5 50       10569             unless(scalar run( command => [$make, $makeflags],
556                                             buffer => \$captured,
557                                             verbose => $verbose )
558                         ) {
559 0         0                 error( loc( "MAKE failed: %1 %2", $!, $captured ) );
560 0         0                 $dist->status->make(0);
561 0         0                 $fail++; last RUN;
  0         0  
562                         }
563                         
564             ### put the output on the stack, don't print it
565 5         3565             msg( $captured, 0 );
566              
567 5         843             $dist->status->make(1);
568              
569             ### add this directory to your lib ###
570 5         552             $self->add_to_includepath();
571                         
572             ### dont bail out here, there's a conditional later on
573             #last RUN if $skiptest;
574                     }
575                     
576             ### 'make test' section ###
577 6 50       265         unless( $skiptest ) {
578              
579             ### turn off our PERL5OPT so no modules from CPANPLUS::inc get
580             ### included in make test -- it should build without
581             ### also, modules that run in taint mode break if we leave
582             ### our code ref in perl5opt
583             ### XXX CPANPLUS::inc functionality is now obsolete.
584             #local $ENV{PERL5OPT} = CPANPLUS::inc->original_perl5opt || '';
585              
586             ### you can turn off running this verbose by changing
587             ### the config setting below, although it is really not
588             ### recommended
589 6   33     1085             my $run_verbose =
      50        
590                                     $verbose ||
591                                     $conf->get_conf('allow_build_interactivity') ||
592                                     0;
593              
594             ### XXX need to add makeflags here too?
595             ### yes, but they should really be split out -- see bug #4143
596 6 50       263             if( scalar run(
597                                     command => [$make, 'test', $makeflags],
598                                     buffer => \$captured,
599                                     verbose => $run_verbose,
600                         ) ) {
601             ### tests might pass because it doesn't have any tests defined
602             ### log this occasion non-verbosely, so our test reporter can
603             ### pick up on this
604 6 50       5028                 if ( NO_TESTS_DEFINED->( $captured ) ) {
605 0         0                     msg( NO_TESTS_DEFINED->( $captured ), 0 )
606                             } else {
607 6         489                     msg( loc( "MAKE TEST passed: %2", $captured ), $verbose );
608                             }
609                         
610 6         834                 $dist->status->test(1);
611                         } else {
612 0         0                 error( loc( "MAKE TEST failed: %1 %2", $!, $captured ) );
613                         
614             ### send out error report here? or do so at a higher level?
615             ### --higher level --kane.
616 0         0                 $dist->status->test(0);
617                            
618             ### mark specifically *test* failure.. so we dont
619             ### send success on force...
620 0         0                 $test_fail++;
621                             
622 0 0       0                 unless( $force ) {
623 0         0                     $fail++; last RUN;
  0         0  
624                             }
625                         }
626                     }
627                 } #</RUN>
628                   
629 6 50       1120     unless( $cb->_chdir( dir => $orig ) ) {
630 0         0         error( loc( "Could not chdir back to start dir '%1'", $orig ) );
631                 }
632                 
633             ### send out test report?
634             ### only do so if the failure is this module, not its prereq
635 6 50 33     898     if( $conf->get_conf('cpantest') and not $prereq_fail) {
636 0 0 0     0         $cb->_send_report(
637                         module => $self,
638                         failed => $test_fail || $fail,
639                         buffer => CPANPLUS::Error->stack_as_string,
640                         verbose => $verbose,
641                         force => $force,
642                     ) or error(loc("Failed to send test report for '%1'",
643                                 $self->module ) );
644                 }
645                         
646 6 50       94     return $dist->status->created( $fail ? 0 : 1);
647             } 
648              
649             =pod
650            
651             =head2 $bool = $dist->install([make => '/path/to/make', makemakerflags => 'EXTRA=FLAGS', force => BOOL, verbose => BOOL])
652            
653             C<install> runs the following command:
654             make install
655            
656             Returns true on success, false on failure.
657            
658             =cut
659              
660             sub install {
661              
662             ### just in case you did the create with ANOTHER dist object linked
663             ### to the same module object
664 1     1 1 59     my $dist = shift();
665 1         100     my $self = $dist->parent;
666 1 50       36     $dist = $self->status->dist_cpan if $self->status->dist_cpan;
667                
668 1         109     my $cb = $self->parent;
669 1         118     my $conf = $cb->configure_object;
670 1         37     my %hash = @_;
671                 
672                 
673 1 50       50     unless( $dist->status->created ) {
674 0         0         error( loc( "You have not successfully created a '%2' distribution yet " .
675                                 "-- cannot install yet", __PACKAGE__ ) );
676 0         0         return;
677                 }
678              
679 1         53     my $dir;
680 1 50       49     unless( $dir = $self->status->extract ) {
681 0         0         error( loc( "No dir found to operate on!" ) );
682 0         0         return;
683                 }
684                 
685 1         80     my $args;
686 1         41     my($force,$verbose,$make,$makeflags);
687 1         29     { local $Params::Check::ALLOW_UNKNOWN = 1;
  1         30  
688 1         23         my $tmpl = {
689                         force => { default => $conf->get_conf('force'),
690                                             store => \$force },
691                         verbose => { default => $conf->get_conf('verbose'),
692                                             store => \$verbose },
693                         make => { default => $conf->get_program('make'),
694                                             store => \$make },
695                         makeflags => { default => $conf->get_conf('makeflags'),
696                                             store => \$makeflags },
697                     };
698                 
699 1 50       18         $args = check( $tmpl, \%hash ) or return;
700                 }
701              
702             ### value set and false -- means failure ###
703 1 50 33     18     if( defined $self->status->installed &&
      33        
704                     !$self->status->installed && !$force
705                 ) {
706 0         0         error( loc( "Module '%1' has failed to install before this session " .
707                                 "-- aborting install", $self->module ) );
708 0         0         return;
709                 }
710              
711                         
712 1         23     $dist->status->_install_args( $args );
713                 
714 1         98     my $orig = cwd();
715 1 50       71834     unless( $cb->_chdir( dir => $dir ) ) {
716 0         0         error( loc( "Could not chdir to build directory '%1'", $dir ) );
717 0         0         return;
718                 }
719                 
720 1         64     my $fail; my $captured;
  1         60  
721                 
722             ### 'make install' section ###
723             ### XXX need makeflags here too?
724             ### yes, but they should really be split out.. see bug #4143
725 1         105     my $cmd = [$make, 'install', $makeflags];
726 1         239     my $sudo = $conf->get_program('sudo');
727 1 50 33     123     unshift @$cmd, $sudo if $sudo and $>;
728                 
729 1 50       120     unless(scalar run( command => $cmd,
730                                     verbose => $verbose,
731                                     buffer => \$captured,
732                 ) ) {
733 0         0         error( loc( "MAKE INSTALL failed: %1 %2", $!, $captured ) );
734 0         0         $fail++;
735                 }
736              
737             ### put the output on the stack, don't print it
738 1         756     msg( $captured, 0 );
739                 
740 1 50       132     unless( $cb->_chdir( dir => $orig ) ) {
741 0         0         error( loc( "Could not chdir back to start dir '%1'", $orig ) );
742                 }
743                 
744 1 50       170     return $dist->status->installed( $fail ? 0 : 1 );
745                 
746             }
747              
748             =pod
749            
750             =head2 $bool = $dist->write_makefile_pl([force => BOOL, verbose => BOOL])
751            
752             This routine can write a C<Makefile.PL> from the information in a
753             module object. It is used to write a C<Makefile.PL> when the original
754             author forgot it (!!).
755            
756             Returns 1 on success and false on failure.
757            
758             The file gets written to the directory the module's been extracted
759             to.
760            
761             =cut
762              
763             sub write_makefile_pl {
764             ### just in case you already did a call for this module object
765             ### just via a different dist object
766 3     3 1 3158     my $dist = shift;
767 3         298     my $self = $dist->parent;
768 3 50       310     $dist = $self->status->dist_cpan if $self->status->dist_cpan;
769 3 50       206     $self->status->dist_cpan( $dist ) unless $self->status->dist_cpan;
770              
771 3         196     my $cb = $self->parent;
772 3         224     my $conf = $cb->configure_object;
773 3         193     my %hash = @_;
774              
775 3         97     my $dir;
776 3 50       121     unless( $dir = $self->status->extract ) {
777 0         0         error( loc( "No dir found to operate on!" ) );
778 0         0         return;
779                 }
780                 
781 3         75     my ($force, $verbose);
782 3         442     my $tmpl = {
783                     force => { default => $conf->get_conf('force'),
784                                             store => \$force },
785                     verbose => { default => $conf->get_conf('verbose'),
786                                             store => \$verbose },
787                 };
788              
789 3 50       166     my $args = check( $tmpl, \%hash ) or return;
790                 
791 3         164     my $file = MAKEFILE_PL->($dir);
792 3 100 66     477     if( -s $file && !$force ) {
793 1         143         msg(loc("Already created '%1' - not doing so again without force",
794                             $file ), $verbose );
795 1         2047         return 1;
796                 }
797              
798             ### due to a bug with AS perl 5.8.4 built 810 (and maybe others)
799             ### opening files with content in them already does nasty things;
800             ### seek to pos 0 and then print, but not truncating the file
801             ### bug reported to activestate on 19 sep 2004:
802             ### http://bugs.activestate.com/show_bug.cgi?id=34051
803 2 50       79     unlink $file if $force;
804              
805 2         284     my $fh = new FileHandle;
806 2 50       1199     unless( $fh->open( ">$file" ) ) {
807 0         0         error( loc( "Could not create file '%1': %2", $file, $! ) );
808 0         0         return;
809                 }
810                 
811 2         751     my $mf = MAKEFILE_PL->();
812 2         67     my $name = $self->module;
813 2         60     my $version = $self->version;
814 2         85     my $author = $self->author->author;
815 2         44     my $href = $self->status->prereqs;
816 4         104     my $prereqs = join ",\n", map {
817 2         181                                 (' ' x 25) . "'$_'\t=> '$href->{$_}'"
818                                         } keys %$href;
819 2   50     56     $prereqs ||= ''; # just in case there are none;
820                                          
821 2         236     print $fh qq|
822             ### Auto-generated $mf by CPANPLUS ###
823            
824             use ExtUtils::MakeMaker;
825            
826             WriteMakefile(
827             NAME => '$name',
828             VERSION => '$version',
829             AUTHOR => '$author',
830             PREREQ_PM => {
831             $prereqs
832             },
833             );
834             \n|;   
835                 
836 2         126     $fh->close;
837 2         27     return 1;
838             }                         
839                     
840             sub dist_dir {
841             ### just in case you already did a call for this module object
842             ### just via a different dist object
843 0     0 0       my $dist = shift;
844 0               my $self = $dist->parent;
845 0 0             $dist = $self->status->dist_cpan if $self->status->dist_cpan;
846 0 0             $self->status->dist_cpan( $dist ) unless $self->status->dist_cpan;
847              
848 0               my $cb = $self->parent;
849 0               my $conf = $cb->configure_object;
850 0               my %hash = @_;
851                 
852 0               my $make; my $verbose;
  0            
853 0               { local $Params::Check::ALLOW_UNKNOWN = 1;
  0            
854 0                   my $tmpl = {
855                         make => { default => $conf->get_program('make'),
856                                                 store => \$make },
857                         verbose => { default => $conf->get_conf('verbose'),
858                                                 store => \$verbose },
859                     };
860                 
861 0 0                 check( $tmpl, \%hash ) or return;
862                 }
863              
864              
865 0               my $dir;
866 0 0             unless( $dir = $self->status->extract ) {
867 0                   error( loc( "No dir found to operate on!" ) );
868 0                   return;
869                 }
870                 
871             ### chdir to work directory ###
872 0               my $orig = cwd();
873 0 0             unless( $cb->_chdir( dir => $dir ) ) {
874 0                   error( loc( "Could not chdir to build directory '%1'", $dir ) );
875 0                   return;
876                 }
877              
878 0               my $fail; my $distdir;
  0            
879 0 0             TRY: {
880 0                   $dist->prepare( @_ ) or (++$fail, last TRY);
881              
882              
883 0                   my $captured;
884 0 0                     unless(scalar run( command => [$make, 'distdir'],
885                                         buffer => \$captured,
886                                         verbose => $verbose )
887                     ) {
888 0                       error( loc( "MAKE DISTDIR failed: %1 %2", $!, $captured ) );
889 0                       ++$fail, last TRY;
890                     }
891              
892             ### /path/to/Foo-Bar-1.2/Foo-Bar-1.2
893 0                   $distdir = File::Spec->catdir( $dir, $self->package_name . '-' .
894                                                             $self->package_version );
895              
896 0 0                 unless( -d $distdir ) {
897 0                       error(loc("Do not know where '%1' got created", 'distdir'));
898 0                       ++$fail, last TRY;
899                     }
900                 }
901              
902 0 0             unless( $cb->_chdir( dir => $orig ) ) {
903 0                   error( loc( "Could not chdir to start directory '%1'", $orig ) );
904 0                   return;
905                 }
906              
907 0 0             return if $fail;
908 0               return $distdir;
909             }    
910              
911              
912             1;
913              
914             # Local variables:
915             # c-indentation-style: bsd
916             # c-basic-offset: 4
917             # indent-tabs-mode: nil
918             # End:
919             # vim: expandtab shiftwidth=4:
920