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   134 use strict;
  20         54  
  20         651  
4              
5 20     20   108 use CPANPLUS::Error;
  20         34  
  20         1790  
6 20     20   167 use CPANPLUS::Internals::Constants;
  20         55  
  20         6976  
7              
8 20     20   145 use Cwd ();
  20         34  
  20         400  
9 20     20   102 use Object::Accessor;
  20         41  
  20         631  
10 20     20   11378 use Parse::CPAN::Meta;
  20         32283  
  20         954  
11              
12 20     20   140 use IPC::Cmd qw[run];
  20         51  
  20         858  
13 20     20   115 use Params::Check qw[check];
  20         39  
  20         749  
14 20     20   114 use Module::Load::Conditional qw[can_load check_install];
  20         41  
  20         865  
15 20     20   105 use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
  20         38  
  20         117  
16              
17 20     20   5441 use vars qw[$VERSION];
  20         44  
  20         1004  
18             $VERSION = "0.9910";
19              
20 20     20   128 use base 'Object::Accessor';
  20         44  
  20         70611  
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 5039 my $self = shift;
112 44   33     585 my $class = ref $self || $self;
113 44         322 my %hash = @_;
114              
115             ### first verify we got a module object ###
116 44         175 my( $mod, $format );
117 44         744 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       361 check( $tmpl, \%hash ) or return;
125              
126 44 50       1953 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         56607 my $obj = $format->SUPER::new;
134              
135 44         807 $obj->mk_accessors( qw[parent status] );
136              
137             ### set the parent
138 44         3105 $obj->parent( $mod );
139              
140             ### create a status object ###
141 44         7098 { my $acc = Object::Accessor->new;
  44         191  
142 44         612 $obj->status($acc);
143              
144             ### add minimum supported accessors
145 44         4954 $acc->mk_accessors( qw[prepared created installed uninstalled
146             distdir dist _metadata] );
147             }
148              
149             ### get the conf object ###
150 44         3887 my $conf = $mod->parent->configure_object();
151              
152             ### check if the format is available in this environment ###
153 44 100 100     387 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       483 unless( $obj->init ) {
160 1         162 error(loc("Dist initialization of '%1' failed for '%2'",
161             $format, $mod->module));
162 1         22 return;
163             }
164              
165             ### return the object
166 42         5609 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   3566 sub _add_dist_types { my $self = shift; push @Dists, @_ };
  1         36  
184              
185             ### backdoor method to exclude dist types
186 1     1   102 sub _ignore_dist_types { my $self = shift; push @Ignore, @_ };
  1         8  
187 1     1   41 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 9090 if ( !$Loaded++ and check_install( module => 'Module::Pluggable',
198             version => '2.4')
199             ) {
200 5         32781 require Module::Pluggable;
201              
202 5         41889 my $only_re = __PACKAGE__ . '::\w+$';
203 5         51 my %except = map { $_ => 1 }
  10         99  
204             INSTALLER_SAMPLE,
205             INSTALLER_BASE;
206              
207 5         171 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         900 my %ignore = map { $_ => $_ } @Ignore;
  1         10  
215              
216 5   66     53 push @Dists, grep { not $ignore{$_} and not $except{$_} }
  13         26567  
217             __PACKAGE__->_dist_types;
218             }
219              
220 99         2249 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         7 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 82 my $dist = shift;
246 21 50       93 my $type = shift or return;
247              
248 21         192 return scalar grep { $_ eq $type } CPANPLUS::Dist->dist_types;
  82         284  
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 469 my $dist = shift;
261 30         753 my $cb = $dist->parent->parent;
262 30         752 my %hash = @_;
263              
264 30         142 my($mod,$ver);
265 30         1084 my $tmpl = {
266             version => { required => 1, store => \$ver },
267             modobj => { required => 1, store => \$mod, allow => IS_MODOBJ },
268             };
269              
270 30 50       636 check( $tmpl, \%hash ) or return;
271              
272 30 100       1876 return 1 if $mod->is_uptodate( version => $ver );
273              
274 19 100       127 if ( $cb->_vcmp( $ver, $mod->version ) > 0 ) {
275              
276 15         76 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         12330 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 936 my $self = shift;
298 10         336 my $mod = $self->parent;
299 10         2839 my %hash = @_;
300              
301 10         68 my ($meta);
302 10         44 my $href = {};
303              
304 10         142 my $tmpl = {
305             file => { store => \$meta },
306             };
307              
308 10         213 $self->_stash_metadata(); # Okay hacks.
309              
310 10 50       61 check( $tmpl, \%hash ) or return;
311              
312 10         747 my $meth = 'configure_requires';
313              
314             {
315              
316             ### the prereqs as we have them now
317 10   100     64 my @args = (
  10         61  
318             defaults => $mod->status->$meth || {},
319             );
320              
321 10 100       900 my @possibles = do { defined $mod->status->extract
  10         140  
322             ? ( META_JSON->( $mod->status->extract ),
323             META_YML->( $mod->status->extract ) )
324             : ()
325             };
326              
327 10 100       149 unshift @possibles, $meta if $meta;
328              
329 10         51 META: foreach my $mfile ( grep { -e } @possibles ) {
  19         351  
330 10         86 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         128 $href = $self->_prereqs_from_meta_file( @args, keys => [ $meth ] );
336             }
337 10         54 last META;
338             }
339              
340             }
341              
342             ### and store it in the module
343 10         55 $mod->status->$meth( $href );
344              
345 10         1042 return { %$href };
346             }
347              
348             sub find_mymeta_requires {
349 3     3 0 28 my $self = shift;
350 3         39 my $mod = $self->parent;
351 3         334 my %hash = @_;
352              
353 3         20 my ($meta);
354 3         15 my $href = {};
355              
356 3         37 my $tmpl = {
357             file => { store => \$meta },
358             };
359              
360 3 50       45 check( $tmpl, \%hash ) or return;
361              
362 3         163 my $meth = 'prereqs';
363              
364             {
365              
366             ### the prereqs as we have them now
367 3   50     21 my @args = (
  3         35  
368             defaults => $mod->status->$meth || {},
369             );
370              
371 3 50       392 my @possibles = do { defined $mod->status->extract
  3         36  
372             ? ( MYMETA_JSON->( $mod->status->extract ),
373             MYMETA_YML->( $mod->status->extract ) )
374             : ()
375             };
376              
377 3 50       30 unshift @possibles, $meta if $meta;
378              
379 3         21 META: foreach my $mfile ( grep { -e } @possibles ) {
  6         140  
380 3         20 push @args, ( file => $mfile );
381 3 50       74 if ( $mfile =~ /\.json/ ) {
382 3         80 $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         15 last META;
390             }
391              
392             }
393              
394             ### and store it in the module
395 3         23 $mod->status->$meth( $href );
396              
397 3         378 return { %$href };
398             }
399              
400             sub _prereqs_from_meta_file {
401 10     10   52 my $self = shift;
402 10         94 my $mod = $self->parent;
403 10         1276 my %hash = @_;
404              
405 10         46 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       33 file => { default => do { defined $mod->status->extract
  10         57  
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       176 check( $tmpl, \%hash ) or return;
420              
421             ### if there's a meta file, we read it;
422 10 50       1894 if( -e $meta ) {
423              
424             ### Parse::CPAN::Meta uses exceptions for errors
425             ### hash returned in list context!!!
426              
427 10         77 local $ENV{PERL_YAML_BACKEND};
428              
429 10         38 my ($doc) = eval { Parse::CPAN::Meta::LoadFile( $meta ) };
  10         64  
430              
431 10 50       16111 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         99 for my $key ( @$keys ) {
439             $defaults = {
440             %$defaults,
441 10         149 %{ $doc->{$key} },
442 10 50       140 } if $doc->{ $key };
443             }
444             }
445              
446             ### and return a copy
447 10         35 return \%{ $defaults };
  10         79  
448             }
449              
450             sub _prereqs_from_meta_json {
451 3     3   16 my $self = shift;
452 3         55 my $mod = $self->parent;
453 3         439 my %hash = @_;
454              
455 3         15 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       15 file => { default => do { defined $mod->status->extract
  3         29  
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       24 check( $tmpl, \%hash ) or return;
470              
471             ### if there's a meta file, we read it;
472 3 50       579 if( -e $meta ) {
473              
474             ### Parse::CPAN::Meta uses exceptions for errors
475             ### hash returned in list context!!!
476              
477 3         43 local $ENV{PERL_JSON_BACKEND};
478              
479 3         20 my ($doc) = eval { Parse::CPAN::Meta->load_file( $meta ) };
  3         109  
480              
481 3 50       68375 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     21 my $prereqs = $doc->{prereqs} || {};
495 3         13 for my $key ( @$keys ) {
496             $defaults = {
497             %$defaults,
498 3         27 %{ $prereqs->{$key}->{requires} },
499 9 100       90 } if $prereqs->{ $key }->{requires};
500             }
501             }
502              
503             ### and return a copy
504 3         9 return \%{ $defaults };
  3         31  
505             }
506              
507             sub _stash_metadata {
508 10     10   58 my $self = shift;
509 10         94 my $mod = $self->parent;
510              
511 10 100       1088 my @possibles = do { defined $mod->status->extract
  10         199  
512             ? ( META_JSON->( $mod->status->extract ),
513             META_YML->( $mod->status->extract ) )
514             : ()
515             };
516              
517 10         248 $self->mk_accessors( qw[_metadata] );
518 10         596 $self->status->_metadata( {} );
519              
520 10         2032 META: foreach my $mfile ( grep { -e } @possibles ) {
  18         441  
521 9 50       150 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         140 local $ENV{PERL_YAML_BACKEND};
533 9         69 my ($doc) = eval { Parse::CPAN::Meta->load_file( $mfile ) };
  9         331  
534 9 50       33672 unless( $doc ) {
535 0         0 error(loc( "Could not read %1: '%2'", $mfile, $@ ));
536 0         0 return;
537             }
538 9         99 $self->status->_metadata( $doc );
539 9         1693 return $doc;
540             }
541             }
542 1         5 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   2542 my $dist = shift;
571 31         257 my $self = $dist->parent;
572 31         3426 my $cb = $self->parent;
573 31         366 my $conf = $cb->configure_object;
574 31         617 my %hash = @_;
575              
576 31         179 my ($prereqs, $format, $verbose, $target, $force, $prereq_build,$tolerant);
577 31         428 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       221 check( $tmpl, \%hash ) or return;
601              
602             ### so there are no prereqs? then don't even bother
603 31 50       10617 return 1 unless keys %$prereqs;
604              
605             ### Make sure we wound up where we started.
606 31         174678 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     2832 }->{ $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         201 my @sorted_prereqs;
631              
632             ### use regex, could either be a module name, or a package name
633 31 50       986 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         695 @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         262 my @install_me;
648              
649             my $flag;
650              
651 31         363 for my $mod ( @sorted_prereqs ) {
652 31         632 ( 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       318 if( $mod eq PERL_CORE ) {
656              
657 2 100       144 unless( $cb->_vcmp( sprintf('v%vd',$^V), $version ) >= 0 ) {
658 1         20 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         130 return;
663             }
664              
665 1         37 next;
666             }
667              
668 29         653 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       339 unless( $modobj ) {
673             # Check if it is a core module
674 3         187 my $sub = CPANPLUS::Module->can(
675             'module_is_supplied_with_perl_core' );
676 3         85 my $core = $sub->( $mod );
677 3 50       43 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       153 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         31 next;
689             }
690              
691             ### it's not uptodate, we need to install it
692 26 100 33     771 if( !$dist->prereq_satisfied(modobj => $modobj, version => $version)) {
    50 33        
693 15         112 msg(loc("Module '%1' requires '%2' version '%3' to be installed ",
694             $self->module, $modobj->module, $version), $verbose );
695              
696 15         478 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       258 if( $target eq TARGET_IGNORE ) {
715              
716             ### but you have modules you need to install
717 2 50       40 if( @install_me ) {
718 2         32 msg(loc("Ignoring prereqs, this may mean your install will fail"),
719             $verbose);
720 2         51 msg(loc("'%1' listed the following dependencies:", $self->module),
721             $verbose);
722              
723 2         45 for my $aref (@install_me) {
724 2         24 my ($mod,$version) = @$aref;
725              
726 2         23 my $str = sprintf "\t%-35s %8s\n", $mod->module, $version;
727 2         21 msg($str,$verbose);
728             }
729              
730 2         253 return;
731              
732             ### ok, no problem, you have all needed prereqs anyway
733             } else {
734 0         0 return 1;
735             }
736             }
737              
738 28         148 for my $aref (@install_me) {
739 13         58 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     162 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     151 if( ( $conf->get_conf('prereqs') == PREREQ_ASK and not
752             $cb->_callbacks->install_prerequisite->($self, $modobj)
753             )
754             ) {
755 1         127 msg(loc("Will not install prerequisite '%1' -- Note " .
756             "that the overall install may fail due to this",
757             $modobj->module), $verbose);
758 1         24 next;
759             }
760              
761             ### value set and false -- means failure ###
762 12 100 66     202 if( defined $modobj->status->installed
763             && !$modobj->status->installed
764             ) {
765 1         154 error( loc( "Prerequisite '%1' failed to install before in " .
766             "this session", $modobj->module ) );
767 1         51 $flag++;
768 1         17 last;
769             }
770              
771             ### part of core?
772 11 100       1309 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         20 next;
778             }
779              
780             ### circular dependency code ###
781 10   100     79 my $pending = $cb->_status->pending_prereqs || {};
782              
783             ### recursive dependency ###
784 10 100       1211 if ( $pending->{ $modobj->module } ) {
785 1         30 error( loc( "Recursive dependency detected (%1) -- skipping",
786             $modobj->module ) );
787 1         35 next;
788             }
789              
790             ### register this dependency as pending ###
791 9         46 $pending->{ $modobj->module } = $modobj;
792 9         56 $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     960 my $pa = $dist->status->_prepare_args || {};
799 9   100     2469 my $ca = $dist->status->_create_args || {};
800 9   50     1786 my $ia = $dist->status->_install_args || {};
801              
802 9 100       1898 unless( $modobj->install( %$pa, %$ca, %$ia,
803             force => $force,
804             verbose => $verbose,
805             format => $format,
806             target => $target )
807             ) {
808 3         29 error(loc("Failed to install '%1' as prerequisite " .
809             "for '%2'", $modobj->module, $self->module ) );
810 3         62 $flag++;
811             }
812              
813             ### unregister the pending dependency ###
814 9         85 $pending->{ $modobj->module } = 0;
815 9         105 $cb->_status->pending_prereqs( $pending );
816              
817 9 100       946 last if $flag;
818              
819             ### don't want us to install? ###
820 6 100       150 if( $target ne TARGET_INSTALL ) {
821 3 50       62 my $dir = $modobj->status->extract
822             or error(loc("No extraction dir for '%1' found ".
823             "-- weird", $modobj->module));
824              
825 3         298 $modobj->add_to_includepath();
826              
827 3         65 next;
828             }
829             }
830              
831             ### reset the $prereqs iterator, in case we bailed out early ###
832 28         177 keys %$prereqs;
833              
834             ### chdir back to where we started
835 28         643 $cb->_chdir( dir => $original_wd );
836              
837 28 100       2424 return 1 unless $flag;
838 4         414 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: