From cf0742d1dc6034fa6c30af66020f9a4d9b40e4b2 Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Wed, 25 Nov 2009 07:45:20 +0000 Subject: Bug 530994: Allow extensions to specify where their template directory is (which allows CPAN-distributed extensions to have templates) Patch by Max Kanat-Alexander (module owner) a=mkanat --- Bugzilla/Extension.pm | 124 ++++++++++++++++++++++++++++++++++++++--------- Bugzilla/Install/Util.pm | 69 +++++++++++++++++++++++++- 2 files changed, 168 insertions(+), 25 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Extension.pm b/Bugzilla/Extension.pm index cd280bb84..8e603c5d4 100644 --- a/Bugzilla/Extension.pm +++ b/Bugzilla/Extension.pm @@ -24,7 +24,9 @@ use strict; use Bugzilla::Constants; use Bugzilla::Error; -use Bugzilla::Install::Util qw(extension_code_files); +use Bugzilla::Install::Util qw( + extension_code_files extension_template_directory + extension_package_directory); use File::Basename; use File::Spec; @@ -69,14 +71,7 @@ sub load { $package = "${class}::$name"; } - # This allows people to override modify_inc in Config.pm, if they - # want to. - if ($package->can('modify_inc')) { - $package->modify_inc($config_file); - } - else { - modify_inc($package, $config_file); - } + __do_call($package, 'modify_inc', $config_file); } if ($map and defined $map->{$extension_file}) { @@ -151,19 +146,15 @@ sub load_all { # directory of the extension. sub modify_inc { my ($class, $file) = @_; - my $lib_dir = File::Spec->catdir(dirname($file), 'lib'); - # Allow Config.pm to override my_inc, if it wants to. - if ($class->can('my_inc')) { - unshift(@INC, sub { $class->my_inc($lib_dir, @_); }); - } - else { - unshift(@INC, sub { my_inc($class, $lib_dir, @_); }); - } + + __do_call($class, 'package_dir', $file); + unshift(@INC, sub { __do_call($class, 'my_inc', @_) }); } # This is what gets put into @INC by modify_inc. sub my_inc { - my ($class, $lib_dir, undef, $file) = @_; + my ($class, undef, $file) = @_; + my $lib_dir = __do_call($class, 'lib_dir'); my @class_parts = split('::', $class); my ($vol, $dir, $file_name) = File::Spec->splitpath($file); my @dir_parts = File::Spec->splitdir($dir); @@ -191,6 +182,36 @@ sub my_inc { use constant enabled => 1; +sub lib_dir { + my $invocant = shift; + my $package_dir = __do_call($invocant, 'package_dir'); + return File::Spec->catdir($package_dir, 'lib'); +} + +sub template_dir { return extension_template_directory(@_); } +sub package_dir { return extension_package_directory(@_); } + +###################### +# Helper Subroutines # +###################### + +# In order to not conflict with extensions' private subroutines, any helpers +# here should start with a double underscore. + +# This is for methods that can optionally be overridden in Config.pm. +# It falls back to the local implementation if $class cannot do +# the method. This is necessary because Config.pm is not a subclass of +# Bugzilla::Extension. +sub __do_call { + my ($class, $method, @args) = @_; + if ($class->can($method)) { + return $class->$method(@args); + } + my $function_ref; + { no strict 'refs'; $function_ref = \&{$method}; } + return $function_ref->($class, @args); +} + 1; __END__ @@ -389,6 +410,16 @@ your extension is a single file named C. If any of this is confusing, just look at the code of the Example extension. It uses this method to specify requirements. +=head2 Templates + +Extensions store templates in a C