diff --git a/lib/App/cpanminus/script.pm b/lib/App/cpanminus/script.pm index 4c82338a0..3ee3f78c8 100644 --- a/lib/App/cpanminus/script.pm +++ b/lib/App/cpanminus/script.pm @@ -79,6 +79,7 @@ sub new { argv => [], local_lib => undef, self_contained => undef, + exclude_vendor => undef, prompt_timeout => 0, prompt => undef, configure_timeout => 60, @@ -173,6 +174,7 @@ sub parse_options { $self->{pod2man} = undef; }, 'self-contained!' => \$self->{self_contained}, + 'exclude-vendor!' => \$self->{exclude_vendor}, 'mirror=s@' => $self->{mirrors}, 'mirror-only!' => \$self->{mirror_only}, 'mirror-index=s' => \$self->{mirror_index}, @@ -339,7 +341,6 @@ sub _doit { my ($volume, $dirs, $file) = File::Spec->splitpath($module); $module = join '::', grep { $_ } File::Spec->splitdir($dirs), $file; } - ($module, my $version) = $self->parse_module_args($module); $self->chdir($cwd); @@ -785,8 +786,8 @@ sub show_version { print " \%Config:\n"; for my $key (qw( archname installsitelib installsitebin installman1dir installman3dir - sitelibexp archlibexp privlibexp )) { - print " $key=$Config{$key}\n"; + sitearchexp sitelibexp vendorarch vendorlibexp archlibexp privlibexp )) { + print " $key=$Config{$key}\n" if $Config{$key}; } print " \%ENV:\n"; @@ -939,9 +940,10 @@ sub _core_only_inc { my($self, $base) = @_; require local::lib; ( - local::lib->resolve_path(local::lib->install_base_perl_path($base)), local::lib->resolve_path(local::lib->install_base_arch_path($base)), - @Config{qw(privlibexp archlibexp)}, + local::lib->resolve_path(local::lib->install_base_perl_path($base)), + (!$self->{exclude_vendor} ? grep {$_} @Config{qw(vendorarch vendorlibexp)} : ()), + @Config{qw(archlibexp privlibexp)}, ); } @@ -1981,7 +1983,11 @@ sub loaded_from_perl_lib { my($self, $meta) = @_; require Config; - for my $dir (qw(archlibexp privlibexp)) { + my @dirs = qw(archlibexp privlibexp); + if ($self->{self_contained} && ! $self->{exclude_vendor} && $Config{vendorarch}) { + unshift @dirs, qw(vendorarch vendorlibexp); + } + for my $dir (@dirs) { my $confdir = $Config{$dir}; if ($confdir eq substr($meta->filename, 0, length($confdir))) { return 1; diff --git a/script/cpanm.PL b/script/cpanm.PL index 1cbbc9028..c452f5377 100755 --- a/script/cpanm.PL +++ b/script/cpanm.PL @@ -193,9 +193,11 @@ directory C, which can be loaded from your application with: use local::lib '/path/to/extlib'; -Note that this option does B reliably work with perl -installations supplied by operating system vendors that strips -standard modules from perl, such as RHEL, Fedora and CentOS. +Note that this option does B reliably work with perl installations +supplied by operating system vendors that strips standard modules from perl, +such as RHEL, Fedora and CentOS, B you also install packages supplying +all the modules that have been stripped. For these systems you will probably +want to install the C meta-package which does just that. =item --self-contained @@ -203,6 +205,12 @@ When examining the dependencies, assume no non-core modules are installed on the system. Handy if you want to bundle application dependencies in one directory so you can distribute to other machines. +=item --exclude-vendor + +Don't include modules installed under the 'vendor' paths when searching for +core modules when the C<--self-contained> flag is in effect. This restores +the behaviour from before version 1.7023 + =item --mirror Specifies the base URL for the CPAN mirror to use, such as diff --git a/xt/exclude-vendor.t b/xt/exclude-vendor.t new file mode 100644 index 000000000..71b881923 --- /dev/null +++ b/xt/exclude-vendor.t @@ -0,0 +1,31 @@ +use xt::Run; +use Test::More; + +# If ExtUtils::MakeMaker is installed under vendor path and not a core path, +# then --exclude-vendor will fail + +use Config; +use Module::Metadata; +my $vendor_path = $Config{vendorlibexp}; +my $core_path = $Config{privlibexp}; + +my $core_mod = 'ExtUtils::MakeMaker'; + +my $core_in_vendor = 0; +if ( Module::Metadata->new_from_module( $core_mod, inc => [$vendor_path] ) ) { + $core_in_vendor = 1; +} +if ( Module::Metadata->new_from_module( $core_mod, inc => [$core_path] ) ) { + $core_in_vendor = 0; +} + +SKIP: { + skip 'Core modules not moved to vendor on this system' unless $core_in_vendor; + + # Something with some core dependencies + run_L( "--exclude-vendor", "URI::Find" ); + + like last_build_log, qr{Installing the dependencies failed: Module 'ExtUtils::MakeMaker'}; +} + +done_testing;