aboutsummaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Hook.pm24
-rw-r--r--Bugzilla/Install/Requirements.pm51
2 files changed, 71 insertions, 4 deletions
diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm
index be4a70077..f8167cd65 100644
--- a/Bugzilla/Hook.pm
+++ b/Bugzilla/Hook.pm
@@ -139,6 +139,30 @@ Params:
=back
+=head2 install-requirements
+
+Because of the way Bugzilla installation works, there can't be a normal
+hook during the time that F<checksetup.pl> checks what modules are
+installed. (C<Bugzilla::Hook> needs to have those modules installed--it's
+a chicken-and-egg problem.)
+
+So instead of the way hooks normally work, this hook just looks for two
+subroutines (or constants, since all constants are just subroutines) in
+your file, called C<OPTIONAL_MODULES> and C<REQUIRED_MODULES>,
+which should return arrayrefs in the same format as C<OPTIONAL_MODULES> and
+C<REQUIRED_MODULES> in L<Bugzilla::Install::Requirements>.
+
+These subroutines will be passed an arrayref that contains the current
+Bugzilla requirements of the same type, in case you want to modify
+Bugzilla's requirements somehow. (Probably the most common would be to
+alter a version number or the "feature" element of C<OPTIONAL_MODULES>.)
+
+F<checksetup.pl> will add these requirements to its own.
+
+Please remember--if you put something in C<REQUIRED_MODULES>, then
+F<checksetup.pl> B<cannot complete> unless the user has that module
+installed! So use C<OPTIONAL_MODULES> whenever you can.
+
=head2 install-update_db
This happens at the very end of all the tables being updated
diff --git a/Bugzilla/Install/Requirements.pm b/Bugzilla/Install/Requirements.pm
index f9bcc9711..14efd15f4 100644
--- a/Bugzilla/Install/Requirements.pm
+++ b/Bugzilla/Install/Requirements.pm
@@ -27,6 +27,7 @@ use strict;
use List::Util qw(max);
use POSIX ();
+use Safe;
use base qw(Exporter);
our @EXPORT = qw(
@@ -43,11 +44,15 @@ our @EXPORT = qw(
use Bugzilla::Constants;
+# 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.
-use constant REQUIRED_MODULES => [
+sub REQUIRED_MODULES {
+ my @modules = (
{
package => 'CGI',
module => 'CGI',
@@ -89,9 +94,15 @@ use constant REQUIRED_MODULES => [
module => ON_WINDOWS ? 'MIME::Tools' : 'MIME::Parser',
version => '5.406'
},
-];
+ );
+
+ my $all_modules = _get_extension_requirements(
+ 'REQUIRED_MODULES', \@modules);
+ return $all_modules;
+};
-use constant OPTIONAL_MODULES => [
+sub OPTIONAL_MODULES {
+ my @modules = (
{
package => 'GD',
module => 'GD',
@@ -194,7 +205,39 @@ use constant OPTIONAL_MODULES => [
version => '0.96',
feature => 'mod_perl'
},
-];
+ );
+
+ my $all_modules = _get_extension_requirements(
+ 'OPTIONAL_MODULES', \@modules);
+ return $all_modules;
+};
+
+# This implements the install-requirements hook described in Bugzilla::Hook.
+sub _get_extension_requirements {
+ my ($function, $base_modules) = @_;
+ my @all_modules;
+ # get a list of all extensions
+ my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*");
+ foreach my $extension (@extensions) {
+ my $file = "$extension/code/install-requirements.pl";
+ if (-e $file) {
+ my $safe = new Safe;
+ # This is a very liberal Safe.
+ $safe->permit(qw(:browse require entereval caller));
+ $safe->rdo($file);
+ if ($@) {
+ warn $@;
+ next;
+ }
+ my $modules = eval { &{$safe->varglob($function)}($base_modules) };
+ next unless $modules;
+ push(@all_modules, @$modules);
+ }
+ }
+
+ unshift(@all_modules, @$base_modules);
+ return \@all_modules;
+};
sub check_requirements {
my ($output) = @_;