diff options
Diffstat (limited to 'Bugzilla')
-rw-r--r-- | Bugzilla/Hook.pm | 24 | ||||
-rw-r--r-- | Bugzilla/Install/Requirements.pm | 51 |
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) = @_; |