summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Install/CPAN.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Install/CPAN.pm')
-rw-r--r--Bugzilla/Install/CPAN.pm339
1 files changed, 0 insertions, 339 deletions
diff --git a/Bugzilla/Install/CPAN.pm b/Bugzilla/Install/CPAN.pm
deleted file mode 100644
index 094784e1a..000000000
--- a/Bugzilla/Install/CPAN.pm
+++ /dev/null
@@ -1,339 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#
-# This Source Code Form is "Incompatible With Secondary Licenses", as
-# defined by the Mozilla Public License, v. 2.0.
-
-package Bugzilla::Install::CPAN;
-
-use 5.10.1;
-use strict;
-use warnings;
-
-use parent qw(Exporter);
-our @EXPORT = qw(
- BZ_LIB
-
- check_cpan_requirements
- set_cpan_config
- install_module
-);
-
-use Bugzilla::Constants;
-use Bugzilla::Install::Requirements qw(have_vers);
-use Bugzilla::Install::Util qw(bin_loc install_string);
-
-use Config;
-use CPAN;
-use Cwd qw(abs_path);
-use File::Path qw(rmtree);
-
-# These are required for install-module.pl to be able to install
-# all modules properly.
-use constant REQUIREMENTS => (
- {
- module => 'CPAN',
- package => 'CPAN',
- version => '1.81',
- },
- {
- # When Module::Build isn't installed, the YAML module allows
- # CPAN to read META.yml to determine that Module::Build first
- # needs to be installed to compile a module.
- module => 'YAML',
- package => 'YAML',
- version => 0,
- },
- {
- # Many modules on CPAN are now built with Dist::Zilla, which
- # unfortunately means they require this version of EU::MM to install.
- module => 'ExtUtils::MakeMaker',
- package => 'ExtUtils-MakeMaker',
- version => '6.31',
- },
-);
-
-# We need the absolute path of ext_libpath, because CPAN chdirs around
-# and so we can't use a relative directory.
-#
-# We need it often enough (and at compile time, in install-module.pl) so
-# we make it a constant.
-use constant BZ_LIB => abs_path(bz_locations()->{ext_libpath});
-
-# CPAN requires nearly all of its parameters to be set, or it will start
-# asking questions to the user. We want to avoid that, so we have
-# defaults here for most of the required parameters we know about, in case
-# any of them aren't set. The rest are handled by set_cpan_defaults().
-use constant CPAN_DEFAULTS => {
- auto_commit => 0,
- # We always force builds, so there's no reason to cache them.
- build_cache => 0,
- build_requires_install_policy => 'yes',
- cache_metadata => 1,
- colorize_output => 1,
- colorize_print => 'bold',
- index_expire => 1,
- scan_cache => 'atstart',
-
- inhibit_startup_message => 1,
-
- bzip2 => bin_loc('bzip2'),
- curl => bin_loc('curl'),
- gzip => bin_loc('gzip'),
- links => bin_loc('links'),
- lynx => bin_loc('lynx'),
- make => bin_loc('make'),
- pager => bin_loc('less'),
- tar => bin_loc('tar'),
- unzip => bin_loc('unzip'),
- wget => bin_loc('wget'),
-
- urllist => ['http://www.cpan.org/'],
-};
-
-sub check_cpan_requirements {
- my ($original_dir, $original_args) = @_;
-
- _require_compiler();
-
- my @install;
- foreach my $module (REQUIREMENTS) {
- my $installed = have_vers($module, 1);
- push(@install, $module) if !$installed;
- }
-
- return if !@install;
-
- my $restart_required;
- foreach my $module (@install) {
- $restart_required = 1 if $module->{module} eq 'CPAN';
- install_module($module->{module}, 1);
- }
-
- if ($restart_required) {
- chdir $original_dir;
- exec($^X, $0, @$original_args);
- }
-}
-
-sub _require_compiler {
- my @errors;
-
- my $cc_name = $Config{cc};
- my $cc_exists = bin_loc($cc_name);
-
- if (!$cc_exists) {
- push(@errors, install_string('install_no_compiler'));
- }
-
- my $make_name = $CPAN::Config->{make};
- my $make_exists = bin_loc($make_name);
-
- if (!$make_exists) {
- push(@errors, install_string('install_no_make'));
- }
-
- die @errors if @errors;
-}
-
-sub install_module {
- my ($name, $test) = @_;
- my $bzlib = BZ_LIB;
-
- # Make Module::AutoInstall install all dependencies and never prompt.
- local $ENV{PERL_AUTOINSTALL} = '--alldeps';
- # This makes Net::SSLeay not prompt the user, if it gets installed.
- # It also makes any other MakeMaker prompts accept their defaults.
- local $ENV{PERL_MM_USE_DEFAULT} = 1;
-
- # Certain modules require special stuff in order to not prompt us.
- my $original_makepl = $CPAN::Config->{makepl_arg};
- # This one's a regex in case we're doing Template::Plugin::GD and it
- # pulls in Template-Toolkit as a dependency.
- if ($name =~ /^Template/) {
- $CPAN::Config->{makepl_arg} .= " TT_ACCEPT=y TT_EXTRAS=n";
- }
- elsif ($name eq 'XML::Twig') {
- $CPAN::Config->{makepl_arg} = "-n $original_makepl";
- }
- elsif ($name eq 'SOAP::Lite') {
- $CPAN::Config->{makepl_arg} .= " --noprompt";
- }
-
- my $module = CPAN::Shell->expand('Module', $name);
- if (!$module) {
- die install_string('no_such_module', { module => $name }) . "\n";
- }
-
- print install_string('install_module',
- { module => $name, version => $module->cpan_version }) . "\n";
-
- if ($test) {
- CPAN::Shell->force('install', $name);
- }
- else {
- CPAN::Shell->notest('install', $name);
- }
-
- # If it installed any binaries in the Bugzilla directory, delete them.
- if (-d "$bzlib/bin") {
- File::Path::rmtree("$bzlib/bin");
- }
-
- $CPAN::Config->{makepl_arg} = $original_makepl;
-}
-
-sub set_cpan_config {
- my $do_global = shift;
- my $bzlib = BZ_LIB;
-
- # We set defaults before we do anything, otherwise CPAN will
- # start asking us questions as soon as we load its configuration.
- eval { require CPAN::Config; };
- _set_cpan_defaults();
-
- # Calling a senseless autoload that does nothing makes us
- # automatically load any existing configuration.
- # We want to avoid the "invalid command" message.
- open(my $saveout, ">&", "STDOUT");
- open(STDOUT, '>', '/dev/null');
- eval { CPAN->ignore_this_error_message_from_bugzilla; };
- undef $@;
- close(STDOUT);
- open(STDOUT, '>&', $saveout);
-
- my $dir = $CPAN::Config->{cpan_home};
- if (!defined $dir || !-w $dir) {
- # If we can't use the standard CPAN build dir, we try to make one.
- $dir = "$ENV{HOME}/.cpan";
- mkdir $dir;
-
- # If we can't make one, we finally try to use the Bugzilla directory.
- if (!-w $dir) {
- print STDERR install_string('cpan_bugzilla_home'), "\n";
- $dir = "$bzlib/.cpan";
- }
- }
- $CPAN::Config->{cpan_home} = $dir;
- $CPAN::Config->{build_dir} = "$dir/build";
- # We always force builds, so there's no reason to cache them.
- $CPAN::Config->{keep_source_where} = "$dir/source";
- # This is set both here and in defaults so that it's always true.
- $CPAN::Config->{inhibit_startup_message} = 1;
- # Automatically install dependencies.
- $CPAN::Config->{prerequisites_policy} = 'follow';
-
- # Unless specified, we install the modules into the Bugzilla directory.
- if (!$do_global) {
- require Config;
-
- $CPAN::Config->{makepl_arg} .= " LIB=\"$bzlib\""
- . " INSTALLMAN1DIR=\"$bzlib/man/man1\""
- . " INSTALLMAN3DIR=\"$bzlib/man/man3\""
- # The bindirs are here because otherwise we'll try to write to
- # the system binary dirs, and that will cause CPAN to die.
- . " INSTALLBIN=\"$bzlib/bin\""
- . " INSTALLSCRIPT=\"$bzlib/bin\""
- # INSTALLDIRS=perl is set because that makes sure that MakeMaker
- # always uses the directories we've specified here.
- . " INSTALLDIRS=perl";
- $CPAN::Config->{mbuild_arg} = " --install_base \"$bzlib\""
- . " --install_path lib=\"$bzlib\""
- . " --install_path arch=\"$bzlib/$Config::Config{archname}\"";
- $CPAN::Config->{mbuild_install_arg} = $CPAN::Config->{mbuild_arg};
-
- # When we're not root, sometimes newer versions of CPAN will
- # try to read/modify things that belong to root, unless we set
- # certain config variables.
- $CPAN::Config->{histfile} = "$dir/histfile";
- $CPAN::Config->{use_sqlite} = 0;
- $CPAN::Config->{prefs_dir} = "$dir/prefs";
-
- # Unless we actually set PERL5LIB, some modules can't install
- # themselves, like DBD::mysql, DBD::Pg, and XML::Twig.
- my $current_lib = $ENV{PERL5LIB} ? $ENV{PERL5LIB} . ':' : '';
- $ENV{PERL5LIB} = $current_lib . $bzlib;
- }
-}
-
-sub _set_cpan_defaults {
- # If CPAN hasn't been configured, we try to use some reasonable defaults.
- foreach my $key (keys %{CPAN_DEFAULTS()}) {
- $CPAN::Config->{$key} = CPAN_DEFAULTS->{$key}
- if !defined $CPAN::Config->{$key};
- }
-
- my @missing;
- # In newer CPANs, this is in HandleConfig. In older CPANs, it's in
- # Config.
- if (eval { require CPAN::HandleConfig }) {
- @missing = CPAN::HandleConfig->missing_config_data;
- }
- else {
- @missing = CPAN::Config->missing_config_data;
- }
-
- foreach my $key (@missing) {
- $CPAN::Config->{$key} = '';
- }
-}
-
-1;
-
-__END__
-
-=head1 NAME
-
-Bugzilla::Install::CPAN - Routines to install Perl modules from CPAN.
-
-=head1 SYNOPSIS
-
- use Bugzilla::Install::CPAN;
-
- set_cpan_config();
- install_module('Module::Name');
-
-=head1 DESCRIPTION
-
-This is primarily used by L<install-module> to do the "hard work" of
-installing CPAN modules.
-
-=head1 SUBROUTINES
-
-=over
-
-=item C<set_cpan_config>
-
-Sets up the configuration of CPAN for this session. Must be called
-before L</install_module>. Takes one boolean parameter. If true,
-L</install_module> will install modules globally instead of to the
-local F<lib/> directory. On most systems, you have to be root to do that.
-
-=item C<install_module>
-
-Installs a module from CPAN. Takes two arguments:
-
-=over
-
-=item C<$name> - The name of the module, just like you'd pass to the
-C<install> command in the CPAN shell.
-
-=item C<$test> - If true, we run tests on this module before installing,
-but we still force the install if the tests fail. This is only used
-when we internally install a newer CPAN module.
-
-=back
-
-Note that calling this function prints a B<lot> of information to
-STDOUT and STDERR.
-
-=back
-
-=head1 B<Methods in need of POD>
-
-=over
-
-=item check_cpan_requirements
-
-=back