summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Install/Util.pm
diff options
context:
space:
mode:
authormkanat%bugzilla.org <>2009-11-24 07:09:41 +0100
committermkanat%bugzilla.org <>2009-11-24 07:09:41 +0100
commit5fc80f94271780b6ff6d1dbba554df35e803ac51 (patch)
treeebc3f2bc12bb32ab280cacb1cd88b35001fb2c0e /Bugzilla/Install/Util.pm
parent78413d851910175fcc8aef2249be377cab7dd7e8 (diff)
downloadbugzilla-5fc80f94271780b6ff6d1dbba554df35e803ac51.tar.gz
bugzilla-5fc80f94271780b6ff6d1dbba554df35e803ac51.tar.xz
Bug 430014: Re-write the code hooks system so that it uses modules instead of individual .pl files
Patch by Max Kanat-Alexander <mkanat@bugzilla.org> (module owner) a=mkanat
Diffstat (limited to 'Bugzilla/Install/Util.pm')
-rw-r--r--Bugzilla/Install/Util.pm122
1 files changed, 105 insertions, 17 deletions
diff --git a/Bugzilla/Install/Util.pm b/Bugzilla/Install/Util.pm
index d3fb4e5f8..254cc237b 100644
--- a/Bugzilla/Install/Util.pm
+++ b/Bugzilla/Install/Util.pm
@@ -37,6 +37,8 @@ use base qw(Exporter);
our @EXPORT_OK = qw(
bin_loc
get_version_and_os
+ extension_code_files
+ extension_requirement_packages
indicate_progress
install_string
include_languages
@@ -79,6 +81,96 @@ sub get_version_and_os {
os_ver => $os_details[3] };
}
+sub _extension_paths {
+ my $dir = bz_locations()->{'extensionsdir'};
+ my @extension_items = glob("$dir/*");
+ my @paths;
+ foreach my $item (@extension_items) {
+ my $basename = basename($item);
+ # Skip CVS directories and any hidden files/dirs.
+ next if ($basename eq 'CVS' or $basename =~ /^\./);
+ if (-d $item) {
+ if (!-e "$item/disabled") {
+ push(@paths, $item);
+ }
+ }
+ elsif ($item =~ /\.pm$/i) {
+ push(@paths, $item);
+ }
+ }
+ return @paths;
+}
+
+sub extension_code_files {
+ my ($requirements_only) = @_;
+ my @files;
+ foreach my $path (_extension_paths()) {
+ my @load_files;
+ if (-d $path) {
+ my $extension_file = "$path/Extension.pm";
+ my $config_file = "$path/Config.pm";
+ if (-e $extension_file) {
+ push(@load_files, $extension_file);
+ }
+ if (-e $config_file) {
+ push(@load_files, $config_file);
+ }
+
+ # Don't load Extension.pm if we just want Config.pm and
+ # we found both.
+ if ($requirements_only and scalar(@load_files) == 2) {
+ shift(@load_files);
+ }
+ }
+ else {
+ push(@load_files, $path);
+ }
+ next if !scalar(@load_files);
+ # We know that these paths are safe, because they came from
+ # extensionsdir and we checked them specifically for their format.
+ # Also, the only thing we ever do with them is pass them to "require".
+ trick_taint($_) foreach @load_files;
+ push(@files, \@load_files);
+ }
+ return \@files;
+}
+
+# Used by _get_extension_requirements in Bugzilla::Install::Requirements.
+sub extension_requirement_packages {
+ # If we're in a .cgi script or some time that's not the requirements phase,
+ # just use Bugzilla->extensions. This avoids running the below code during
+ # a normal Bugzilla page, which is important because the below code
+ # doesn't actually function right if it runs after
+ # Bugzilla::Extension->load_all (because stuff has already been loaded).
+ # (This matters because almost every page calls Bugzilla->feature, which
+ # calls OPTIONAL_MODULES, which calls this method.)
+ if (eval { Bugzilla->extensions }) {
+ return Bugzilla->extensions;
+ }
+ my $packages = _cache()->{extension_requirement_packages};
+ return $packages if $packages;
+ $packages = [];
+ my %package_map;
+
+ my $extension_files = extension_code_files('requirements only');
+ foreach my $file_set (@$extension_files) {
+ my $file = shift @$file_set;
+ my $name = require $file;
+ if ($name =~ /^\d+$/) {
+ die install_string('extension_must_return_name',
+ { file => $file, returned => $name });
+ }
+ my $package = "Bugzilla::Extension::$name";
+ $package_map{$file} = $package;
+ push(@$packages, $package);
+ }
+ _cache()->{extension_requirement_packages} = $packages;
+ # Used by Bugzilla::Extension->load if it's called after this method
+ # (which only happens during checksetup.pl, currently).
+ _cache()->{extension_requirement_package_map} = \%package_map;
+ return $packages;
+}
+
sub indicate_progress {
my ($params) = @_;
my $current = $params->{current};
@@ -93,8 +185,8 @@ sub indicate_progress {
sub install_string {
my ($string_id, $vars) = @_;
- _cache()->{template_include_path} ||= template_include_path();
- my $path = _cache()->{template_include_path};
+ _cache()->{install_string_path} ||= template_include_path();
+ my $path = _cache()->{install_string_path};
my $string_template;
# Find the first template that defines this string.
@@ -134,10 +226,10 @@ sub include_languages {
# function in Bugzilla->request_cache. This is done to improve the
# performance of the template processing.
my $to_be_cached = 0;
- if (exists $ENV{'SERVER_SOFTWARE'} and not @_) {
- my $cache = Bugzilla->request_cache;
+ if (not @_) {
+ my $cache = _cache();
if (exists $cache->{include_languages}) {
- return @{$cache->{include_languages}}
+ return @{ $cache->{include_languages} };
}
$to_be_cached = 1;
}
@@ -202,8 +294,7 @@ sub include_languages {
# Cache the result if we are in CGI mode and called without parameter
# (see the comment at the top of this function).
if ($to_be_cached) {
- my $cache = Bugzilla->request_cache;
- $cache->{include_languages} = \@usedlanguages;
+ _cache()->{include_languages} = \@usedlanguages;
}
return @usedlanguages;
@@ -241,12 +332,8 @@ sub template_base_directories {
# First, we add extension template directories, because extension templates
# override standard templates. Extensions may be localized in the same way
# that Bugzilla templates are localized.
- my @template_dirs;
- my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*");
- foreach my $extension (@extensions) {
- next if (-e "$extension/disabled" or !-d "$extension/template");
- push(@template_dirs, "$extension/template");
- }
+ my @extensions = grep { -d "$_/template" } _extension_paths();
+ my @template_dirs = map { "$_/template" } @extensions;
push(@template_dirs, bz_locations()->{'templatedir'});
return \@template_dirs;
}
@@ -384,12 +471,13 @@ sub init_console {
}
# This is like request_cache, but it's used only by installation code
-# for setup.cgi and things like that.
+# for checksetup.pl and things like that.
our $_cache = {};
sub _cache {
- if ($ENV{MOD_PERL}) {
- require Apache2::RequestUtil;
- return Apache2::RequestUtil->request->pnotes();
+ # If the normal request_cache is available (which happens any time
+ # after the requirements phase) then we should use that.
+ if (eval { Bugzilla->request_cache; }) {
+ return Bugzilla->request_cache;
}
return $_cache;
}