1 package CPANPLUS::Module;
9 use CPANPLUS::Module::Signature;
10 use CPANPLUS::Module::Checksums;
11 use CPANPLUS::Internals::Constants;
15 use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
16 use IPC::Cmd qw[can_run run];
17 use File::Find qw[find];
18 use Params::Check qw[check];
19 use File::Basename qw[dirname];
20 use Module::Load::Conditional qw[can_load check_install];
22 $Params::Check::VERBOSE = 1;
24 @ISA = qw[ CPANPLUS::Module::Signature CPANPLUS::Module::Checksums];
34 ### get a module object from the CPANPLUS::Backend object
35 my $mod = $cb->module_tree('Some::Module');
49 C<CPANPLUS::Module> creates objects from the information in the
50 source files. These can then be used to query and perform actions
51 on, like fetching or installing.
53 These objects should only be created internally. For C<fake> objects,
54 there's the C<CPANPLUS::Module::Fake> class. To obtain a module object
55 consult the C<CPANPLUS::Backend> documentation.
60 module => { default => '', required => 1 }, # full module name
61 version => { default => '0.0' }, # version number
62 path => { default => '', required => 1 }, # extended path on the
64 # /author/id/K/KA/KANE
65 comment => { default => ''}, # comment on module
66 package => { default => '', required => 1 }, # package name, like
68 description => { default => '' }, # description of the
70 dslip => { default => EMPTY_DSLIP }, # dslip information
71 _id => { required => 1 }, # id of the Internals
73 _status => { no_override => 1 }, # stores status object
74 author => { default => '', required => 1,
75 allow => IS_AUTHOBJ }, # module author
76 mtime => { default => '' },
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
87 ### autogenerate accessors ###
88 for my $key ( keys %$tmpl ) {
91 my $sub = $rename{$key} || $key;
93 *{__PACKAGE__."::$sub"} = sub {
94 $_[0]->{$key} = $_[1] if @_ > 1;
107 Returns a list of all accessor methods to the object
111 ### *name is an alias, include it explicitly
112 sub accessors { return ('name', keys %$tmpl) };
116 An objects of this class has the following accessors:
130 Version of the module. Defaults to '0.0' if none was provided.
134 Extended path on the mirror.
138 Any comment about the module -- largely unused.
142 The name of the package.
146 Description of the module -- only registered modules have this.
150 The five character dslip string, that represents meta-data of the
151 module -- again, only registered modules have this.
158 ### if this module has relevant dslip info, return it
159 return $self->_dslip if $self->_dslip ne EMPTY_DSLIP;
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;
167 ### ok, really no dslip info found, return the default
176 The C<CPANPLUS::Module::Status> object associated with this object.
181 The C<CPANPLUS::Module::Author> object associated with this object.
185 The C<CPANPLUS::Internals> object that spawned this module object.
191 ### Alias ->name to ->module, for human beings.
196 my $obj = CPANPLUS::Internals->_retrieve_id( $self->_id );
201 =head1 STATUS ACCESSORS
203 C<CPANPLUS> caches a lot of results from method calls and saves data
204 it collected along the road for later reuse.
206 C<CPANPLUS> uses this internally, but it is also available for the end
207 user. You can get a status object by calling:
211 You can then query the object as follows:
217 The installer type used for this distribution. Will be one of
218 'makemaker' or 'build'. This determines whether C<CPANPLUS::Dist::MM>
219 or C<CPANPLUS::Dist::Build> will be used to build this distribution.
223 The dist object used to do the CPAN-side of the installation. Either
224 a C<CPANPLUS::Dist::MM> or C<CPANPLUS::Dist::Build> object.
228 The custom dist object used to do the operating specific side of the
229 installation, if you've chosen to use this. For example, if you've
230 chosen to install using the C<ports> format, this may be a
231 C<CPANPLUS::Dist::Ports> object.
233 Undefined if you didn't specify a separate format to install through.
235 =item prereqs | requires
237 A hashref of prereqs this distribution was found to have. Will look
240 { Carp => 0.01, strict => 0 }
242 Might be undefined if the distribution didn't have any prerequisites.
244 =item configure_requires
246 Like prereqs, but these are necessary to be installed before the
247 build process can even begin.
251 Flag indicating, if a signature check was done, whether it was OK or
256 The directory this distribution was extracted to.
260 The location this distribution was fetched to.
264 The text of this distributions README file.
268 Flag indicating if an uninstall call was done successfully.
272 Flag indicating if the C<create> call to your dist object was done
277 Flag indicating if the C<install> call to your dist object was done
282 The location of this distributions CHECKSUMS file.
286 Flag indicating if the checksums check was done successfully.
290 The checksum value this distribution is expected to have
296 =head2 $self = CPANPLUS::Module->new( OPTIONS )
298 This method returns a C<CPANPLUS::Module> object. Normal users
299 should never call this method directly, but instead use the
300 C<CPANPLUS::Backend> to obtain module objects.
302 This example illustrates a C<new()> call with all required arguments:
304 CPANPLUS::Module->new(
306 path => 'authors/id/A/AA/AAA',
307 package => 'Foo-1.0.tgz',
308 author => $author_object,
309 _id => INTERNALS_OBJECT_ID,
312 Every accessor is also a valid option to pass to C<new>.
314 Returns a module object on success and false on failure.
320 my($class, %hash) = @_;
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;
326 my $object = check( $tmpl, \%hash ) or return;
328 bless $object, $class;
333 ### only create status objects when they're actually asked for
336 return $self->_status if $self->_status;
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
342 checksum_ok checksum_value _fetch_from
346 ### create an alias from 'requires' to 'prereqs', so it's more in
347 ### line with 'configure_requires';
348 $acc->mk_aliases( requires => 'prereqs' );
350 $self->_status( $acc );
352 return $self->_status;
356 ### flush the cache of this object ###
359 $self->status->mk_flush;
363 =head2 $mod->package_name( [$package_string] )
365 Returns the name of the package a module is in. For C<Acme::Bleach>
366 that might be C<Acme-Bleach>.
368 =head2 $mod->package_version( [$package_string] )
370 Returns the version of the package a module is in. For a module
371 in the package C<Acme-Bleach-1.1.tar.gz> this would be C<1.1>.
373 =head2 $mod->package_extension( [$package_string] )
375 Returns the suffix added by the compression method of a package a
376 certain module is in. For a module in C<Acme-Bleach-1.1.tar.gz>, this
379 =head2 $mod->package_is_perl_core
381 Returns a boolean indicating of the package a particular module is in,
382 is actually a core perl distribution.
384 =head2 $mod->module_is_supplied_with_perl_core( [version => $]] )
386 Returns a boolean indicating whether C<ANY VERSION> of this module
387 was supplied with the current running perl's core package.
389 =head2 $mod->is_bundle
391 Returns a boolean indicating if the module you are looking at, is
392 actually a bundle. Bundles are identified as modules whose name starts
395 =head2 $mod->is_autobundle;
397 Returns a boolean indicating if the module you are looking at, is
398 actually an autobundle as generated by C<< $cb->autobundle >>.
400 =head2 $mod->is_third_party
402 Returns a boolean indicating whether the package is a known third-party
403 module (i.e. it's not provided by the standard Perl distribution and
404 is not available on the CPAN, but on a third party software provider).
405 See L<Module::ThirdParty> for more details.
407 =head2 $mod->third_party_information
409 Returns a reference to a hash with more information about a third-party
410 module. See the documentation about C<module_information()> in
411 L<Module::ThirdParty> for more details.
415 { ### fetches the test reports for a certain module ###
422 while ( my($type, $index) = each %map ) {
423 my $name = 'package_' . $type;
428 my $val = shift || $self->package;
429 my @res = $self->parent->_split_package_string( package => $val );
431 ### return the corresponding index from the result
432 return $res[$index] if @res;
437 sub package_is_perl_core {
439 my $cb = $self->parent;
441 ### check if the package looks like a perl core package
442 return 1 if $self->package_name eq PERL_CORE;
444 ### address #44562: ::Module->package_is_perl_code : problem comparing
445 ### version strings -- use $cb->_vcmp to avoid warnings when version
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
451 ### if the package is newer than installed, then it's dual-lifed
452 return if $cb->_vcmp($self->version, $self->installed_version) > 0;
454 ### if the package is newer or equal to the corelist,
455 ### then it's dual-lifed
456 return if $cb->_vcmp( $self->version, $core ) >= 0;
458 ### otherwise, it's older than corelist, thus unsuitable.
462 ### not in corelist, not a perl core package.
466 sub module_is_supplied_with_perl_core {
468 my $ver = shift || $];
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;
476 ### check Module::CoreList to see if it's a core package
477 require Module::CoreList;
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
483 my $core = $Module::CoreList::version{ 0+$ver }->{ $name };
488 ### make sure Bundle-Foo also gets flagged as bundle
493 return 1 if $self->module =~ /^bundle(?:-|::)/i;
496 return 1 if $self->is_autobundle;
502 ### full path to a generated autobundle
505 my $conf = $self->parent->configure_object;
506 my $prefix = $conf->_get_build('autobundle_prefix');
508 return 1 if $self->module eq $prefix;
515 return unless can_load( modules => { 'Module::ThirdParty' => 0 } );
517 return Module::ThirdParty::is_3rd_party( $self->name );
520 sub third_party_information {
523 return unless $self->is_third_party;
525 return Module::ThirdParty::module_information( $self->name );
531 =head2 $clone = $self->clone
533 Clones the current module object for tinkering with.
534 It will have a clean C<CPANPLUS::Module::Status> object, as well as
535 a fake C<CPANPLUS::Module::Author> object.
539 { ### accessors dont change during run time, so only compute once
540 my @acc = grep !/status/, __PACKAGE__->accessors();
545 ### clone the object ###
546 my %data = map { $_ => $self->$_ } @acc;
548 my $obj = CPANPLUS::Module::Fake->new( %data );
556 =head2 $where = $self->fetch
558 Fetches the module from a CPAN mirror.
559 Look at L<CPANPLUS::Internals::Fetch::_fetch()> for details on the
560 options you can pass.
566 my $cb = $self->parent;
569 my %args = ( module => $self );
571 ### if a custom fetch location got specified before, add that here
572 $args{fetch_from} = $self->status->_fetch_from
573 if $self->status->_fetch_from;
575 my $where = $cb->_fetch( @_, %args ) or return;
577 ### do an md5 check ###
578 if( !$self->status->_fetch_from and
579 $cb->configure_object->get_conf('md5') and
580 $self->package ne CHECKSUMS
582 unless( $self->_validate_checksum ) {
583 error( loc( "Checksum error for '%1' -- will not trust package",
594 =head2 $path = $self->extract
596 Extracts the fetched module.
597 Look at L<CPANPLUS::Internals::Extract::_extract()> for details on
598 the options you can pass.
604 my $cb = $self->parent;
606 unless( $self->status->fetch ) {
607 error( loc( "You have not fetched '%1' yet -- cannot extract",
612 ### can't extract these, so just use the basedir for the file
613 if( $self->is_autobundle ) {
615 ### this is expected to be set after an extract call
616 $self->get_installer_type;
618 return $self->status->extract( dirname( $self->status->fetch ) );
621 return $cb->_extract( @_, module => $self );
624 =head2 $type = $self->get_installer_type([prefer_makefile => BOOL])
626 Gets the installer type for this module. This may either be C<build> or
627 C<makemaker>. If C<Module::Build> is unavailable or no installer type
628 is available, it will fall back to C<makemaker>. If both are available,
629 it will pick the one indicated by your config, or by the
630 C<prefer_makefile> option you can pass to this function.
632 Returns the installer type on success, and false on error.
636 sub get_installer_type {
638 my $cb = $self->parent;
639 my $conf = $cb->configure_object;
642 my ($prefer_makefile,$verbose);
644 prefer_makefile => { default => $conf->get_conf('prefer_makefile'),
645 store => \$prefer_makefile, allow => BOOLEANS },
646 verbose => { default => $conf->get_conf('verbose'),
647 store => \$verbose },
650 check( $tmpl, \%hash ) or return;
654 ### autobundles use their own installer, so return that
655 if( $self->is_autobundle ) {
656 $type = INSTALLER_AUTOBUNDLE;
659 my $extract = $self->status->extract();
662 "Cannot determine installer type of unextracted module '%1'",
668 ### check if it's a makemaker or a module::build type dist ###
669 my $found_build = -e BUILD_PL->( $extract );
670 my $found_makefile = -e MAKEFILE_PL->( $extract );
672 $type = INSTALLER_BUILD if !$prefer_makefile && $found_build;
673 $type = INSTALLER_BUILD if $found_build && !$found_makefile;
674 $type = INSTALLER_MM if $prefer_makefile && $found_makefile;
675 $type = INSTALLER_MM if $found_makefile && !$found_build;
678 ### ok, so it's a 'build' installer, but you don't /have/ module build
679 if( $type eq INSTALLER_BUILD and
680 not CPANPLUS::Dist->has_dist_type( INSTALLER_BUILD )
683 ### XXX this is for recording purposes only. We *have* to install
684 ### these before even creating a dist object, or we'll get an error
685 ### saying 'no such dist type';
686 my $href = $self->status->configure_requires || {};
687 my $deps = { INSTALLER_BUILD, 0, %$href };
689 $self->status->configure_requires( $deps );
691 msg(loc("This module requires '%1' and '%2' to be installed first. ".
692 "Adding these modules to your prerequisites list",
693 'Module::Build', INSTALLER_BUILD
697 ### ok, actually we found neither ###
699 error( loc( "Unable to find '%1' or '%2' for '%3'; ".
700 "Will default to '%4' but might be unable ".
701 "to install!", BUILD_PL->(), MAKEFILE_PL->(),
702 $self->module, INSTALLER_MM ) );
703 $type = INSTALLER_MM;
706 return $self->status->installer_type( $type ) if $type;
712 =head2 $dist = $self->dist([target => 'prepare|create', format => DISTRIBUTION_TYPE, args => {key => val}]);
714 Create a distribution object, ready to be installed.
715 Distribution type defaults to your config settings
717 The optional C<args> hashref is passed on to the specific distribution
718 types' C<create> method after being dereferenced.
720 Returns a distribution object on success, false on failure.
722 See C<CPANPLUS::Dist> for details.
728 my $cb = $self->parent;
729 my $conf = $cb->configure_object;
732 ### have you determined your installer type yet? if not, do it here,
734 $self->get_installer_type unless $self->status->installer_type;
736 my($type,$args,$target);
738 format => { default => $conf->get_conf('dist_type') ||
739 $self->status->installer_type,
741 target => { default => TARGET_CREATE, store => \$target },
742 args => { default => {}, store => \$args },
745 check( $tmpl, \%hash ) or return;
747 ### ok, check for $type. Do we have it?
748 unless( CPANPLUS::Dist->has_dist_type( $type ) ) {
750 ### ok, we don't have it. Is it C::D::Build? if so we can install the
752 ### XXX we _could_ do this for any type we dont have actually...
753 if( $type eq INSTALLER_BUILD ) {
754 msg(loc("Bootstrapping installer '%1'", $type));
756 ### don't propagate the format, it's the one we're trying to
757 ### bootstrap, so it'll be an infinite loop if we do
759 $cb->module_tree( $type )->install( target => $target, %$args ) or
761 error(loc("Could not bootstrap installer '%1' -- ".
762 "can not continue", $type));
766 ### re-scan for available modules now
767 CPANPLUS::Dist->rescan_dist_types;
769 unless( CPANPLUS::Dist->has_dist_type( $type ) ) {
770 error(loc("Newly installed installer type '%1' should be ".
771 "available, but is not! -- aborting", $type));
774 msg(loc("Installer '%1' succesfully bootstrapped", $type));
777 ### some other plugin you dont have. Abort
779 error(loc("Installer type '%1' not found. Please verify your ".
780 "installation -- aborting", $type ));
785 ### make sure we don't overwrite it, just in case we came
786 ### back from a ->save_state. This allows restoration to
788 my( $dist, $dist_cpan );
790 unless( $dist = $self->status->dist ) {
791 $dist = $type->new( module => $self ) or return;
792 $self->status->dist( $dist );
795 unless( $dist_cpan = $self->status->dist_cpan ) {
797 $dist_cpan = $type eq $self->status->installer_type
798 ? $self->status->dist
799 : $self->status->installer_type->new( module => $self );
802 $self->status->dist_cpan( $dist_cpan );
807 ### first prepare the dist
808 $dist->prepare( %$args ) or return;
809 $self->status->prepared(1);
811 ### you just wanted us to prepare?
812 last DIST if $target eq TARGET_PREPARE;
814 $dist->create( %$args ) or return;
815 $self->status->created(1);
823 =head2 $bool = $mod->prepare( )
825 Convenience method around C<install()> that prepares a module
826 without actually building it. This is equivalent to invoking C<install>
827 with C<target> set to C<prepare>
829 Returns true on success, false on failure.
835 return $self->install( @_, target => TARGET_PREPARE );
838 =head2 $bool = $mod->create( )
840 Convenience method around C<install()> that creates a module.
841 This is equivalent to invoking C<install> with C<target> set to
844 Returns true on success, false on failure.
850 return $self->install( @_, target => TARGET_CREATE );
853 =head2 $bool = $mod->test( )
855 Convenience wrapper around C<install()> that tests a module, without
857 It's the equivalent to invoking C<install()> with C<target> set to
858 C<create> and C<skiptest> set to C<0>.
860 Returns true on success, false on failure.
866 return $self->install( @_, target => TARGET_CREATE, skiptest => 0 );
871 =head2 $bool = $self->install([ target => 'prepare|create|install', format => FORMAT_TYPE, extractdir => DIRECTORY, fetchdir => DIRECTORY, prefer_bin => BOOL, force => BOOL, verbose => BOOL, ..... ]);
873 Installs the current module. This includes fetching it and extracting
874 it, if this hasn't been done yet, as well as creating a distribution
877 This means you can pass it more arguments than described above, which
878 will be passed on to the relevant methods as they are called.
880 See C<CPANPLUS::Internals::Fetch>, C<CPANPLUS::Internals::Extract> and
881 C<CPANPLUS::Dist> for details.
883 Returns true on success, false on failure.
889 my $cb = $self->parent;
890 my $conf = $cb->configure_object;
893 my $args; my $target; my $format;
894 { ### so we can use the rest of the args to the create calls etc ###
895 local $Params::Check::NO_DUPLICATES = 1;
896 local $Params::Check::ALLOW_UNKNOWN = 1;
898 ### targets 'dist' and 'test' are now completely ignored ###
900 ### match this allow list with Dist->_resolve_prereqs
901 target => { default => TARGET_INSTALL, store => \$target,
902 allow => [TARGET_PREPARE, TARGET_CREATE,
904 force => { default => $conf->get_conf('force'), },
905 verbose => { default => $conf->get_conf('verbose'), },
906 format => { default => $conf->get_conf('dist_type'),
910 $args = check( $tmpl, \%hash ) or return;
914 ### if this target isn't 'install', we will need to at least 'create'
915 ### every prereq, so it can build
916 ### XXX prereq_target of 'prepare' will do weird things here, and is
918 $args->{'prereq_target'} ||= TARGET_CREATE if $target ne TARGET_INSTALL;
920 ### check if it's already upto date ###
921 if( $target eq TARGET_INSTALL and !$args->{'force'} and
922 !$self->package_is_perl_core() and # separate rules apply
923 ( $self->status->installed() or $self->is_uptodate ) and
924 !INSTALL_VIA_PACKAGE_MANAGER->($format)
926 msg(loc("Module '%1' already up to date, won't install without force",
927 $self->module), $args->{'verbose'} );
928 return $self->status->installed(1);
931 # if it's a non-installable core package, abort the install.
932 if( $self->package_is_perl_core() ) {
933 # if the installed is newer, say so.
934 if( $self->installed_version > $self->version ) {
935 error(loc("The core Perl %1 module '%2' (%3) is more ".
936 "recent than the latest release on CPAN (%4). ".
938 $], $self->module, $self->installed_version,
940 # if the installed matches, say so.
941 } elsif( $self->installed_version == $self->version ) {
942 error(loc("The core Perl %1 module '%2' (%3) can only ".
943 "be installed by Perl itself. ".
945 $], $self->module, $self->installed_version ) );
946 # otherwise, the installed is older; say so.
948 error(loc("The core Perl %1 module '%2' can only be ".
949 "upgraded from %3 to %4 by Perl itself (%5). ".
951 $], $self->module, $self->installed_version,
952 $self->version, $self->package ) );
956 ### it might be a known 3rd party module
957 } elsif ( $self->is_third_party ) {
958 my $info = $self->third_party_information;
960 "%1 is a known third-party module.\n\n".
961 "As it isn't available on the CPAN, CPANPLUS can't install " .
962 "it automatically. Therefore you need to install it manually " .
963 "before proceeding.\n\n".
964 "%2 is part of %3, published by %4, and should be available ".
965 "for download at the following address:\n\t%5",
966 $self->name, $self->name, $info->{name}, $info->{author},
973 ### fetch it if need be ###
974 unless( $self->status->fetch ) {
976 for (qw[prefer_bin fetchdir]) {
977 $params->{$_} = $args->{$_} if exists $args->{$_};
979 for (qw[force verbose]) {
980 $params->{$_} = $args->{$_} if defined $args->{$_};
982 $self->fetch( %$params ) or return;
985 ### extract it if need be ###
986 unless( $self->status->extract ) {
988 for (qw[prefer_bin extractdir]) {
989 $params->{$_} = $args->{$_} if exists $args->{$_};
991 for (qw[force verbose]) {
992 $params->{$_} = $args->{$_} if defined $args->{$_};
994 $self->extract( %$params ) or return;
997 $format ||= $self->status->installer_type;
1000 error( loc( "Don't know what installer to use; " .
1001 "Couldn't find either '%1' or '%2' in the extraction " .
1002 "directory '%3' -- will be unable to install",
1003 BUILD_PL->(), MAKEFILE_PL->(), $self->status->extract ) );
1005 $self->status->installed(0);
1010 ### do SIGNATURE checks? ###
1011 ### XXX check status and not recheck EVERY time?
1012 if( $conf->get_conf('signature') ) {
1013 unless( $self->check_signature( verbose => $args->{verbose} ) ) {
1014 error( loc( "Signature check failed for module '%1' ".
1015 "-- Not trusting this module, aborting install",
1017 $self->status->signature(0);
1019 ### send out test report on broken sig
1020 if( $conf->get_conf('cpantest') ) {
1024 buffer => CPANPLUS::Error->stack_as_string,
1025 verbose => $args->{verbose},
1026 force => $args->{force},
1027 ) or error(loc("Failed to send test report for '%1'",
1034 ### signature OK ###
1035 $self->status->signature(1);
1039 ### a target of 'create' basically means not to run make test ###
1040 ### eh, no it /doesn't/.. skiptest => 1 means skiptest => 1.
1041 #$args->{'skiptest'} = 1 if $target eq 'create';
1043 ### bundle rules apply ###
1044 if( $self->is_bundle ) {
1045 ### check what we need to install ###
1046 my @prereqs = $self->bundle_modules();
1047 unless( @prereqs ) {
1048 error( loc( "Bundle '%1' does not specify any modules to install",
1051 ### XXX mark an error here? ###
1055 my $dist = $self->dist( format => $format,
1059 error( loc( "Unable to create a new distribution object for '%1' " .
1060 "-- cannot continue", $self->module ) );
1064 return 1 if $target ne TARGET_INSTALL;
1066 my $ok = $dist->install( %$args ) ? 1 : 0;
1068 $self->status->installed($ok);
1074 =pod @list = $self->bundle_modules()
1076 Returns a list of module objects the Bundle specifies.
1078 This requires you to have extracted the bundle already, using the
1079 C<extract()> method.
1081 Returns false on error.
1085 sub bundle_modules {
1087 my $cb = $self->parent;
1089 unless( $self->is_bundle ) {
1090 error( loc("'%1' is not a bundle", $self->module ) );
1096 ### autobundles are special files generated by CPANPLUS. If we can
1097 ### read the file, we can determine the prereqs
1098 if( $self->is_autobundle ) {
1100 unless( $where = $self->status->fetch ) {
1101 error(loc("Don't know where '%1' was fetched to", $self->package));
1107 ### regular bundle::* upload
1110 unless( $dir = $self->status->extract ) {
1111 error(loc("Don't know where '%1' was extracted to", $self->module));
1116 wanted => sub { push @files, File::Spec->rel2abs($_) if /\.pm/i },
1121 my $prereqs = {}; my @list; my $seen = {};
1122 for my $file ( @files ) {
1123 my $fh = FileHandle->new($file)
1124 or( error(loc("Could not open '%1' for reading: %2",
1128 while( local $_ = <$fh> ) {
1129 ### quick hack to read past the header of the file ###
1130 last if $flag && m|^=head|i;
1132 ### from perldoc cpan:
1134 ### In this pod section each line obeys the format
1135 ### Module_Name [Version_String] [- optional text]
1136 $flag = 1 if m|^=head1 CONTENTS|i;
1138 if ($flag && /^(?!=)(\S+)\s*(\S+)?/) {
1140 my $version = $cb->_version_to_number( version => $2 );
1142 my $obj = $cb->module_tree($module);
1145 error(loc("Cannot find bundled module '%1'", $module),
1146 loc("-- it does not seem to exist") );
1150 ### make sure we list no duplicates ###
1151 unless( $seen->{ $obj->module }++ ) {
1153 $prereqs->{ $module } =
1154 $cb->_version_to_number( version => $version );
1160 ### store the prereqs we just found ###
1161 $self->status->prereqs( $prereqs );
1168 =head2 $text = $self->readme
1170 Fetches the readme belonging to this module and stores it under
1171 C<< $obj->status->readme >>. Returns the readme as a string on
1172 success and returns false on failure.
1178 my $conf = $self->parent->configure_object;
1180 ### did we already dl the readme once? ###
1181 return $self->status->readme() if $self->status->readme();
1183 ### this should be core ###
1184 return unless can_load( modules => { FileHandle => '0.0' },
1188 ### get a clone of the current object, with a fresh status ###
1189 my $obj = $self->clone or return;
1191 ### munge the package name
1192 my $pkg = README->( $obj );
1193 $obj->package($pkg);
1196 { ### disable checksum fetches on readme downloads
1198 my $tmp = $conf->get_conf( 'md5' );
1199 $conf->set_conf( md5 => 0 );
1201 $file = $obj->fetch;
1203 $conf->set_conf( md5 => $tmp );
1205 return unless $file;
1208 ### read the file into a scalar, to store in the original object ###
1209 my $fh = new FileHandle;
1210 unless( $fh->open($file) ) {
1211 error( loc( "Could not open file '%1': %2", $file, $! ) );
1215 my $in = do{ local $/; <$fh> };
1218 return $self->status->readme( $in );
1223 =head2 $version = $self->installed_version()
1225 Returns the currently installed version of this module, if any.
1227 =head2 $where = $self->installed_file()
1229 Returns the location of the currently installed file of this module,
1232 =head2 $dir = $self->installed_dir()
1234 Returns the directory (or more accurately, the C<@INC> handle) from
1235 which this module was loaded, if any.
1237 =head2 $bool = $self->is_uptodate([version => VERSION_NUMBER])
1239 Returns a boolean indicating if this module is uptodate or not.
1243 ### uptodate/installed functions
1244 { my $map = { # hashkey, alternate rv
1245 installed_version => ['version', 0 ],
1246 installed_file => ['file', ''],
1247 installed_dir => ['dir', ''],
1248 is_uptodate => ['uptodate', 0 ],
1251 while( my($method, $aref) = each %$map ) {
1252 my($key,$alt_rv) = @$aref;
1256 ### never use the @INC hooks to find installed versions of
1257 ### modules -- they're just there in case they're not on the
1258 ### perl install, but the user shouldn't trust them for *other*
1260 ### XXX CPANPLUS::inc is now obsolete, so this should not
1261 ### be needed anymore
1262 #local @INC = CPANPLUS::inc->original_inc;
1266 ### make sure check_install is not looking in %INC, as
1267 ### that may contain some of our sneakily loaded modules
1268 ### that aren't installed as such. -- kane
1269 local $Module::Load::Conditional::CHECK_INC_HASH = 0;
1270 my $href = check_install(
1271 module => $self->module,
1272 version => $self->version,
1276 return $href->{$key} || $alt_rv;
1285 =head2 $href = $self->details()
1287 Returns a hashref with key/value pairs offering more information about
1288 a particular module. For example, for C<Time::HiRes> it might look like
1291 Author Jarkko Hietaniemi (jhi@iki.fi)
1292 Description High resolution time, sleep, and alarm
1293 Development Stage Released
1294 Installed File /usr/local/perl/lib/Time/Hires.pm
1295 Interface Style plain Functions, no references used
1296 Language Used C and perl, a C compiler will be needed
1297 Package Time-HiRes-1.65.tar.gz
1298 Public License Unknown
1299 Support Level Developer
1300 Version Installed 1.52
1301 Version on CPAN 1.65
1307 my $conf = $self->parent->configure_object();
1308 my $cb = $self->parent;
1312 Author => loc("%1 (%2)", $self->author->author(),
1313 $self->author->email() ),
1314 Package => $self->package,
1315 Description => $self->description || loc('None given'),
1316 'Version on CPAN' => $self->version,
1319 ### check if we have the module installed
1320 ### if so, add version have and version on cpan
1321 $res->{'Version Installed'} = $self->installed_version
1322 if $self->installed_version;
1323 $res->{'Installed File'} = $self->installed_file if $self->installed_file;
1326 for my $item( split '', $self->dslip ) {
1327 $res->{ $cb->_dslip_defs->[$i]->[0] } =
1328 $cb->_dslip_defs->[$i]->[1]->{$item} || loc('Unknown');
1335 =head2 @list = $self->contains()
1337 Returns a list of module objects that represent the modules also
1338 present in the package of this module.
1340 For example, for C<Archive::Tar> this might return:
1343 Archive::Tar::Constant
1350 my $cb = $self->parent;
1351 my $pkg = $self->package;
1353 my @mods = $cb->search( type => 'package', allow => [qr/^$pkg$/] );
1360 =head2 @list_of_hrefs = $self->fetch_report()
1362 This function queries the CPAN testers database at
1363 I<http://testers.cpan.org/> for test results of specified module
1364 objects, module names or distributions.
1366 Look at L<CPANPLUS::Internals::Report::_query_report()> for details on
1367 the options you can pass and the return value to expect.
1373 my $cb = $self->parent;
1375 return $cb->_query_report( @_, module => $self );
1380 =head2 $bool = $self->uninstall([type => [all|man|prog])
1382 This function uninstalls the specified module object.
1384 You can install 2 types of files, either C<man> pages or C<prog>ram
1385 files. Alternately you can specify C<all> to uninstall both (which
1388 Returns true on success and false on failure.
1390 Do note that this does an uninstall via the so-called C<.packlist>,
1391 so if you used a module installer like say, C<ports> or C<apt>, you
1392 should not use this, but use your package manager instead.
1398 my $conf = $self->parent->configure_object();
1401 my ($type,$verbose);
1403 type => { default => 'all', allow => [qw|man prog all|],
1405 verbose => { default => $conf->get_conf('verbose'),
1406 store => \$verbose },
1407 force => { default => $conf->get_conf('force') },
1410 ### XXX add a warning here if your default install dist isn't
1411 ### makefile or build -- that means you are using a package manager
1412 ### and this will not do what you think!
1414 my $args = check( $tmpl, \%hash ) or return;
1416 if( $conf->get_conf('dist_type') and (
1417 ($conf->get_conf('dist_type') ne INSTALLER_BUILD) or
1418 ($conf->get_conf('dist_type') ne INSTALLER_MM))
1420 msg(loc("You have a default installer type set (%1) ".
1421 "-- you should probably use that package manager to " .
1422 "uninstall modules", $conf->get_conf('dist_type')), $verbose);
1425 ### check if we even have the module installed -- no point in continuing
1427 unless( $self->installed_version ) {
1428 error( loc( "Module '%1' is not installed, so cannot uninstall",
1433 ### nothing to uninstall ###
1434 my $files = $self->files( type => $type ) or return;
1435 my $dirs = $self->directory_tree( type => $type ) or return;
1436 my $sudo = $conf->get_program('sudo');
1438 ### just in case there's no file; M::B doensn't provide .packlists yet ###
1439 my $pack = $self->packlist;
1440 $pack = $pack->[0]->packlist_file() if $pack;
1442 ### first remove the files, then the dirs if they are empty ###
1444 for my $file( @$files, $pack ) {
1445 next unless defined $file && -f $file;
1447 msg(loc("Unlinking '%1'", $file), $verbose);
1449 my @cmd = ($^X, "-eunlink+q[$file]");
1450 unshift @cmd, $sudo if $sudo;
1453 unless ( run( command => \@cmd,
1454 verbose => $verbose,
1455 buffer => \$buffer )
1457 error(loc("Failed to unlink '%1': '%2'",$file, $buffer));
1462 for my $dir ( sort @$dirs ) {
1464 opendir DIR, $dir or next;
1465 my @count = readdir(DIR);
1468 next unless @count == 2; # . and ..
1470 msg(loc("Removing '%1'", $dir), $verbose);
1472 ### this fails on my win2k machines.. it indeed leaves the
1473 ### dir, but it's not a critical error, since the files have
1474 ### been removed. --kane
1475 #unless( rmdir $dir ) {
1476 # error( loc( "Could not remove '%1': %2", $dir, $! ) )
1477 # unless $^O eq 'MSWin32';
1480 my @cmd = ($^X, "-e", "rmdir q[$dir]");
1481 unshift @cmd, $sudo if $sudo;
1484 unless ( run( command => \@cmd,
1485 verbose => $verbose,
1486 buffer => \$buffer )
1488 error(loc("Failed to rmdir '%1': %2",$dir,$buffer));
1493 $self->status->uninstall(!$flag);
1494 $self->status->installed( $flag ? 1 : undef);
1501 =head2 @modobj = $self->distributions()
1503 Returns a list of module objects representing all releases for this
1504 module on success, false on failure.
1512 my @list = $self->author->distributions( %hash, module => $self ) or return;
1514 ### it's another release then by the same author ###
1515 return grep { $_->package_name eq $self->package_name } @list;
1520 =head2 @list = $self->files ()
1522 Returns a list of files used by this module, if it is installed.
1524 =head2 @list = $self->directory_tree ()
1526 Returns a list of directories used by this module.
1528 =head2 @list = $self->packlist ()
1530 Returns the C<ExtUtils::Packlist> object for this module.
1532 =head2 @list = $self->validate ()
1534 Returns a list of files that are missing for this modules, but
1535 are present in the .packlist file.
1539 for my $sub (qw[files directory_tree packlist validate]) {
1542 return shift->_extutils_installed( @_, method => $sub );
1546 ### generic method to call an ExtUtils::Installed method ###
1547 sub _extutils_installed {
1549 my $cb = $self->parent;
1550 my $conf = $cb->configure_object;
1551 my $home = $cb->_home_dir; # may be needed to fix up prefixes
1554 my ($verbose,$type,$method);
1556 verbose => { default => $conf->get_conf('verbose'),
1557 store => \$verbose, },
1558 type => { default => 'all',
1559 allow => [qw|prog man all|],
1561 method => { required => 1,
1563 allow => [qw|files directory_tree packlist
1568 my $args = check( $tmpl, \%hash ) or return;
1570 ### old versions of cygwin + perl < 5.8 are buggy here. bail out if we
1571 ### find we're being used by them
1572 { my $err = ON_OLD_CYGWIN;
1573 if($err) { error($err); return };
1576 return unless can_load(
1577 modules => { 'ExtUtils::Installed' => '0.0' },
1578 verbose => $verbose,
1581 my @config_names = (
1583 { lib => 'privlib', # perl-only
1584 arch => 'archlib', # compiled code
1585 prefix => 'prefix', # prefix to both
1590 prefix => 'siteprefix',
1593 { lib => 'vendorlib',
1594 arch => 'vendorarch',
1595 prefix => 'vendorprefix',
1599 ### search in your regular @INC, and anything you added to your config.
1600 ### this lets EU::Installed find .packlists that are *not* in the standard
1601 ### compiled in @INC path. Requires EU::I 1.42 or up. this addresses #33438
1602 ### make sure the archname path is also added, as that's where the .packlist
1603 ### files are written
1605 for my $lib ( @{ $conf->get_conf('lib') } ) {
1608 ### and just the standard dir
1611 ### figure out what an MM prefix expands to. Basically, it's the
1612 ### site install target from %Config, ie: /opt/lib/perl5/site_perl/5.8.8
1613 ### minus the site wide prefix, ie: /opt
1614 ### this lets users add the dir they have set as their EU::MM PREFIX
1615 ### to our 'lib' config and it Just Works
1616 ### the arch specific dir, ie:
1617 ### /opt/lib/perl5/site_perl/5.8.8/darwin-2level
1618 ### XXX is this the right thing to do?
1620 ### we add all 6 dir combos for prefixes:
1624 ### /foo/site/lib/arch
1626 ### /foo/vendor/lib/arch
1627 for my $href ( @config_names ) {
1628 for my $key ( qw[lib arch] ) {
1630 ### look up the config value -- use EXP for the EXPANDED
1631 ### version, so no ~ etc are found in there
1632 my $dir = $Config::Config{ $href->{ $key } .'exp' } or next;
1633 my $prefix = $Config::Config{ $href->{prefix} };
1635 ### prefix may be relative to home, and contain a ~
1636 ### if so, fix it up.
1637 $prefix =~ s/^~/$home/;
1639 ### remove the prefix from it, so we can append to our $lib
1640 $dir =~ s/^\Q$prefix\E//;
1642 ### do the appending
1643 push @libs, File::Spec->catdir( $lib, $dir );
1650 unless( $inst = ExtUtils::Installed->new( extra_libs => \@libs ) ) {
1651 error( loc("Could not create an '%1' object", 'ExtUtils::Installed' ) );
1653 ### in case it's being used directly... ###
1658 { ### EU::Installed can die =/
1660 eval { @files = $inst->$method( $self->module, $type ) };
1664 error( loc("Could not get '%1' for '%2': %3",
1665 $method, $self->module, $@ ) );
1669 return wantarray ? @files : \@files;
1673 =head2 $bool = $self->add_to_includepath;
1675 Adds the current modules path to C<@INC> and C<$PERL5LIB>. This allows
1676 you to add the module from its build dir to your path.
1678 You can reset C<@INC> and C<$PERL5LIB> to its original state when you
1679 started the program, by calling:
1681 $self->parent->flush('lib');
1685 sub add_to_includepath {
1687 my $cb = $self->parent;
1689 if( my $dir = $self->status->extract ) {
1691 $cb->_add_to_includepath(
1693 File::Spec->catdir(BLIB->($dir), LIB),
1694 File::Spec->catdir(BLIB->($dir), ARCH),
1700 error(loc( "No extract dir registered for '%1' -- can not add ".
1701 "add builddir to search path!", $self->module ));
1711 =head2 $path = $self->best_path_to_module_build();
1715 If a newer version of Module::Build is found in your path, it will
1716 return this C<special> path. If the newest version of C<Module::Build>
1717 is found in your regular C<@INC>, the method will return false. This
1718 indicates you do not need to add a special directory to your C<@INC>.
1720 Note that this is only relevant if you're building your own
1721 C<CPANPLUS::Dist::*> plugin -- the built-in dist types already have
1726 ### make sure we're always running 'perl Build.PL' and friends
1727 ### against the highest version of module::build available
1728 sub best_path_to_module_build {
1731 ### Since M::B will actually shell out and run the Build.PL, we must
1732 ### make sure it refinds the proper version of M::B in the path.
1733 ### that may be either in our cp::inc or in site_perl, or even a
1734 ### new M::B being installed.
1735 ### don't add anything else here, as that might screw up prereq checks
1737 ### XXX this might be needed for Dist::MM too, if a makefile.pl is
1738 ### masquerading as a Build.PL
1740 ### did we find the most recent module::build in our installer path?
1742 ### XXX can't do changes to @INC, they're being ignored by
1743 ### new_from_context when writing a Build script. see ticket:
1744 ### #8826 Module::Build ignores changes to @INC when writing Build
1745 ### from new_from_context
1746 ### XXX applied schwern's patches (as seen on CPANPLUS::Devel 10/12/04)
1747 ### and upped the version to 0.26061 of the bundled version, and things
1750 ### this functionality is now obsolete -- prereqs should be installed
1751 ### and we no longer use the CPANPLUS::inc magic.. so comment this out.
1752 # require Module::Build;
1753 # if( CPANPLUS::inc->path_to('Module::Build') and (
1754 # CPANPLUS::inc->path_to('Module::Build') eq
1755 # CPANPLUS::inc->installer_path )
1758 # ### if the module being installed is *not* Module::Build
1759 # ### itself -- as that would undoubtedly be newer -- add
1760 # ### the path to the installers to @INC
1761 # ### if it IS module::build itself, add 'lib' to its path,
1762 # ### as the Build.PL would do as well, but the API doesn't.
1763 # ### this makes self updates possible
1764 # return $self->module eq 'Module::Build'
1766 # : CPANPLUS::inc->installer_path;
1769 ### otherwise, the path was found through a 'normal' way of
1778 Please report bugs or other issues to E<lt>bug-cpanplus@rt.cpan.org<gt>.
1782 This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
1786 The CPAN++ interface (of which this module is a part of) is copyright (c)
1787 2001 - 2007, Jos Boumans E<lt>kane@cpan.orgE<gt>. All rights reserved.
1789 This library is free software; you may redistribute and/or modify it
1790 under the same terms as Perl itself.
1795 # c-indentation-style: bsd
1797 # indent-tabs-mode: nil
1799 # vim: expandtab shiftwidth=4: