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 Module::Load::Conditional qw[can_load check_install];
21 $Params::Check::VERBOSE = 1;
23 @ISA = qw[ CPANPLUS::Module::Signature CPANPLUS::Module::Checksums];
33 ### get a module object from the CPANPLUS::Backend object
34 my $mod = $cb->module_tree('Some::Module');
48 C<CPANPLUS::Module> creates objects from the information in the
49 source files. These can then be used to query and perform actions
50 on, like fetching or installing.
52 These objects should only be created internally. For C<fake> objects,
53 there's the C<CPANPLUS::Module::Fake> class. To obtain a module object
54 consult the C<CPANPLUS::Backend> documentation.
59 module => { default => '', required => 1 }, # full module name
60 version => { default => '0.0' }, # version number
61 path => { default => '', required => 1 }, # extended path on the
63 # /author/id/K/KA/KANE
64 comment => { default => ''}, # comment on module
65 package => { default => '', required => 1 }, # package name, like
67 description => { default => '' }, # description of the
69 dslip => { default => EMPTY_DSLIP }, # dslip information
70 _id => { required => 1 }, # id of the Internals
72 _status => { no_override => 1 }, # stores status object
73 author => { default => '', required => 1,
74 allow => IS_AUTHOBJ }, # module author
75 mtime => { default => '' },
78 ### some of these will be resolved by wrapper functions that
79 ### do Clever Things to find the actual value, so don't create
80 ### an autogenerated sub for that just here, take an alternate
81 ### name to allow for a wrapper
86 ### autogenerate accessors ###
87 for my $key ( keys %$tmpl ) {
90 my $sub = $rename{$key} || $key;
92 *{__PACKAGE__."::$sub"} = sub {
93 $_[0]->{$key} = $_[1] if @_ > 1;
106 Returns a list of all accessor methods to the object
110 ### *name is an alias, include it explicitly
111 sub accessors { return ('name', keys %$tmpl) };
115 An objects of this class has the following accessors:
129 Version of the module. Defaults to '0.0' if none was provided.
133 Extended path on the mirror.
137 Any comment about the module -- largely unused.
141 The name of the package.
145 Description of the module -- only registered modules have this.
149 The five character dslip string, that represents meta-data of the
150 module -- again, only registered modules have this.
157 ### if this module has relevant dslip info, return it
158 return $self->_dslip if $self->_dslip ne EMPTY_DSLIP;
160 ### if not, look at other modules in the same package,
161 ### see if *they* have any dslip info
162 for my $mod ( $self->contains ) {
163 return $mod->_dslip if $mod->_dslip ne EMPTY_DSLIP;
166 ### ok, really no dslip info found, return the default
175 The C<CPANPLUS::Module::Status> object associated with this object.
180 The C<CPANPLUS::Module::Author> object associated with this object.
184 The C<CPANPLUS::Internals> object that spawned this module object.
190 ### Alias ->name to ->module, for human beings.
195 my $obj = CPANPLUS::Internals->_retrieve_id( $self->_id );
200 =head1 STATUS ACCESSORS
202 C<CPANPLUS> caches a lot of results from method calls and saves data
203 it collected along the road for later reuse.
205 C<CPANPLUS> uses this internally, but it is also available for the end
206 user. You can get a status object by calling:
210 You can then query the object as follows:
216 The installer type used for this distribution. Will be one of
217 'makemaker' or 'build'. This determines whether C<CPANPLUS::Dist::MM>
218 or C<CPANPLUS::Dist::Build> will be used to build this distribution.
222 The dist object used to do the CPAN-side of the installation. Either
223 a C<CPANPLUS::Dist::MM> or C<CPANPLUS::Dist::Build> object.
227 The custom dist object used to do the operating specific side of the
228 installation, if you've chosen to use this. For example, if you've
229 chosen to install using the C<ports> format, this may be a
230 C<CPANPLUS::Dist::Ports> object.
232 Undefined if you didn't specify a separate format to install through.
236 A hashref of prereqs this distribution was found to have. Will look
239 { Carp => 0.01, strict => 0 }
241 Might be undefined if the distribution didn't have any prerequisites.
245 Flag indicating, if a signature check was done, whether it was OK or
250 The directory this distribution was extracted to.
254 The location this distribution was fetched to.
258 The text of this distributions README file.
262 Flag indicating if an uninstall call was done successfully.
266 Flag indicating if the C<create> call to your dist object was done
271 Flag indicating if the C<install> call to your dist object was done
276 The location of this distributions CHECKSUMS file.
280 Flag indicating if the checksums check was done successfully.
284 The checksum value this distribution is expected to have
290 =head2 $self = CPANPLUS::Module::new( OPTIONS )
292 This method returns a C<CPANPLUS::Module> object. Normal users
293 should never call this method directly, but instead use the
294 C<CPANPLUS::Backend> to obtain module objects.
296 This example illustrates a C<new()> call with all required arguments:
298 CPANPLUS::Module->new(
300 path => 'authors/id/A/AA/AAA',
301 package => 'Foo-1.0.tgz',
302 author => $author_object,
303 _id => INTERNALS_OBJECT_ID,
306 Every accessor is also a valid option to pass to C<new>.
308 Returns a module object on success and false on failure.
314 my($class, %hash) = @_;
316 ### don't check the template for sanity
317 ### -- we know it's good and saves a lot of performance
318 local $Params::Check::SANITY_CHECK_TEMPLATE = 0;
320 my $object = check( $tmpl, \%hash ) or return;
322 bless $object, $class;
327 ### only create status objects when they're actually asked for
330 return $self->_status if $self->_status;
332 my $acc = Object::Accessor->new;
333 $acc->mk_accessors( qw[ installer_type dist_cpan dist prereqs
334 signature extract fetch readme uninstall
335 created installed prepared checksums files
336 checksum_ok checksum_value _fetch_from] );
338 $self->_status( $acc );
340 return $self->_status;
344 ### flush the cache of this object ###
347 $self->status->mk_flush;
351 =head2 $mod->package_name
353 Returns the name of the package a module is in. For C<Acme::Bleach>
354 that might be C<Acme-Bleach>.
356 =head2 $mod->package_version
358 Returns the version of the package a module is in. For a module
359 in the package C<Acme-Bleach-1.1.tar.gz> this would be C<1.1>.
361 =head2 $mod->package_extension
363 Returns the suffix added by the compression method of a package a
364 certain module is in. For a module in C<Acme-Bleach-1.1.tar.gz>, this
367 =head2 $mod->package_is_perl_core
369 Returns a boolean indicating of the package a particular module is in,
370 is actually a core perl distribution.
372 =head2 $mod->module_is_supplied_with_perl_core( [version => $]] )
374 Returns a boolean indicating whether C<ANY VERSION> of this module
375 was supplied with the current running perl's core package.
377 =head2 $mod->is_bundle
379 Returns a boolean indicating if the module you are looking at, is
380 actually a bundle. Bundles are identified as modules whose name starts
383 =head2 $mod->is_third_party
385 Returns a boolean indicating whether the package is a known third-party
386 module (i.e. it's not provided by the standard Perl distribution and
387 is not available on the CPAN, but on a third party software provider).
388 See L<Module::ThirdParty> for more details.
390 =head2 $mod->third_party_information
392 Returns a reference to a hash with more information about a third-party
393 module. See the documentation about C<module_information()> in
394 L<Module::ThirdParty> for more details.
398 { ### fetches the test reports for a certain module ###
405 while ( my($type, $index) = each %map ) {
406 my $name = 'package_' . $type;
411 my @res = $self->parent->_split_package_string(
412 package => $self->package
415 ### return the corresponding index from the result
416 return $res[$index] if @res;
421 sub package_is_perl_core {
424 ### check if the package looks like a perl core package
425 return 1 if $self->package_name eq PERL_CORE;
427 my $core = $self->module_is_supplied_with_perl_core;
428 ### ok, so it's found in the core, BUT it could be dual-lifed
430 ### if the package is newer than installed, then it's dual-lifed
431 return if $self->version > $self->installed_version;
433 ### if the package is newer or equal to the corelist,
434 ### then it's dual-lifed
435 return if $self->version >= $core;
437 ### otherwise, it's older than corelist, thus unsuitable.
441 ### not in corelist, not a perl core package.
445 sub module_is_supplied_with_perl_core {
447 my $ver = shift || $];
449 ### check Module::CoreList to see if it's a core package
450 require Module::CoreList;
451 my $core = $Module::CoreList::version{ $ver }->{ $self->module };
456 ### make sure Bundle-Foo also gets flagged as bundle
458 return shift->module =~ /^bundle(?:-|::)/i ? 1 : 0;
464 return unless can_load( modules => { 'Module::ThirdParty' => 0 } );
466 return Module::ThirdParty::is_3rd_party( $self->name );
469 sub third_party_information {
472 return unless $self->is_third_party;
474 return Module::ThirdParty::module_information( $self->name );
480 =head2 $clone = $self->clone
482 Clones the current module object for tinkering with.
483 It will have a clean C<CPANPLUS::Module::Status> object, as well as
484 a fake C<CPANPLUS::Module::Author> object.
491 ### clone the object ###
493 for my $acc ( grep !/status/, __PACKAGE__->accessors() ) {
494 $data{$acc} = $self->$acc();
497 my $obj = CPANPLUS::Module::Fake->new( %data );
504 =head2 $where = $self->fetch
506 Fetches the module from a CPAN mirror.
507 Look at L<CPANPLUS::Internals::Fetch::_fetch()> for details on the
508 options you can pass.
514 my $cb = $self->parent;
517 my %args = ( module => $self );
519 ### if a custom fetch location got specified before, add that here
520 $args{fetch_from} = $self->status->_fetch_from
521 if $self->status->_fetch_from;
523 my $where = $cb->_fetch( @_, %args ) or return;
525 ### do an md5 check ###
526 if( !$self->status->_fetch_from and
527 $cb->configure_object->get_conf('md5') and
528 $self->package ne CHECKSUMS
530 unless( $self->_validate_checksum ) {
531 error( loc( "Checksum error for '%1' -- will not trust package",
542 =head2 $path = $self->extract
544 Extracts the fetched module.
545 Look at L<CPANPLUS::Internals::Extract::_extract()> for details on
546 the options you can pass.
552 my $cb = $self->parent;
554 unless( $self->status->fetch ) {
555 error( loc( "You have not fetched '%1' yet -- cannot extract",
560 return $cb->_extract( @_, module => $self );
563 =head2 $type = $self->get_installer_type([prefer_makefile => BOOL])
565 Gets the installer type for this module. This may either be C<build> or
566 C<makemaker>. If C<Module::Build> is unavailable or no installer type
567 is available, it will fall back to C<makemaker>. If both are available,
568 it will pick the one indicated by your config, or by the
569 C<prefer_makefile> option you can pass to this function.
571 Returns the installer type on success, and false on error.
575 sub get_installer_type {
577 my $cb = $self->parent;
578 my $conf = $cb->configure_object;
583 prefer_makefile => { default => $conf->get_conf('prefer_makefile'),
584 store => \$prefer_makefile, allow => BOOLEANS },
587 check( $tmpl, \%hash ) or return;
589 my $extract = $self->status->extract();
591 error(loc("Cannot determine installer type of unextracted module '%1'",
597 ### check if it's a makemaker or a module::build type dist ###
598 my $found_build = -e BUILD_PL->( $extract );
599 my $found_makefile = -e MAKEFILE_PL->( $extract );
602 $type = INSTALLER_BUILD if !$prefer_makefile && $found_build;
603 $type = INSTALLER_BUILD if $found_build && !$found_makefile;
604 $type = INSTALLER_MM if $prefer_makefile && $found_makefile;
605 $type = INSTALLER_MM if $found_makefile && !$found_build;
607 ### ok, so it's a 'build' installer, but you don't /have/ module build
608 if( $type eq INSTALLER_BUILD and (
609 not grep { $_ eq INSTALLER_BUILD } CPANPLUS::Dist->dist_types )
611 error( loc( "This module requires '%1' and '%2' to be installed, ".
612 "but you don't have it! Will fall back to ".
613 "'%3', but might not be able to install!",
614 'Module::Build', INSTALLER_BUILD, INSTALLER_MM ) );
615 $type = INSTALLER_MM;
617 ### ok, actually we found neither ###
619 error( loc( "Unable to find '%1' or '%2' for '%3'; ".
620 "Will default to '%4' but might be unable ".
621 "to install!", BUILD_PL->(), MAKEFILE_PL->(),
622 $self->module, INSTALLER_MM ) );
623 $type = INSTALLER_MM;
626 return $self->status->installer_type( $type ) if $type;
632 =head2 $dist = $self->dist([target => 'prepare|create', format => DISTRIBUTION_TYPE, args => {key => val}]);
634 Create a distribution object, ready to be installed.
635 Distribution type defaults to your config settings
637 The optional C<args> hashref is passed on to the specific distribution
638 types' C<create> method after being dereferenced.
640 Returns a distribution object on success, false on failure.
642 See C<CPANPLUS::Dist> for details.
648 my $cb = $self->parent;
649 my $conf = $cb->configure_object;
652 ### have you determined your installer type yet? if not, do it here,
654 $self->get_installer_type unless $self->status->installer_type;
657 my($type,$args,$target);
659 format => { default => $conf->get_conf('dist_type') ||
660 $self->status->installer_type,
662 target => { default => TARGET_CREATE, store => \$target },
663 args => { default => {}, store => \$args },
666 check( $tmpl, \%hash ) or return;
668 my $dist = CPANPLUS::Dist->new(
673 my $dist_cpan = $type eq $self->status->installer_type
675 : CPANPLUS::Dist->new(
676 format => $self->status->installer_type,
681 $self->status->dist_cpan( $dist_cpan );
682 $self->status->dist( $dist );
685 ### first prepare the dist
686 $dist->prepare( %$args ) or return;
687 $self->status->prepared(1);
689 ### you just wanted us to prepare?
690 last DIST if $target eq TARGET_PREPARE;
692 $dist->create( %$args ) or return;
693 $self->status->created(1);
701 =head2 $bool = $mod->prepare( )
703 Convenience method around C<install()> that prepares a module
704 without actually building it. This is equivalent to invoking C<install>
705 with C<target> set to C<prepare>
707 Returns true on success, false on failure.
713 return $self->install( @_, target => TARGET_PREPARE );
716 =head2 $bool = $mod->create( )
718 Convenience method around C<install()> that creates a module.
719 This is equivalent to invoking C<install> with C<target> set to
722 Returns true on success, false on failure.
728 return $self->install( @_, target => TARGET_CREATE );
731 =head2 $bool = $mod->test( )
733 Convenience wrapper around C<install()> that tests a module, without
735 It's the equivalent to invoking C<install()> with C<target> set to
736 C<create> and C<skiptest> set to C<0>.
738 Returns true on success, false on failure.
744 return $self->install( @_, target => TARGET_CREATE, skiptest => 0 );
749 =head2 $bool = $self->install([ target => 'prepare|create|install', format => FORMAT_TYPE, extractdir => DIRECTORY, fetchdir => DIRECTORY, prefer_bin => BOOL, force => BOOL, verbose => BOOL, ..... ]);
751 Installs the current module. This includes fetching it and extracting
752 it, if this hasn't been done yet, as well as creating a distribution
755 This means you can pass it more arguments than described above, which
756 will be passed on to the relevant methods as they are called.
758 See C<CPANPLUS::Internals::Fetch>, C<CPANPLUS::Internals::Extract> and
759 C<CPANPLUS::Dist> for details.
761 Returns true on success, false on failure.
767 my $cb = $self->parent;
768 my $conf = $cb->configure_object;
771 my $args; my $target; my $format;
772 { ### so we can use the rest of the args to the create calls etc ###
773 local $Params::Check::NO_DUPLICATES = 1;
774 local $Params::Check::ALLOW_UNKNOWN = 1;
776 ### targets 'dist' and 'test' are now completely ignored ###
778 ### match this allow list with Dist->_resolve_prereqs
779 target => { default => TARGET_INSTALL, store => \$target,
780 allow => [TARGET_PREPARE, TARGET_CREATE,
782 force => { default => $conf->get_conf('force'), },
783 verbose => { default => $conf->get_conf('verbose'), },
784 format => { default => $conf->get_conf('dist_type'),
788 $args = check( $tmpl, \%hash ) or return;
792 ### if this target isn't 'install', we will need to at least 'create'
793 ### every prereq, so it can build
794 ### XXX prereq_target of 'prepare' will do weird things here, and is
796 $args->{'prereq_target'} ||= TARGET_CREATE if $target ne TARGET_INSTALL;
798 ### check if it's already upto date ###
799 if( $target eq TARGET_INSTALL and !$args->{'force'} and
800 !$self->package_is_perl_core() and # separate rules apply
801 ( $self->status->installed() or $self->is_uptodate ) and
802 !INSTALL_VIA_PACKAGE_MANAGER->($format)
804 msg(loc("Module '%1' already up to date, won't install without force",
805 $self->module), $args->{'verbose'} );
806 return $self->status->installed(1);
809 # if it's a non-installable core package, abort the install.
810 if( $self->package_is_perl_core() ) {
811 # if the installed is newer, say so.
812 if( $self->installed_version > $self->version ) {
813 error(loc("The core Perl %1 module '%2' (%3) is more ".
814 "recent than the latest release on CPAN (%4). ".
816 $], $self->module, $self->installed_version,
818 # if the installed matches, say so.
819 } elsif( $self->installed_version == $self->version ) {
820 error(loc("The core Perl %1 module '%2' (%3) can only ".
821 "be installed by Perl itself. ".
823 $], $self->module, $self->installed_version ) );
824 # otherwise, the installed is older; say so.
826 error(loc("The core Perl %1 module '%2' can only be ".
827 "upgraded from %3 to %4 by Perl itself (%5). ".
829 $], $self->module, $self->installed_version,
830 $self->version, $self->package ) );
834 ### it might be a known 3rd party module
835 } elsif ( $self->is_third_party ) {
836 my $info = $self->third_party_information;
838 "%1 is a known third-party module.\n\n".
839 "As it isn't available on the CPAN, CPANPLUS can't install " .
840 "it automatically. Therefore you need to install it manually " .
841 "before proceeding.\n\n".
842 "%2 is part of %3, published by %4, and should be available ".
843 "for download at the following address:\n\t%5",
844 $self->name, $self->name, $info->{name}, $info->{author},
851 ### fetch it if need be ###
852 unless( $self->status->fetch ) {
854 for (qw[prefer_bin fetchdir]) {
855 $params->{$_} = $args->{$_} if exists $args->{$_};
857 for (qw[force verbose]) {
858 $params->{$_} = $args->{$_} if defined $args->{$_};
860 $self->fetch( %$params ) or return;
863 ### extract it if need be ###
864 unless( $self->status->extract ) {
866 for (qw[prefer_bin extractdir]) {
867 $params->{$_} = $args->{$_} if exists $args->{$_};
869 for (qw[force verbose]) {
870 $params->{$_} = $args->{$_} if defined $args->{$_};
872 $self->extract( %$params ) or return;
875 $format ||= $self->status->installer_type;
878 error( loc( "Don't know what installer to use; " .
879 "Couldn't find either '%1' or '%2' in the extraction " .
880 "directory '%3' -- will be unable to install",
881 BUILD_PL->(), MAKEFILE_PL->(), $self->status->extract ) );
883 $self->status->installed(0);
888 ### do SIGNATURE checks? ###
889 if( $conf->get_conf('signature') ) {
890 unless( $self->check_signature( verbose => $args->{verbose} ) ) {
891 error( loc( "Signature check failed for module '%1' ".
892 "-- Not trusting this module, aborting install",
894 $self->status->signature(0);
896 ### send out test report on broken sig
897 if( $conf->get_conf('cpantest') ) {
901 buffer => CPANPLUS::Error->stack_as_string,
902 verbose => $args->{verbose},
903 force => $args->{force},
904 ) or error(loc("Failed to send test report for '%1'",
912 $self->status->signature(1);
916 ### a target of 'create' basically means not to run make test ###
917 ### eh, no it /doesn't/.. skiptest => 1 means skiptest => 1.
918 #$args->{'skiptest'} = 1 if $target eq 'create';
920 ### bundle rules apply ###
921 if( $self->is_bundle ) {
922 ### check what we need to install ###
923 my @prereqs = $self->bundle_modules();
925 error( loc( "Bundle '%1' does not specify any modules to install",
928 ### XXX mark an error here? ###
932 my $dist = $self->dist( format => $format,
936 error( loc( "Unable to create a new distribution object for '%1' " .
937 "-- cannot continue", $self->module ) );
941 return 1 if $target ne TARGET_INSTALL;
943 my $ok = $dist->install( %$args ) ? 1 : 0;
945 $self->status->installed($ok);
951 =pod @list = $self->bundle_modules()
953 Returns a list of module objects the Bundle specifies.
955 This requires you to have extracted the bundle already, using the
958 Returns false on error.
964 my $cb = $self->parent;
966 unless( $self->is_bundle ) {
967 error( loc("'%1' is not a bundle", $self->module ) );
972 unless( $dir = $self->status->extract ) {
973 error( loc("Don't know where '%1' was extracted to", $self->module ) );
979 wanted => sub { push @files, File::Spec->rel2abs($_) if /\.pm/i; },
983 my $prereqs = {}; my @list; my $seen = {};
984 for my $file ( @files ) {
985 my $fh = FileHandle->new($file)
986 or( error(loc("Could not open '%1' for reading: %2",
991 ### quick hack to read past the header of the file ###
992 last if $flag && m|^=head|i;
994 ### from perldoc cpan:
996 ### In this pod section each line obeys the format
997 ### Module_Name [Version_String] [- optional text]
998 $flag = 1 if m|^=head1 CONTENTS|i;
1000 if ($flag && /^(?!=)(\S+)\s*(\S+)?/) {
1002 my $version = $2 || '0';
1004 my $obj = $cb->module_tree($module);
1007 error(loc("Cannot find bundled module '%1'", $module),
1008 loc("-- it does not seem to exist") );
1012 ### make sure we list no duplicates ###
1013 unless( $seen->{ $obj->module }++ ) {
1015 $prereqs->{ $module } =
1016 $cb->_version_to_number( version => $version );
1022 ### store the prereqs we just found ###
1023 $self->status->prereqs( $prereqs );
1030 =head2 $text = $self->readme
1032 Fetches the readme belonging to this module and stores it under
1033 C<< $obj->status->readme >>. Returns the readme as a string on
1034 success and returns false on failure.
1040 my $conf = $self->parent->configure_object;
1042 ### did we already dl the readme once? ###
1043 return $self->status->readme() if $self->status->readme();
1045 ### this should be core ###
1046 return unless can_load( modules => { FileHandle => '0.0' },
1050 ### get a clone of the current object, with a fresh status ###
1051 my $obj = $self->clone or return;
1053 ### munge the package name
1054 my $pkg = README->( $obj );
1055 $obj->package($pkg);
1058 { ### disable checksum fetches on readme downloads
1060 my $tmp = $conf->get_conf( 'md5' );
1061 $conf->set_conf( md5 => 0 );
1063 $file = $obj->fetch;
1065 $conf->set_conf( md5 => $tmp );
1067 return unless $file;
1070 ### read the file into a scalar, to store in the original object ###
1071 my $fh = new FileHandle;
1072 unless( $fh->open($file) ) {
1073 error( loc( "Could not open file '%1': %2", $file, $! ) );
1078 { local $/; $in = <$fh> };
1081 return $self->status->readme( $in );
1086 =head2 $version = $self->installed_version()
1088 Returns the currently installed version of this module, if any.
1090 =head2 $where = $self->installed_file()
1092 Returns the location of the currently installed file of this module,
1095 =head2 $bool = $self->is_uptodate([version => VERSION_NUMBER])
1097 Returns a boolean indicating if this module is uptodate or not.
1101 ### uptodate/installed functions
1102 { my $map = { # hashkey, alternate rv
1103 installed_version => ['version', 0 ],
1104 installed_file => ['file', ''],
1105 is_uptodate => ['uptodate', 0 ],
1108 while( my($method, $aref) = each %$map ) {
1109 my($key,$alt_rv) = @$aref;
1113 ### never use the @INC hooks to find installed versions of
1114 ### modules -- they're just there in case they're not on the
1115 ### perl install, but the user shouldn't trust them for *other*
1117 ### XXX CPANPLUS::inc is now obsolete, so this should not
1118 ### be needed anymore
1119 #local @INC = CPANPLUS::inc->original_inc;
1123 ### make sure check_install is not looking in %INC, as
1124 ### that may contain some of our sneakily loaded modules
1125 ### that aren't installed as such. -- kane
1126 local $Module::Load::Conditional::CHECK_INC_HASH = 0;
1127 my $href = check_install(
1128 module => $self->module,
1129 version => $self->version,
1133 return $href->{$key} || $alt_rv;
1142 =head2 $href = $self->details()
1144 Returns a hashref with key/value pairs offering more information about
1145 a particular module. For example, for C<Time::HiRes> it might look like
1148 Author Jarkko Hietaniemi (jhi@iki.fi)
1149 Description High resolution time, sleep, and alarm
1150 Development Stage Released
1151 Installed File /usr/local/perl/lib/Time/Hires.pm
1152 Interface Style plain Functions, no references used
1153 Language Used C and perl, a C compiler will be needed
1154 Package Time-HiRes-1.65.tar.gz
1155 Public License Unknown
1156 Support Level Developer
1157 Version Installed 1.52
1158 Version on CPAN 1.65
1164 my $conf = $self->parent->configure_object();
1165 my $cb = $self->parent;
1169 Author => loc("%1 (%2)", $self->author->author(),
1170 $self->author->email() ),
1171 Package => $self->package,
1172 Description => $self->description || loc('None given'),
1173 'Version on CPAN' => $self->version,
1176 ### check if we have the module installed
1177 ### if so, add version have and version on cpan
1178 $res->{'Version Installed'} = $self->installed_version
1179 if $self->installed_version;
1180 $res->{'Installed File'} = $self->installed_file if $self->installed_file;
1183 for my $item( split '', $self->dslip ) {
1184 $res->{ $cb->_dslip_defs->[$i]->[0] } =
1185 $cb->_dslip_defs->[$i]->[1]->{$item} || loc('Unknown');
1192 =head2 @list = $self->contains()
1194 Returns a list of module objects that represent the modules also
1195 present in the package of this module.
1197 For example, for C<Archive::Tar> this might return:
1200 Archive::Tar::Constant
1207 my $cb = $self->parent;
1208 my $pkg = $self->package;
1210 my @mods = $cb->search( type => 'package', allow => [qr/^$pkg$/] );
1217 =head2 @list_of_hrefs = $self->fetch_report()
1219 This function queries the CPAN testers database at
1220 I<http://testers.cpan.org/> for test results of specified module
1221 objects, module names or distributions.
1223 Look at L<CPANPLUS::Internals::Report::_query_report()> for details on
1224 the options you can pass and the return value to expect.
1230 my $cb = $self->parent;
1232 return $cb->_query_report( @_, module => $self );
1237 =head2 $bool = $self->uninstall([type => [all|man|prog])
1239 This function uninstalls the specified module object.
1241 You can install 2 types of files, either C<man> pages or C<prog>ram
1242 files. Alternately you can specify C<all> to uninstall both (which
1245 Returns true on success and false on failure.
1247 Do note that this does an uninstall via the so-called C<.packlist>,
1248 so if you used a module installer like say, C<ports> or C<apt>, you
1249 should not use this, but use your package manager instead.
1255 my $conf = $self->parent->configure_object();
1258 my ($type,$verbose);
1260 type => { default => 'all', allow => [qw|man prog all|],
1262 verbose => { default => $conf->get_conf('verbose'),
1263 store => \$verbose },
1264 force => { default => $conf->get_conf('force') },
1267 ### XXX add a warning here if your default install dist isn't
1268 ### makefile or build -- that means you are using a package manager
1269 ### and this will not do what you think!
1271 my $args = check( $tmpl, \%hash ) or return;
1273 if( $conf->get_conf('dist_type') and (
1274 ($conf->get_conf('dist_type') ne INSTALLER_BUILD) or
1275 ($conf->get_conf('dist_type') ne INSTALLER_MM))
1277 msg(loc("You have a default installer type set (%1) ".
1278 "-- you should probably use that package manager to " .
1279 "uninstall modules", $conf->get_conf('dist_type')), $verbose);
1282 ### check if we even have the module installed -- no point in continuing
1284 unless( $self->installed_version ) {
1285 error( loc( "Module '%1' is not installed, so cannot uninstall",
1290 ### nothing to uninstall ###
1291 my $files = $self->files( type => $type ) or return;
1292 my $dirs = $self->directory_tree( type => $type ) or return;
1293 my $sudo = $conf->get_program('sudo');
1295 ### just in case there's no file; M::B doensn't provide .packlists yet ###
1296 my $pack = $self->packlist;
1297 $pack = $pack->[0]->packlist_file() if $pack;
1299 ### first remove the files, then the dirs if they are empty ###
1301 for my $file( @$files, $pack ) {
1302 next unless defined $file && -f $file;
1304 msg(loc("Unlinking '%1'", $file), $verbose);
1306 my @cmd = ($^X, "-eunlink+q[$file]");
1307 unshift @cmd, $sudo if $sudo;
1310 unless ( run( command => \@cmd,
1311 verbose => $verbose,
1312 buffer => \$buffer )
1314 error(loc("Failed to unlink '%1': '%2'",$file, $buffer));
1319 for my $dir ( sort @$dirs ) {
1321 open DIR, $dir or next;
1322 my @count = readdir(DIR);
1325 next unless @count == 2; # . and ..
1327 msg(loc("Removing '%1'", $dir), $verbose);
1329 ### this fails on my win2k machines.. it indeed leaves the
1330 ### dir, but it's not a critical error, since the files have
1331 ### been removed. --kane
1332 #unless( rmdir $dir ) {
1333 # error( loc( "Could not remove '%1': %2", $dir, $! ) )
1334 # unless $^O eq 'MSWin32';
1337 my @cmd = ($^X, "-ermdir+q[$dir]");
1338 unshift @cmd, $sudo if $sudo;
1341 unless ( run( command => \@cmd,
1342 verbose => $verbose,
1343 buffer => \$buffer )
1345 error(loc("Failed to rmdir '%1': %2",$dir,$buffer));
1350 $self->status->uninstall(!$flag);
1351 $self->status->installed( $flag ? 1 : undef);
1358 =head2 @modobj = $self->distributions()
1360 Returns a list of module objects representing all releases for this
1361 module on success, false on failure.
1369 my @list = $self->author->distributions( %hash, module => $self ) or return;
1371 ### it's another release then by the same author ###
1372 return grep { $_->package_name eq $self->package_name } @list;
1377 =head2 @list = $self->files ()
1379 Returns a list of files used by this module, if it is installed.
1384 return shift->_extutils_installed( @_, method => 'files' );
1389 =head2 @list = $self->directory_tree ()
1391 Returns a list of directories used by this module.
1395 sub directory_tree {
1396 return shift->_extutils_installed( @_, method => 'directory_tree' );
1401 =head2 @list = $self->packlist ()
1403 Returns the C<ExtUtils::Packlist> object for this module.
1408 return shift->_extutils_installed( @_, method => 'packlist' );
1413 =head2 @list = $self->validate ()
1415 Returns a list of files that are missing for this modules, but
1416 are present in the .packlist file.
1421 return shift->_extutils_installed( method => 'validate' );
1424 ### generic method to call an ExtUtils::Installed method ###
1425 sub _extutils_installed {
1427 my $conf = $self->parent->configure_object();
1430 my ($verbose,$type,$method);
1432 verbose => { default => $conf->get_conf('verbose'),
1433 store => \$verbose, },
1434 type => { default => 'all',
1435 allow => [qw|prog man all|],
1437 method => { required => 1,
1439 allow => [qw|files directory_tree packlist
1444 my $args = check( $tmpl, \%hash ) or return;
1446 ### old versions of cygwin + perl < 5.8 are buggy here. bail out if we
1447 ### find we're being used by them
1448 { my $err = ON_OLD_CYGWIN;
1449 if($err) { error($err); return };
1452 return unless can_load(
1453 modules => { 'ExtUtils::Installed' => '0.0' },
1454 verbose => $verbose,
1458 unless( $inst = ExtUtils::Installed->new() ) {
1459 error( loc("Could not create an '%1' object", 'ExtUtils::Installed' ) );
1461 ### in case it's being used directly... ###
1466 { ### EU::Installed can die =/
1468 eval { @files = $inst->$method( $self->module, $type ) };
1472 error( loc("Could not get '%1' for '%2': %3",
1473 $method, $self->module, $@ ) );
1477 return wantarray ? @files : \@files;
1481 =head2 $bool = $self->add_to_includepath;
1483 Adds the current modules path to C<@INC> and C<$PERL5LIB>. This allows
1484 you to add the module from it's build dir to your path.
1486 You can reset C<@INC> and C<$PERL5LIB> to it's original state when you
1487 started the program, by calling:
1489 $self->parent->flush('lib');
1493 sub add_to_includepath {
1495 my $cb = $self->parent;
1497 if( my $dir = $self->status->extract ) {
1499 $cb->_add_to_includepath(
1501 File::Spec->catdir(BLIB->($dir), LIB),
1502 File::Spec->catdir(BLIB->($dir), ARCH),
1508 error(loc( "No extract dir registered for '%1' -- can not add ".
1509 "add builddir to search path!", $self->module ));
1519 =head2 $path = $self->best_path_to_module_build();
1523 If a newer version of Module::Build is found in your path, it will
1524 return this C<special> path. If the newest version of C<Module::Build>
1525 is found in your regular C<@INC>, the method will return false. This
1526 indicates you do not need to add a special directory to your C<@INC>.
1528 Note that this is only relevant if you're building your own
1529 C<CPANPLUS::Dist::*> plugin -- the built-in dist types already have
1534 ### make sure we're always running 'perl Build.PL' and friends
1535 ### against the highest version of module::build available
1536 sub best_path_to_module_build {
1539 ### Since M::B will actually shell out and run the Build.PL, we must
1540 ### make sure it refinds the proper version of M::B in the path.
1541 ### that may be either in our cp::inc or in site_perl, or even a
1542 ### new M::B being installed.
1543 ### don't add anything else here, as that might screw up prereq checks
1545 ### XXX this might be needed for Dist::MM too, if a makefile.pl is
1546 ### masquerading as a Build.PL
1548 ### did we find the most recent module::build in our installer path?
1550 ### XXX can't do changes to @INC, they're being ignored by
1551 ### new_from_context when writing a Build script. see ticket:
1552 ### #8826 Module::Build ignores changes to @INC when writing Build
1553 ### from new_from_context
1554 ### XXX applied schwern's patches (as seen on CPANPLUS::Devel 10/12/04)
1555 ### and upped the version to 0.26061 of the bundled version, and things
1558 ### this functionality is now obsolete -- prereqs should be installed
1559 ### and we no longer use the CPANPLUS::inc magic.. so comment this out.
1560 # require Module::Build;
1561 # if( CPANPLUS::inc->path_to('Module::Build') and (
1562 # CPANPLUS::inc->path_to('Module::Build') eq
1563 # CPANPLUS::inc->installer_path )
1566 # ### if the module being installed is *not* Module::Build
1567 # ### itself -- as that would undoubtedly be newer -- add
1568 # ### the path to the installers to @INC
1569 # ### if it IS module::build itself, add 'lib' to its path,
1570 # ### as the Build.PL would do as well, but the API doesn't.
1571 # ### this makes self updates possible
1572 # return $self->module eq 'Module::Build'
1574 # : CPANPLUS::inc->installer_path;
1577 ### otherwise, the path was found through a 'normal' way of
1586 Please report bugs or other issues to E<lt>bug-cpanplus@rt.cpan.org<gt>.
1590 This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
1594 The CPAN++ interface (of which this module is a part of) is copyright (c)
1595 2001 - 2007, Jos Boumans E<lt>kane@cpan.orgE<gt>. All rights reserved.
1597 This library is free software; you may redistribute and/or modify it
1598 under the same terms as Perl itself.
1603 # c-indentation-style: bsd
1605 # indent-tabs-mode: nil
1607 # vim: expandtab shiftwidth=4: