aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Install')
-rw-r--r--Bugzilla/Install/CPAN.pm27
-rw-r--r--Bugzilla/Install/DB.pm120
-rw-r--r--Bugzilla/Install/Filesystem.pm180
-rw-r--r--Bugzilla/Install/Localconfig.pm24
-rw-r--r--Bugzilla/Install/Requirements.pm133
-rw-r--r--Bugzilla/Install/Util.pm82
6 files changed, 421 insertions, 145 deletions
diff --git a/Bugzilla/Install/CPAN.pm b/Bugzilla/Install/CPAN.pm
index 8a880df80..094784e1a 100644
--- a/Bugzilla/Install/CPAN.pm
+++ b/Bugzilla/Install/CPAN.pm
@@ -6,8 +6,12 @@
# defined by the Mozilla Public License, v. 2.0.
package Bugzilla::Install::CPAN;
+
+use 5.10.1;
use strict;
-use base qw(Exporter);
+use warnings;
+
+use parent qw(Exporter);
our @EXPORT = qw(
BZ_LIB
@@ -161,20 +165,9 @@ sub install_module {
if (!$module) {
die install_string('no_such_module', { module => $name }) . "\n";
}
- my $version = $module->cpan_version;
- my $module_name = $name;
-
- if ($name eq 'LWP::UserAgent' && $^V lt v5.8.8) {
- # LWP 6.x requires Perl 5.8.8 or newer.
- # As PAUSE only indexes the very last version of each module,
- # we have to specify the path to the tarball ourselves.
- $name = 'GAAS/libwww-perl-5.837.tar.gz';
- # This tarball contains LWP::UserAgent 5.835.
- $version = '5.835';
- }
print install_string('install_module',
- { module => $module_name, version => $version }) . "\n";
+ { module => $name, version => $module->cpan_version }) . "\n";
if ($test) {
CPAN::Shell->force('install', $name);
@@ -336,3 +329,11 @@ 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
diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm
index 023ef7523..96f14ec0f 100644
--- a/Bugzilla/Install/DB.pm
+++ b/Bugzilla/Install/DB.pm
@@ -10,7 +10,9 @@ package Bugzilla::Install::DB;
# NOTE: This package may "use" any modules that it likes,
# localconfig is available, and params are up to date.
+use 5.10.1;
use strict;
+use warnings;
use Bugzilla::Constants;
use Bugzilla::Hook;
@@ -23,6 +25,7 @@ use Bugzilla::Field;
use Date::Parse;
use Date::Format;
+use Digest;
use IO::File;
use List::MoreUtils qw(uniq);
use URI;
@@ -270,10 +273,6 @@ sub update_table_definitions {
$dbh->bz_add_column('attachments', 'isprivate',
{TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'});
- $dbh->bz_add_column("bugs", "alias", {TYPE => "varchar(20)"});
- $dbh->bz_add_index('bugs', 'bugs_alias_idx',
- {TYPE => 'UNIQUE', FIELDS => [qw(alias)]});
-
_move_quips_into_db();
$dbh->bz_drop_column("namedqueries", "watchfordiffs");
@@ -700,12 +699,36 @@ sub update_table_definitions {
# 2012-08-01 koosha.khajeh@gmail.com - Bug 187753
_shorten_long_quips();
- # 2012-12-23 LpSolit@gmail.com - Bug 824361
+ # 2012-12-29 reed@reedloden.com - Bug 785283
+ _add_password_salt_separator();
+
+ # 2013-01-02 LpSolit@gmail.com - Bug 824361
_fix_longdescs_indexes();
# 2013-02-04 dkl@mozilla.com - Bug 824346
_fix_flagclusions_indexes();
+ # 2013-08-26 sgreen@redhat.com - Bug 903895
+ _fix_components_primary_key();
+
+ # 2014-06-09 dylan@mozilla.com - Bug 1022923
+ $dbh->bz_add_index('bug_user_last_visit',
+ 'bug_user_last_visit_last_visit_ts_idx',
+ ['last_visit_ts']);
+
+ # 2014-07-14 sgreen@redhat.com - Bug 726696
+ $dbh->bz_alter_column('tokens', 'tokentype',
+ {TYPE => 'varchar(16)', NOTNULL => 1});
+
+ # 2014-07-27 LpSolit@gmail.com - Bug 1044561
+ _fix_user_api_keys_indexes();
+
+ # 2014-08-11 sgreen@redhat.com - Bug 1012506
+ _update_alias();
+
+ # 2014-11-10 dkl@mozilla.com - Bug 1093928
+ $dbh->bz_drop_column('longdescs', 'is_markdown');
+
################################################################
# New --TABLE-- changes should go *** A B O V E *** this point #
################################################################
@@ -863,8 +886,8 @@ sub _populate_longdescs {
if (!$who) {
# This username doesn't exist. Maybe someone
- # renamed him or something. Invent a new profile
- # entry disabled, just to represent him.
+ # renamed them or something. Invent a new profile
+ # entry disabled, just to represent them.
$dbh->do("INSERT INTO profiles (login_name,
cryptpassword, disabledtext)
VALUES (?,?,?)", undef, $name, '*',
@@ -1424,9 +1447,9 @@ sub _use_ids_for_products_and_components {
print "Updating the database to use component IDs.\n";
$dbh->bz_add_column("components", "id",
- {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1});
+ {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1});
$dbh->bz_add_column("bugs", "component_id",
- {TYPE => 'INT2', NOTNULL => 1}, 0);
+ {TYPE => 'INT3', NOTNULL => 1}, 0);
my %components;
$sth = $dbh->prepare("SELECT id, value, product_id FROM components");
@@ -2537,7 +2560,7 @@ sub _fix_whine_queries_title_and_op_sys_value {
undef, "Other", "other");
if (Bugzilla->params->{'defaultopsys'} eq 'other') {
# We can't actually fix the param here, because WriteParams() will
- # make $datadir/params unwriteable to the webservergroup.
+ # make $datadir/params.json unwriteable to the webservergroup.
# It's too much of an ugly hack to copy the permission-fixing code
# down to here. (It would create more potential future bugs than
# it would solve problems.)
@@ -3785,6 +3808,39 @@ sub _shorten_long_quips {
$dbh->bz_alter_column('quips', 'quip', { TYPE => 'varchar(512)', NOTNULL => 1});
}
+sub _add_password_salt_separator {
+ my $dbh = Bugzilla->dbh;
+
+ $dbh->bz_start_transaction();
+
+ my $profiles = $dbh->selectall_arrayref("SELECT userid, cryptpassword FROM profiles WHERE ("
+ . $dbh->sql_regexp("cryptpassword", "'^[^,]+{'") . ")");
+
+ if (@$profiles) {
+ say "Adding salt separator to password hashes...";
+
+ my $query = $dbh->prepare("UPDATE profiles SET cryptpassword = ? WHERE userid = ?");
+ my %algo_sizes;
+
+ foreach my $profile (@$profiles) {
+ my ($userid, $hash) = @$profile;
+ my ($algorithm) = $hash =~ /{([^}]+)}$/;
+
+ $algo_sizes{$algorithm} ||= length(Digest->new($algorithm)->b64digest);
+
+ # Calculate the salt length by taking the stored hash and
+ # subtracting the combined lengths of the hash size, the
+ # algorithm name, and 2 for the {} surrounding the name.
+ my $not_salt_len = $algo_sizes{$algorithm} + length($algorithm) + 2;
+ my $salt_len = length($hash) - $not_salt_len;
+
+ substr($hash, $salt_len, 0, ',');
+ $query->execute($hash, $userid);
+ }
+ }
+ $dbh->bz_commit_transaction();
+}
+
sub _fix_flagclusions_indexes {
my $dbh = Bugzilla->dbh;
foreach my $table ('flaginclusions', 'flagexclusions') {
@@ -3814,6 +3870,50 @@ sub _fix_flagclusions_indexes {
}
}
+sub _fix_components_primary_key {
+ my $dbh = Bugzilla->dbh;
+ if ($dbh->bz_column_info('components', 'id')->{TYPE} ne 'MEDIUMSERIAL') {
+ $dbh->bz_drop_related_fks('components', 'id');
+ $dbh->bz_alter_column("components", "id",
+ {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1});
+ $dbh->bz_alter_column("flaginclusions", "component_id",
+ {TYPE => 'INT3'});
+ $dbh->bz_alter_column("flagexclusions", "component_id",
+ {TYPE => 'INT3'});
+ $dbh->bz_alter_column("bugs", "component_id",
+ {TYPE => 'INT3', NOTNULL => 1});
+ $dbh->bz_alter_column("component_cc", "component_id",
+ {TYPE => 'INT3', NOTNULL => 1});
+ }
+}
+
+sub _fix_user_api_keys_indexes {
+ my $dbh = Bugzilla->dbh;
+
+ if ($dbh->bz_index_info('user_api_keys', 'user_api_keys_key')) {
+ $dbh->bz_drop_index('user_api_keys', 'user_api_keys_key');
+ $dbh->bz_add_index('user_api_keys', 'user_api_keys_api_key_idx',
+ { FIELDS => ['api_key'], TYPE => 'UNIQUE' });
+ }
+ if ($dbh->bz_index_info('user_api_keys', 'user_api_keys_user_id')) {
+ $dbh->bz_drop_index('user_api_keys', 'user_api_keys_user_id');
+ $dbh->bz_add_index('user_api_keys', 'user_api_keys_user_id_idx', ['user_id']);
+ }
+}
+
+sub _update_alias {
+ my $dbh = Bugzilla->dbh;
+ return unless $dbh->bz_column_info('bugs', 'alias');
+
+ # We need to move the aliases from the bugs table to the bugs_aliases table
+ $dbh->do(q{
+ INSERT INTO bugs_aliases (bug_id, alias)
+ SELECT bug_id, alias FROM bugs WHERE alias IS NOT NULL
+ });
+
+ $dbh->bz_drop_column('bugs', 'alias');
+}
+
1;
__END__
diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
index 9721c1702..5003047c3 100644
--- a/Bugzilla/Install/Filesystem.pm
+++ b/Bugzilla/Install/Filesystem.pm
@@ -15,7 +15,9 @@ package Bugzilla::Install::Filesystem;
# * Files do not have the correct permissions.
# * The database does not exist.
+use 5.10.1;
use strict;
+use warnings;
use Bugzilla::Constants;
use Bugzilla::Error;
@@ -28,10 +30,12 @@ use File::Find;
use File::Path;
use File::Basename;
use File::Copy qw(move);
+use File::Spec;
+use File::Slurp;
use IO::File;
use POSIX ();
-use base qw(Exporter);
+use parent qw(Exporter);
our @EXPORT = qw(
update_filesystem
create_htaccess
@@ -57,7 +61,7 @@ use constant HT_DEFAULT_DENY => <<EOT;
</IfVersion>
</IfModule>
<IfModule !mod_version.c>
- Deny from all
+ Deny from all
</IfModule>
EOT
@@ -130,6 +134,7 @@ sub FILESYSTEM {
my $localconfig = bz_locations()->{'localconfig'};
my $template_cache = bz_locations()->{'template_cache'};
my $graphsdir = bz_locations()->{'graphsdir'};
+ my $assetsdir = bz_locations()->{'assetsdir'};
# We want to set the permissions the same for all localconfig files
# across all PROJECTs, so we do something special with $localconfig,
@@ -165,6 +170,7 @@ sub FILESYSTEM {
'jobqueue.pl' => { perms => WS_EXECUTE },
'migrate.pl' => { perms => OWNER_EXECUTE },
'install-module.pl' => { perms => OWNER_EXECUTE },
+ 'clean-bug-user-last-visit.pl' => { perms => WS_EXECUTE },
'Bugzilla.pm' => { perms => CGI_READ },
"$localconfig*" => { perms => CGI_READ },
@@ -181,7 +187,7 @@ sub FILESYSTEM {
'docs/style.css' => { perms => WS_SERVE },
'docs/*/rel_notes.txt' => { perms => WS_SERVE },
'docs/*/README.docs' => { perms => OWNER_WRITE },
- "$datadir/params" => { perms => CGI_WRITE },
+ "$datadir/params.json" => { perms => CGI_WRITE },
"$datadir/old-params.txt" => { perms => OWNER_WRITE },
"$extensionsdir/create.pl" => { perms => OWNER_EXECUTE },
"$extensionsdir/*/*.pl" => { perms => WS_EXECUTE },
@@ -211,6 +217,8 @@ sub FILESYSTEM {
dirs => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE },
"$datadir/db" => { files => CGI_WRITE,
dirs => DIR_CGI_WRITE },
+ $assetsdir => { files => WS_SERVE,
+ dirs => DIR_CGI_OVERWRITE | DIR_ALSO_WS_SERVE },
# Readable directories
"$datadir/mining" => { files => CGI_READ,
@@ -270,7 +278,8 @@ sub FILESYSTEM {
# The name of each directory that we should actually *create*,
# pointing at its default permissions.
my %create_dirs = (
- # This is DIR_ALSO_WS_SERVE because it contains $webdotdir.
+ # This is DIR_ALSO_WS_SERVE because it contains $webdotdir and
+ # $assetsdir.
$datadir => DIR_CGI_OVERWRITE | DIR_ALSO_WS_SERVE,
# Directories that are read-only for cgi scripts
"$datadir/mining" => DIR_CGI_READ,
@@ -281,6 +290,7 @@ sub FILESYSTEM {
$attachdir => DIR_CGI_WRITE,
$graphsdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
$webdotdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
+ $assetsdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
# Directories that contain content served directly by the web server.
"$skinsdir/custom" => DIR_WS_SERVE,
"$skinsdir/contrib" => DIR_WS_SERVE,
@@ -409,8 +419,8 @@ EOT
</IfModule>
</FilesMatch>
-# Allow access to .png files created by a local copy of 'dot'
-<FilesMatch \\.png\$>
+ # Allow access to .png files created by a local copy of 'dot'
+ <FilesMatch \\.png\$>
<IfModule mod_version.c>
<IfVersion < 2.4>
Allow from all
@@ -448,6 +458,48 @@ EOT
</IfModule>
EOT
},
+
+ "$assetsdir/.htaccess" => { perms => WS_SERVE, contents => <<EOT
+# Allow access to .css files
+<FilesMatch \\.(css|js)\$>
+ <IfModule mod_version.c>
+ <IfVersion < 2.4>
+ Allow from all
+ </IfVersion>
+ <IfVersion >= 2.4>
+ <IfModule mod_perl.c>
+ Allow from all
+ </IfModule>
+ <IfModule !mod_perl.c>
+ Require all granted
+ </IfModule>
+ </IfVersion>
+ </IfModule>
+ <IfModule !mod_version.c>
+ Allow from all
+ </IfModule>
+</FilesMatch>
+
+# And no directory listings, either.
+<IfModule mod_version.c>
+ <IfVersion < 2.4>
+ Deny from all
+ </IfVersion>
+ <IfVersion >= 2.4>
+ <IfModule mod_perl.c>
+ Deny from all
+ </IfModule>
+ <IfModule !mod_perl.c>
+ Require all denied
+ </IfModule>
+ </IfVersion>
+</IfModule>
+<IfModule !mod_version.c>
+ Deny from all
+</IfModule>
+EOT
+ },
+
);
Bugzilla::Hook::process('install_filesystem', {
@@ -482,6 +534,7 @@ sub update_filesystem {
my $datadir = bz_locations->{'datadir'};
my $graphsdir = bz_locations->{'graphsdir'};
+ my $assetsdir = bz_locations->{'assetsdir'};
# If the graphs/ directory doesn't exist, we're upgrading from
# a version old enough that we need to update the $datadir/mining
# format.
@@ -489,6 +542,13 @@ sub update_filesystem {
_update_old_charts($datadir);
}
+ # If there is a file named '-All-' in $datadir/mining, then we're still
+ # having mining files named by product name, and we need to convert them to
+ # files named by product ID.
+ if (-e File::Spec->catfile($datadir, 'mining', '-All-')) {
+ _update_old_mining_filenames(File::Spec->catdir($datadir, 'mining'));
+ }
+
# By sorting the dirs, we assure that shorter-named directories
# (meaning parent directories) are always created before their
# child directories.
@@ -515,6 +575,13 @@ sub update_filesystem {
_rename_file($oldparamsfile, "$datadir/$oldparamsfile");
}
+ # Remove old assets htaccess file to force recreation with correct values.
+ if (-e "$assetsdir/.htaccess") {
+ if (read_file("$assetsdir/.htaccess") =~ /<FilesMatch \\\.css\$>/) {
+ unlink("$assetsdir/.htaccess");
+ }
+ }
+
_create_files(%files);
if ($params->{index_html}) {
_create_files(%{$fs->{index_html}});
@@ -558,6 +625,7 @@ EOT
_remove_empty_css_files();
_convert_single_file_skins();
+ _remove_dynamic_assets();
}
sub _remove_empty_css_files {
@@ -602,6 +670,27 @@ sub _convert_single_file_skins {
}
}
+# delete all automatically generated css/js files to force recreation at the
+# next request.
+sub _remove_dynamic_assets {
+ my @files = (
+ glob(bz_locations()->{assetsdir} . '/*.css'),
+ glob(bz_locations()->{assetsdir} . '/*.js'),
+ );
+ foreach my $file (@files) {
+ unlink($file);
+ }
+
+ # remove old skins/assets directory
+ my $old_path = bz_locations()->{skinsdir} . '/assets';
+ if (-d $old_path) {
+ foreach my $file (glob("$old_path/*.css")) {
+ unlink($file);
+ }
+ rmdir($old_path);
+ }
+}
+
sub create_htaccess {
_create_files(%{FILESYSTEM()->{htaccess}});
@@ -730,6 +819,59 @@ sub _update_old_charts {
}
}
+# The old naming scheme has product names as mining file names; we rename them
+# to product IDs.
+sub _update_old_mining_filenames {
+ my ($miningdir) = @_;
+ my @conversion_errors;
+
+ require Bugzilla::Product;
+
+ # We use a dummy product instance with ID 0, representing all products
+ my $product_all = {id => 0, name => '-All-'};
+ bless($product_all, 'Bugzilla::Product');
+
+ print "Updating old charting data file names...";
+ my @products = Bugzilla::Product->get_all();
+ push(@products, $product_all);
+ foreach my $product (@products) {
+ if (-e File::Spec->catfile($miningdir, $product->id)) {
+ push(@conversion_errors,
+ { product => $product,
+ message => 'A file named "' . $product->id .
+ '" already exists.' });
+ }
+ }
+
+ if (! @conversion_errors) {
+ # Renaming mining files should work now without a hitch.
+ foreach my $product (@products) {
+ if (! rename(File::Spec->catfile($miningdir, $product->name),
+ File::Spec->catfile($miningdir, $product->id))) {
+ push(@conversion_errors,
+ { product => $product,
+ message => $! });
+ }
+ }
+ }
+
+ # Error reporting
+ if (! @conversion_errors) {
+ print " done.\n";
+ }
+ else {
+ print " FAILED:\n";
+ foreach my $error (@conversion_errors) {
+ printf "Cannot rename charting data file for product %d (%s): %s\n",
+ $error->{product}->id, $error->{product}->name,
+ $error->{message};
+ }
+ print "You need to empty the \"$miningdir\" directory, then run\n",
+ " collectstats.pl --regenerate\n",
+ "in order to clean this up.\n";
+ }
+}
+
sub fix_dir_permissions {
my ($dir) = @_;
return if ON_WINDOWS;
@@ -961,3 +1103,29 @@ how they are supposed to be set in Bugzilla's current configuration.
If it fails to set the permissions, a warning will be printed to STDERR.
=back
+
+=head1 B<Methods in need of POD>
+
+=over
+
+=item CGI_WRITE
+
+=item DIR_WS_SERVE
+
+=item DIR_ALSO_WS_SERVE
+
+=item WS_SERVE
+
+=item FILESYSTEM
+
+=item WS_EXECUTE
+
+=item CGI_READ
+
+=item DIR_CGI_READ
+
+=item DIR_CGI_WRITE
+
+=item DIR_CGI_OVERWRITE
+
+=back
diff --git a/Bugzilla/Install/Localconfig.pm b/Bugzilla/Install/Localconfig.pm
index 881f6c956..7f473cc77 100644
--- a/Bugzilla/Install/Localconfig.pm
+++ b/Bugzilla/Install/Localconfig.pm
@@ -15,7 +15,9 @@ package Bugzilla::Install::Localconfig;
# * Files do not have the correct permissions
# * The database is not up to date
+use 5.10.1;
use strict;
+use warnings;
use Bugzilla::Constants;
use Bugzilla::Install::Util qw(bin_loc install_string);
@@ -26,7 +28,7 @@ use File::Basename qw(dirname);
use Safe;
use Term::ANSIColor;
-use base qw(Exporter);
+use parent qw(Exporter);
our @EXPORT_OK = qw(
read_localconfig
@@ -79,12 +81,24 @@ use constant LOCALCONFIG_VARS => (
default => 1,
},
{
- name => 'index_html',
- default => 0,
+ name => 'db_mysql_ssl_ca_file',
+ default => '',
+ },
+ {
+ name => 'db_mysql_ssl_ca_path',
+ default => '',
+ },
+ {
+ name => 'db_mysql_ssl_client_cert',
+ default => '',
},
{
- name => 'cvsbin',
- default => sub { bin_loc('cvs') },
+ name => 'db_mysql_ssl_client_key',
+ default => '',
+ },
+ {
+ name => 'index_html',
+ default => 0,
},
{
name => 'interdiffbin',
diff --git a/Bugzilla/Install/Requirements.pm b/Bugzilla/Install/Requirements.pm
index fbd7d7882..f723543b8 100644
--- a/Bugzilla/Install/Requirements.pm
+++ b/Bugzilla/Install/Requirements.pm
@@ -13,23 +13,17 @@ package Bugzilla::Install::Requirements;
# Subroutines may "require" and "import" from modules, but they
# MUST NOT "use."
+use 5.10.1;
use strict;
-use version;
+use warnings;
use Bugzilla::Constants;
-use Bugzilla::Install::Util qw(vers_cmp install_string bin_loc
+use Bugzilla::Install::Util qw(install_string bin_loc
extension_requirement_packages);
use List::Util qw(max);
use Term::ANSIColor;
-# Return::Value 1.666002 pollutes the error log with warnings about this
-# deprecated module. We have to set NO_CLUCK = 1 before loading Email::Send
-# in have_vers() to disable these warnings.
-BEGIN {
- $Return::Value::NO_CLUCK = 1;
-}
-
-use base qw(Exporter);
+use parent qw(Exporter);
our @EXPORT = qw(
REQUIRED_MODULES
OPTIONAL_MODULES
@@ -55,6 +49,8 @@ use constant APACHE_MODULES => {
mod_headers => 'headers_module',
mod_env => 'env_module',
mod_expires => 'expires_module',
+ mod_rewrite => 'rewrite_module',
+ mod_version => 'version_module'
};
# These are all of the binaries that we could possibly use that can
@@ -86,7 +82,6 @@ use constant APACHE_PATH => [qw(
# 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 $perl_ver = sprintf('%vd', $^V);
my @modules = (
{
package => 'CGI.pm',
@@ -106,40 +101,36 @@ sub REQUIRED_MODULES {
module => 'Date::Format',
version => '2.23'
},
- # 0.28 fixed some important bugs in DateTime.
+ # 0.75 fixes a warning thrown with Perl 5.17 and newer.
{
package => 'DateTime',
module => 'DateTime',
- version => '0.28'
+ version => '0.75'
},
- # 0.79 is required to work on Windows Vista and Windows Server 2008.
- # As correctly detecting the flavor of Windows is not easy,
- # we require this version for all Windows installations.
- # 0.71 fixes a major bug affecting all platforms.
+ # 1.64 fixes a taint issue preventing the local timezone from
+ # being determined on some systems.
{
package => 'DateTime-TimeZone',
module => 'DateTime::TimeZone',
- version => ON_WINDOWS ? '0.79' : '0.71'
+ version => '1.64'
},
# 1.54 is required for Perl 5.10+. It also makes DBD::Oracle happy.
{
package => 'DBI',
module => 'DBI',
- version => (vers_cmp($perl_ver, '5.13.3') > -1) ? '1.614' : '1.54'
+ version => ($^V >= v5.13.3) ? '1.614' : '1.54'
},
- # 2.22 fixes various problems related to UTF8 strings in hash keys,
- # as well as line endings on Windows.
+ # 2.24 contains several useful text virtual methods.
{
package => 'Template-Toolkit',
module => 'Template',
- version => '2.22'
+ version => '2.24'
},
- # 2.04 implement the "Test" method (to write to data/mailer.testfile).
+ # 1.300011 has a debug mode for SMTP and automatically pass -i to sendmail.
{
- package => 'Email-Send',
- module => 'Email::Send',
- version => ON_WINDOWS ? '2.16' : '2.04',
- blacklist => ['^2\.196$']
+ package => 'Email-Sender',
+ module => 'Email::Sender',
+ version => '1.300011',
},
{
package => 'Email-MIME',
@@ -150,9 +141,8 @@ sub REQUIRED_MODULES {
{
package => 'URI',
module => 'URI',
- # This version properly handles a semicolon as the delimiter
- # in a URL query string.
- version => '1.37',
+ # 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.
{
@@ -165,10 +155,22 @@ sub REQUIRED_MODULES {
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, {
+ push(@modules,
+ {
package => 'Win32',
module => 'Win32',
# 0.35 fixes a memory leak in GetOSVersion, which we use.
@@ -179,7 +181,14 @@ sub REQUIRED_MODULES {
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');
@@ -188,7 +197,6 @@ sub REQUIRED_MODULES {
};
sub OPTIONAL_MODULES {
- my $perl_ver = sprintf('%vd', $^V);
my @modules = (
{
package => 'GD',
@@ -199,10 +207,9 @@ sub OPTIONAL_MODULES {
{
package => 'Chart',
module => 'Chart::Lines',
- # Versions below 2.1 cannot be detected accurately.
- # There is no 2.1.0 release (it was 2.1), but .0 is required to fix
+ # Versions below 2.4.1 cannot be compared accurately, see
# https://rt.cpan.org/Public/Bug/Display.html?id=28218.
- version => '2.1.0',
+ version => '2.4.1',
feature => [qw(new_charts old_charts)],
},
{
@@ -283,6 +290,8 @@ sub OPTIONAL_MODULES {
# 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
@@ -297,26 +306,20 @@ sub OPTIONAL_MODULES {
package => 'JSON-RPC',
module => 'JSON::RPC',
version => 0,
- feature => ['jsonrpc'],
- },
- {
- package => 'JSON-XS',
- module => 'JSON::XS',
- # 2.0 is the first version that will work with JSON::RPC.
- version => '2.0',
- feature => ['jsonrpc_faster'],
+ feature => ['jsonrpc', 'rest'],
},
{
package => 'Test-Taint',
module => 'Test::Taint',
- version => 0,
- feature => ['jsonrpc', 'xmlrpc'],
+ # 1.06 no longer throws warnings with Perl 5.10+.
+ version => 1.06,
+ feature => ['jsonrpc', 'xmlrpc', 'rest'],
},
{
# We need the 'utf8_mode' method of HTML::Parser, for HTML::Scrubber.
package => 'HTML-Parser',
module => 'HTML::Parser',
- version => (vers_cmp($perl_ver, '5.13.3') > -1) ? '3.67' : '3.40',
+ version => ($^V >= v5.13.3) ? '3.67' : '3.40',
feature => ['html_desc'],
},
{
@@ -368,12 +371,6 @@ sub OPTIONAL_MODULES {
version => 0,
feature => ['jobqueue'],
},
- {
- package => 'File-Slurp',
- module => 'File::Slurp',
- version => '9999.13',
- feature => ['jobqueue'],
- },
# mod_perl
{
@@ -403,6 +400,22 @@ sub OPTIONAL_MODULES {
version => '0',
feature => ['typesniffer'],
},
+
+ # memcached
+ {
+ package => 'Cache-Memcached',
+ module => 'Cache::Memcached',
+ version => '0',
+ feature => ['memcached'],
+ },
+
+ # Documentation
+ {
+ package => 'File-Copy-Recursive',
+ module => 'File::Copy::Recursive',
+ version => 0,
+ feature => ['documentation'],
+ }
);
my $extra_modules = _get_extension_requirements('OPTIONAL_MODULES');
@@ -416,14 +429,18 @@ use constant FEATURE_FILES => (
jsonrpc => ['Bugzilla/WebService/Server/JSONRPC.pm', 'jsonrpc.cgi'],
xmlrpc => ['Bugzilla/WebService/Server/XMLRPC.pm', 'xmlrpc.cgi',
'Bugzilla/WebService.pm', 'Bugzilla/WebService/*.pm'],
+ rest => ['Bugzilla/WebService/Server/REST.pm', 'rest.cgi',
+ 'Bugzilla/WebService/Server/REST/Resources/*.pm'],
moving => ['importxml.pl'],
auth_ldap => ['Bugzilla/Auth/Verify/LDAP.pm'],
auth_radius => ['Bugzilla/Auth/Verify/RADIUS.pm'],
+ documentation => ['docs/makedocs.pl'],
inbound_email => ['email_in.pl'],
jobqueue => ['Bugzilla/Job/*', 'Bugzilla/JobQueue.pm',
'Bugzilla/JobQueue/*', 'jobqueue.pl'],
patch_viewer => ['Bugzilla/Attachment/PatchReader.pm'],
updates => ['Bugzilla/Update.pm'],
+ memcached => ['Bugzilla/Memcache.pm'],
);
# This implements the REQUIRED_MODULES and OPTIONAL_MODULES stuff
@@ -506,7 +523,7 @@ sub _missing_apache_modules {
return [];
}
my @missing;
- foreach my $module (keys %$modules) {
+ foreach my $module (sort keys %$modules) {
my $ok = _check_apache_module($module, $modules->{$module},
$cmd_info, $output);
push(@missing, $module) if !$ok;
@@ -940,3 +957,11 @@ Returns a hashref where file names are the keys and the value is the feature
that must be enabled in order to compile that file.
=back
+
+=head1 B<Methods in need of POD>
+
+=over
+
+=item print_module_instructions
+
+=back
diff --git a/Bugzilla/Install/Util.pm b/Bugzilla/Install/Util.pm
index cbc41db32..c05037061 100644
--- a/Bugzilla/Install/Util.pm
+++ b/Bugzilla/Install/Util.pm
@@ -11,7 +11,9 @@ package Bugzilla::Install::Util;
# module may require *only* Bugzilla::Constants and built-in
# perl modules.
+use 5.10.1;
use strict;
+use warnings;
use Bugzilla::Constants;
@@ -23,7 +25,7 @@ use Scalar::Util qw(tainted);
use Term::ANSIColor qw(colored);
use PerlIO;
-use base qw(Exporter);
+use parent qw(Exporter);
our @EXPORT_OK = qw(
bin_loc
get_version_and_os
@@ -37,7 +39,6 @@ our @EXPORT_OK = qw(
include_languages
success
template_include_path
- vers_cmp
init_console
);
@@ -475,49 +476,6 @@ sub template_include_path {
return \@include_path;
}
-# This is taken straight from Sort::Versions 1.5, which is not included
-# with perl by default.
-sub vers_cmp {
- my ($a, $b) = @_;
-
- # Remove leading zeroes - Bug 344661
- $a =~ s/^0*(\d.+)/$1/;
- $b =~ s/^0*(\d.+)/$1/;
-
- my @A = ($a =~ /([-.]|\d+|[^-.\d]+)/g);
- my @B = ($b =~ /([-.]|\d+|[^-.\d]+)/g);
-
- my ($A, $B);
- while (@A and @B) {
- $A = shift @A;
- $B = shift @B;
- if ($A eq '-' and $B eq '-') {
- next;
- } elsif ( $A eq '-' ) {
- return -1;
- } elsif ( $B eq '-') {
- return 1;
- } elsif ($A eq '.' and $B eq '.') {
- next;
- } elsif ( $A eq '.' ) {
- return -1;
- } elsif ( $B eq '.' ) {
- return 1;
- } elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) {
- if ($A =~ /^0/ || $B =~ /^0/) {
- return $A cmp $B if $A cmp $B;
- } else {
- return $A <=> $B if $A <=> $B;
- }
- } else {
- $A = uc $A;
- $B = uc $B;
- return $A cmp $B if $A cmp $B;
- }
- }
- @A <=> @B;
-}
-
sub no_checksetup_from_cgi {
print "Content-Type: text/html; charset=UTF-8\r\n\r\n";
print install_string('no_checksetup_from_cgi');
@@ -893,26 +851,36 @@ Used by L<Bugzilla::Template> to determine the languages' list which
are compiled with the browser's I<Accept-Language> and the languages
of installed templates.
-=item C<vers_cmp>
+=back
+
+=head1 B<Methods in need of POD>
=over
-=item B<Description>
+=item supported_languages
-This is a comparison function, like you would use in C<sort>, except that
-it compares two version numbers. So, for example, 2.10 would be greater
-than 2.2.
+=item extension_template_directory
-It's based on versioncmp from L<Sort::Versions>, with some Bugzilla-specific
-fixes.
+=item extension_code_files
-=item B<Params>: C<$a> and C<$b> - The versions you want to compare.
+=item extension_web_directory
-=item B<Returns>
+=item trick_taint
-C<-1> if C<$a> is less than C<$b>, C<0> if they are equal, or C<1> if C<$a>
-is greater than C<$b>.
+=item success
-=back
+=item trim
+
+=item extension_package_directory
+
+=item set_output_encoding
+
+=item extension_requirement_packages
+
+=item prevent_windows_dialog_boxes
+
+=item sortQvalue
+
+=item no_checksetup_from_cgi
=back