File Coverage

lib/CPANPLUS/Dist.pm
Criterion Covered Total %
statement 262 291 90.0
branch 75 110 68.1
condition 33 49 67.3
subroutine 26 26 100.0
pod 6 7 85.7
total 402 483 83.2


line stmt bran cond sub pod time code
1             package CPANPLUS::Dist;
2              
3 20     20   146 use strict;
  20         42  
  20         716  
4              
5 20     20   126 use CPANPLUS::Error;
  20         52  
  20         1788  
6 20     20   187 use CPANPLUS::Internals::Constants;
  20         42  
  20         7120  
7              
8 20     20   146 use Cwd ();
  20         59  
  20         424  
9 20     20   103 use Object::Accessor;
  20         46  
  20         674  
10 20     20   10792 use Parse::CPAN::Meta;
  20         33519  
  20         1037  
11              
12 20     20   154 use IPC::Cmd qw[run];
  20         50  
  20         915  
13 20     20   121 use Params::Check qw[check];
  20         42  
  20         836  
14 20     20   118 use Module::Load::Conditional qw[can_load check_install];
  20         40  
  20         959  
15 20     20   118 use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
  20         61  
  20         171  
16              
17 20     20   5444 use vars qw[$VERSION];
  20         44  
  20         1246  
18             $VERSION = "0.9914";
19              
20 20     20   146 use base 'Object::Accessor';
  20         44  
  20         72638  
21              
22             local $Params::Check::VERBOSE = 1;
23              
24             =pod
25              
26             =head1 NAME
27              
28             CPANPLUS::Dist - base class for plugins
29              
30             =head1 SYNOPSIS
31              
32             my $dist = CPANPLUS::Dist::YOUR_DIST_TYPE_HERE->new(
33             module => $modobj,
34             );
35              
36             =head1 DESCRIPTION
37              
38             C is a base class for C
39             and C. Developers of other C
40             plugins should look at C.
41              
42             =head1 ACCESSORS
43              
44             =over 4
45              
46             =item parent()
47              
48             Returns the C object that parented this object.
49              
50             =item status()
51              
52             Returns the C object that keeps the status for
53             this module.
54              
55             =back
56              
57             =head1 STATUS ACCESSORS
58              
59             All accessors can be accessed as follows:
60             $deb->status->ACCESSOR
61              
62             =over 4
63              
64             =item created()
65              
66             Boolean indicating whether the dist was created successfully.
67             Explicitly set to C<0> when failed, so a value of C may be
68             interpreted as C.
69              
70             =item installed()
71              
72             Boolean indicating whether the dist was installed successfully.
73             Explicitly set to C<0> when failed, so a value of C may be
74             interpreted as C.
75              
76             =item uninstalled()
77              
78             Boolean indicating whether the dist was uninstalled successfully.
79             Explicitly set to C<0> when failed, so a value of C may be
80             interpreted as C.
81              
82             =item dist()
83              
84             The location of the final distribution. This may be a file or
85             directory, depending on how your distribution plug in of choice
86             works. This will be set upon a successful create.
87              
88             =cut
89              
90             =back
91              
92             =head2 $dist = CPANPLUS::Dist::YOUR_DIST_TYPE_HERE->new( module => MODOBJ );
93              
94             Create a new C object based on the
95             provided C.
96              
97             *** DEPRECATED ***
98             The optional argument C is used to indicate what type of dist
99             you would like to create (like C or
100             C and so on ).
101              
102             C<< CPANPLUS::Dist->new >> is exclusively meant as a method to be
103             inherited by C.
104              
105             Returns a C object on success
106             and false on failure.
107              
108             =cut
109              
110             sub new {
111 44     44 1 4658 my $self = shift;
112 44   33     565 my $class = ref $self || $self;
113 44         267 my %hash = @_;
114              
115             ### first verify we got a module object ###
116 44         124 my( $mod, $format );
117 44         556 my $tmpl = {
118             module => { required => 1, allow => IS_MODOBJ, store => \$mod },
119             ### for backwards compatibility
120             format => { default => $class, store => \$format,
121             allow => [ __PACKAGE__->dist_types ],
122             },
123             };
124 44 50       322 check( $tmpl, \%hash ) or return;
125              
126 44 50       1685 unless( can_load( modules => { $format => '0.0' }, verbose => 1 ) ) {
127 0         0 error(loc("'%1' not found -- you need '%2' version '%3' or higher ".
128             "to detect plugins", $format, 'Module::Pluggable','2.4'));
129 0         0 return;
130             }
131              
132             ### get an empty o::a object for this class
133 44         56836 my $obj = $format->SUPER::new;
134              
135 44         1049 $obj->mk_accessors( qw[parent status] );
136              
137             ### set the parent
138 44         3008 $obj->parent( $mod );
139              
140             ### create a status object ###
141 44         6684 { my $acc = Object::Accessor->new;
  44         177  
142 44         532 $obj->status($acc);
143              
144             ### add minimum supported accessors
145 44         4755 $acc->mk_accessors( qw[prepared created installed uninstalled
146             distdir dist _metadata] );
147             }
148              
149             ### get the conf object ###
150 44         3938 my $conf = $mod->parent->configure_object();
151              
152             ### check if the format is available in this environment ###
153 44 100 100     350 if( $conf->_get_build('sanity_check') and not $obj->format_available ) {
154 1         9 error( loc( "Format '%1' is not available", $format) );
155 1         13 return;
156             }
157              
158             ### now initialize it or admit failure
159 43 100       425 unless( $obj->init ) {
160 1         156 error(loc("Dist initialization of '%1' failed for '%2'",
161             $format, $mod->module));
162 1         14 return;
163             }
164              
165             ### return the object
166 42         5038 return $obj;
167             }
168              
169             =head2 @dists = CPANPLUS::Dist->dist_types;
170              
171             Returns a list of the CPANPLUS::Dist::* classes available
172              
173             =cut
174              
175             ### returns a list of dist_types we support
176             ### will get overridden by Module::Pluggable if loaded
177             ### XXX add support for 'plugin' dir in config as well
178             { my $Loaded;
179             my @Dists = (INSTALLER_MM);
180             my @Ignore = ();
181              
182             ### backdoor method to add more dist types
183 1     1   3427 sub _add_dist_types { my $self = shift; push @Dists, @_ };
  1         25  
184              
185             ### backdoor method to exclude dist types
186 1     1   114 sub _ignore_dist_types { my $self = shift; push @Ignore, @_ };
  1         5  
187 1     1   53 sub _reset_dist_ignore { @Ignore = () };
188              
189             ### locally add the plugins dir to @INC, so we can find extra plugins
190             #local @INC = @INC, File::Spec->catdir(
191             # $conf->get_conf('base'),
192             # $conf->_get_build('plugins') );
193              
194             ### load any possible plugins
195             sub dist_types {
196              
197 99 100 66 99 1 9298 if ( !$Loaded++ and check_install( module => 'Module::Pluggable',
198             version => '2.4')
199             ) {
200 5         34767 require Module::Pluggable;
201              
202 5         43478 my $only_re = __PACKAGE__ . '::\w+$';
203 5         42 my %except = map { $_ => 1 }
  10         97  
204             INSTALLER_SAMPLE,
205             INSTALLER_BASE;
206              
207 5         178 Module::Pluggable->import(
208             sub_name => '_dist_types',
209             search_path => __PACKAGE__,
210             only => qr/$only_re/,
211             require => 1,
212             except => [ keys %except ]
213             );
214 5         917 my %ignore = map { $_ => $_ } @Ignore;
  1         10  
215              
216 5   66     41 push @Dists, grep { not $ignore{$_} and not $except{$_} }
  13         29082  
217             __PACKAGE__->_dist_types;
218             }
219              
220 99         1930 return @Dists;
221             }
222              
223             =head2 $bool = CPANPLUS::Dist->rescan_dist_types;
224              
225             Rescans C<@INC> for available dist types. Useful if you've installed new
226             C classes and want to make them available to the
227             current process.
228              
229             =cut
230              
231             sub rescan_dist_types {
232 1     1 1 3 my $dist = shift;
233 1         2 $Loaded = 0; # reset the flag;
234 1         4 return $dist->dist_types;
235             }
236             }
237              
238             =head2 $bool = CPANPLUS::Dist->has_dist_type( $type )
239              
240             Returns true if distribution type C<$type> is loaded/supported.
241              
242             =cut
243              
244             sub has_dist_type {
245 21     21 1 84 my $dist = shift;
246 21 50       83 my $type = shift or return;
247              
248 21         155 return scalar grep { $_ eq $type } CPANPLUS::Dist->dist_types;
  82         277  
249             }
250              
251             =head2 $bool = $dist->prereq_satisfied( modobj => $modobj, version => $version_spec )
252              
253             Returns true if this prereq is satisfied. Returns false if it's not.
254             Also issues an error if it seems "unsatisfiable," i.e. if it can't be
255             found on CPAN or the latest CPAN version doesn't satisfy it.
256              
257             =cut
258              
259             sub prereq_satisfied {
260 30     30 1 384 my $dist = shift;
261 30         688 my $cb = $dist->parent->parent;
262 30         580 my %hash = @_;
263              
264 30         115 my($mod,$ver);
265 30         900 my $tmpl = {
266             version => { required => 1, store => \$ver },
267             modobj => { required => 1, store => \$mod, allow => IS_MODOBJ },
268             };
269              
270 30 50       614 check( $tmpl, \%hash ) or return;
271              
272 30 100       1849 return 1 if $mod->is_uptodate( version => $ver );
273              
274 19 100       118 if ( $cb->_vcmp( $ver, $mod->version ) > 0 ) {
275              
276 15         71 error(loc(
277             "This distribution depends on %1, but the latest version".
278             " of %2 on CPAN (%3) doesn't satisfy the specific version".
279             " dependency (%4). You may have to resolve this dependency ".
280             "manually.",
281             $mod->module, $mod->module, $mod->version, $ver ));
282              
283             }
284              
285 19         310 return;
286             }
287              
288             =head2 $configure_requires = $dist->find_configure_requires( [file => /path/to/META.yml] )
289              
290             Reads the configure_requires for this distribution from the META.yml or META.json
291             file in the root directory and returns a hashref with module names
292             and versions required.
293              
294             =cut
295              
296             sub find_configure_requires {
297 10     10 1 863 my $self = shift;
298 10         314 my $mod = $self->parent;
299 10         2932 my %hash = @_;
300              
301 10         40 my ($meta);
302 10         46 my $href = {};
303              
304 10         101 my $tmpl = {
305             file => { store => \$meta },
306             };
307              
308 10         194 $self->_stash_metadata(); # Okay hacks.
309              
310 10 50       82 check( $tmpl, \%hash ) or return;
311              
312 10         843 my $meth = 'configure_requires';
313              
314             {
315              
316             ### the prereqs as we have them now
317 10   100     44 my @args = (
  10         103  
318             defaults => $mod->status->$meth || {},
319             );
320              
321 10 100       1045 my @possibles = do { defined $mod->status->extract
  10         87  
322             ? ( META_JSON->( $mod->status->extract ),
323             META_YML->( $mod->status->extract ) )
324             : ()
325             };
326              
327 10 100       181 unshift @possibles, $meta if $meta;
328              
329 10         50 META: foreach my $mfile ( grep { -e } @possibles ) {
  19         481  
330 10         123 push @args, ( file => $mfile );
331 10 50       84 if ( $mfile =~ /\.json/ ) {
332 0         0 $href = $self->_prereqs_from_meta_json( @args, keys => [ 'configure' ] );
333             }
334             else {
335 10         160 $href = $self->_prereqs_from_meta_file( @args, keys => [ $meth ] );
336             }
337 10         57 last META;
338             }
339              
340             }
341              
342             ### and store it in the module
343 10         59 $mod->status->$meth( $href );
344              
345 10         1150 return { %$href };
346             }
347              
348             sub find_mymeta_requires {
349 3     3 0 13 my $self = shift;
350 3         52 my $mod = $self->parent;
351 3         404 my %hash = @_;
352              
353 3         19 my ($meta);
354 3         16 my $href = {};
355              
356 3         25 my $tmpl = {
357             file => { store => \$meta },
358             };
359              
360 3 50       26 check( $tmpl, \%hash ) or return;
361              
362 3         189 my $meth = 'prereqs';
363              
364             {
365              
366             ### the prereqs as we have them now
367 3   50     20 my @args = (
  3         62  
368             defaults => $mod->status->$meth || {},
369             );
370              
371 3 50       407 my @possibles = do { defined $mod->status->extract
  3         26  
372             ? ( MYMETA_JSON->( $mod->status->extract ),
373             MYMETA_YML->( $mod->status->extract ) )
374             : ()
375             };
376              
377 3 50       41 unshift @possibles, $meta if $meta;
378              
379 3         23 META: foreach my $mfile ( grep { -e } @possibles ) {
  6         135  
380 3         15 push @args, ( file => $mfile );
381 3 50       66 if ( $mfile =~ /\.json/ ) {
382 3         88 $href = $self->_prereqs_from_meta_json( @args,
383             keys => [ qw|build test runtime| ] );
384             }
385             else {
386 0         0 $href = $self->_prereqs_from_meta_file( @args,
387             keys => [ qw|build_requires requires| ] );
388             }
389 3         28 last META;
390             }
391              
392             }
393              
394             ### and store it in the module
395 3         35 $mod->status->$meth( $href );
396              
397 3         465 return { %$href };
398             }
399              
400             sub _prereqs_from_meta_file {
401 10     10   50 my $self = shift;
402 10         98 my $mod = $self->parent;
403 10         1410 my %hash = @_;
404              
405 10         54 my( $meta, $defaults, $keys );
406             my $tmpl = { ### check if we have an extract path. if not, we
407             ### get 'undef value' warnings from file::spec
408 10 100       38 file => { default => do { defined $mod->status->extract
  10         50  
409             ? META_YML->( $mod->status->extract )
410             : '' },
411             store => \$meta,
412             },
413             defaults => { required => 1, default => {}, strict_type => 1,
414             store => \$defaults },
415             keys => { required => 1, default => [], strict_type => 1,
416             store => \$keys },
417             };
418              
419 10 50       192 check( $tmpl, \%hash ) or return;
420              
421             ### if there's a meta file, we read it;
422 10 50       2105 if( -e $meta ) {
423              
424             ### Parse::CPAN::Meta uses exceptions for errors
425             ### hash returned in list context!!!
426              
427 10         79 local $ENV{PERL_YAML_BACKEND};
428              
429 10         40 my ($doc) = eval { Parse::CPAN::Meta::LoadFile( $meta ) };
  10         96  
430              
431 10 50       16755 unless( $doc ) {
432 0         0 error(loc( "Could not read %1: '%2'", $meta, $@ ));
433 0         0 return $defaults;
434             }
435              
436             ### read the keys now, make sure not to throw
437             ### away anything that was already added
438 10         97 for my $key ( @$keys ) {
439             $defaults = {
440             %$defaults,
441 10         152 %{ $doc->{$key} },
442 10 50       97 } if $doc->{ $key };
443             }
444             }
445              
446             ### and return a copy
447 10         45 return \%{ $defaults };
  10         86  
448             }
449              
450             sub _prereqs_from_meta_json {
451 3     3   17 my $self = shift;
452 3         43 my $mod = $self->parent;
453 3         464 my %hash = @_;
454              
455 3         22 my( $meta, $defaults, $keys );
456             my $tmpl = { ### check if we have an extract path. if not, we
457             ### get 'undef value' warnings from file::spec
458 3 50       11 file => { default => do { defined $mod->status->extract
  3         38  
459             ? META_JSON->( $mod->status->extract )
460             : '' },
461             store => \$meta,
462             },
463             defaults => { required => 1, default => {}, strict_type => 1,
464             store => \$defaults },
465             keys => { required => 1, default => [], strict_type => 1,
466             store => \$keys },
467             };
468              
469 3 50       22 check( $tmpl, \%hash ) or return;
470              
471             ### if there's a meta file, we read it;
472 3 50       9128 if( -e $meta ) {
473              
474             ### Parse::CPAN::Meta uses exceptions for errors
475             ### hash returned in list context!!!
476              
477 3         52 local $ENV{PERL_JSON_BACKEND};
478              
479 3         21 my ($doc) = eval { Parse::CPAN::Meta->load_file( $meta ) };
  3         92  
480              
481 3 50       60614 unless( $doc ) {
482 0         0 error(loc( "Could not read %1: '%2'", $meta, $@ ));
483 0         0 return $defaults;
484             }
485              
486             ### read the keys now, make sure not to throw
487             ### away anything that was already added
488             #for my $key ( @$keys ) {
489             # $defaults = {
490             # %$defaults,
491             # %{ $doc->{$key} },
492             # } if $doc->{ $key };
493             #}
494 3   50     38 my $prereqs = $doc->{prereqs} || {};
495 3         12 for my $key ( @$keys ) {
496             $defaults = {
497             %$defaults,
498 3         39 %{ $prereqs->{$key}->{requires} },
499 9 100       131 } if $prereqs->{ $key }->{requires};
500             }
501             }
502              
503             ### and return a copy
504 3         16 return \%{ $defaults };
  3         37  
505             }
506              
507             sub _stash_metadata {
508 10     10   50 my $self = shift;
509 10         121 my $mod = $self->parent;
510              
511 10 100       1186 my @possibles = do { defined $mod->status->extract
  10         232  
512             ? ( META_JSON->( $mod->status->extract ),
513             META_YML->( $mod->status->extract ) )
514             : ()
515             };
516              
517 10         250 $self->mk_accessors( qw[_metadata] );
518 10         569 $self->status->_metadata( {} );
519              
520 10         2268 META: foreach my $mfile ( grep { -e } @possibles ) {
  18         459  
521 9 50       158 if ( $mfile =~ /\.json/ ) {
522 0         0 local $ENV{PERL_JSON_BACKEND};
523 0         0 my ($doc) = eval { Parse::CPAN::Meta->load_file( $mfile ) };
  0         0  
524 0 0       0 unless( $doc ) {
525 0         0 error(loc( "Could not read %1: '%2'", $mfile, $@ ));
526 0         0 return;
527             }
528 0         0 $self->status->_metadata( $doc );
529 0         0 return $doc;
530             }
531             else {
532 9         134 local $ENV{PERL_YAML_BACKEND};
533 9         61 my ($doc) = eval { Parse::CPAN::Meta->load_file( $mfile ) };
  9         309  
534 9 50       33734 unless( $doc ) {
535 0         0 error(loc( "Could not read %1: '%2'", $mfile, $@ ));
536 0         0 return;
537             }
538 9         112 $self->status->_metadata( $doc );
539 9         1978 return $doc;
540             }
541             }
542 1         9 return;
543             }
544              
545              
546             =head2 $bool = $dist->_resolve_prereqs( ... )
547              
548             Makes sure prerequisites are resolved
549              
550             format The dist class to use to make the prereqs
551             (ie. CPANPLUS::Dist::MM)
552              
553             prereqs Hash of the prerequisite modules and their versions
554              
555             target What to do with the prereqs.
556             create => Just build them
557             install => Install them
558             ignore => Ignore them
559              
560             prereq_build If true, always build the prereqs even if already
561             resolved
562              
563             verbose Be verbose
564              
565             force Force the prereq to be built, even if already resolved
566              
567             =cut
568              
569             sub _resolve_prereqs {
570 31     31   2488 my $dist = shift;
571 31         308 my $self = $dist->parent;
572 31         3685 my $cb = $self->parent;
573 31         363 my $conf = $cb->configure_object;
574 31         630 my %hash = @_;
575              
576 31         198 my ($prereqs, $format, $verbose, $target, $force, $prereq_build,$tolerant);
577 31         429 my $tmpl = {
578             ### XXX perhaps this should not be required, since it may not be
579             ### packaged, just installed...
580             ### Let it be empty as well -- that means the $modobj->install
581             ### routine will figure it out, which is fine if we didn't have any
582             ### very specific wishes (it will even detect the favourite
583             ### dist_type).
584             format => { required => 1, store => \$format,
585             allow => ['',__PACKAGE__->dist_types], },
586             prereqs => { required => 1, default => { },
587             strict_type => 1, store => \$prereqs },
588             verbose => { default => $conf->get_conf('verbose'),
589             store => \$verbose },
590             force => { default => $conf->get_conf('force'),
591             store => \$force },
592             ### make sure allow matches with $mod->install's list
593             target => { default => '', store => \$target,
594             allow => ['',qw[create ignore install]] },
595             prereq_build => { default => 0, store => \$prereq_build },
596             tolerant => { default => $conf->get_conf('allow_unknown_prereqs'),
597             store => \$tolerant },
598             };
599              
600 31 50       245 check( $tmpl, \%hash ) or return;
601              
602             ### so there are no prereqs? then don't even bother
603 31 50       10919 return 1 unless keys %$prereqs;
604              
605             ### Make sure we wound up where we started.
606 31         202792 my $original_wd = Cwd::cwd;
607              
608             ### so you didn't provide an explicit target.
609             ### maybe your config can tell us what to do.
610             $target ||= {
611             PREREQ_ASK, TARGET_INSTALL, # we'll bail out if the user says no
612             PREREQ_BUILD, TARGET_CREATE,
613             PREREQ_IGNORE, TARGET_IGNORE,
614             PREREQ_INSTALL, TARGET_INSTALL,
615 31   50     2414 }->{ $conf->get_conf('prereqs') } || '';
      66        
616              
617             ### XXX BIG NASTY HACK XXX FIXME at some point.
618             ### when installing Bundle::CPANPLUS::Dependencies, we want to
619             ### install all packages matching 'cpanplus' to be installed last,
620             ### as all CPANPLUS' prereqs are being installed as well, but are
621             ### being loaded for bootstrapping purposes. This means CPANPLUS
622             ### can find them, but for example cpanplus::dist::build won't,
623             ### which gets messy FAST. So, here we sort our prereqs only IF
624             ### the parent module is Bundle::CPANPLUS::Dependencies.
625             ### Really, we would want some sort of sorted prereq mechanism,
626             ### but Bundle:: doesn't support it, and we flatten everything
627             ### to a hash internally. A sorted hash *might* do the trick if
628             ### we got a transparent implementation.. that would mean we would
629             ### just have to remove the 'sort' here, and all will be well
630 31         208 my @sorted_prereqs;
631              
632             ### use regex, could either be a module name, or a package name
633 31 50       720 if( $self->module =~ /^Bundle(::|-)CPANPLUS(::|-)Dependencies/ ) {
634 0         0 my (@first, @last);
635 0         0 for my $mod ( sort keys %$prereqs ) {
636 0 0       0 $mod =~ /CPANPLUS/
637             ? push @last, $mod
638             : push @first, $mod;
639             }
640 0         0 @sorted_prereqs = (@first, @last);
641             } else {
642 31         719 @sorted_prereqs = sort keys %$prereqs;
643             }
644              
645             ### first, transfer this key/value pairing into a
646             ### list of module objects + desired versions
647 31         231 my @install_me;
648              
649             my $flag;
650              
651 31         352 for my $mod ( @sorted_prereqs ) {
652 31         561 ( my $version = $prereqs->{$mod} ) =~ s#[^0-9\._]+##g;
653              
654             ### 'perl' is a special case, there's no mod object for it
655 31 100       317 if( $mod eq PERL_CORE ) {
656              
657 2 100       105 unless( $cb->_vcmp( sprintf('v%vd',$^V), $version ) >= 0 ) {
658 1         24 error(loc( "Module '%1' needs perl version '%2', but you ".
659             "only have version '%3' -- can not proceed",
660             $self->module, $version,
661             $cb->_perl_version( perl => $^X ) ) );
662 1         105 return;
663             }
664              
665 1         21 next;
666             }
667              
668 29         557 my $modobj = $cb->module_tree($mod);
669              
670             #### XXX we ignore the version, and just assume that the latest
671             #### version from cpan will meet your requirements... dodgy =/
672 29 100       170 unless( $modobj ) {
673             # Check if it is a core module
674 3         147 my $sub = CPANPLUS::Module->can(
675             'module_is_supplied_with_perl_core' );
676 3         78 my $core = $sub->( $mod );
677 3 50       39 unless ( defined $core ) {
678 0         0 error( loc( "No such module '%1' found on CPAN", $mod ) );
679 0 0       0 $flag++ unless $tolerant;
680 0         0 next;
681             }
682 3 50       145 if ( $cb->_vcmp( $version, $core ) > 0 ) {
683 0         0 error(loc( "Version of core module '%1' ('%2') is too low for ".
684             "'%3' (needs '%4') -- carrying on but this may be a problem",
685             $mod, $core,
686             $self->module, $version ));
687             }
688 3         33 next;
689             }
690              
691             ### it's not uptodate, we need to install it
692 26 100 33     547 if( !$dist->prereq_satisfied(modobj => $modobj, version => $version)) {
    50 33        
693 15         84 msg(loc("Module '%1' requires '%2' version '%3' to be installed ",
694             $self->module, $modobj->module, $version), $verbose );
695              
696 15         235 push @install_me, [$modobj, $version];
697              
698             ### it's not an MM or Build format, that means it's a package
699             ### manager... we'll need to install it as well, via the PM
700             } elsif ( INSTALL_VIA_PACKAGE_MANAGER->($format) and
701             !$modobj->package_is_perl_core and
702             ($target ne TARGET_IGNORE)
703             ) {
704 0         0 msg(loc("Module '%1' depends on '%2', may need to build a '%3' ".
705             "package for it as well", $self->module, $modobj->module,
706             $format));
707 0         0 push @install_me, [$modobj, $version];
708             }
709             }
710              
711              
712              
713             ### so you just want to ignore prereqs? ###
714 30 100       186 if( $target eq TARGET_IGNORE ) {
715              
716             ### but you have modules you need to install
717 2 50       26 if( @install_me ) {
718 2         38 msg(loc("Ignoring prereqs, this may mean your install will fail"),
719             $verbose);
720 2         35 msg(loc("'%1' listed the following dependencies:", $self->module),
721             $verbose);
722              
723 2         27 for my $aref (@install_me) {
724 2         19 my ($mod,$version) = @$aref;
725              
726 2         25 my $str = sprintf "\t%-35s %8s\n", $mod->module, $version;
727 2         23 msg($str,$verbose);
728             }
729              
730 2         161 return;
731              
732             ### ok, no problem, you have all needed prereqs anyway
733             } else {
734 0         0 return 1;
735             }
736             }
737              
738 28         244 for my $aref (@install_me) {
739 13         62 my($modobj,$version) = @$aref;
740              
741             ### another prereq may have already installed this one...
742             ### so don't ask again if the module turns out to be uptodate
743             ### see bug [#11840]
744             ### if either force or prereq_build are given, the prereq
745             ### should be built anyway
746 13 50 66     107 next if (!$force and !$prereq_build) &&
      66        
747             $dist->prereq_satisfied(modobj => $modobj, version => $version);
748              
749             ### either we're told to ignore the prereq,
750             ### or the user wants us to ask him
751 13 100 100     127 if( ( $conf->get_conf('prereqs') == PREREQ_ASK and not
752             $cb->_callbacks->install_prerequisite->($self, $modobj)
753             )
754             ) {
755 1         126 msg(loc("Will not install prerequisite '%1' -- Note " .
756             "that the overall install may fail due to this",
757             $modobj->module), $verbose);
758 1         22 next;
759             }
760              
761             ### value set and false -- means failure ###
762 12 100 66     169 if( defined $modobj->status->installed
763             && !$modobj->status->installed
764             ) {
765 1         119 error( loc( "Prerequisite '%1' failed to install before in " .
766             "this session", $modobj->module ) );
767 1         22 $flag++;
768 1         5 last;
769             }
770              
771             ### part of core?
772 11 100       1266 if( $modobj->package_is_perl_core ) {
773 1         22 error(loc("Prerequisite '%1' is perl-core (%2) -- not ".
774             "installing that. -- Note that the overall ".
775             "install may fail due to this.",
776             $modobj->module, $modobj->package ) );
777 1         25 next;
778             }
779              
780             ### circular dependency code ###
781 10   100     91 my $pending = $cb->_status->pending_prereqs || {};
782              
783             ### recursive dependency ###
784 10 100       1221 if ( $pending->{ $modobj->module } ) {
785 1         47 error( loc( "Recursive dependency detected (%1) -- skipping",
786             $modobj->module ) );
787 1         25 next;
788             }
789              
790             ### register this dependency as pending ###
791 9         657 $pending->{ $modobj->module } = $modobj;
792 9         41 $cb->_status->pending_prereqs( $pending );
793              
794             ### call $modobj->install rather than doing
795             ### CPANPLUS::Dist->new and the like ourselves,
796             ### since ->install will take care of fetch &&
797             ### extract as well
798 9   100     1108 my $pa = $dist->status->_prepare_args || {};
799 9   100     1837 my $ca = $dist->status->_create_args || {};
800 9   50     1725 my $ia = $dist->status->_install_args || {};
801              
802 9 100       1802 unless( $modobj->install( %$pa, %$ca, %$ia,
803             force => $force,
804             verbose => $verbose,
805             format => $format,
806             target => $target )
807             ) {
808 3         37 error(loc("Failed to install '%1' as prerequisite " .
809             "for '%2'", $modobj->module, $self->module ) );
810 3         44 $flag++;
811             }
812              
813             ### unregister the pending dependency ###
814 9         100 $pending->{ $modobj->module } = 0;
815 9         114 $cb->_status->pending_prereqs( $pending );
816              
817 9 100       909 last if $flag;
818              
819             ### don't want us to install? ###
820 6 100       118 if( $target ne TARGET_INSTALL ) {
821 3 50       36 my $dir = $modobj->status->extract
822             or error(loc("No extraction dir for '%1' found ".
823             "-- weird", $modobj->module));
824              
825 3         341 $modobj->add_to_includepath();
826              
827 3         73 next;
828             }
829             }
830              
831             ### reset the $prereqs iterator, in case we bailed out early ###
832 28         139 keys %$prereqs;
833              
834             ### chdir back to where we started
835 28         516 $cb->_chdir( dir => $original_wd );
836              
837 28 100       2088 return 1 unless $flag;
838 4         317 return;
839             }
840              
841             1;
842              
843             # Local variables:
844             # c-indentation-style: bsd
845             # c-basic-offset: 4
846             # indent-tabs-mode: nil
847             # End:
848             # vim: expandtab shiftwidth=4: