Commit 2c33712d authored by Dylan Hardison's avatar Dylan Hardison

Bug 1246528 - Use Makefile.PL and allow Bugzilla use cpanm-compatible local dependencies

r=dkl,a=dylan
parent a8adffb5
/**/.htaccess /**/.htaccess
/lib/* /lib/*
/local/*
/template/en/custom /template/en/custom
/docs/en/rst/extensions/* /docs/en/rst/extensions/*
/docs/en/rst/api/extensions/* /docs/en/rst/api/extensions/*
...@@ -12,6 +13,10 @@ ...@@ -12,6 +13,10 @@
/localconfig /localconfig
/cpanfile /cpanfile
/index.html /index.html
/Makefile
/MYMETA.*
/pm_to_blib
/blib
/skins/contrib/Dusk/admin.css /skins/contrib/Dusk/admin.css
/skins/contrib/Dusk/bug.css /skins/contrib/Dusk/bug.css
...@@ -34,7 +34,6 @@ use Bugzilla::Extension; ...@@ -34,7 +34,6 @@ use Bugzilla::Extension;
use Bugzilla::Field; use Bugzilla::Field;
use Bugzilla::Flag; use Bugzilla::Flag;
use Bugzilla::Install::Localconfig qw(read_localconfig); use Bugzilla::Install::Localconfig qw(read_localconfig);
use Bugzilla::Install::Requirements qw(OPTIONAL_MODULES have_vers);
use Bugzilla::Install::Util qw(init_console include_languages i_am_persistent); use Bugzilla::Install::Util qw(init_console include_languages i_am_persistent);
use Bugzilla::Memcached; use Bugzilla::Memcached;
use Bugzilla::Template; use Bugzilla::Template;
...@@ -47,6 +46,7 @@ use File::Spec::Functions; ...@@ -47,6 +46,7 @@ use File::Spec::Functions;
use DateTime::TimeZone; use DateTime::TimeZone;
use Date::Parse; use Date::Parse;
use Safe; use Safe;
use List::Util qw(first);
##################################################################### #####################################################################
# Constants # Constants
...@@ -245,32 +245,66 @@ sub api_server { ...@@ -245,32 +245,66 @@ sub api_server {
return $cache->{api_server}; return $cache->{api_server};
} }
use constant _CAN_HAS_FEATURE => eval {
require CPAN::Meta;
require Module::Runtime;
require CPAN::Meta::Check;
Module::Runtime->import(qw(require_module));
CPAN::Meta::Check->import(qw(verify_dependencies));
1;
};
sub feature { sub feature {
my ($class, $feature) = @_; my ($class, $feature_name) = @_;
return 0 unless _CAN_HAS_FEATURE;
return unless $class->has_feature($feature_name);
my $cache = $class->request_cache;
my $feature = $cache->{feature_map}{$feature_name};
# Bugzilla expects this will also load all the modules.. so we have to do that.
# Later we should put a deprecation warning here, and favor calling has_feature().
return 1 if $cache->{feature_loaded}{$feature_name};
my @modules = $feature->requirements_for('runtime', 'requires')->required_modules;
require_module($_) foreach @modules;
$cache->{feature_loaded}{$feature_name} = 1;
return 1;
}
sub has_feature {
my ($class, $feature_name) = @_;
return 0 unless _CAN_HAS_FEATURE;
my $cache = $class->request_cache; my $cache = $class->request_cache;
return $cache->{feature}->{$feature} return $cache->{feature}->{$feature_name}
if exists $cache->{feature}->{$feature}; if exists $cache->{feature}->{$feature_name};
my $feature_map = $cache->{feature_map}; my $dir = bz_locations()->{libpath};
if (!$feature_map) { my $feature_map = $cache->{feature_map} //= do {
foreach my $package (@{ OPTIONAL_MODULES() }) { my @meta_json = map { File::Spec->catfile($dir, $_) } qw( MYMETA.json META.json );
foreach my $f (@{ $package->{feature} }) { my $file = first { -f $_ } @meta_json;
$feature_map->{$f} ||= []; my %map;
push(@{ $feature_map->{$f} }, $package); if ($file) {
open my $meta_fh, '<', $file or die "unable to open $file: $!";
my $str = do { local $/ = undef; scalar <$meta_fh> };
trick_taint($str);
close $meta_fh;
my $meta = CPAN::Meta->load_json_string($str);
foreach my $feature ($meta->features) {
$map{$feature->identifier} = $feature->prereqs;
} }
} }
$cache->{feature_map} = $feature_map;
}
if (!$feature_map->{$feature}) { \%map;
ThrowCodeError('invalid_feature', { feature => $feature }); };
}
my $success = 1; ThrowCodeError('invalid_feature', { feature => $feature_name }) if !$feature_map->{$feature_name};
foreach my $package (@{ $feature_map->{$feature} }) { my $success = !verify_dependencies($feature_map->{$feature_name}, 'runtime', 'requires');
have_vers($package) or $success = 0;
} $cache->{feature}{$feature_name} = $success;
$cache->{feature}->{$feature} = $success;
return $success; return $success;
} }
...@@ -1015,8 +1049,12 @@ this Bugzilla installation. ...@@ -1015,8 +1049,12 @@ this Bugzilla installation.
=item C<feature> =item C<feature>
Tells you whether or not a specific feature is enabled. For names Wrapper around C<has_feature()> that also loads all of required modules into the runtime.
of features, see C<OPTIONAL_MODULES> in C<Bugzilla::Install::Requirements>.
=item C<has_feature>
Consults F<MYMETA.yml> for optional Bugzilla features and returns true if all the requirements
are installed.
=item C<api_server> =item C<api_server>
......
...@@ -20,7 +20,7 @@ use Bugzilla::Hook; ...@@ -20,7 +20,7 @@ use Bugzilla::Hook;
use Bugzilla::Util qw(datetime_from trick_taint); use Bugzilla::Util qw(datetime_from trick_taint);
use File::Basename qw(basename); use File::Basename qw(basename);
use File::Glob qw(:bsd_glob); use File::Glob qw(:glob);
use List::MoreUtils qw(none uniq); use List::MoreUtils qw(none uniq);
use MIME::Base64 qw(decode_base64 encode_base64); use MIME::Base64 qw(decode_base64 encode_base64);
use Moo; use Moo;
......
...@@ -516,41 +516,11 @@ use constant INSTALLATION_MODE_NON_INTERACTIVE => 1; ...@@ -516,41 +516,11 @@ use constant INSTALLATION_MODE_NON_INTERACTIVE => 1;
# Data about what we require for different databases. # Data about what we require for different databases.
use constant DB_MODULE => { use constant DB_MODULE => {
# MySQL 5.0.15 was the first production 5.0.x release. # MySQL 5.0.15 was the first production 5.0.x release.
'mysql' => {db => 'Bugzilla::DB::Mysql', db_version => '5.0.15', mysql => { db => 'Bugzilla::DB::Mysql', db_version => '5.0.15', name => 'MySQL'},
dbd => { pg => { db => 'Bugzilla::DB::Pg', db_version => '9.00.0000', name => 'PostgreSQL'},
package => 'DBD-mysql', oracle => { db => 'Bugzilla::DB::Oracle', db_version => '10.02.0', name => 'Oracle'},
module => 'DBD::mysql', # SQLite 3.6.22 fixes a WHERE clause problem that may affect us.
# Disallow development versions sqlite => { db => 'Bugzilla::DB::Sqlite', db_version => '3.6.22', name => 'SQLite'},
blacklist => ['_'],
# For UTF-8 support. 4.001 makes sure that blobs aren't
# marked as UTF-8.
version => '4.001',
},
name => 'MySQL'},
'pg' => {db => 'Bugzilla::DB::Pg', db_version => '9.00.0000',
dbd => {
package => 'DBD-Pg',
module => 'DBD::Pg',
# Pg 9.2 requires 2.19.3 as spclocation no longer exists.
version => '2.19.3',
},
name => 'PostgreSQL'},
'oracle'=> {db => 'Bugzilla::DB::Oracle', db_version => '10.02.0',
dbd => {
package => 'DBD-Oracle',
module => 'DBD::Oracle',
version => '1.19',
},
name => 'Oracle'},
# SQLite 3.6.22 fixes a WHERE clause problem that may affect us.
sqlite => {db => 'Bugzilla::DB::Sqlite', db_version => '3.6.22',
dbd => {
package => 'DBD-SQLite',
module => 'DBD::SQLite',
# 1.29 is the version that contains 3.6.22.
version => '1.29',
},
name => 'SQLite'},
}; };
# True if we're on Win32. # True if we're on Win32.
......
...@@ -165,10 +165,6 @@ sub bz_check_requirements { ...@@ -165,10 +165,6 @@ sub bz_check_requirements {
. bz_locations()->{'localconfig'}; . bz_locations()->{'localconfig'};
} }
# Check the existence and version of the DBD that we need.
my $dbd = $db->{dbd};
_bz_check_dbd($db, $output);
# We don't try to connect to the actual database if $db_check is # We don't try to connect to the actual database if $db_check is
# disabled. # disabled.
unless ($lc->{db_check}) { unless ($lc->{db_check}) {
...@@ -183,27 +179,6 @@ sub bz_check_requirements { ...@@ -183,27 +179,6 @@ sub bz_check_requirements {
print "\n" if $output; print "\n" if $output;
} }
sub _bz_check_dbd {
my ($db, $output) = @_;
my $dbd = $db->{dbd};
unless (have_vers($dbd, $output)) {
my $sql_server = $db->{name};
my $command = install_command($dbd);
my $root = ROOT_USER;
my $dbd_mod = $dbd->{module};
my $dbd_ver = $dbd->{version};
die <<EOT;
For $sql_server, Bugzilla requires that perl's $dbd_mod $dbd_ver or later be
installed. To install this module, run the following command (as $root):
$command
EOT
}
}
sub bz_check_server_version { sub bz_check_server_version {
my ($self, $db, $output) = @_; my ($self, $db, $output) = @_;
......
# 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
...@@ -161,10 +161,8 @@ sub FILESYSTEM { ...@@ -161,10 +161,8 @@ sub FILESYSTEM {
'email_in.pl' => { perms => WS_EXECUTE }, 'email_in.pl' => { perms => WS_EXECUTE },
'sanitycheck.pl' => { perms => WS_EXECUTE }, 'sanitycheck.pl' => { perms => WS_EXECUTE },
'checksetup.pl' => { perms => OWNER_EXECUTE }, 'checksetup.pl' => { perms => OWNER_EXECUTE },
'runtests.pl' => { perms => OWNER_EXECUTE },
'jobqueue.pl' => { perms => OWNER_EXECUTE }, 'jobqueue.pl' => { perms => OWNER_EXECUTE },
'migrate.pl' => { perms => OWNER_EXECUTE }, 'migrate.pl' => { perms => OWNER_EXECUTE },
'install-module.pl' => { perms => OWNER_EXECUTE },
'clean-bug-user-last-visit.pl' => { perms => WS_EXECUTE }, 'clean-bug-user-last-visit.pl' => { perms => WS_EXECUTE },
'app.psgi' => { perms => CGI_READ }, 'app.psgi' => { perms => CGI_READ },
......
...@@ -27,16 +27,11 @@ use parent qw(Exporter); ...@@ -27,16 +27,11 @@ use parent qw(Exporter);
use autodie; use autodie;
our @EXPORT = qw( our @EXPORT = qw(
REQUIRED_MODULES
OPTIONAL_MODULES
FEATURE_FILES FEATURE_FILES
check_requirements check_requirements
check_webdotbase check_webdotbase
check_font_file check_font_file
export_cpanfile
have_vers
install_command
map_files_to_features map_files_to_features
); );
...@@ -74,425 +69,13 @@ use constant APACHE_PATH => [qw( ...@@ -74,425 +69,13 @@ use constant APACHE_PATH => [qw(
/usr/local/libexec /usr/local/libexec
)]; )];
# The below two constants are subroutines so that they can implement
# a hook. Other than that they are actually constants.
# "package" is the perl package we're checking for. "module" is the name
# of the actual module we load with "require" to see if the package is
# installed or not. "version" is the version we need, or 0 if we'll accept
# any version.
#
# "blacklist" is an arrayref of regular expressions that describe versions that
# are 'blacklisted'--that is, even if the version is high enough, Bugzilla
# will refuse to say that it's OK to run with that version.
sub REQUIRED_MODULES {
my @modules = (
{
package => 'CGI.pm',
module => 'CGI',
# 3.51 fixes a security problem that affects Bugzilla.
# (bug 591165)
version => '3.51',
},
{
package => 'Digest-SHA',
module => 'Digest::SHA',
version => 0
},
# 0.23 fixes incorrect handling of 1/2 & 3/4 timezones.
{
package => 'TimeDate',
module => 'Date::Format',
version => '2.23'
},
# 0.75 fixes a warning thrown with Perl 5.17 and newer.
{
package => 'DateTime',
module => 'DateTime',
version => '0.75'
},
# 1.64 fixes a taint issue preventing the local timezone from
# being determined on some systems.
{
package => 'DateTime-TimeZone',
module => 'DateTime::TimeZone',
version => '1.64'
},
# 1.54 is required for Perl 5.10+. It also makes DBD::Oracle happy.
{
package => 'DBI',
module => 'DBI',
version => ($^V >= v5.13.3) ? '1.614' : '1.54'
},
# 2.24 contains several useful text virtual methods.
{
package => 'Template-Toolkit',
module => 'Template',
version => '2.24'
},
# 1.300011 has a debug mode for SMTP and automatically pass -i to sendmail.
{
package => 'Email-Sender',
module => 'Email::Sender',
version => '1.300011',
},
{
package => 'Email-MIME',
module => 'Email::MIME',
# This fixes a memory leak in walk_parts that affected jobqueue.pl.
version => '1.904'
},
{
package => 'URI',
module => 'URI',
# Follows RFC 3986 to escape characters in URI::Escape.
version => '1.55',
},
# 0.32 fixes several memory leaks in the XS version of some functions.
{
package => 'List-MoreUtils',
module => 'List::MoreUtils',
version => 0.32,
},
{
package => 'Math-Random-ISAAC',
module => 'Math::Random::ISAAC',
version => '1.0.1',
},
{
package => 'File-Slurp',
module => 'File::Slurp',
version => '9999.13',
},
{
package => 'JSON-XS',
module => 'JSON::XS',
# 2.0 is the first version that will work with JSON::RPC.
version => '2.01',
},
);
if (ON_WINDOWS) {
push(@modules,
{
package => 'Win32',
module => 'Win32',
# 0.35 fixes a memory leak in GetOSVersion, which we use.
version => 0.35,
},
{
package => 'Win32-API',
module => 'Win32::API',
# 0.55 fixes a bug with char* that might affect Bugzilla::RNG.
version => '0.55',
},
{
package => 'DateTime-TimeZone-Local-Win32',
module => 'DateTime::TimeZone::Local::Win32',
# We require DateTime::TimeZone 1.64, so this version must match.
version => '1.64',
}
);
}
my $extra_modules = _get_extension_requirements('REQUIRED_MODULES');
push(@modules, @$extra_modules);
return \@modules;
};
sub OPTIONAL_MODULES {
my @modules = (
{
package => 'GD',
module => 'GD',
version => '1.20',
feature => [qw(graphical_reports new_charts old_charts)],
},
{
package => 'Chart',
module => 'Chart::Lines',
# Versions below 2.4.10 throw deprecation warnings, and will crash in
# Perl 2.21 and above.
version => '2.4.10',
feature => [qw(new_charts old_charts)],
},
{
package => 'Template-GD',
# This module tells us whether or not Template-GD is installed
# on Template-Toolkits after 2.14, and still works with 2.14 and lower.
module => 'Template::Plugin::GD::Image',
version => 0,
feature => ['graphical_reports'],
},
{
package => 'GDTextUtil',
module => 'GD::Text',
version => 0,
feature => ['graphical_reports'],
},
{
package => 'GDGraph',
module => 'GD::Graph',
version => 0,
feature => ['graphical_reports'],
},
{
package => 'MIME-tools',
# MIME::Parser is packaged as MIME::Tools on ActiveState Perl
module => ON_WINDOWS ? 'MIME::Tools' : 'MIME::Parser',
version => '5.406',
feature => ['moving'],
},
{
package => 'libwww-perl',
module => 'LWP::UserAgent',
version => 0,
feature => ['updates'],
},
{
package => 'XML-Twig',
module => 'XML::Twig',
version => 0,
feature => ['moving', 'updates'],
},
{
package => 'PatchReader',
module => 'PatchReader',
# 0.9.6 fixes two notable bugs and significantly improves the UX.
version => '0.9.6',
feature => ['patch_viewer'],
},
{
package => 'perl-ldap',
module => 'Net::LDAP',
version => 0,
feature => ['auth_ldap'],
},
{
package => 'Authen-SASL',
module => 'Authen::SASL',
version => 0,
feature => ['smtp_auth'],
},
{
package => 'Net-SMTP-SSL',
module => 'Net::SMTP::SSL',
version => 1.01,
feature => ['smtp_ssl'],
},
{
package => 'RadiusPerl',
module => 'Authen::Radius',
version => 0,
feature => ['auth_radius'],
},
# XXX - Once we require XMLRPC::Lite 0.717 or higher, we can
# remove SOAP::Lite from the list.
{
package => 'SOAP-Lite',
module => 'SOAP::Lite',
# Fixes various bugs, including 542931 and 552353 + stops
# throwing warnings with Perl 5.12.
version => '0.712',
# SOAP::Transport::HTTP 1.12 is bogus.
blacklist => ['^1\.12$'],
feature => ['xmlrpc'],
},
# Since SOAP::Lite 1.0, XMLRPC::Lite is no longer included
# and so it must be checked separately.
{
package => 'XMLRPC-Lite',
module => 'XMLRPC::Lite',
version => '0.712',
feature => ['xmlrpc'],
},
{
package => 'JSON-RPC',
module => 'JSON::RPC',
version => 0,
feature => ['jsonrpc'],
},
{
package => 'Plack',
module => 'Plack',
# 1.0031 contains a security fix which would affect us.
# It also fixes warnings thrown in Perl 5.20 and newer.
version => 1.0031,
feature => ['psgi'],
},
{
package => 'CGI-Compile',
module => 'CGI::Compile',
version => 0,
feature => ['psgi'],
},
{
package => 'CGI-Emulate-PSGI',
module => 'CGI::Emulate::PSGI',
version => 0,
feature => ['psgi'],
},
{
package => 'Test-Taint',
module => 'Test::Taint',
# 1.06 no longer throws warnings with Perl 5.10+.
version => 1.06,
feature => ['jsonrpc', 'xmlrpc', 'rest'],
},
{
package => 'Moo',
module => 'Moo',
version => 2,
feature => ['rest']
},
{
package => 'Module-Runtime',
module => 'Module::Runtime',
version => 0,
feature => ['rest']
},
{
package => 'HTTP-Request',
module => 'HTTP::Request',
version => 0,
feature => ['rest']
},
{
package => 'HTTP-Response',
module => 'HTTP::Response',
version => 0,
feature => ['rest']
},
{
# We need the 'utf8_mode' method of HTML::Parser, for HTML::Scrubber.
package => 'HTML-Parser',
module => 'HTML::Parser',
version => ($^V >= v5.13.3) ? '3.67' : '3.40',
feature => ['html_desc'],
},
{
package => 'HTML-Scrubber',
module => 'HTML::Scrubber',
version => 0,
feature => ['html_desc'],
},
{
# we need version 2.21 of Encode for mime_name
package => 'Encode',
module => 'Encode',
version => 2.21,
feature => ['detect_charset'],
},
{
package => 'Encode-Detect',
module => 'Encode::Detect',
version => 0,
feature => ['detect_charset'],
},
# Inbound Email
{
package => 'Email-Reply',
module => 'Email::Reply',
version => 0,
feature => ['inbound_email'],
},
{
package => 'HTML-FormatText-WithLinks',
module => 'HTML::FormatText::WithLinks',
# We need 0.13 to set the "bold" marker to "*".
version => '0.13',
feature => ['inbound_email'],
},
# Mail Queueing
{
package => 'TheSchwartz',
module => 'TheSchwartz',
# 1.10 supports declining of jobs.
version => 1.10,
feature => ['jobqueue'],
},
{
package => 'Daemon-Generic',
module => 'Daemon::Generic',
version => 0,
feature => ['jobqueue'],
},
# mod_perl
{
package => 'mod_perl',
module => 'mod_perl2',
version => '1.999022',
feature => ['mod_perl'],
},
{
package => 'Apache-SizeLimit',
module => 'Apache2::SizeLimit',
# 0.96 properly determines process size on Linux.
version => '0.96',
feature => ['mod_perl'],
},
# typesniffer
{
package => 'File-MimeInfo',
module => 'File::MimeInfo::Magic',
version => '0',
feature => ['typesniffer'],
},
{
package => 'IO-stringy',
module => 'IO::Scalar',
version => '0',
feature => ['typesniffer'],
},
# memcached
{
package => 'Cache-Memcached-Fast',
module => 'Cache::Memcached::Fast',
version => '0.17',
feature => ['memcached'],
},
# Markdown
{
package => 'Text-MultiMarkdown',
module => 'Text::MultiMarkdown',
# 1.0.34 supports definition lists.
version => '1.000034',
feature => ['markdown'],
},
# Documentation
{
package => 'File-Copy-Recursive',
module => 'File::Copy::Recursive',
version => 0,
feature => ['documentation'],
},
{
package => 'File-Which',
module => 'File::Which',
version => 0,
feature => ['documentation'],
},
);
my $extra_modules = _get_extension_requirements('OPTIONAL_MODULES');
push(@modules, @$extra_modules);
return \@modules;
};
# This maps features to the files that require that feature in order # This maps features to the files that require that feature in order
# to compile. It is used by t/001compile.t and mod_perl.pl. # to compile. It is used by t/001compile.t and mod_perl.pl.
use constant FEATURE_FILES => ( use constant FEATURE_FILES => (
jsonrpc => ['Bugzilla/WebService/Server/JSONRPC.pm', 'jsonrpc.cgi'], jsonrpc => ['Bugzilla/WebService/Server/JSONRPC.pm', 'jsonrpc.cgi'],
xmlrpc => ['Bugzilla/WebService/Server/XMLRPC.pm', 'xmlrpc.cgi', xmlrpc => ['Bugzilla/WebService/Server/XMLRPC.pm', 'xmlrpc.cgi',
'Bugzilla/WebService.pm', 'Bugzilla/WebService/*.pm'], 'Bugzilla/WebService.pm', 'Bugzilla/WebService/*.pm'],
rest => ['Bugzilla/API/Server.pm', 'rest.cgi', rest => ['Bugzilla/API/Server.pm', 'rest.cgi', 'Bugzilla/API/*/*.pm',
'Bugzilla/API/*/Server.pm', 'Bugzilla/API/*/Resource/*.pm'], 'Bugzilla/API/*/Server.pm', 'Bugzilla/API/*/Resource/*.pm'],
psgi => ['app.psgi'], psgi => ['app.psgi'],
moving => ['importxml.pl'], moving => ['importxml.pl'],
...@@ -506,71 +89,19 @@ use constant FEATURE_FILES => ( ...@@ -506,71 +89,19 @@ use constant FEATURE_FILES => (
updates => ['Bugzilla/Update.pm'], updates => ['Bugzilla/Update.pm'],
markdown => ['Bugzilla/Markdown.pm'], markdown => ['Bugzilla/Markdown.pm'],
memcached => ['Bugzilla/Memcache.pm'], memcached => ['Bugzilla/Memcache.pm'],
auth_delegation => ['auth.cgi'],
); );
# This implements the REQUIRED_MODULES and OPTIONAL_MODULES stuff
# described in in Bugzilla::Extension.
sub _get_extension_requirements {
my ($function) = @_;
my $packages = extension_requirement_packages();
my @modules;
foreach my $package (@$packages) {
if ($package->can($function)) {
my $extra_modules = $package->$function;
push(@modules, @$extra_modules);
}
}
return \@modules;
};
sub check_requirements { sub check_requirements {
my ($output) = @_; my ($output) = @_;
print "\n", install_string('checking_modules'), "\n" if $output;
my $root = ROOT_USER;
my $missing = _check_missing(REQUIRED_MODULES, $output);
print "\n", install_string('checking_dbd'), "\n" if $output;
my $have_one_dbd = 0;
my $db_modules = DB_MODULE;
foreach my $db (keys %$db_modules) {
my $dbd = $db_modules->{$db}->{dbd};
$have_one_dbd = 1 if have_vers($dbd, $output);
}
print "\n", install_string('checking_optional'), "\n" if $output;
my $missing_optional = _check_missing(OPTIONAL_MODULES, $output);
my $missing_apache = _missing_apache_modules(APACHE_MODULES, $output); my $missing_apache = _missing_apache_modules(APACHE_MODULES, $output);
# If we're running on Windows, reset the input line terminator so that # If we're running on Windows, reset the input line terminator so that
# console input works properly - loading CGI tends to mess it up # console input works properly - loading CGI tends to mess it up
$/ = "\015\012" if ON_WINDOWS; $/ = "\015\012" if ON_WINDOWS;
my $pass = !scalar(@$missing) && $have_one_dbd; return { apache => $missing_apache };
return {
pass => $pass,
one_dbd => $have_one_dbd,
missing => $missing,
optional => $missing_optional,
apache => $missing_apache,
any_missing => !$pass || scalar(@$missing_optional),
};
}
# A helper for check_requirements
sub _check_missing {
my ($modules, $output) = @_;
my @missing;
foreach my $module (@$modules) {
unless (have_vers($module, $output)) {
push(@missing, $module);
}
}
return \@missing;
} }
sub _missing_apache_modules { sub _missing_apache_modules {
...@@ -621,109 +152,6 @@ sub _check_apache_module { ...@@ -621,109 +152,6 @@ sub _check_apache_module {
return $ok; return $ok;
} }
sub print_module_instructions {
my ($check_results, $output) = @_;
# First we print the long explanatory messages.
if (scalar @{$check_results->{missing}}) {
print install_string('modules_message_required');
}
if (!$check_results->{one_dbd}) {
print install_string('modules_message_db');
}
if (my @missing = @{$check_results->{optional}} and $output) {
print install_string('modules_message_optional');
# Now we have to determine how large the table cols will be.
my $longest_name = max(map(length($_->{package}), @missing));
# The first column header is at least 11 characters long.
$longest_name = 11 if $longest_name < 11;
# The table is TABLE_WIDTH characters long. There are seven mandatory
# characters (* and space) in the string. So, we have a total
# of TABLE_WIDTH - 7 characters to work with.
my $remaining_space = (TABLE_WIDTH - 7) - $longest_name;
print '*' x TABLE_WIDTH . "\n";
printf "* \%${longest_name}s * %-${remaining_space}s *\n",
'MODULE NAME', 'ENABLES FEATURE(S)';
print '*' x TABLE_WIDTH . "\n";
foreach my $package (@missing) {
printf "* \%${longest_name}s * %-${remaining_space}s *\n",
$package->{package},
_translate_feature($package->{feature});
}
}
if (my @missing = @{ $check_results->{apache} }) {
print install_string('modules_message_apache');
my $missing_string = join(', ', @missing);
my $size = TABLE_WIDTH - 7;
printf "* \%-${size}s *\n", $missing_string;
my $spaces = TABLE_WIDTH - 2;
print "*", (' ' x $spaces), "*\n";
}
my $need_module_instructions =
( (!$output and @{$check_results->{missing}})
or ($output and $check_results->{any_missing}) ) ? 1 : 0;
if ($need_module_instructions or @{ $check_results->{apache} }) {
# If any output was required, we want to close the "table"
print "*" x TABLE_WIDTH . "\n";
}
# And now we print the actual installation commands.
if (my @missing = @{$check_results->{optional}} and $output) {
print install_string('commands_optional') . "\n\n";
foreach my $module (@missing) {
my $command = install_command($module);
printf "%15s: $command\n", $module->{package};
}
print "\n";
}
if (!$check_results->{one_dbd}) {
print install_string('commands_dbd') . "\n";
my %db_modules = %{DB_MODULE()};
foreach my $db (keys %db_modules) {
my $command = install_command($db_modules{$db}->{dbd});
printf "%10s: \%s\n", $db_modules{$db}->{name}, $command;
}
print "\n";
}
if (my @missing = @{$check_results->{missing}}) {
print colored(install_string('commands_required'), COLOR_ERROR), "\n";
foreach my $package (@missing) {
my $command = install_command($package);
print " $command\n";
}
}
if ($output && $check_results->{any_missing} && !ON_ACTIVESTATE
&& !$check_results->{hide_all})
{
print install_string('install_all', { perl => $^X });
}
if (!$check_results->{pass}) {
print colored(install_string('installation_failed'), COLOR_ERROR),
"\n\n";
}
}
sub _translate_feature {
my $features = shift;
my @strings;
foreach my $feature (@$features) {
push(@strings, install_string("feature_$feature"));
}
return join(', ', @strings);
}
sub check_webdotbase { sub check_webdotbase {
my ($output) = @_; my ($output) = @_;
...@@ -781,59 +209,6 @@ sub check_font_file { ...@@ -781,59 +209,6 @@ sub check_font_file {
return $readable && $ttf; return $readable && $ttf;
} }
# This was originally clipped from the libnet Makefile.PL, adapted here for
# accurate version checking.
sub have_vers {
my ($params, $output) = @_;
my $module = $params->{module};
my $package = $params->{package};
if (!$package) {
$package = $module;
$package =~ s/::/-/g;
}
my $wanted = $params->{version};
eval "require $module;";
# Don't let loading a module change the output-encoding of STDOUT
# or STDERR. (CGI.pm tries to set "binmode" on these file handles when
# it's loaded, and other modules may do the same in the future.)
Bugzilla::Install::Util::set_output_encoding();
# VERSION is provided by UNIVERSAL::, and can be called even if
# the module isn't loaded. We eval'uate ->VERSION because it can die
# when the version is not valid (yes, this happens from time to time).
# In that case, we use an uglier method to get the version.
my $vnum = eval { $module->VERSION };
if ($@) {
no strict 'refs';
$vnum = ${"${module}::VERSION"};
# If we come here, then the version is not a valid one.
# We try to sanitize it.
if ($vnum =~ /^((\d+)(\.\d+)*)/) {
$vnum = $1;
}
}
$vnum ||= -1;
# Must do a string comparison as $vnum may be of the form 5.10.1.
my $vok = ($vnum ne '-1' && version->new($vnum) >= version->new($wanted)) ? 1 : 0;
my $blacklisted;
if ($vok && $params->{blacklist}) {
$blacklisted = grep($vnum =~ /$_/, @{$params->{blacklist}});
$vok = 0 if $blacklisted;
}
if ($output) {
_checking_for({
package => $package, ok => $vok, wanted => $wanted,
found => $vnum, blacklisted => $blacklisted
});
}
return $vok ? 1 : 0;
}
sub _checking_for { sub _checking_for {
my ($params) = @_; my ($params) = @_;
my ($package, $ok, $wanted, $blacklisted, $found) = my ($package, $ok, $wanted, $blacklisted, $found) =
...@@ -872,23 +247,6 @@ sub _checking_for { ...@@ -872,23 +247,6 @@ sub _checking_for {
print $ok ? $str : colored($str, COLOR_ERROR); print $ok ? $str : colored($str, COLOR_ERROR);
} }
sub install_command {
my $module = shift;
my ($command, $package);
if (ON_ACTIVESTATE) {
$command = 'ppm install %s';
$package = $module->{package};
}
else {
$command = "$^X install-module.pl \%s";
# Non-Windows installations need to use module names, because
# CPAN doesn't understand package names.
$package = $module->{module};
}
return sprintf $command, $package;
}
# This does a reverse mapping for FEATURE_FILES. # This does a reverse mapping for FEATURE_FILES.
sub map_files_to_features { sub map_files_to_features {
my %features = FEATURE_FILES; my %features = FEATURE_FILES;
...@@ -904,68 +262,6 @@ sub map_files_to_features { ...@@ -904,68 +262,6 @@ sub map_files_to_features {
return \%files; return \%files;
} }
sub export_cpanfile {
my $cpanfile;
# Required modules
foreach my $module (@{ REQUIRED_MODULES() }) {
my $requires = "requires '" . $module->{module} . "'";
$requires .= ", '" . $module->{version} . "'" if $module->{version};
$requires .= ";\n";
$cpanfile .= $requires;
}
# Recommended modules
$cpanfile .= "\n# Optional\n";
my %features;
foreach my $module (@{ OPTIONAL_MODULES() }) {
next if $module->{package} eq 'mod_perl'; # Skip mod_perl since this would be installed by distro
if (exists $module->{feature}) {
foreach my $feature (@{ $module->{feature} }) {
# cpanm requires that each feature only be defined in the cpanfile
# once, so we use an intermediate hash to consolidate/de-dupe the
# modules associated with each feature.
$features{$feature}{$module->{module}} = $module->{version};
}
}
else {
my $recommends = "";
$recommends .= "recommends '" . $module->{module} . "'";
$recommends .= ", '" . $module->{version} . "'" if $module->{version};
$recommends .= ";\n";
$cpanfile .= $recommends;
}
}
foreach my $feature (sort keys %features) {
my $recommends = "";
$recommends .= "feature '" . $feature . "' => sub {\n";
foreach my $module (sort keys %{ $features{$feature} }) {
my $version = $features{$feature}{$module};
$recommends .= " recommends '" . $module . "'";
$recommends .= ", '$version'" if $version;
$recommends .= ";\n";
}
$recommends .= "};\n";
$cpanfile .= $recommends;
}
# Database modules
$cpanfile .= "\n# Database support\n";
foreach my $db (keys %{ DB_MODULE() }) {
next if !exists DB_MODULE->{$db}->{dbd};
my $dbd = DB_MODULE->{$db}->{dbd};
my $recommends .= "feature '$db' => sub {\n";
$recommends .= " recommends '" . $dbd->{module} . "'";
$recommends .= ", '" . $dbd->{version} . "'" if $dbd->{version};
$recommends .= ";\n};\n";
$cpanfile .= $recommends;
}
# Write out the cpanfile to the document root
my $file = bz_locations()->{'libpath'} . '/cpanfile';
open(my $fh, '>', $file);
print $fh $cpanfile;
close $fh;
success(install_string('cpanfile_created', { file => $file }));
}
1; 1;
__END__ __END__
...@@ -985,31 +281,6 @@ perl modules it requires.) ...@@ -985,31 +281,6 @@ perl modules it requires.)
=over =over
=item C<REQUIRED_MODULES>
An arrayref of hashrefs that describes the perl modules required by
Bugzilla. The hashes have three keys:
=over
=item C<package> - The name of the Perl package that you'd find on
CPAN for this requirement.
=item C<module> - The name of a module that can be passed to the
C<install> command in C<CPAN.pm> to install this module.
=item C<version> - The version of this module that we require, or C<0>
if any version is acceptable.
=back
=item C<OPTIONAL_MODULES>
An arrayref of hashrefs that describes the perl modules that add
additional features to Bugzilla if installed. Its hashes have all
the fields of L</REQUIRED_MODULES>, plus a C<feature> item--an arrayref
of strings that describe what features require this module.
=item C<FEATURE_FILES> =item C<FEATURE_FILES>
A hashref that describes what files should only be compiled if a certain A hashref that describes what files should only be compiled if a certain
...@@ -1047,21 +318,8 @@ A hashref containing these values: ...@@ -1047,21 +318,8 @@ A hashref containing these values:
=over =over
=item C<pass> - Whether or not we have all the mandatory requirements.
=item C<missing> - An arrayref containing any required modules that
are not installed or that are not up-to-date. Each item in the array is
a hashref in the format of items from L</REQUIRED_MODULES>.
=item C<optional> - The same as C<missing>, but for optional modules.
=item C<apache> - The name of each optional Apache module that is missing. =item C<apache> - The name of each optional Apache module that is missing.
=item C<have_one_dbd> - True if at least one C<DBD::> module is installed.
=item C<any_missing> - True if there are any missing Perl modules, even
optional modules.
=back =back
=back =back
...@@ -1086,45 +344,6 @@ Params: C<$output> - C<$true> if you want the function to ...@@ -1086,45 +344,6 @@ Params: C<$output> - C<$true> if you want the function to
Returns: C<1> if the check was successful, C<0> otherwise. Returns: C<1> if the check was successful, C<0> otherwise.
=item C<export_cpanfile>
Description: Based on C<REQUIRED_MODULES> and C<OPTIONAL_MODULES>,
the function outputs text useful for writing to a
C<cpanfile>. C<cpanfile> can be used by utilities
such as C<cpanm> for installing the Perl dependencies
needed by an application.
Params: None
Returns: Text output for writing to a C<cpanfile>.
=item C<have_vers($module, $output)>
Description: Tells you whether or not you have the appropriate
version of the module requested. It also prints
out a message to the user explaining the check
and the result.
Params: C<$module> - A hashref, in the format of an item from
L</REQUIRED_MODULES>.
C<$output> - Set to true if you want this function to
print information to STDOUT about what it's
doing.
Returns: C<1> if you have the module installed and you have the
appropriate version. C<0> otherwise.
=item C<install_command($module)>
Description: Prints out the appropriate command to install the
module specified, depending on whether you're
on Windows or Linux.
Params: C<$module> - A hashref, in the format of an item from
L</REQUIRED_MODULES>.
Returns: nothing
=item C<map_files_to_features> =item C<map_files_to_features>
Returns a hashref where file names are the keys and the value is the feature Returns a hashref where file names are the keys and the value is the feature
...@@ -1132,10 +351,3 @@ that must be enabled in order to compile that file. ...@@ -1132,10 +351,3 @@ that must be enabled in order to compile that file.
=back =back
=head1 B<Methods in need of POD>
=over
=item print_module_instructions
=back
...@@ -506,9 +506,9 @@ sub _UnescapeSpecialChars { ...@@ -506,9 +506,9 @@ sub _UnescapeSpecialChars {
# are bound together with underscores, the string has the desired form. # are bound together with underscores, the string has the desired form.
sub _has_multiple_underscores { sub _has_multiple_underscores {
my $string = shift; my $string = shift;
return 0 unless defined($string) && length($string); return 0 unless $string;
return 0 if $string =~ /[\t\s]+/; return 0 if $string =~ /\s/;
return 1 if scalar (split /_/, $string) > 1; return 1 if $string =~ /_/;
return 0; return 0;
} }
......
{
"abstract" : "Bugzilla Bug Tracking System",
"author" : [
"Bugzilla Developers <developers@bugzilla.org>"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150005",
"license" : [
"unknown"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : "2"
},
"name" : "Bugzilla",
"no_index" : {
"directory" : [
"t",
"inc"
]
},
"optional_features" : {
"auth_delegation" : {
"description" : "Auth Delegation",
"prereqs" : {
"runtime" : {
"requires" : {
"LWP::UserAgent" : "0"
}
}
}
},
"auth_ldap" : {
"description" : "LDAP Authentication",
"prereqs" : {
"runtime" : {
"requires" : {
"Net::LDAP" : "0"
}
}
}
},
"auth_radius" : {
"description" : "RADIUS Authentication",
"prereqs" : {
"runtime" : {
"requires" : {
"Authen::Radius" : "0"
}
}
}
},
"detect_charset" : {
"description" : "Automatic charset detection for text attachments",
"prereqs" : {
"runtime" : {
"requires" : {
"Encode" : "2.21",
"Encode::Detect" : "0"
}
}
}
},
"documentation" : {
"description" : "Documentation",
"prereqs" : {
"runtime" : {
"requires" : {
"File::Copy::Recursive" : "0",
"File::Which" : "0"
}
}
}
},
"features" : {
"description" : "Base support for Features",
"prereqs" : {
"runtime" : {
"requires" : {
"CPAN::Meta" : "0",
"CPAN::Meta::Check" : "0",
"Module::Runtime" : "0"
}
}
}
},
"graphical_reports" : {
"description" : "Graphical Reports",
"prereqs" : {
"runtime" : {
"requires" : {
"GD" : "1.20",
"GD::Graph" : "0",
"GD::Text" : "0",
"Template::Plugin::GD::Image" : "0"
}
}
}
},
"html_desc" : {
"description" : "More HTML in Product/Group Descriptions",
"prereqs" : {
"runtime" : {
"requires" : {
"HTML::Parser" : "3.67",
"HTML::Scrubber" : "0"
}
}
}
},
"inbound_email" : {
"description" : "Inbound Email",
"prereqs" : {
"runtime" : {
"requires" : {
"Email::Reply" : "0",
"HTML::FormatText::WithLinks" : "0.13"
}
}
}
},
"jobqueue" : {
"description" : "Mail Queueing",
"prereqs" : {
"runtime" : {
"requires" : {
"Daemon::Generic" : "0",
"TheSchwartz" : "1.1"
}
}
}
},
"jsonrpc" : {
"description" : "JSON-RPC Interface",
"prereqs" : {
"runtime" : {
"requires" : {
"JSON::RPC" : "0",
"Test::Taint" : "1.06"
}
}
}
},
"markdown" : {
"description" : "Markdown syntax support for comments",
"prereqs" : {
"runtime" : {
"requires" : {
"Text::MultiMarkdown" : "1.000034"
}
}
}
},
"memcached" : {
"description" : "Memcached Support",
"prereqs" : {
"runtime" : {
"requires" : {
"Cache::Memcached::Fast" : "0.17"
}
}
}
},
"mod_perl" : {
"description" : "mod_perl support under Apache",
"prereqs" : {
"runtime" : {
"requires" : {
"mod_perl2" : "0"
}
}
}
},
"moving" : {
"description" : "Move Bugs Between Installations",
"prereqs" : {
"runtime" : {
"requires" : {
"MIME::Parser" : "5.406",
"XML::Twig" : "0"
}
}
}
},
"mysql" : {
"description" : "MySQL database support",
"prereqs" : {
"runtime" : {
"requires" : {
"DBD::mysql" : "4.001"
}
}
}
},
"new_charts" : {
"description" : "New Charts",
"prereqs" : {
"runtime" : {
"requires" : {
"Chart::Lines" : "v2.4.10",
"GD" : "1.20"
}
}
}
},
"old_charts" : {
"description" : "Old Charts",
"prereqs" : {
"runtime" : {
"requires" : {
"Chart::Lines" : "v2.4.10",
"GD" : "1.20"
}
}
}
},
"oracle" : {
"description" : "Oracle database support",
"prereqs" : {
"runtime" : {
"requires" : {
"DBD::Oracle" : "1.19"
}
}
}
},
"patch_viewer" : {
"description" : "Patch Viewer",
"prereqs" : {
"runtime" : {
"requires" : {
"PatchReader" : "v0.9.6"
}
}
}
},
"pg" : {
"description" : "Postgres database support",
"prereqs" : {
"runtime" : {
"requires" : {
"DBD::Pg" : "v2.19.3"
}
}
}
},
"psgi" : {
"description" : "Plack/PSGI support",
"prereqs" : {
"runtime" : {
"requires" : {
"CGI::Compile" : "0",
"CGI::Emulate::PSGI" : "0",
"Plack" : "1.0031"
}
}
}
},
"rest" : {
"description" : "REST Interface",
"prereqs" : {
"runtime" : {
"requires" : {
"HTTP::Request" : "0",
"HTTP::Response" : "0",
"Module::Runtime" : "0",
"Moo" : "2",
"Test::Taint" : "1.06"
}
}
}
},
"smtp_auth" : {
"description" : "SMTP Authentication",
"prereqs" : {
"runtime" : {
"requires" : {
"Authen::SASL" : "0"
}
}
}
},
"smtp_ssl" : {
"description" : "SSL Support for SMTP",
"prereqs" : {
"runtime" : {
"requires" : {
"Net::SMTP::SSL" : "1.01"
}
}
}
},
"sqlite" : {
"description" : "SQLite database support",
"prereqs" : {
"runtime" : {
"requires" : {
"DBD::SQLite" : "1.29"
}
}
}
},
"typesniffer" : {
"description" : "Sniff MIME type of attachments",
"prereqs" : {
"runtime" : {
"requires" : {
"File::MimeInfo::Magic" : "0",
"IO::Scalar" : "0"
}
}
}
},
"updates" : {
"description" : "Automatic Update Notifications",
"prereqs" : {
"runtime" : {
"requires" : {
"LWP::UserAgent" : "0",
"XML::Twig" : "0"
}
}
}
},
"xmlrpc" : {
"description" : "XML-RPC Interface",
"prereqs" : {
"runtime" : {
"requires" : {
"SOAP::Lite" : "0.712",
"Test::Taint" : "1.06",
"XMLRPC::Lite" : "0.712"
}
}
}
}
},
"prereqs" : {
"build" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "6.55"
}
},
"runtime" : {
"requires" : {
"CGI" : "3.51",
"DBI" : "1.614",
"Date::Format" : "2.23",
"DateTime" : "0.75",
"DateTime::TimeZone" : "1.64",
"Digest::SHA" : "0",
"Email::MIME" : "1.904",
"Email::Sender" : "1.300011",
"File::Slurp" : "9999.13",
"JSON::XS" : "2.01",
"List::MoreUtils" : "0.32",
"Math::Random::ISAAC" : "v1.0.1",
"Template" : "2.24",
"URI" : "1.55",
"perl" : "5.010001"
}
},
"test" : {
"requires" : {
"Pod::Coverage" : "0",
"Test::More" : "0",
"Test::Perl::Critic" : "0"
}
}
},
"release_status" : "stable",
"version" : "5.1",
"x_serialization_backend" : "JSON::PP version 2.27300"
}
---
abstract: 'Bugzilla Bug Tracking System'
author:
- 'Bugzilla Developers <developers@bugzilla.org>'
build_requires:
ExtUtils::MakeMaker: '0'
Pod::Coverage: '0'
Test::More: '0'
Test::Perl::Critic: '0'
configure_requires:
ExtUtils::MakeMaker: '6.55'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150005'
license: unknown
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: '1.4'
name: Bugzilla
no_index:
directory:
- t
- inc
optional_features:
auth_delegation:
description: 'Auth Delegation'
requires:
LWP::UserAgent: '0'
auth_ldap:
description: 'LDAP Authentication'
requires:
Net::LDAP: '0'
auth_radius:
description: 'RADIUS Authentication'
requires:
Authen::Radius: '0'
detect_charset:
description: 'Automatic charset detection for text attachments'
requires:
Encode: '2.21'
Encode::Detect: '0'
documentation:
description: Documentation
requires:
File::Copy::Recursive: '0'
File::Which: '0'
features:
description: 'Base support for Features'
requires:
CPAN::Meta: '0'
CPAN::Meta::Check: '0'
Module::Runtime: '0'
graphical_reports:
description: 'Graphical Reports'
requires:
GD: '1.20'
GD::Graph: '0'
GD::Text: '0'
Template::Plugin::GD::Image: '0'
html_desc:
description: 'More HTML in Product/Group Descriptions'
requires:
HTML::Parser: '3.67'
HTML::Scrubber: '0'
inbound_email:
description: 'Inbound Email'
requires:
Email::Reply: '0'
HTML::FormatText::WithLinks: '0.13'
jobqueue:
description: 'Mail Queueing'
requires:
Daemon::Generic: '0'
TheSchwartz: '1.1'
jsonrpc:
description: 'JSON-RPC Interface'
requires:
JSON::RPC: '0'
Test::Taint: '1.06'
markdown:
description: 'Markdown syntax support for comments'
requires:
Text::MultiMarkdown: '1.000034'
memcached:
description: 'Memcached Support'
requires:
Cache::Memcached::Fast: '0.17'
mod_perl:
description: 'mod_perl support under Apache'
requires:
mod_perl2: '0'
moving:
description: 'Move Bugs Between Installations'
requires:
MIME::Parser: '5.406'
XML::Twig: '0'
mysql:
description: 'MySQL database support'
requires:
DBD::mysql: '4.001'
new_charts:
description: 'New Charts'
requires:
Chart::Lines: v2.4.10
GD: '1.20'
old_charts:
description: 'Old Charts'
requires:
Chart::Lines: v2.4.10
GD: '1.20'
oracle:
description: 'Oracle database support'
requires:
DBD::Oracle: '1.19'
patch_viewer:
description: 'Patch Viewer'
requires:
PatchReader: v0.9.6
pg:
description: 'Postgres database support'
requires:
DBD::Pg: v2.19.3
psgi:
description: 'Plack/PSGI support'
requires:
CGI::Compile: '0'
CGI::Emulate::PSGI: '0'
Plack: '1.0031'
rest:
description: 'REST Interface'
requires:
HTTP::Request: '0'
HTTP::Response: '0'
Module::Runtime: '0'
Moo: '2'
Test::Taint: '1.06'
smtp_auth:
description: 'SMTP Authentication'
requires:
Authen::SASL: '0'
smtp_ssl:
description: 'SSL Support for SMTP'
requires:
Net::SMTP::SSL: '1.01'
sqlite:
description: 'SQLite database support'
requires:
DBD::SQLite: '1.29'
typesniffer:
description: 'Sniff MIME type of attachments'
requires:
File::MimeInfo::Magic: '0'
IO::Scalar: '0'
updates:
description: 'Automatic Update Notifications'
requires:
LWP::UserAgent: '0'
XML::Twig: '0'
xmlrpc:
description: 'XML-RPC Interface'
requires:
SOAP::Lite: '0.712'
Test::Taint: '1.06'
XMLRPC::Lite: '0.712'
requires:
CGI: '3.51'
DBI: '1.614'
Date::Format: '2.23'
DateTime: '0.75'
DateTime::TimeZone: '1.64'
Digest::SHA: '0'
Email::MIME: '1.904'
Email::Sender: '1.300011'
File::Slurp: '9999.13'
JSON::XS: '2.01'
List::MoreUtils: '0.32'
Math::Random::ISAAC: v1.0.1
Template: '2.24'
URI: '1.55'
perl: '5.010001'
version: '5.1'
x_serialization_backend: 'CPAN::Meta::YAML version 0.012'
#!/usr/bin/perl
# 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.
# This file has detailed POD docs, do "perldoc checksetup.pl" to see them.
######################################################################
# Initialization
######################################################################
use 5.10.1;
use strict;
use warnings;
use lib qw(. lib local/lib/perl5);
use ExtUtils::MakeMaker 6.55;
use Bugzilla::Constants qw(BUGZILLA_VERSION);
use File::Basename;
use File::Spec;
# META.json and META.yml exist only for the benefit of older
# installs where cpanm can't get the optional features out of Makefile.PL
# Unfortunately having META.json and META.yml commited to the repo is weird
# and MakeMaker always prefers their content to the internal data (unless CPAN::META
# is not installed).
# Since we (Bugzilla) require this cludge, we hide the files from MakeMaker.
BEGIN {
warn "Hiding META.{json,yml} from MakeMaker...\n";
rename('META.json', 'META.json.hide') || unlink("META.json");
rename('META.yml', 'META.yml.hide') || unlink("META.yml");
}
END {
warn "Unhiding META.{json,yml}...\n";
rename('META.json.hide', 'META.json');
rename('META.yml.hide', 'META.yml');
}
# PREREQ_PM
my %requires = (
'CGI' => '3.51',
'DBI' => '1.614',
'Date::Format' => '2.23',
'DateTime' => '0.75',
'DateTime::TimeZone' => '1.64',
'Digest::SHA' => 0,
'Email::MIME' => '1.904',
'Email::Sender' => '1.300011',
'File::Slurp' => '9999.13',
'JSON::XS' => '2.01',
'List::MoreUtils' => '0.32',
'Math::Random::ISAAC' => '1.0.1',
'Template' => '2.24',
'URI' => '1.55',
);
my %optional_features = (
features => {
prereqs => { runtime => { requires => { 'CPAN::Meta::Check' => 0, 'Module::Runtime' => 0, 'CPAN::Meta' => 0, }, }, },
description => "Base support for Features"
},
smtp_auth => {
prereqs => { runtime => { requires => { 'Authen::SASL' => 0 } } },
description => 'SMTP Authentication'
},
detect_charset => {
prereqs => { runtime => { requires => { 'Encode::Detect' => 0, Encode => '2.21' } } },
description => 'Automatic charset detection for text attachments'
},
new_charts => {
description => 'New Charts',
prereqs => { runtime => { requires => { 'Chart::Lines' => 'v2.4.10', GD => '1.20' } } }
},
html_desc => {
description => 'More HTML in Product/Group Descriptions',
prereqs => { runtime => { requires => { 'HTML::Parser' => '3.67', 'HTML::Scrubber' => 0 } } }
},
markdown => {
description => 'Markdown syntax support for comments',
prereqs => { runtime => { requires => { 'Text::MultiMarkdown' => '1.000034' } } }
},
pg => {
prereqs => { runtime => { requires => { 'DBD::Pg' => 'v2.19.3' } } },
description => 'Postgres database support'
},
memcached => {
description => 'Memcached Support',
prereqs => { runtime => { requires => { 'Cache::Memcached::Fast' => '0.17' } } }
},
auth_delegation => {
description => 'Auth Delegation',
prereqs => { runtime => { requires => { 'LWP::UserAgent' => 0 } } }
},
updates => {
description => 'Automatic Update Notifications',
prereqs => { runtime => { requires => { 'LWP::UserAgent' => 0, 'XML::Twig' => 0 } } }
},
auth_radius => {
description => 'RADIUS Authentication',
prereqs => { runtime => { requires => { 'Authen::Radius' => 0 } } }
},
documentation => {
prereqs => { runtime => { requires => { 'File::Which' => 0, 'File::Copy::Recursive' => 0 } } },
description => 'Documentation',
},
xmlrpc => {
description => 'XML-RPC Interfaze',
prereqs => {
runtime =>
{ requires => { 'XMLRPC::Lite' => '0.712', 'SOAP::Lite' => '0.712', 'Test::Taint' => '1.06' } }
}
},
auth_ldap => {
prereqs => { runtime => { requires => { 'Net::LDAP' => 0 } } },
description => 'LDAP Authentication'
},
old_charts => {
prereqs => { runtime => { requires => { GD => '1.20', 'Chart::Lines' => 'v2.4.10' } } },
description => 'Old Charts'
},
moving => {
prereqs => { runtime => { requires => { 'MIME::Parser' => '5.406', 'XML::Twig' => 0 } } },
description => 'Move Bugs Between Installations'
},
oracle => {
description => 'Oracle database support',
prereqs => { runtime => { requires => { 'DBD::Oracle' => '1.19' } } }
},
typesniffer => {
prereqs => { runtime => { requires => { 'IO::Scalar' => 0, 'File::MimeInfo::Magic' => 0 } } },
description => 'Sniff MIME type of attachments'
},
sqlite => {
prereqs => { runtime => { requires => { 'DBD::SQLite' => '1.29' } } },
description => 'SQLite database support'
},
smtp_ssl => {
prereqs => { runtime => { requires => { 'Net::SMTP::SSL' => '1.01' } } },
description => 'SSL Support for SMTP'
},
mysql => {
description => 'MySQL database support',
prereqs => { runtime => { requires => { 'DBD::mysql' => '4.001' } } }
},
jsonrpc => {
description => 'JSON-RPC Interface',
prereqs => { runtime => { requires => { 'JSON::RPC' => 0, 'Test::Taint' => '1.06' } } }
},
graphical_reports => {
description => 'Graphical Reports',
prereqs => {
runtime => {
requires => {
'GD::Text' => 0,
'Template::Plugin::GD::Image' => 0,
'GD::Graph' => 0,
GD => '1.20',
}
}
}
},
mod_perl => {
description => 'mod_perl support under Apache',
prereqs => { runtime => { requires => { 'mod_perl2' => '0' } } }
},
inbound_email => {
prereqs => { runtime => { requires => { 'Email::Reply' => 0, 'HTML::FormatText::WithLinks' => '0.13' } } },
description => 'Inbound Email'
},
patch_viewer => {
description => 'Patch Viewer',
prereqs => { runtime => { requires => { PatchReader => 'v0.9.6' } } }
},
rest => {
description => 'REST Interface',
prereqs => {
runtime => {
requires => {
'Test::Taint' => '1.06',
'HTTP::Request' => 0,
'HTTP::Response' => 0,
Moo => 2,
'Module::Runtime' => 0
}
}
}
},
jobqueue => {
description => 'Mail Queueing',
prereqs => { runtime => { requires => { TheSchwartz => '1.1', 'Daemon::Generic' => 0 } } }
},
psgi => {
description => 'Plack/PSGI support',
prereqs => {
runtime => { requires => { Plack => '1.0031', 'CGI::Compile' => 0, 'CGI::Emulate::PSGI' => 0 } }
}
},
);
for my $file (glob("extensions/*/Config.pm")) {
my $dir = dirname($file);
my $name = basename($dir);
next if -f File::Spec->catfile($dir, "disabled");
require $file;
my $class = "Bugzilla::Extension::$name";
if ($class->can("REQUIRED_MODULES")) {
foreach my $required_module (@{ $class->REQUIRED_MODULES() }) {
$requires{$required_module->{module}} = $required_module->{version};
}
}
if ($class->can('OPTIONAL_MODULES')) {
my $default_feature = 'extension_' . lc($name) . '_optional';
foreach my $mod (@{ $class->OPTIONAL_MODULES }) {
my @features = $mod->{feature} ? @{$mod->{feature}} : ($default_feature);
foreach my $feature (@features) {
$optional_features{$feature}{prereqs}{runtime}{requires}{$mod->{module}} = $mod->{version} // 0;
}
}
}
}
WriteMakefile(
NAME => 'Bugzilla',
AUTHOR => q{Bugzilla Developers <developers@bugzilla.org>},
VERSION => BUGZILLA_VERSION,
ABSTRACT => 'Bugzilla Bug Tracking System',
LICENSE => 'Mozilla_2_0',
MIN_PERL_VERSION => '5.10.1',
CONFIGURE_REQUIRES => { 'ExtUtils::MakeMaker' => '6.55' },
PREREQ_PM => \%requires,
TEST_REQUIRES => { 'Test::More' => 0, 'Pod::Coverage' => 0, 'Test::Perl::Critic' => 0, },
META_MERGE => {
"meta-spec" => { url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec", version => "2" },
dynamic_config => 1,
dog => 1,
optional_features => \%optional_features,
},
);
sub MY::postamble {
return <<MAKE;
GEN_CPANFILE_ARGS = -A -U mod_perl -U oracle
cpanfile: MYMETA.json
\t\$(PERLRUN) gen-cpanfile.pl \$(GEN_CPANFILE_ARGS)
MAKE
}
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -11,9 +11,14 @@ use strict; ...@@ -11,9 +11,14 @@ use strict;
use warnings; use warnings;
use File::Basename; use File::Basename;
use lib dirname(__FILE__); use File::Spec;
BEGIN {
require lib;
my $dir = dirname(__FILE__);
lib->import($dir, File::Spec->catdir($dir, "lib"), File::Spec->catdir($dir, qw(local lib perl5)));
}
use Bugzilla::Constants (); use Bugzilla::Constants ();
use lib Bugzilla::Constants::bz_locations()->{ext_libpath};
use Plack; use Plack;
use Plack::Builder; use Plack::Builder;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::BugMail; use Bugzilla::BugMail;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -31,7 +31,7 @@ use 5.10.1; ...@@ -31,7 +31,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -18,7 +18,7 @@ use warnings; ...@@ -18,7 +18,7 @@ use warnings;
use File::Basename; use File::Basename;
BEGIN { chdir dirname($0); } BEGIN { chdir dirname($0); }
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Getopt::Long qw(:config bundling); use Getopt::Long qw(:config bundling);
use Pod::Usage; use Pod::Usage;
...@@ -41,7 +41,7 @@ Bugzilla::Install::Util::no_checksetup_from_cgi() if $ENV{'SERVER_SOFTWARE'}; ...@@ -41,7 +41,7 @@ Bugzilla::Install::Util::no_checksetup_from_cgi() if $ENV{'SERVER_SOFTWARE'};
init_console(); init_console();
my %switch; my %switch;
GetOptions(\%switch, 'help|h|?', 'check-modules', 'cpanfile', GetOptions(\%switch, 'help|h|?',
'no-templates|t', 'verbose|v|no-silent', 'no-templates|t', 'verbose|v|no-silent',
'make-admin=s', 'reset-password=s', 'version|V', 'make-admin=s', 'reset-password=s', 'version|V',
'no-permissions|p'); 'no-permissions|p');
...@@ -49,12 +49,6 @@ GetOptions(\%switch, 'help|h|?', 'check-modules', 'cpanfile', ...@@ -49,12 +49,6 @@ GetOptions(\%switch, 'help|h|?', 'check-modules', 'cpanfile',
# Print the help message if that switch was selected. # Print the help message if that switch was selected.
pod2usage({-verbose => 1, -exitval => 1}) if $switch{'help'}; pod2usage({-verbose => 1, -exitval => 1}) if $switch{'help'};
# Export cpanfile and exit
if ($switch{cpanfile}) {
export_cpanfile();
exit;
}
# Read in the "answers" file if it exists, for running in # Read in the "answers" file if it exists, for running in
# non-interactive mode. # non-interactive mode.
my $answers_file = $ARGV[0]; my $answers_file = $ARGV[0];
...@@ -64,11 +58,7 @@ print(install_string('header', get_version_and_os()) . "\n") unless $silent; ...@@ -64,11 +58,7 @@ print(install_string('header', get_version_and_os()) . "\n") unless $silent;
exit 0 if $switch{'version'}; exit 0 if $switch{'version'};
# Check required --MODULES-- # Check required --MODULES--
my $module_results = check_requirements(!$silent); my $module_results = check_requirements(!$silent);
Bugzilla::Install::Requirements::print_module_instructions(
$module_results, !$silent);
exit 1 if !$module_results->{pass};
# Break out if checking the modules is all we have been asked to do. # Break out if checking the modules is all we have been asked to do.
exit 0 if $switch{'check-modules'};
########################################################################### ###########################################################################
# Load Bugzilla Modules # Load Bugzilla Modules
...@@ -245,7 +235,7 @@ checksetup.pl - A do-it-all upgrade and installation script for Bugzilla. ...@@ -245,7 +235,7 @@ checksetup.pl - A do-it-all upgrade and installation script for Bugzilla.
=head1 SYNOPSIS =head1 SYNOPSIS
./checksetup.pl [--help|--check-modules|--version] ./checksetup.pl [--help|--version]
./checksetup.pl [SCRIPT [--verbose]] [--no-templates|-t] ./checksetup.pl [SCRIPT [--verbose]] [--no-templates|-t]
[--make-admin=user@domain.com] [--make-admin=user@domain.com]
[--reset-password=user@domain.com] [--reset-password=user@domain.com]
...@@ -266,16 +256,6 @@ the L</"RUNNING CHECKSETUP NON-INTERACTIVELY"> section. ...@@ -266,16 +256,6 @@ the L</"RUNNING CHECKSETUP NON-INTERACTIVELY"> section.
Display this help text Display this help text
=item B<--cpanfile>
Outputs a cpanfile in the document root listing the current and optional
modules with their respective versions. This file can be used by <cpanm>
and other utilities used to install Perl dependencies.
=item B<--check-modules>
Only check for correct module dependencies and quit afterward.
=item B<--make-admin>=username@domain.com =item B<--make-admin>=username@domain.com
Makes the specified user into a Bugzilla administrator. This is Makes the specified user into a Bugzilla administrator. This is
......
...@@ -22,7 +22,7 @@ It takes no arguments and produces no output except in the case of errors. ...@@ -22,7 +22,7 @@ It takes no arguments and produces no output except in the case of errors.
use 5.10.1; use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Getopt::Long qw(:config bundling); use Getopt::Long qw(:config bundling);
use Pod::Usage; use Pod::Usage;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
use Bugzilla::DB; use Bugzilla::DB;
......
...@@ -10,7 +10,7 @@ use warnings; ...@@ -10,7 +10,7 @@ use warnings;
use File::Basename; use File::Basename;
BEGIN { chdir dirname($0) . "/.."; } BEGIN { chdir dirname($0) . "/.."; }
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Config qw(:admin); use Bugzilla::Config qw(:admin);
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Install::Filesystem qw(fix_all_file_permissions); use Bugzilla::Install::Filesystem qw(fix_all_file_permissions);
......
...@@ -31,7 +31,7 @@ merge-users.pl - Merge two user accounts. ...@@ -31,7 +31,7 @@ merge-users.pl - Merge two user accounts.
=cut =cut
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
...@@ -88,17 +88,18 @@ if (exists $switch{'charset'}) { ...@@ -88,17 +88,18 @@ if (exists $switch{'charset'}) {
} }
if ($switch{'guess'}) { if ($switch{'guess'}) {
if (!eval { require Encode::Detect::Detector }) { if (!Bugzilla->has_feature('detect_charset')) {
my $root = ROOT_USER; my $root = ROOT_USER;
print STDERR <<EOT; print STDERR <<EOT;
Using --guess requires that Encode::Detect be installed. To install Using --guess requires that Encode::Detect be installed. To install
Encode::Detect, run the following command: Encode::Detect, run the following command:
$^X install-module.pl Encode::Detect cpanm --installdeps --with-feature=detect_charset -l local .
EOT EOT
exit; exit;
} }
require Encode::Detect;
} }
my %overrides; my %overrides;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Util; use Bugzilla::Util;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Net::LDAP; use Net::LDAP;
use Bugzilla; use Bugzilla;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Error; use Bugzilla::Error;
......
...@@ -11,7 +11,6 @@ cd $BUGZILLA_ROOT ...@@ -11,7 +11,6 @@ cd $BUGZILLA_ROOT
# Install Perl dependencies # Install Perl dependencies
CPANM="cpanm --quiet --notest --skip-satisfied" CPANM="cpanm --quiet --notest --skip-satisfied"
perl checksetup.pl --cpanfile
$CPANM --installdeps --with-recommends --with-all-features \ $CPANM --installdeps --with-recommends --with-all-features \
--without-feature oracle --without-feature sqlite --without-feature pg . --without-feature oracle --without-feature sqlite --without-feature pg .
......
...@@ -149,27 +149,18 @@ times, Bugzilla may require a version of a Perl module newer than the one ...@@ -149,27 +149,18 @@ times, Bugzilla may require a version of a Perl module newer than the one
your distribution packages, in which case you will need to install a your distribution packages, in which case you will need to install a
Bugzilla-only copy of the newer version. Bugzilla-only copy of the newer version.
At this point you probably need to become ``root``, e.g. by using To make sure you have all the core requirements to run Bugzilla, you should run the following command:
:command:`su`. You should remain as root until the end of the install. This
can be avoided in some circumstances if you are a member of your webserver's
group, but being root is easier and will always work.
To check whether you have all the required modules, run: :command:`perl Makefile.PL`
:command:`./checksetup.pl --check-modules` Should this command warn about missing prerequisites -- or prerequisites that are too old,
you may use cpanm to install these.
You can run this command as many times as necessary. :command:`curl -L http://cpanmin.us | perl - --installdeps -l local .`
If you have not already installed the necessary modules, and want to do it If you want a more full-featured Bugzilla, use the following command:
system-wide, invoke your package manager appropriately at this point.
Alternatively, you can install all missing modules locally (i.e. just for
Bugzilla) like this:
:command:`./install-module.pl --all` :command:`curl -L http://cpanmin.us | perl - --installdeps -l local --with-all-features --without-feature mod_perl --without-feature oracle --without-feature mysql --without-feature pg .`
Or, you can pass an individual module name:
:command:`./install-module.pl <modulename>`
.. _linux-config-webserver: .. _linux-config-webserver:
......
...@@ -71,22 +71,16 @@ will need to agree to this. ...@@ -71,22 +71,16 @@ will need to agree to this.
Perl Modules Perl Modules
============ ============
Bugzilla requires a number of Perl modules. On Mac OS X, the easiest thing to Bugzilla requires a number of Perl modules. Generally, the best way to install
do is to install local copies (rather than system-wide copies) of any ones these is with the cpanm command.
that you don't already have. However, if you do want to install them
system-wide, run the below commands as root with the :command:`--global`
option.
To check whether you have all the required modules and what is still missing, Generally, the best way to install these is with cpanm:
run:
:command:`perl checksetup.pl --check-modules` :command:`curl -L http://cpanmin.us | perl - --installdeps -l local .`
You can run this command as many times as necessary. If you want a more full-featured Bugzilla:
Install all missing modules locally like this: :command:`curl -L http://cpanmin.us | perl - --installdeps -l local --with-all-features --without-feature oracle --without-feature mysql --without-feature pg`
:command:`perl install-module.pl --all`
.. _macosx-config-webserver: .. _macosx-config-webserver:
......
...@@ -30,7 +30,7 @@ use warnings; ...@@ -30,7 +30,7 @@ use warnings;
use File::Basename; use File::Basename;
BEGIN { chdir dirname($0); } BEGIN { chdir dirname($0); }
use lib qw(.. ../lib lib); use lib qw(.. ../lib lib ../local/lib/perl5);
use Cwd; use Cwd;
use File::Copy::Recursive qw(rcopy); use File::Copy::Recursive qw(rcopy);
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -11,7 +11,7 @@ use 5.10.1; ...@@ -11,7 +11,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Util; use Bugzilla::Util;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -14,7 +14,7 @@ use 5.10.1; ...@@ -14,7 +14,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -20,7 +20,7 @@ BEGIN { ...@@ -20,7 +20,7 @@ BEGIN {
chdir dirname($a); chdir dirname($a);
} }
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Data::Dumper; use Data::Dumper;
use Email::Address; use Email::Address;
......
...@@ -20,7 +20,7 @@ use 5.10.1; ...@@ -20,7 +20,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -13,7 +13,7 @@ use warnings; ...@@ -13,7 +13,7 @@ use warnings;
use File::Basename; use File::Basename;
BEGIN { chdir dirname($0); } BEGIN { chdir dirname($0); }
use lib qw(.. ../lib); use lib qw(.. ../lib ../local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
#!/usr/bin/perl
# 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.
# This file has detailed POD docs, do "perldoc checksetup.pl" to see them.
######################################################################
# Initialization
######################################################################
use 5.10.1;
use strict;
use warnings;
use lib qw(lib local/lib/perl5);
use Getopt::Long qw(:config gnu_getopt);
if (-f "MYMETA.json") {
eval {
require CPAN::Meta;
require Module::CPANfile;
my (@with_feature, @without_feature);
my $with_all_features = 0;
GetOptions(
'with-all-features|A!' => \$with_all_features,
'with-feature|D=s@' => \@with_feature,
'without-feature|U=s@' => \@without_feature
);
my $meta = CPAN::Meta->load_file("MYMETA.json");
my @phases = qw(configure build test develop runtime);
my @types = qw(requires recommends suggests conflicts);
my %features;
if ($with_all_features) {
$features{$_->identifier} = 1 foreach ($meta->features);
}
$features{$_} = 1 foreach @with_feature;
$features{$_} = 0 foreach @without_feature;
my @features = grep { $features{$_} } keys %features;
my $prereqs = $meta->effective_prereqs(\@features)->as_string_hash;
my $filtered = {};
while (my($phase, $types) = each %$prereqs) {
while (my($type, $reqs) = each %$types) {
$filtered->{$phase}{$type} = $reqs;
}
}
my $cpanfile = Module::CPANfile->from_prereqs($filtered);
open my $cpanfile_fh, '>', 'cpanfile' or die "cannot write to cpanfile: $!";
print $cpanfile_fh $cpanfile->to_string();
close $cpanfile_fh;
};
die "Unable generate cpanfile: $@\n" if $@;
}
else {
die "MYMETA.yml is missing, cannot generate cpanfile\n";
}
...@@ -46,7 +46,7 @@ BEGIN { ...@@ -46,7 +46,7 @@ BEGIN {
chdir(File::Basename::dirname($dir)); chdir(File::Basename::dirname($dir));
} }
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
# Data dumber is used for debugging, I got tired of copying it back in # Data dumber is used for debugging, I got tired of copying it back in
# and then removing it. # and then removing it.
#use Data::Dumper; #use Data::Dumper;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
#!/usr/bin/perl
# 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.
use 5.10.1;
use strict;
use warnings;
# Have to abs_path('.') or calls to Bugzilla modules won't work once
# CPAN has chdir'ed around. We do all of this in this funny order to
# make sure that we use the lib/ modules instead of the base Perl modules,
# in case the lib/ modules are newer.
use Cwd qw(abs_path cwd);
use lib abs_path('.');
use Bugzilla::Constants;
use lib abs_path(bz_locations()->{ext_libpath});
use Bugzilla::Install::CPAN;
use Bugzilla::Constants;
use Bugzilla::Install::Requirements;
use Bugzilla::Install::Util qw(bin_loc init_console);
use Data::Dumper;
use Getopt::Long;
use Pod::Usage;
init_console();
my @original_args = @ARGV;
my $original_dir = cwd();
our %switch;
GetOptions(\%switch, 'all|a', 'upgrade-all|u', 'show-config|s', 'global|g',
'shell', 'help|h');
pod2usage({ -verbose => 1 }) if $switch{'help'};
if (ON_ACTIVESTATE) {
print <<END;
You cannot run this script when using ActiveState Perl. Please follow
the instructions given by checksetup.pl to install missing Perl modules.
END
exit;
}
pod2usage({ -verbose => 0 }) if (!%switch && !@ARGV);
set_cpan_config($switch{'global'});
if ($switch{'show-config'}) {
print Dumper($CPAN::Config);
exit;
}
check_cpan_requirements($original_dir, \@original_args);
if ($switch{'shell'}) {
CPAN::shell();
exit;
}
if ($switch{'all'} || $switch{'upgrade-all'}) {
my @modules;
if ($switch{'upgrade-all'}) {
@modules = (@{REQUIRED_MODULES()}, @{OPTIONAL_MODULES()});
push(@modules, DB_MODULE->{$_}->{dbd}) foreach (keys %{DB_MODULE()});
}
else {
# This is the only time we need a Bugzilla-related module, so
# we require them down here. Otherwise this script can be run from
# any directory, even outside of Bugzilla itself.
my $reqs = check_requirements(0);
@modules = (@{$reqs->{missing}}, @{$reqs->{optional}});
my $dbs = DB_MODULE;
foreach my $db (keys %$dbs) {
push(@modules, $dbs->{$db}->{dbd})
if !have_vers($dbs->{$db}->{dbd}, 0);
}
}
foreach my $module (@modules) {
my $cpan_name = $module->{module};
# --all shouldn't include mod_perl2, because it can have some complex
# configuration, and really should be installed on its own.
next if $cpan_name eq 'mod_perl2';
next if $cpan_name eq 'DBD::Oracle' and !$ENV{ORACLE_HOME};
next if $cpan_name eq 'DBD::Pg' and !bin_loc('pg_config');
install_module($cpan_name);
}
}
foreach my $module (@ARGV) {
install_module($module);
}
__END__
=head1 NAME
install-module.pl - Installs or upgrades modules from CPAN.
This script does not run on Windows.
=head1 SYNOPSIS
./install-module.pl Module::Name [--global]
./install-module.pl --all [--global]
./install-module.pl --upgrade-all [--global]
./install-module.pl --show-config
./install-module.pl --shell
Do "./install-module.pl --help" for more information.
=head1 OPTIONS
=over
=item B<Module::Name>
The name of a module that you want to install from CPAN. This is the
same thing that you'd give to the C<install> command in the CPAN shell.
You can specify multiple module names separated by a space to install
multiple modules.
=item B<--global>
This makes install-module install modules globally for all applications,
instead of just for Bugzilla.
On most systems, you have to be root for C<--global> to work.
=item B<--all>
This will make install-module do its best to install every required
and optional module that is not installed that Bugzilla can use.
Some modules may fail to install. You can run checksetup.pl to see
which installed properly.
=item B<--upgrade-all>
This is like C<--all>, except it forcibly installs the very latest
version of every Bugzilla prerequisite, whether or not you already
have them installed.
=item B<--show-config>
Prints out the CPAN configuration in raw Perl format. Useful for debugging.
=item B<--shell>
Starts a CPAN shell using the configuration of F<install-module.pl>.
=item B<--help>
Shows this help.
=back
...@@ -18,7 +18,7 @@ BEGIN { ...@@ -18,7 +18,7 @@ BEGIN {
chdir dirname($a); chdir dirname($a);
} }
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::JobQueue::Runner; use Bugzilla::JobQueue::Runner;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -12,7 +12,7 @@ use warnings; ...@@ -12,7 +12,7 @@ use warnings;
use File::Basename; use File::Basename;
BEGIN { chdir dirname($0); } BEGIN { chdir dirname($0); }
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Migrate; use Bugzilla::Migrate;
......
...@@ -15,9 +15,14 @@ use warnings; ...@@ -15,9 +15,14 @@ use warnings;
# This sets up our libpath without having to specify it in the mod_perl # This sets up our libpath without having to specify it in the mod_perl
# configuration. # configuration.
use File::Basename; use File::Basename;
use lib dirname(__FILE__); use File::Spec;
BEGIN {
require lib;
my $dir = dirname(__FILE__);
lib->import($dir, File::Spec->catdir($dir, "lib"), File::Spec->catdir($dir, qw(local lib perl5)));
}
use Bugzilla::Constants (); use Bugzilla::Constants ();
use lib Bugzilla::Constants::bz_locations()->{'ext_libpath'};
# If you have an Apache2::Status handler in your Apache configuration, # If you have an Apache2::Status handler in your Apache configuration,
# you need to load Apache2::Status *here*, so that any later-loaded modules # you need to load Apache2::Status *here*, so that any later-loaded modules
......
...@@ -17,7 +17,7 @@ use 5.10.1; ...@@ -17,7 +17,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Error; use Bugzilla::Error;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Attachment; use Bugzilla::Attachment;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Bug; use Bugzilla::Bug;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Mailer; use Bugzilla::Mailer;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Util; use Bugzilla::Util;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
#!/usr/bin/perl
# 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.
use 5.10.1;
use diagnostics;
use strict;
use warnings;
use lib qw(lib);
use Test::Harness qw(&runtests $verbose);
$verbose = 0;
my $onlytest = "";
foreach (@ARGV) {
if (/^(?:-v|--verbose)$/) {
$verbose = 1;
}
else {
$onlytest = sprintf("%0.3d",$_);
}
}
runtests(glob("t/$onlytest*.t"));
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Bug; use Bugzilla::Bug;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Error; use Bugzilla::Error;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Error; use Bugzilla::Error;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use File::Temp; use File::Temp;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Error; use Bugzilla::Error;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Date::Parse; # strptime use Date::Parse; # strptime
......
...@@ -14,7 +14,7 @@ use 5.10.1; ...@@ -14,7 +14,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib t); use lib qw(. lib local/lib/perl5 t);
use Config; use Config;
use Support::Files; use Support::Files;
use Test::More tests => scalar(@Support::Files::testitems) use Test::More tests => scalar(@Support::Files::testitems)
...@@ -86,8 +86,7 @@ foreach my $file (@testitems) { ...@@ -86,8 +86,7 @@ foreach my $file (@testitems) {
and $file ne "Bugzilla/DB/Schema.pm") and $file ne "Bugzilla/DB/Schema.pm")
{ {
my $module = lc($1); my $module = lc($1);
my $dbd = DB_MODULE->{$module}->{dbd}->{module}; Bugzilla->feature($module) or skip "$file: Driver for $module not installed", 1;
eval("use $dbd; 1") or skip "$file: $dbd not installed", 1;
} }
compile_file($file); compile_file($file);
......
...@@ -14,7 +14,7 @@ use 5.10.1; ...@@ -14,7 +14,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib 't'; use lib qw(. lib local/lib/perl5 t);
use Support::Files; use Support::Files;
......
...@@ -13,7 +13,7 @@ use 5.10.1; ...@@ -13,7 +13,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib 't'; use lib qw(. lib local/lib/perl5 t);
use Support::Templates; use Support::Templates;
......
...@@ -13,7 +13,7 @@ use 5.10.1; ...@@ -13,7 +13,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib 't'; use lib qw(. lib local/lib/perl5 t);
use Support::Files; use Support::Files;
use Support::Templates; use Support::Templates;
......
...@@ -14,7 +14,7 @@ use 5.10.1; ...@@ -14,7 +14,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib 't'; use lib qw(. lib local/lib/perl5 t);
use Support::Files; use Support::Files;
# -1 because 006spellcheck.t must not be checked. # -1 because 006spellcheck.t must not be checked.
......
...@@ -13,7 +13,7 @@ use 5.10.1; ...@@ -13,7 +13,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib 't'; use lib qw(. lib local/lib/perl5 t);
use Support::Files; use Support::Files;
use Test::More tests => 17; use Test::More tests => 17;
use DateTime; use DateTime;
......
...@@ -19,7 +19,7 @@ use 5.10.1; ...@@ -19,7 +19,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib t); use lib qw(. lib local/lib/perl5 t);
use Bugzilla::Constants; use Bugzilla::Constants;
use Support::Templates; use Support::Templates;
......
...@@ -19,7 +19,7 @@ use 5.10.1; ...@@ -19,7 +19,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib 't'; use lib qw(. lib local/lib/perl5 t);
use Support::Files; use Support::Files;
use Support::Templates; use Support::Templates;
......
...@@ -14,7 +14,7 @@ use 5.10.1; ...@@ -14,7 +14,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib t); use lib qw(. lib local/lib/perl5 t);
use Support::Files; use Support::Files;
use Test::More qw(no_plan); use Test::More qw(no_plan);
......
...@@ -14,7 +14,7 @@ use 5.10.1; ...@@ -14,7 +14,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib 't'; use lib qw(. lib local/lib/perl5 t);
use Support::Files; use Support::Files;
use Pod::Checker; use Pod::Checker;
......
...@@ -15,7 +15,7 @@ use 5.10.1; ...@@ -15,7 +15,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib t); use lib qw(. lib local/lib/perl5 t);
use Bugzilla::Constants; use Bugzilla::Constants;
use Bugzilla::WebService::Constants; use Bugzilla::WebService::Constants;
......
...@@ -16,7 +16,7 @@ use 5.10.1; ...@@ -16,7 +16,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. t lib); use lib qw(. lib local/lib/perl5 t);
use Bugzilla; use Bugzilla;
use Bugzilla::DB::Schema; use Bugzilla::DB::Schema;
......
...@@ -18,7 +18,7 @@ our @additional_files = (); ...@@ -18,7 +18,7 @@ our @additional_files = ();
our @files = glob('*'); our @files = glob('*');
find(sub { push(@files, $File::Find::name) if $_ =~ /\.pm$/;}, qw(Bugzilla docs)); find(sub { push(@files, $File::Find::name) if $_ =~ /\.pm$/;}, qw(Bugzilla docs));
push(@files, 'extensions/create.pl', 'docs/makedocs.pl'); push(@files, 'extensions/create.pl', 'docs/makedocs.pl', 'cpanfile');
our @extensions = our @extensions =
grep { $_ ne 'extensions/create.pl' && ! -e "$_/disabled" } grep { $_ ne 'extensions/create.pl' && ! -e "$_/disabled" }
......
...@@ -89,42 +89,10 @@ END ...@@ -89,42 +89,10 @@ END
Extensions must return their name, not <code>1</code> or a number. See Extensions must return their name, not <code>1</code> or a number. See
the documentation of Bugzilla::Extension for details. the documentation of Bugzilla::Extension for details.
END END
feature_auth_ldap => 'LDAP Authentication',
feature_auth_radius => 'RADIUS Authentication',
feature_documentation => 'Documentation',
feature_graphical_reports => 'Graphical Reports',
feature_html_desc => 'More HTML in Product/Group Descriptions',
feature_inbound_email => 'Inbound Email',
feature_jobqueue => 'Mail Queueing',
feature_jsonrpc => 'JSON-RPC Interface',
feature_new_charts => 'New Charts',
feature_old_charts => 'Old Charts',
feature_memcached => 'Memcached Support',
feature_mod_perl => 'mod_perl',
feature_moving => 'Move Bugs Between Installations',
feature_patch_viewer => 'Patch Viewer',
feature_psgi => 'PSGI Support',
feature_rest => 'REST Interface',
feature_smtp_auth => 'SMTP Authentication',
feature_smtp_ssl => 'SSL Support for SMTP',
feature_updates => 'Automatic Update Notifications',
feature_xmlrpc => 'XML-RPC Interface',
feature_detect_charset => 'Automatic charset detection for text attachments',
feature_typesniffer => 'Sniff MIME type of attachments',
feature_markdown => 'Markdown syntax support for comments',
file_remove => 'Removing ##name##...', file_remove => 'Removing ##name##...',
file_rename => 'Renaming ##from## to ##to##...', file_rename => 'Renaming ##from## to ##to##...',
header => "* This is Bugzilla ##bz_ver## on perl ##perl_ver##\n" header => "* This is Bugzilla ##bz_ver## on perl ##perl_ver##\n"
. "* Running on ##os_name## ##os_ver##", . "* Running on ##os_name## ##os_ver##",
install_all => <<EOT,
To attempt an automatic install of every required and optional module
with one command, do:
##perl## install-module.pl --all
EOT
install_data_too_long => <<EOT, install_data_too_long => <<EOT,
WARNING: Some of the data in the ##table##.##column## column is longer than WARNING: Some of the data in the ##table##.##column## column is longer than
its new length limit of ##max_length## characters. The data that needs to be its new length limit of ##max_length## characters. The data that needs to be
...@@ -132,15 +100,6 @@ fixed is printed below with the value of the ##id_column## column first and ...@@ -132,15 +100,6 @@ fixed is printed below with the value of the ##id_column## column first and
then the value of the ##column## column that needs to be fixed: then the value of the ##column## column that needs to be fixed:
EOT EOT
install_module => 'Installing ##module## version ##version##...',
installation_failed => '*** Installation aborted. Read the messages above. ***',
install_no_compiler => <<END,
ERROR: Using install-module.pl requires that you install a compiler, such as
gcc.
END
install_no_make => <<END,
ERROR: Using install-module.pl requires that you install "make".
END
lc_new_vars => <<'END', lc_new_vars => <<'END',
This version of Bugzilla contains some variables that you may want to This version of Bugzilla contains some variables that you may want to
change and adapt to your local settings. The following variables are change and adapt to your local settings. The following variables are
......
...@@ -14,7 +14,7 @@ use 5.10.1; ...@@ -14,7 +14,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::BugMail; use Bugzilla::BugMail;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -13,7 +13,7 @@ use 5.10.1; ...@@ -13,7 +13,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Error; use Bugzilla::Error;
......
...@@ -14,7 +14,7 @@ use 5.10.1; ...@@ -14,7 +14,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -18,7 +18,7 @@ use 5.10.1; ...@@ -18,7 +18,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Mailer; use Bugzilla::Mailer;
......
...@@ -10,7 +10,7 @@ use 5.10.1; ...@@ -10,7 +10,7 @@ use 5.10.1;
use strict; use strict;
use warnings; use warnings;
use lib qw(. lib); use lib qw(. lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
use strict; use strict;
use warnings; use warnings;
use lib qw(. xt/lib lib); use lib qw(. xt/lib lib local/lib/perl5);
use Bugzilla; use Bugzilla;
use Bugzilla::Constants; use Bugzilla::Constants;
use Bugzilla::Test::Search; use Bugzilla::Test::Search;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment