Commit ab577dc1 authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 530767: Allow for CPAN distribution of extensions

Patch by Max Kanat-Alexander <mkanat@bugzilla.org> (module owner) a=mkanat
parent c62ddd06
......@@ -93,6 +93,21 @@ sub load {
$package->modify_inc($extension_file) if !$config_file;
}
$class->_validate_package($package, $extension_file);
return $package;
}
sub _validate_package {
my ($class, $package, $extension_file) = @_;
# For extensions from data/extensions/additional, we don't have a file
# name, so we fake it.
if (!$extension_file) {
$extension_file = $package;
$extension_file =~ s/::/\//g;
$extension_file .= '.pm';
}
if (!eval { $package->NAME }) {
ThrowCodeError('extension_no_name',
{ filename => $extension_file, package => $package });
......@@ -104,19 +119,30 @@ sub load {
package => $package,
class => $class });
}
return $package;
}
sub load_all {
my $class = shift;
my $file_sets = extension_code_files();
my ($file_sets, $extra_packages) = extension_code_files();
my @packages;
foreach my $file_set (@$file_sets) {
my $package = $class->load(@$file_set);
push(@packages, $package);
}
# Extensions from data/extensions/additional
foreach my $package (@$extra_packages) {
# Don't load an "additional" extension if we already have an extension
# loaded with that name.
next if grep($_ eq $package, @packages);
# Untaint the package name
$package =~ /([\w:]+)/;
$package = $1;
eval("require $package") || die $@;
$package->_validate_package($package);
push(@packages, $package);
}
return \@packages;
}
......@@ -402,6 +428,39 @@ for its module pre-requisites, but you don't want the module to be used
by Bugzilla, then you should make your extension's L</enabled> method
return C<0> or some false value.
=head1 DISTRIBUTING EXTENSIONS
If you've made an extension and you want to publish it, the first
thing you'll want to do is package up your extension's code and
then put a link to it in the appropriate section of
L<http://wiki.mozilla.org/Bugzilla:Addons>.
=head2 Distributing on CPAN
If you want a centralized distribution point that makes it easy
for Bugzilla users to install your extension, it is possible to
distribute your Bugzilla Extension through CPAN.
The details of making a standard CPAN module are too much to
go into here, but a lot of it is covered in L<perlmodlib>
and on L<http://www.cpan.org/> among other places.
When you distribute your extension via CPAN, your F<Extension.pm>
should simply install itself as F<Bugzilla/Extension/Foo.pm>,
where C<Foo> is the name of your module. You do not need a separate
F<Config.pm> file, because CPAN itself will handle installing
the prerequisites of your module, so Bugzilla doesn't have to
worry about it.
=head3 Using a module distributed on CPAN
There is a file named F<data/extensions/additional> in Bugzilla.
This is a plain-text file. Each line is the name of a module,
like C<Bugzilla::Extension::Foo>. In addition to the extensions
in the F<extensions/> directory, each module listed in this file
will be loaded as a Bugzilla Extension whenever Bugzilla loads or
uses extensions.
=head1 ADDITIONAL CONSTANTS
In addition to C<NAME>, there are some other constants you might
......
......@@ -198,6 +198,7 @@ sub FILESYSTEM {
my %create_dirs = (
$datadir => $ws_dir_full_control,
"$datadir/mining" => $ws_dir_readable,
"$datadir/extensions" => $ws_dir_readable,
$attachdir => $ws_dir_writeable,
$extensionsdir => $ws_dir_readable,
graphs => $ws_dir_writeable,
......@@ -208,7 +209,10 @@ sub FILESYSTEM {
# The name of each file, pointing at its default permissions and
# default contents.
my %create_files = ();
my %create_files = (
"$datadir/extensions/additional" => { perms => $ws_readable,
contents => '' },
);
# Each standard stylesheet has an associated custom stylesheet that
# we create. Also, we create placeholders for standard stylesheets
......
......@@ -130,7 +130,16 @@ sub extension_code_files {
trick_taint($_) foreach @load_files;
push(@files, \@load_files);
}
return \@files;
my @additional;
my $datadir = bz_locations()->{'datadir'};
my $addl_file = "$datadir/extensions/additional";
if (-e $addl_file) {
open(my $fh, '<', $addl_file) || die "$addl_file: $!";
@additional = map { trim($_) } <$fh>;
close($fh);
}
return (\@files, \@additional);
}
# Used by _get_extension_requirements in Bugzilla::Install::Requirements.
......@@ -150,8 +159,8 @@ sub extension_requirement_packages {
$packages = [];
my %package_map;
my $extension_files = extension_code_files('requirements only');
foreach my $file_set (@$extension_files) {
my ($file_sets, $extra_packages) = extension_code_files('requirements only');
foreach my $file_set (@$file_sets) {
my $file = shift @$file_set;
my $name = require $file;
if ($name =~ /^\d+$/) {
......@@ -162,6 +171,11 @@ sub extension_requirement_packages {
$package_map{$file} = $package;
push(@$packages, $package);
}
foreach my $package (@$extra_packages) {
eval("require $package") || die $@;
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).
......@@ -495,6 +509,15 @@ sub trick_taint {
return (defined($_[0]));
}
sub trim {
my ($str) = @_;
if ($str) {
$str =~ s/^\s+//g;
$str =~ s/\s+$//g;
}
return $str;
}
__END__
=head1 NAME
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment