This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update CPANPLUS to CPAN version 0.9007
[perl5.git] / cpan / CPANPLUS / lib / CPANPLUS / Module.pm
CommitLineData
6aaee015
RGS
1package CPANPLUS::Module;
2
3use strict;
4use vars qw[@ISA];
5
6
7use CPANPLUS::Dist;
8use CPANPLUS::Error;
9use CPANPLUS::Module::Signature;
10use CPANPLUS::Module::Checksums;
11use CPANPLUS::Internals::Constants;
12
13use FileHandle;
14
15use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
16use IPC::Cmd qw[can_run run];
17use File::Find qw[find];
18use Params::Check qw[check];
4443dd53 19use File::Basename qw[dirname];
6aaee015
RGS
20use Module::Load::Conditional qw[can_load check_install];
21
22$Params::Check::VERBOSE = 1;
23
24@ISA = qw[ CPANPLUS::Module::Signature CPANPLUS::Module::Checksums];
25
26=pod
27
28=head1 NAME
29
30CPANPLUS::Module
31
32=head1 SYNOPSIS
33
34 ### get a module object from the CPANPLUS::Backend object
35 my $mod = $cb->module_tree('Some::Module');
36
37 ### accessors
38 $mod->version;
39 $mod->package;
40
41 ### methods
42 $mod->fetch;
43 $mod->extract;
44 $mod->install;
45
46
47=head1 DESCRIPTION
48
49C<CPANPLUS::Module> creates objects from the information in the
50source files. These can then be used to query and perform actions
51on, like fetching or installing.
52
53These objects should only be created internally. For C<fake> objects,
54there's the C<CPANPLUS::Module::Fake> class. To obtain a module object
55consult the C<CPANPLUS::Backend> documentation.
56
57=cut
58
59my $tmpl = {
60 module => { default => '', required => 1 }, # full module name
61 version => { default => '0.0' }, # version number
62 path => { default => '', required => 1 }, # extended path on the
63 # cpan mirror, like
64 # /author/id/K/KA/KANE
65 comment => { default => ''}, # comment on module
66 package => { default => '', required => 1 }, # package name, like
67 # 'bar-baz-1.03.tgz'
68 description => { default => '' }, # description of the
69 # module
5879cbe1 70 dslip => { default => EMPTY_DSLIP }, # dslip information
6aaee015
RGS
71 _id => { required => 1 }, # id of the Internals
72 # parent object
73 _status => { no_override => 1 }, # stores status object
74 author => { default => '', required => 1,
75 allow => IS_AUTHOBJ }, # module author
76 mtime => { default => '' },
77};
78
5879cbe1
RGS
79### some of these will be resolved by wrapper functions that
80### do Clever Things to find the actual value, so don't create
81### an autogenerated sub for that just here, take an alternate
82### name to allow for a wrapper
83{ my %rename = (
84 dslip => '_dslip'
85 );
86
87 ### autogenerate accessors ###
88 for my $key ( keys %$tmpl ) {
89 no strict 'refs';
90
91 my $sub = $rename{$key} || $key;
92
93 *{__PACKAGE__."::$sub"} = sub {
94 $_[0]->{$key} = $_[1] if @_ > 1;
95 return $_[0]->{$key};
96 }
6aaee015
RGS
97 }
98}
99
5879cbe1 100
6aaee015
RGS
101=pod
102
103=head1 CLASS METHODS
104
105=head2 accessors ()
106
107Returns a list of all accessor methods to the object
108
109=cut
110
111### *name is an alias, include it explicitly
112sub accessors { return ('name', keys %$tmpl) };
113
114=head1 ACCESSORS
115
116An objects of this class has the following accessors:
117
118=over 4
119
120=item name
121
122Name of the module.
123
124=item module
125
126Name of the module.
127
128=item version
129
130Version of the module. Defaults to '0.0' if none was provided.
131
132=item path
133
134Extended path on the mirror.
135
136=item comment
137
138Any comment about the module -- largely unused.
139
140=item package
141
142The name of the package.
143
144=item description
145
146Description of the module -- only registered modules have this.
147
148=item dslip
149
150The five character dslip string, that represents meta-data of the
151module -- again, only registered modules have this.
152
5879cbe1
RGS
153=cut
154
155sub dslip {
156 my $self = shift;
157
158 ### if this module has relevant dslip info, return it
159 return $self->_dslip if $self->_dslip ne EMPTY_DSLIP;
160
161 ### if not, look at other modules in the same package,
162 ### see if *they* have any dslip info
163 for my $mod ( $self->contains ) {
164 return $mod->_dslip if $mod->_dslip ne EMPTY_DSLIP;
165 }
166
167 ### ok, really no dslip info found, return the default
168 return EMPTY_DSLIP;
169}
170
171
172=pod
173
6aaee015
RGS
174=item status
175
176The C<CPANPLUS::Module::Status> object associated with this object.
177(see below).
178
179=item author
180
181The C<CPANPLUS::Module::Author> object associated with this object.
182
183=item parent
184
185The C<CPANPLUS::Internals> object that spawned this module object.
186
187=back
188
189=cut
190
191### Alias ->name to ->module, for human beings.
192*name = *module;
193
194sub parent {
195 my $self = shift;
196 my $obj = CPANPLUS::Internals->_retrieve_id( $self->_id );
197
198 return $obj;
199}
200
201=head1 STATUS ACCESSORS
202
203C<CPANPLUS> caches a lot of results from method calls and saves data
204it collected along the road for later reuse.
205
206C<CPANPLUS> uses this internally, but it is also available for the end
207user. You can get a status object by calling:
208
209 $modobj->status
210
211You can then query the object as follows:
212
213=over 4
214
215=item installer_type
216
217The installer type used for this distribution. Will be one of
218'makemaker' or 'build'. This determines whether C<CPANPLUS::Dist::MM>
219or C<CPANPLUS::Dist::Build> will be used to build this distribution.
220
221=item dist_cpan
222
223The dist object used to do the CPAN-side of the installation. Either
224a C<CPANPLUS::Dist::MM> or C<CPANPLUS::Dist::Build> object.
225
226=item dist
227
228The custom dist object used to do the operating specific side of the
229installation, if you've chosen to use this. For example, if you've
230chosen to install using the C<ports> format, this may be a
231C<CPANPLUS::Dist::Ports> object.
232
233Undefined if you didn't specify a separate format to install through.
234
4443dd53 235=item prereqs | requires
6aaee015
RGS
236
237A hashref of prereqs this distribution was found to have. Will look
238something like this:
239
240 { Carp => 0.01, strict => 0 }
241
242Might be undefined if the distribution didn't have any prerequisites.
243
4443dd53
JB
244=item configure_requires
245
246Like prereqs, but these are necessary to be installed before the
247build process can even begin.
248
6aaee015
RGS
249=item signature
250
251Flag indicating, if a signature check was done, whether it was OK or
252not.
253
254=item extract
255
256The directory this distribution was extracted to.
257
258=item fetch
259
260The location this distribution was fetched to.
261
262=item readme
263
264The text of this distributions README file.
265
266=item uninstall
267
268Flag indicating if an uninstall call was done successfully.
269
270=item created
271
272Flag indicating if the C<create> call to your dist object was done
273successfully.
274
275=item installed
276
277Flag indicating if the C<install> call to your dist object was done
278successfully.
279
280=item checksums
281
282The location of this distributions CHECKSUMS file.
283
284=item checksum_ok
285
286Flag indicating if the checksums check was done successfully.
287
288=item checksum_value
289
290The checksum value this distribution is expected to have
291
292=back
293
294=head1 METHODS
295
4443dd53 296=head2 $self = CPANPLUS::Module->new( OPTIONS )
6aaee015
RGS
297
298This method returns a C<CPANPLUS::Module> object. Normal users
299should never call this method directly, but instead use the
300C<CPANPLUS::Backend> to obtain module objects.
301
302This example illustrates a C<new()> call with all required arguments:
303
304 CPANPLUS::Module->new(
305 module => 'Foo',
306 path => 'authors/id/A/AA/AAA',
307 package => 'Foo-1.0.tgz',
308 author => $author_object,
309 _id => INTERNALS_OBJECT_ID,
310 );
311
312Every accessor is also a valid option to pass to C<new>.
313
314Returns a module object on success and false on failure.
315
316=cut
317
318
319sub new {
320 my($class, %hash) = @_;
321
322 ### don't check the template for sanity
323 ### -- we know it's good and saves a lot of performance
324 local $Params::Check::SANITY_CHECK_TEMPLATE = 0;
325
326 my $object = check( $tmpl, \%hash ) or return;
327
328 bless $object, $class;
329
330 return $object;
331}
332
333### only create status objects when they're actually asked for
334sub status {
335 my $self = shift;
336 return $self->_status if $self->_status;
337
338 my $acc = Object::Accessor->new;
339 $acc->mk_accessors( qw[ installer_type dist_cpan dist prereqs
340 signature extract fetch readme uninstall
341 created installed prepared checksums files
4443dd53
JB
342 checksum_ok checksum_value _fetch_from
343 configure_requires
344 ] );
345
346 ### create an alias from 'requires' to 'prereqs', so it's more in
347 ### line with 'configure_requires';
348 $acc->mk_aliases( requires => 'prereqs' );
6aaee015
RGS
349
350 $self->_status( $acc );
351
352 return $self->_status;
353}
354
355
356### flush the cache of this object ###
357sub _flush {
358 my $self = shift;
359 $self->status->mk_flush;
360 return 1;
361}
362
4443dd53 363=head2 $mod->package_name( [$package_string] )
6aaee015
RGS
364
365Returns the name of the package a module is in. For C<Acme::Bleach>
366that might be C<Acme-Bleach>.
367
4443dd53 368=head2 $mod->package_version( [$package_string] )
6aaee015
RGS
369
370Returns the version of the package a module is in. For a module
371in the package C<Acme-Bleach-1.1.tar.gz> this would be C<1.1>.
372
4443dd53 373=head2 $mod->package_extension( [$package_string] )
6aaee015
RGS
374
375Returns the suffix added by the compression method of a package a
376certain module is in. For a module in C<Acme-Bleach-1.1.tar.gz>, this
377would be C<tar.gz>.
378
379=head2 $mod->package_is_perl_core
380
381Returns a boolean indicating of the package a particular module is in,
382is actually a core perl distribution.
383
384=head2 $mod->module_is_supplied_with_perl_core( [version => $]] )
385
386Returns a boolean indicating whether C<ANY VERSION> of this module
387was supplied with the current running perl's core package.
388
389=head2 $mod->is_bundle
390
391Returns a boolean indicating if the module you are looking at, is
392actually a bundle. Bundles are identified as modules whose name starts
393with C<Bundle::>.
394
4443dd53
JB
395=head2 $mod->is_autobundle;
396
397Returns a boolean indicating if the module you are looking at, is
398actually an autobundle as generated by C<< $cb->autobundle >>.
399
6aaee015
RGS
400=head2 $mod->is_third_party
401
402Returns a boolean indicating whether the package is a known third-party
403module (i.e. it's not provided by the standard Perl distribution and
404is not available on the CPAN, but on a third party software provider).
405See L<Module::ThirdParty> for more details.
406
407=head2 $mod->third_party_information
408
409Returns a reference to a hash with more information about a third-party
410module. See the documentation about C<module_information()> in
411L<Module::ThirdParty> for more details.
412
413=cut
414
415{ ### fetches the test reports for a certain module ###
416 my %map = (
417 name => 0,
418 version => 1,
419 extension => 2,
420 );
421
422 while ( my($type, $index) = each %map ) {
423 my $name = 'package_' . $type;
424
425 no strict 'refs';
426 *$name = sub {
427 my $self = shift;
4443dd53
JB
428 my $val = shift || $self->package;
429 my @res = $self->parent->_split_package_string( package => $val );
6aaee015
RGS
430
431 ### return the corresponding index from the result
432 return $res[$index] if @res;
433 return;
434 };
435 }
436
437 sub package_is_perl_core {
438 my $self = shift;
20afcebf 439 my $cb = $self->parent;
6aaee015
RGS
440
441 ### check if the package looks like a perl core package
442 return 1 if $self->package_name eq PERL_CORE;
443
20afcebf
JB
444 ### address #44562: ::Module->package_is_perl_code : problem comparing
445 ### version strings -- use $cb->_vcmp to avoid warnings when version
446 ### have _ in them
447
6aaee015
RGS
448 my $core = $self->module_is_supplied_with_perl_core;
449 ### ok, so it's found in the core, BUT it could be dual-lifed
d4e225aa 450 if (defined $core) {
6aaee015 451 ### if the package is newer than installed, then it's dual-lifed
20afcebf
JB
452 return if $cb->_vcmp($self->version, $self->installed_version) > 0;
453
6aaee015
RGS
454 ### if the package is newer or equal to the corelist,
455 ### then it's dual-lifed
20afcebf 456 return if $cb->_vcmp( $self->version, $core ) >= 0;
6aaee015
RGS
457
458 ### otherwise, it's older than corelist, thus unsuitable.
459 return 1;
460 }
461
462 ### not in corelist, not a perl core package.
463 return;
464 }
465
466 sub module_is_supplied_with_perl_core {
467 my $self = shift;
468 my $ver = shift || $];
469
4443dd53
JB
470 ### allow it to be called as a package function as well like:
471 ### CPANPLUS::Module::module_is_supplied_with_perl_core('Config')
472 ### so that we can check the status of modules that aren't released
473 ### to CPAN, but are part of the core.
474 my $name = ref $self ? $self->module : $self;
475
6aaee015
RGS
476 ### check Module::CoreList to see if it's a core package
477 require Module::CoreList;
4443dd53
JB
478
479 ### Address #41157: Module::module_is_supplied_with_perl_core()
480 ### broken for perl 5.10: Module::CoreList's version key for the
481 ### hash has a different number of trailing zero than $] aka
482 ### $PERL_VERSION.
6aaee015 483
d4e225aa
CBW
484 my $core;
485
486 if ( exists $Module::CoreList::version{ 0+$ver }->{ $name } ) {
487 $core = $Module::CoreList::version{ 0+$ver }->{ $name };
488 $core = 0 unless $core;
489 }
6aaee015
RGS
490 return $core;
491 }
492
493 ### make sure Bundle-Foo also gets flagged as bundle
494 sub is_bundle {
4443dd53
JB
495 my $self = shift;
496
497 ### cpan'd bundle
498 return 1 if $self->module =~ /^bundle(?:-|::)/i;
499
500 ### autobundle
501 return 1 if $self->is_autobundle;
502
503 ### neither
504 return;
505 }
506
507 ### full path to a generated autobundle
508 sub is_autobundle {
509 my $self = shift;
510 my $conf = $self->parent->configure_object;
511 my $prefix = $conf->_get_build('autobundle_prefix');
512
513 return 1 if $self->module eq $prefix;
514 return;
6aaee015
RGS
515 }
516
517 sub is_third_party {
518 my $self = shift;
519
520 return unless can_load( modules => { 'Module::ThirdParty' => 0 } );
521
522 return Module::ThirdParty::is_3rd_party( $self->name );
523 }
524
525 sub third_party_information {
526 my $self = shift;
527
528 return unless $self->is_third_party;
529
530 return Module::ThirdParty::module_information( $self->name );
531 }
532}
533
534=pod
535
536=head2 $clone = $self->clone
537
538Clones the current module object for tinkering with.
539It will have a clean C<CPANPLUS::Module::Status> object, as well as
540a fake C<CPANPLUS::Module::Author> object.
541
542=cut
543
4443dd53
JB
544{ ### accessors dont change during run time, so only compute once
545 my @acc = grep !/status/, __PACKAGE__->accessors();
546
547 sub clone {
548 my $self = shift;
549
550 ### clone the object ###
551 my %data = map { $_ => $self->$_ } @acc;
552
553 my $obj = CPANPLUS::Module::Fake->new( %data );
554
555 return $obj;
6aaee015 556 }
6aaee015
RGS
557}
558
559=pod
560
561=head2 $where = $self->fetch
562
563Fetches the module from a CPAN mirror.
564Look at L<CPANPLUS::Internals::Fetch::_fetch()> for details on the
565options you can pass.
566
567=cut
568
569sub fetch {
570 my $self = shift;
571 my $cb = $self->parent;
572
573 ### custom args
574 my %args = ( module => $self );
575
576 ### if a custom fetch location got specified before, add that here
577 $args{fetch_from} = $self->status->_fetch_from
578 if $self->status->_fetch_from;
579
580 my $where = $cb->_fetch( @_, %args ) or return;
581
582 ### do an md5 check ###
583 if( !$self->status->_fetch_from and
584 $cb->configure_object->get_conf('md5') and
585 $self->package ne CHECKSUMS
586 ) {
587 unless( $self->_validate_checksum ) {
588 error( loc( "Checksum error for '%1' -- will not trust package",
589 $self->package) );
590 return;
591 }
592 }
593
594 return $where;
595}
596
597=pod
598
599=head2 $path = $self->extract
600
601Extracts the fetched module.
602Look at L<CPANPLUS::Internals::Extract::_extract()> for details on
603the options you can pass.
604
605=cut
606
607sub extract {
608 my $self = shift;
609 my $cb = $self->parent;
610
611 unless( $self->status->fetch ) {
612 error( loc( "You have not fetched '%1' yet -- cannot extract",
613 $self->module) );
614 return;
615 }
4443dd53
JB
616
617 ### can't extract these, so just use the basedir for the file
618 if( $self->is_autobundle ) {
619
620 ### this is expected to be set after an extract call
621 $self->get_installer_type;
622
623 return $self->status->extract( dirname( $self->status->fetch ) );
624 }
625
6aaee015
RGS
626 return $cb->_extract( @_, module => $self );
627}
628
629=head2 $type = $self->get_installer_type([prefer_makefile => BOOL])
630
631Gets the installer type for this module. This may either be C<build> or
632C<makemaker>. If C<Module::Build> is unavailable or no installer type
633is available, it will fall back to C<makemaker>. If both are available,
634it will pick the one indicated by your config, or by the
635C<prefer_makefile> option you can pass to this function.
636
637Returns the installer type on success, and false on error.
638
639=cut
640
641sub get_installer_type {
642 my $self = shift;
643 my $cb = $self->parent;
644 my $conf = $cb->configure_object;
645 my %hash = @_;
646
4443dd53 647 my ($prefer_makefile,$verbose);
6aaee015
RGS
648 my $tmpl = {
649 prefer_makefile => { default => $conf->get_conf('prefer_makefile'),
4443dd53
JB
650 store => \$prefer_makefile, allow => BOOLEANS },
651 verbose => { default => $conf->get_conf('verbose'),
652 store => \$verbose },
6aaee015
RGS
653 };
654
655 check( $tmpl, \%hash ) or return;
656
6aaee015 657 my $type;
4443dd53
JB
658
659 ### autobundles use their own installer, so return that
660 if( $self->is_autobundle ) {
661 $type = INSTALLER_AUTOBUNDLE;
662
663 } else {
664 my $extract = $self->status->extract();
665 unless( $extract ) {
666 error(loc(
667 "Cannot determine installer type of unextracted module '%1'",
668 $self->module
669 ));
670 return;
671 }
672
673 ### check if it's a makemaker or a module::build type dist ###
674 my $found_build = -e BUILD_PL->( $extract );
675 my $found_makefile = -e MAKEFILE_PL->( $extract );
676
677 $type = INSTALLER_BUILD if !$prefer_makefile && $found_build;
678 $type = INSTALLER_BUILD if $found_build && !$found_makefile;
679 $type = INSTALLER_MM if $prefer_makefile && $found_makefile;
680 $type = INSTALLER_MM if $found_makefile && !$found_build;
681 }
6aaee015
RGS
682
683 ### ok, so it's a 'build' installer, but you don't /have/ module build
02f445e1 684 ### XXX duplicated from CPANPLUS::Selfupdate. fix somehow?
a0995fd4 685 if( $type and $type eq INSTALLER_BUILD and (
4443dd53 686 not CPANPLUS::Dist->has_dist_type( INSTALLER_BUILD )
02f445e1
JB
687 or not $cb->module_tree( INSTALLER_BUILD )
688 ->is_uptodate( version => '0.24' )
689 ) ) {
4443dd53
JB
690
691 ### XXX this is for recording purposes only. We *have* to install
692 ### these before even creating a dist object, or we'll get an error
693 ### saying 'no such dist type';
02f445e1 694 ### XXX duplicated from CPANPLUS::Selfupdate. fix somehow?
4443dd53 695 my $href = $self->status->configure_requires || {};
02f445e1 696 my $deps = { INSTALLER_BUILD, '0.24', %$href };
4443dd53
JB
697
698 $self->status->configure_requires( $deps );
699
700 msg(loc("This module requires '%1' and '%2' to be installed first. ".
701 "Adding these modules to your prerequisites list",
702 'Module::Build', INSTALLER_BUILD
703 ), $verbose );
704
6aaee015
RGS
705
706 ### ok, actually we found neither ###
707 } elsif ( !$type ) {
708 error( loc( "Unable to find '%1' or '%2' for '%3'; ".
709 "Will default to '%4' but might be unable ".
710 "to install!", BUILD_PL->(), MAKEFILE_PL->(),
711 $self->module, INSTALLER_MM ) );
712 $type = INSTALLER_MM;
713 }
714
715 return $self->status->installer_type( $type ) if $type;
716 return;
717}
718
719=pod
720
721=head2 $dist = $self->dist([target => 'prepare|create', format => DISTRIBUTION_TYPE, args => {key => val}]);
722
723Create a distribution object, ready to be installed.
724Distribution type defaults to your config settings
725
726The optional C<args> hashref is passed on to the specific distribution
727types' C<create> method after being dereferenced.
728
729Returns a distribution object on success, false on failure.
730
731See C<CPANPLUS::Dist> for details.
732
733=cut
734
735sub dist {
736 my $self = shift;
737 my $cb = $self->parent;
738 my $conf = $cb->configure_object;
739 my %hash = @_;
740
741 ### have you determined your installer type yet? if not, do it here,
742 ### we need the info
743 $self->get_installer_type unless $self->status->installer_type;
744
6aaee015
RGS
745 my($type,$args,$target);
746 my $tmpl = {
747 format => { default => $conf->get_conf('dist_type') ||
748 $self->status->installer_type,
749 store => \$type },
750 target => { default => TARGET_CREATE, store => \$target },
751 args => { default => {}, store => \$args },
752 };
753
754 check( $tmpl, \%hash ) or return;
755
4443dd53
JB
756 ### ok, check for $type. Do we have it?
757 unless( CPANPLUS::Dist->has_dist_type( $type ) ) {
758
759 ### ok, we don't have it. Is it C::D::Build? if so we can install the
760 ### whole thing now
761 ### XXX we _could_ do this for any type we dont have actually...
762 if( $type eq INSTALLER_BUILD ) {
763 msg(loc("Bootstrapping installer '%1'", $type));
764
765 ### don't propagate the format, it's the one we're trying to
766 ### bootstrap, so it'll be an infinite loop if we do
767
768 $cb->module_tree( $type )->install( target => $target, %$args ) or
769 do {
770 error(loc("Could not bootstrap installer '%1' -- ".
771 "can not continue", $type));
772 return;
773 };
774
775 ### re-scan for available modules now
776 CPANPLUS::Dist->rescan_dist_types;
777
778 unless( CPANPLUS::Dist->has_dist_type( $type ) ) {
779 error(loc("Newly installed installer type '%1' should be ".
780 "available, but is not! -- aborting", $type));
781 return;
782 } else {
783 msg(loc("Installer '%1' succesfully bootstrapped", $type));
784 }
785
786 ### some other plugin you dont have. Abort
787 } else {
788 error(loc("Installer type '%1' not found. Please verify your ".
789 "installation -- aborting", $type ));
790 return;
791 }
792 }
793
20afcebf
JB
794 ### make sure we don't overwrite it, just in case we came
795 ### back from a ->save_state. This allows restoration to
796 ### work correctly
797 my( $dist, $dist_cpan );
798
799 unless( $dist = $self->status->dist ) {
800 $dist = $type->new( module => $self ) or return;
801 $self->status->dist( $dist );
802 }
803
804 unless( $dist_cpan = $self->status->dist_cpan ) {
805
806 $dist_cpan = $type eq $self->status->installer_type
807 ? $self->status->dist
4443dd53 808 : $self->status->installer_type->new( module => $self );
6aaee015 809
20afcebf
JB
810
811 $self->status->dist_cpan( $dist_cpan );
812 }
813
6aaee015
RGS
814
815 DIST: {
8bc57f96
DM
816 ### just wanted the $dist object?
817 last DIST if $target eq TARGET_INIT;
818
6aaee015
RGS
819 ### first prepare the dist
820 $dist->prepare( %$args ) or return;
821 $self->status->prepared(1);
822
823 ### you just wanted us to prepare?
824 last DIST if $target eq TARGET_PREPARE;
825
826 $dist->create( %$args ) or return;
827 $self->status->created(1);
828 }
829
830 return $dist;
831}
832
833=pod
834
835=head2 $bool = $mod->prepare( )
836
837Convenience method around C<install()> that prepares a module
838without actually building it. This is equivalent to invoking C<install>
839with C<target> set to C<prepare>
840
841Returns true on success, false on failure.
842
843=cut
844
845sub prepare {
846 my $self = shift;
847 return $self->install( @_, target => TARGET_PREPARE );
848}
849
850=head2 $bool = $mod->create( )
851
852Convenience method around C<install()> that creates a module.
853This is equivalent to invoking C<install> with C<target> set to
854C<create>
855
856Returns true on success, false on failure.
857
858=cut
859
860sub create {
861 my $self = shift;
862 return $self->install( @_, target => TARGET_CREATE );
863}
864
865=head2 $bool = $mod->test( )
866
867Convenience wrapper around C<install()> that tests a module, without
868installing it.
869It's the equivalent to invoking C<install()> with C<target> set to
870C<create> and C<skiptest> set to C<0>.
871
872Returns true on success, false on failure.
873
874=cut
875
876sub test {
877 my $self = shift;
878 return $self->install( @_, target => TARGET_CREATE, skiptest => 0 );
879}
880
881=pod
882
8bc57f96 883=head2 $bool = $self->install([ target => 'init|prepare|create|install', format => FORMAT_TYPE, extractdir => DIRECTORY, fetchdir => DIRECTORY, prefer_bin => BOOL, force => BOOL, verbose => BOOL, ..... ]);
6aaee015
RGS
884
885Installs the current module. This includes fetching it and extracting
886it, if this hasn't been done yet, as well as creating a distribution
887object for it.
888
889This means you can pass it more arguments than described above, which
890will be passed on to the relevant methods as they are called.
891
892See C<CPANPLUS::Internals::Fetch>, C<CPANPLUS::Internals::Extract> and
893C<CPANPLUS::Dist> for details.
894
895Returns true on success, false on failure.
896
897=cut
898
899sub install {
900 my $self = shift;
901 my $cb = $self->parent;
902 my $conf = $cb->configure_object;
903 my %hash = @_;
904
905 my $args; my $target; my $format;
906 { ### so we can use the rest of the args to the create calls etc ###
907 local $Params::Check::NO_DUPLICATES = 1;
908 local $Params::Check::ALLOW_UNKNOWN = 1;
909
910 ### targets 'dist' and 'test' are now completely ignored ###
911 my $tmpl = {
912 ### match this allow list with Dist->_resolve_prereqs
913 target => { default => TARGET_INSTALL, store => \$target,
914 allow => [TARGET_PREPARE, TARGET_CREATE,
8bc57f96 915 TARGET_INSTALL, TARGET_INIT ] },
6aaee015
RGS
916 force => { default => $conf->get_conf('force'), },
917 verbose => { default => $conf->get_conf('verbose'), },
918 format => { default => $conf->get_conf('dist_type'),
919 store => \$format },
920 };
921
922 $args = check( $tmpl, \%hash ) or return;
923 }
924
925
926 ### if this target isn't 'install', we will need to at least 'create'
927 ### every prereq, so it can build
928 ### XXX prereq_target of 'prepare' will do weird things here, and is
929 ### not supported.
930 $args->{'prereq_target'} ||= TARGET_CREATE if $target ne TARGET_INSTALL;
931
932 ### check if it's already upto date ###
933 if( $target eq TARGET_INSTALL and !$args->{'force'} and
934 !$self->package_is_perl_core() and # separate rules apply
935 ( $self->status->installed() or $self->is_uptodate ) and
936 !INSTALL_VIA_PACKAGE_MANAGER->($format)
937 ) {
938 msg(loc("Module '%1' already up to date, won't install without force",
939 $self->module), $args->{'verbose'} );
940 return $self->status->installed(1);
941 }
942
943 # if it's a non-installable core package, abort the install.
944 if( $self->package_is_perl_core() ) {
945 # if the installed is newer, say so.
946 if( $self->installed_version > $self->version ) {
947 error(loc("The core Perl %1 module '%2' (%3) is more ".
948 "recent than the latest release on CPAN (%4). ".
949 "Aborting install.",
950 $], $self->module, $self->installed_version,
951 $self->version ) );
952 # if the installed matches, say so.
953 } elsif( $self->installed_version == $self->version ) {
954 error(loc("The core Perl %1 module '%2' (%3) can only ".
955 "be installed by Perl itself. ".
956 "Aborting install.",
957 $], $self->module, $self->installed_version ) );
958 # otherwise, the installed is older; say so.
959 } else {
960 error(loc("The core Perl %1 module '%2' can only be ".
961 "upgraded from %3 to %4 by Perl itself (%5). ".
962 "Aborting install.",
963 $], $self->module, $self->installed_version,
964 $self->version, $self->package ) );
965 }
966 return;
967
968 ### it might be a known 3rd party module
969 } elsif ( $self->is_third_party ) {
970 my $info = $self->third_party_information;
971 error(loc(
972 "%1 is a known third-party module.\n\n".
973 "As it isn't available on the CPAN, CPANPLUS can't install " .
974 "it automatically. Therefore you need to install it manually " .
975 "before proceeding.\n\n".
976 "%2 is part of %3, published by %4, and should be available ".
977 "for download at the following address:\n\t%5",
978 $self->name, $self->name, $info->{name}, $info->{author},
979 $info->{url}
980 ));
981
982 return;
983 }
984
985 ### fetch it if need be ###
986 unless( $self->status->fetch ) {
987 my $params;
988 for (qw[prefer_bin fetchdir]) {
989 $params->{$_} = $args->{$_} if exists $args->{$_};
990 }
991 for (qw[force verbose]) {
992 $params->{$_} = $args->{$_} if defined $args->{$_};
993 }
994 $self->fetch( %$params ) or return;
995 }
996
997 ### extract it if need be ###
998 unless( $self->status->extract ) {
999 my $params;
1000 for (qw[prefer_bin extractdir]) {
1001 $params->{$_} = $args->{$_} if exists $args->{$_};
1002 }
1003 for (qw[force verbose]) {
1004 $params->{$_} = $args->{$_} if defined $args->{$_};
1005 }
1006 $self->extract( %$params ) or return;
1007 }
1008
9abc3fab 1009 $args->{'prereq_format'} = $format if $format;
6aaee015
RGS
1010 $format ||= $self->status->installer_type;
1011
1012 unless( $format ) {
1013 error( loc( "Don't know what installer to use; " .
1014 "Couldn't find either '%1' or '%2' in the extraction " .
1015 "directory '%3' -- will be unable to install",
1016 BUILD_PL->(), MAKEFILE_PL->(), $self->status->extract ) );
1017
1018 $self->status->installed(0);
1019 return;
1020 }
1021
1022
1023 ### do SIGNATURE checks? ###
20afcebf 1024 ### XXX check status and not recheck EVERY time?
6aaee015
RGS
1025 if( $conf->get_conf('signature') ) {
1026 unless( $self->check_signature( verbose => $args->{verbose} ) ) {
1027 error( loc( "Signature check failed for module '%1' ".
1028 "-- Not trusting this module, aborting install",
1029 $self->module ) );
1030 $self->status->signature(0);
1031
1032 ### send out test report on broken sig
1033 if( $conf->get_conf('cpantest') ) {
1034 $cb->_send_report(
1035 module => $self,
1036 failed => 1,
1037 buffer => CPANPLUS::Error->stack_as_string,
1038 verbose => $args->{verbose},
1039 force => $args->{force},
1040 ) or error(loc("Failed to send test report for '%1'",
1041 $self->module ) );
1042 }
1043
1044 return;
1045
1046 } else {
1047 ### signature OK ###
1048 $self->status->signature(1);
1049 }
1050 }
1051
1052 ### a target of 'create' basically means not to run make test ###
1053 ### eh, no it /doesn't/.. skiptest => 1 means skiptest => 1.
1054 #$args->{'skiptest'} = 1 if $target eq 'create';
1055
1056 ### bundle rules apply ###
1057 if( $self->is_bundle ) {
1058 ### check what we need to install ###
1059 my @prereqs = $self->bundle_modules();
1060 unless( @prereqs ) {
1061 error( loc( "Bundle '%1' does not specify any modules to install",
1062 $self->module ) );
1063
1064 ### XXX mark an error here? ###
1065 }
1066 }
1067
1068 my $dist = $self->dist( format => $format,
1069 target => $target,
1070 args => $args );
1071 unless( $dist ) {
1072 error( loc( "Unable to create a new distribution object for '%1' " .
1073 "-- cannot continue", $self->module ) );
1074 return;
1075 }
1076
1077 return 1 if $target ne TARGET_INSTALL;
1078
1079 my $ok = $dist->install( %$args ) ? 1 : 0;
1080
1081 $self->status->installed($ok);
1082
1083 return 1 if $ok;
1084 return;
1085}
1086
1087=pod @list = $self->bundle_modules()
1088
1089Returns a list of module objects the Bundle specifies.
1090
1091This requires you to have extracted the bundle already, using the
1092C<extract()> method.
1093
1094Returns false on error.
1095
1096=cut
1097
1098sub bundle_modules {
1099 my $self = shift;
1100 my $cb = $self->parent;
1101
1102 unless( $self->is_bundle ) {
1103 error( loc("'%1' is not a bundle", $self->module ) );
1104 return;
1105 }
1106
6aaee015 1107 my @files;
4443dd53
JB
1108
1109 ### autobundles are special files generated by CPANPLUS. If we can
1110 ### read the file, we can determine the prereqs
1111 if( $self->is_autobundle ) {
1112 my $where;
1113 unless( $where = $self->status->fetch ) {
1114 error(loc("Don't know where '%1' was fetched to", $self->package));
1115 return;
1116 }
1117
1118 push @files, $where
1119
1120 ### regular bundle::* upload
1121 } else {
1122 my $dir;
1123 unless( $dir = $self->status->extract ) {
1124 error(loc("Don't know where '%1' was extracted to", $self->module));
1125 return;
1126 }
1127
1128 find( {
1129 wanted => sub { push @files, File::Spec->rel2abs($_) if /\.pm/i },
1130 no_chdir => 1,
1131 }, $dir );
1132 }
6aaee015
RGS
1133
1134 my $prereqs = {}; my @list; my $seen = {};
1135 for my $file ( @files ) {
1136 my $fh = FileHandle->new($file)
1137 or( error(loc("Could not open '%1' for reading: %2",
1138 $file,$!)), next );
1139
1140 my $flag;
4443dd53 1141 while( local $_ = <$fh> ) {
6aaee015
RGS
1142 ### quick hack to read past the header of the file ###
1143 last if $flag && m|^=head|i;
1144
1145 ### from perldoc cpan:
1146 ### =head1 CONTENTS
1147 ### In this pod section each line obeys the format
1148 ### Module_Name [Version_String] [- optional text]
1149 $flag = 1 if m|^=head1 CONTENTS|i;
1150
1151 if ($flag && /^(?!=)(\S+)\s*(\S+)?/) {
1152 my $module = $1;
4443dd53 1153 my $version = $cb->_version_to_number( version => $2 );
6aaee015
RGS
1154
1155 my $obj = $cb->module_tree($module);
1156
1157 unless( $obj ) {
1158 error(loc("Cannot find bundled module '%1'", $module),
1159 loc("-- it does not seem to exist") );
1160 next;
1161 }
1162
1163 ### make sure we list no duplicates ###
1164 unless( $seen->{ $obj->module }++ ) {
1165 push @list, $obj;
1166 $prereqs->{ $module } =
1167 $cb->_version_to_number( version => $version );
1168 }
1169 }
1170 }
1171 }
1172
1173 ### store the prereqs we just found ###
1174 $self->status->prereqs( $prereqs );
1175
1176 return @list;
1177}
1178
1179=pod
1180
1181=head2 $text = $self->readme
1182
1183Fetches the readme belonging to this module and stores it under
1184C<< $obj->status->readme >>. Returns the readme as a string on
1185success and returns false on failure.
1186
1187=cut
1188
1189sub readme {
1190 my $self = shift;
1191 my $conf = $self->parent->configure_object;
1192
1193 ### did we already dl the readme once? ###
1194 return $self->status->readme() if $self->status->readme();
1195
1196 ### this should be core ###
1197 return unless can_load( modules => { FileHandle => '0.0' },
1198 verbose => 1,
1199 );
1200
1201 ### get a clone of the current object, with a fresh status ###
1202 my $obj = $self->clone or return;
1203
1204 ### munge the package name
1205 my $pkg = README->( $obj );
1206 $obj->package($pkg);
1207
1208 my $file;
1209 { ### disable checksum fetches on readme downloads
1210
1211 my $tmp = $conf->get_conf( 'md5' );
1212 $conf->set_conf( md5 => 0 );
1213
1214 $file = $obj->fetch;
1215
1216 $conf->set_conf( md5 => $tmp );
1217
1218 return unless $file;
1219 }
1220
1221 ### read the file into a scalar, to store in the original object ###
1222 my $fh = new FileHandle;
1223 unless( $fh->open($file) ) {
1224 error( loc( "Could not open file '%1': %2", $file, $! ) );
1225 return;
1226 }
1227
4443dd53 1228 my $in = do{ local $/; <$fh> };
6aaee015
RGS
1229 $fh->close;
1230
1231 return $self->status->readme( $in );
1232}
1233
1234=pod
1235
1236=head2 $version = $self->installed_version()
1237
1238Returns the currently installed version of this module, if any.
1239
1240=head2 $where = $self->installed_file()
1241
1242Returns the location of the currently installed file of this module,
1243if any.
1244
4443dd53
JB
1245=head2 $dir = $self->installed_dir()
1246
1247Returns the directory (or more accurately, the C<@INC> handle) from
1248which this module was loaded, if any.
1249
6aaee015
RGS
1250=head2 $bool = $self->is_uptodate([version => VERSION_NUMBER])
1251
1252Returns a boolean indicating if this module is uptodate or not.
1253
1254=cut
1255
1256### uptodate/installed functions
1257{ my $map = { # hashkey, alternate rv
1258 installed_version => ['version', 0 ],
1259 installed_file => ['file', ''],
4443dd53 1260 installed_dir => ['dir', ''],
6aaee015
RGS
1261 is_uptodate => ['uptodate', 0 ],
1262 };
1263
1264 while( my($method, $aref) = each %$map ) {
1265 my($key,$alt_rv) = @$aref;
1266
1267 no strict 'refs';
1268 *$method = sub {
1269 ### never use the @INC hooks to find installed versions of
1270 ### modules -- they're just there in case they're not on the
1271 ### perl install, but the user shouldn't trust them for *other*
1272 ### modules!
1273 ### XXX CPANPLUS::inc is now obsolete, so this should not
1274 ### be needed anymore
1275 #local @INC = CPANPLUS::inc->original_inc;
1276
1277 my $self = shift;
1278
1279 ### make sure check_install is not looking in %INC, as
1280 ### that may contain some of our sneakily loaded modules
1281 ### that aren't installed as such. -- kane
1282 local $Module::Load::Conditional::CHECK_INC_HASH = 0;
d74adc6a
CBW
1283 ### this should all that is required for deprecated core modules
1284 local $Module::Load::Conditional::DEPRECATED = 1;
6aaee015
RGS
1285 my $href = check_install(
1286 module => $self->module,
1287 version => $self->version,
1288 @_,
1289 );
1290
1291 return $href->{$key} || $alt_rv;
1292 }
1293 }
1294}
1295
1296
1297
1298=pod
1299
1300=head2 $href = $self->details()
1301
1302Returns a hashref with key/value pairs offering more information about
1303a particular module. For example, for C<Time::HiRes> it might look like
1304this:
1305
1306 Author Jarkko Hietaniemi (jhi@iki.fi)
1307 Description High resolution time, sleep, and alarm
1308 Development Stage Released
1309 Installed File /usr/local/perl/lib/Time/Hires.pm
1310 Interface Style plain Functions, no references used
1311 Language Used C and perl, a C compiler will be needed
1312 Package Time-HiRes-1.65.tar.gz
1313 Public License Unknown
1314 Support Level Developer
1315 Version Installed 1.52
1316 Version on CPAN 1.65
1317
1318=cut
1319
1320sub details {
1321 my $self = shift;
1322 my $conf = $self->parent->configure_object();
1323 my $cb = $self->parent;
1324 my %hash = @_;
1325
1326 my $res = {
1327 Author => loc("%1 (%2)", $self->author->author(),
1328 $self->author->email() ),
1329 Package => $self->package,
1330 Description => $self->description || loc('None given'),
1331 'Version on CPAN' => $self->version,
1332 };
1333
1334 ### check if we have the module installed
1335 ### if so, add version have and version on cpan
1336 $res->{'Version Installed'} = $self->installed_version
1337 if $self->installed_version;
1338 $res->{'Installed File'} = $self->installed_file if $self->installed_file;
1339
1340 my $i = 0;
1341 for my $item( split '', $self->dslip ) {
1342 $res->{ $cb->_dslip_defs->[$i]->[0] } =
1343 $cb->_dslip_defs->[$i]->[1]->{$item} || loc('Unknown');
1344 $i++;
1345 }
1346
1347 return $res;
1348}
1349
1350=head2 @list = $self->contains()
1351
1352Returns a list of module objects that represent the modules also
1353present in the package of this module.
1354
1355For example, for C<Archive::Tar> this might return:
1356
1357 Archive::Tar
1358 Archive::Tar::Constant
1359 Archive::Tar::File
1360
1361=cut
1362
1363sub contains {
1364 my $self = shift;
1365 my $cb = $self->parent;
1366 my $pkg = $self->package;
5879cbe1 1367
6aaee015
RGS
1368 my @mods = $cb->search( type => 'package', allow => [qr/^$pkg$/] );
1369
1370 return @mods;
1371}
1372
1373=pod
1374
1375=head2 @list_of_hrefs = $self->fetch_report()
1376
1377This function queries the CPAN testers database at
1378I<http://testers.cpan.org/> for test results of specified module
1379objects, module names or distributions.
1380
1381Look at L<CPANPLUS::Internals::Report::_query_report()> for details on
1382the options you can pass and the return value to expect.
1383
1384=cut
1385
1386sub fetch_report {
1387 my $self = shift;
1388 my $cb = $self->parent;
1389
1390 return $cb->_query_report( @_, module => $self );
1391}
1392
1393=pod
1394
1395=head2 $bool = $self->uninstall([type => [all|man|prog])
1396
1397This function uninstalls the specified module object.
1398
1399You can install 2 types of files, either C<man> pages or C<prog>ram
1400files. Alternately you can specify C<all> to uninstall both (which
1401is the default).
1402
1403Returns true on success and false on failure.
1404
1405Do note that this does an uninstall via the so-called C<.packlist>,
1406so if you used a module installer like say, C<ports> or C<apt>, you
1407should not use this, but use your package manager instead.
1408
1409=cut
1410
1411sub uninstall {
1412 my $self = shift;
1413 my $conf = $self->parent->configure_object();
1414 my %hash = @_;
1415
1416 my ($type,$verbose);
1417 my $tmpl = {
1418 type => { default => 'all', allow => [qw|man prog all|],
1419 store => \$type },
1420 verbose => { default => $conf->get_conf('verbose'),
1421 store => \$verbose },
1422 force => { default => $conf->get_conf('force') },
1423 };
1424
1425 ### XXX add a warning here if your default install dist isn't
1426 ### makefile or build -- that means you are using a package manager
1427 ### and this will not do what you think!
1428
1429 my $args = check( $tmpl, \%hash ) or return;
1430
1431 if( $conf->get_conf('dist_type') and (
1432 ($conf->get_conf('dist_type') ne INSTALLER_BUILD) or
1433 ($conf->get_conf('dist_type') ne INSTALLER_MM))
1434 ) {
1435 msg(loc("You have a default installer type set (%1) ".
1436 "-- you should probably use that package manager to " .
1437 "uninstall modules", $conf->get_conf('dist_type')), $verbose);
1438 }
1439
1440 ### check if we even have the module installed -- no point in continuing
1441 ### otherwise
1442 unless( $self->installed_version ) {
1443 error( loc( "Module '%1' is not installed, so cannot uninstall",
1444 $self->module ) );
1445 return;
1446 }
1447
1448 ### nothing to uninstall ###
1449 my $files = $self->files( type => $type ) or return;
1450 my $dirs = $self->directory_tree( type => $type ) or return;
1451 my $sudo = $conf->get_program('sudo');
1452
1453 ### just in case there's no file; M::B doensn't provide .packlists yet ###
1454 my $pack = $self->packlist;
1455 $pack = $pack->[0]->packlist_file() if $pack;
1456
1457 ### first remove the files, then the dirs if they are empty ###
1458 my $flag = 0;
1459 for my $file( @$files, $pack ) {
1460 next unless defined $file && -f $file;
1461
1462 msg(loc("Unlinking '%1'", $file), $verbose);
1463
1464 my @cmd = ($^X, "-eunlink+q[$file]");
1465 unshift @cmd, $sudo if $sudo;
1466
1467 my $buffer;
1468 unless ( run( command => \@cmd,
1469 verbose => $verbose,
1470 buffer => \$buffer )
1471 ) {
1472 error(loc("Failed to unlink '%1': '%2'",$file, $buffer));
1473 $flag++;
1474 }
1475 }
1476
1477 for my $dir ( sort @$dirs ) {
1478 local *DIR;
4443dd53 1479 opendir DIR, $dir or next;
6aaee015
RGS
1480 my @count = readdir(DIR);
1481 close DIR;
1482
1483 next unless @count == 2; # . and ..
1484
1485 msg(loc("Removing '%1'", $dir), $verbose);
1486
1487 ### this fails on my win2k machines.. it indeed leaves the
1488 ### dir, but it's not a critical error, since the files have
1489 ### been removed. --kane
1490 #unless( rmdir $dir ) {
1491 # error( loc( "Could not remove '%1': %2", $dir, $! ) )
1492 # unless $^O eq 'MSWin32';
1493 #}
1494
4443dd53 1495 my @cmd = ($^X, "-e", "rmdir q[$dir]");
6aaee015
RGS
1496 unshift @cmd, $sudo if $sudo;
1497
1498 my $buffer;
1499 unless ( run( command => \@cmd,
1500 verbose => $verbose,
1501 buffer => \$buffer )
1502 ) {
1503 error(loc("Failed to rmdir '%1': %2",$dir,$buffer));
1504 $flag++;
1505 }
1506 }
1507
1508 $self->status->uninstall(!$flag);
1509 $self->status->installed( $flag ? 1 : undef);
1510
1511 return !$flag;
1512}
1513
1514=pod
1515
1516=head2 @modobj = $self->distributions()
1517
1518Returns a list of module objects representing all releases for this
1519module on success, false on failure.
1520
1521=cut
1522
1523sub distributions {
1524 my $self = shift;
1525 my %hash = @_;
1526
1527 my @list = $self->author->distributions( %hash, module => $self ) or return;
1528
1529 ### it's another release then by the same author ###
1530 return grep { $_->package_name eq $self->package_name } @list;
1531}
1532
1533=pod
1534
1535=head2 @list = $self->files ()
1536
1537Returns a list of files used by this module, if it is installed.
1538
6aaee015
RGS
1539=head2 @list = $self->directory_tree ()
1540
1541Returns a list of directories used by this module.
1542
6aaee015
RGS
1543=head2 @list = $self->packlist ()
1544
1545Returns the C<ExtUtils::Packlist> object for this module.
1546
6aaee015
RGS
1547=head2 @list = $self->validate ()
1548
1549Returns a list of files that are missing for this modules, but
1550are present in the .packlist file.
1551
1552=cut
1553
20afcebf
JB
1554for my $sub (qw[files directory_tree packlist validate]) {
1555 no strict 'refs';
1556 *$sub = sub {
1557 return shift->_extutils_installed( @_, method => $sub );
1558 }
6aaee015
RGS
1559}
1560
1561### generic method to call an ExtUtils::Installed method ###
1562sub _extutils_installed {
1563 my $self = shift;
20afcebf
JB
1564 my $cb = $self->parent;
1565 my $conf = $cb->configure_object;
1566 my $home = $cb->_home_dir; # may be needed to fix up prefixes
6aaee015
RGS
1567 my %hash = @_;
1568
1569 my ($verbose,$type,$method);
1570 my $tmpl = {
1571 verbose => { default => $conf->get_conf('verbose'),
1572 store => \$verbose, },
1573 type => { default => 'all',
1574 allow => [qw|prog man all|],
1575 store => \$type, },
1576 method => { required => 1,
1577 store => \$method,
1578 allow => [qw|files directory_tree packlist
1579 validate|],
1580 },
1581 };
1582
1583 my $args = check( $tmpl, \%hash ) or return;
1584
1585 ### old versions of cygwin + perl < 5.8 are buggy here. bail out if we
1586 ### find we're being used by them
1587 { my $err = ON_OLD_CYGWIN;
1588 if($err) { error($err); return };
1589 }
1590
1591 return unless can_load(
1592 modules => { 'ExtUtils::Installed' => '0.0' },
1593 verbose => $verbose,
1594 );
1595
20afcebf
JB
1596 my @config_names = (
1597 ### lib
1598 { lib => 'privlib', # perl-only
1599 arch => 'archlib', # compiled code
1600 prefix => 'prefix', # prefix to both
1601 },
1602 ### site
1603 { lib => 'sitelib',
1604 arch => 'sitearch',
1605 prefix => 'siteprefix',
1606 },
1607 ### vendor
1608 { lib => 'vendorlib',
1609 arch => 'vendorarch',
1610 prefix => 'vendorprefix',
1611 },
1612 );
1613
4443dd53
JB
1614 ### search in your regular @INC, and anything you added to your config.
1615 ### this lets EU::Installed find .packlists that are *not* in the standard
1616 ### compiled in @INC path. Requires EU::I 1.42 or up. this addresses #33438
1617 ### make sure the archname path is also added, as that's where the .packlist
1618 ### files are written
1619 my @libs;
1620 for my $lib ( @{ $conf->get_conf('lib') } ) {
1621 require Config;
20afcebf
JB
1622
1623 ### and just the standard dir
1624 push @libs, $lib;
1625
4443dd53
JB
1626 ### figure out what an MM prefix expands to. Basically, it's the
1627 ### site install target from %Config, ie: /opt/lib/perl5/site_perl/5.8.8
1628 ### minus the site wide prefix, ie: /opt
1629 ### this lets users add the dir they have set as their EU::MM PREFIX
1630 ### to our 'lib' config and it Just Works
20afcebf
JB
1631 ### the arch specific dir, ie:
1632 ### /opt/lib/perl5/site_perl/5.8.8/darwin-2level
4443dd53 1633 ### XXX is this the right thing to do?
4443dd53 1634
20afcebf
JB
1635 ### we add all 6 dir combos for prefixes:
1636 ### /foo/lib
1637 ### /foo/lib/arch
1638 ### /foo/site/lib
1639 ### /foo/site/lib/arch
1640 ### /foo/vendor/lib
1641 ### /foo/vendor/lib/arch
1642 for my $href ( @config_names ) {
1643 for my $key ( qw[lib arch] ) {
4443dd53 1644
20afcebf
JB
1645 ### look up the config value -- use EXP for the EXPANDED
1646 ### version, so no ~ etc are found in there
1647 my $dir = $Config::Config{ $href->{ $key } .'exp' } or next;
1648 my $prefix = $Config::Config{ $href->{prefix} };
1649
1650 ### prefix may be relative to home, and contain a ~
1651 ### if so, fix it up.
1652 $prefix =~ s/^~/$home/;
1653
1654 ### remove the prefix from it, so we can append to our $lib
1655 $dir =~ s/^\Q$prefix\E//;
1656
1657 ### do the appending
1658 push @libs, File::Spec->catdir( $lib, $dir );
1659
1660 }
1661 }
4443dd53
JB
1662 }
1663
1664 my $inst;
1665 unless( $inst = ExtUtils::Installed->new( extra_libs => \@libs ) ) {
6aaee015
RGS
1666 error( loc("Could not create an '%1' object", 'ExtUtils::Installed' ) );
1667
1668 ### in case it's being used directly... ###
1669 return;
1670 }
1671
1672
1673 { ### EU::Installed can die =/
1674 my @files;
1675 eval { @files = $inst->$method( $self->module, $type ) };
1676
1677 if( $@ ) {
1678 chomp $@;
1679 error( loc("Could not get '%1' for '%2': %3",
1680 $method, $self->module, $@ ) );
1681 return;
1682 }
1683
1684 return wantarray ? @files : \@files;
1685 }
1686}
1687
1688=head2 $bool = $self->add_to_includepath;
1689
1690Adds the current modules path to C<@INC> and C<$PERL5LIB>. This allows
4443dd53 1691you to add the module from its build dir to your path.
6aaee015 1692
4443dd53 1693You can reset C<@INC> and C<$PERL5LIB> to its original state when you
6aaee015
RGS
1694started the program, by calling:
1695
1696 $self->parent->flush('lib');
1697
1698=cut
1699
1700sub add_to_includepath {
1701 my $self = shift;
1702 my $cb = $self->parent;
1703
1704 if( my $dir = $self->status->extract ) {
1705
1706 $cb->_add_to_includepath(
1707 directories => [
1708 File::Spec->catdir(BLIB->($dir), LIB),
1709 File::Spec->catdir(BLIB->($dir), ARCH),
1710 BLIB->($dir),
1711 ]
1712 ) or return;
1713
1714 } else {
1715 error(loc( "No extract dir registered for '%1' -- can not add ".
1716 "add builddir to search path!", $self->module ));
1717 return;
1718 }
1719
1720 return 1;
1721
1722}
1723
1724=pod
1725
1726=head2 $path = $self->best_path_to_module_build();
1727
1728B<OBSOLETE>
1729
1730If a newer version of Module::Build is found in your path, it will
1731return this C<special> path. If the newest version of C<Module::Build>
1732is found in your regular C<@INC>, the method will return false. This
1733indicates you do not need to add a special directory to your C<@INC>.
1734
1735Note that this is only relevant if you're building your own
1736C<CPANPLUS::Dist::*> plugin -- the built-in dist types already have
1737this taken care of.
1738
1739=cut
1740
1741### make sure we're always running 'perl Build.PL' and friends
1742### against the highest version of module::build available
1743sub best_path_to_module_build {
1744 my $self = shift;
1745
1746 ### Since M::B will actually shell out and run the Build.PL, we must
1747 ### make sure it refinds the proper version of M::B in the path.
1748 ### that may be either in our cp::inc or in site_perl, or even a
1749 ### new M::B being installed.
1750 ### don't add anything else here, as that might screw up prereq checks
1751
1752 ### XXX this might be needed for Dist::MM too, if a makefile.pl is
1753 ### masquerading as a Build.PL
1754
1755 ### did we find the most recent module::build in our installer path?
1756
1757 ### XXX can't do changes to @INC, they're being ignored by
1758 ### new_from_context when writing a Build script. see ticket:
1759 ### #8826 Module::Build ignores changes to @INC when writing Build
1760 ### from new_from_context
1761 ### XXX applied schwern's patches (as seen on CPANPLUS::Devel 10/12/04)
1762 ### and upped the version to 0.26061 of the bundled version, and things
1763 ### work again
1764
1765 ### this functionality is now obsolete -- prereqs should be installed
1766 ### and we no longer use the CPANPLUS::inc magic.. so comment this out.
1767# require Module::Build;
1768# if( CPANPLUS::inc->path_to('Module::Build') and (
1769# CPANPLUS::inc->path_to('Module::Build') eq
1770# CPANPLUS::inc->installer_path )
1771# ) {
1772#
1773# ### if the module being installed is *not* Module::Build
1774# ### itself -- as that would undoubtedly be newer -- add
1775# ### the path to the installers to @INC
1776# ### if it IS module::build itself, add 'lib' to its path,
1777# ### as the Build.PL would do as well, but the API doesn't.
1778# ### this makes self updates possible
1779# return $self->module eq 'Module::Build'
1780# ? 'lib'
1781# : CPANPLUS::inc->installer_path;
1782# }
1783
1784 ### otherwise, the path was found through a 'normal' way of
1785 ### scanning @INC.
1786 return;
1787}
1788
1789=pod
1790
1791=head1 BUG REPORTS
1792
1793Please report bugs or other issues to E<lt>bug-cpanplus@rt.cpan.org<gt>.
1794
1795=head1 AUTHOR
1796
1797This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
1798
1799=head1 COPYRIGHT
1800
1801The CPAN++ interface (of which this module is a part of) is copyright (c)
18022001 - 2007, Jos Boumans E<lt>kane@cpan.orgE<gt>. All rights reserved.
1803
1804This library is free software; you may redistribute and/or modify it
1805under the same terms as Perl itself.
1806
1807=cut
1808
1809# Local variables:
1810# c-indentation-style: bsd
1811# c-basic-offset: 4
1812# indent-tabs-mode: nil
1813# End:
1814# vim: expandtab shiftwidth=4:
1815
18161;
1817
1818__END__
1819
1820todo:
1821reports();