File Coverage

blib/lib/cPanel/TaskQueue/PluginManager.pm
Criterion Covered Total %
statement 63 65 96.9
branch 30 34 88.2
condition 16 18 88.8
subroutine 7 7 100.0
pod 5 5 100.0
total 121 129 93.8


line stmt bran cond sub pod time code
1             package cPanel::TaskQueue::PluginManager;
2             {
3             $cPanel::TaskQueue::PluginManager::VERSION = '0.606';
4             }
5              
6             # cpanel - cPanel/TaskQueue/PluginManager.pm Copyright(c) 2014 cPanel, Inc.
7             # All rights Reserved.
8             # copyright@cpanel.net http://cpanel.net
9             #
10             # Redistribution and use in source and binary forms, with or without
11             # modification, are permitted provided that the following conditions are met:
12             # * Redistributions of source code must retain the above copyright
13             # notice, this list of conditions and the following disclaimer.
14             # * Redistributions in binary form must reproduce the above copyright
15             # notice, this list of conditions and the following disclaimer in the
16             # documentation and/or other materials provided with the distribution.
17             # * Neither the name of the owner nor the names of its contributors may
18             # be used to endorse or promote products derived from this software
19             # without specific prior written permission.
20             #
21             # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22             # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23             # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24             # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
25             # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26             # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27             # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28             # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29             # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30             # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31              
32 5     5   127719 use strict;
  5         10  
  5         176  
33 5     5   2520 use cPanel::TaskQueue ();
  5         16  
  5         6019  
34              
35             my %plugins_list;
36              
37             sub load_all_plugins {
38 7     7 1 5635 my %opts = @_;
39              
40 7 100 100     71 die "No directory list supplied.\n" unless exists $opts{'directories'} and 'ARRAY' eq ref $opts{'directories'};
41 5 100 100     50 die "No namespace list supplied.\n" unless exists $opts{'namespaces'} and 'ARRAY' eq ref $opts{'namespaces'};
42 3         8 foreach my $dir ( @{ $opts{'directories'} } ) {
  3         10  
43 4         8 foreach my $ns ( @{ $opts{'namespaces'} } ) {
  4         12  
44 6         18 load_plugins( $dir, $ns );
45             }
46             }
47             }
48              
49             sub load_plugins {
50 15     15 1 5202 my ( $root_dir, $namespace ) = @_;
51              
52 15 100 100     183 die "No directory supplied for finding plugins.\n" unless defined $root_dir and length $root_dir;
53 13 100       332 die "Supplied directory '$root_dir' does not exist.\n" unless -d $root_dir;
54 12 100       28 die "Supplied directory '$root_dir' not part of Perl's include path.\n" unless grep { $_ eq $root_dir } @INC;
  131         250  
55              
56 11 100 100     75 die "No namespace for plugins specified.\n" unless defined $namespace and length $namespace;
57 9 100       73 die "Namespace '$namespace' not a valid Perl namespace.\n"
58             unless $namespace =~ m{^ \w+ (?: :: \w+ )* $}x;
59              
60 8         43 my $ns_dir = join( '/', $root_dir, split( '::', $namespace ) );
61              
62             # not having the namespace in that root is not an error.
63 8 100       170 return unless -d $ns_dir;
64              
65 4 50       230 opendir( my $dir, $ns_dir ) or die "Unable to read directory '$ns_dir': $!\n";
66 4         124 my @files = grep { !/^\.\.?$/ } readdir($dir);
  31         92  
67 4 50       81 closedir($dir) or die "Failed to close directory '$ns_dir': $!\n";
68              
69             # TODO: Do we want to handle subdirectories?
70 4 50 33     11 my @modules = map { ( /^(\w+)\.pm$/ and -f "$ns_dir/$_" ) ? $1 : () } @files;
  23         787  
71 4         16 foreach my $mod (@modules) {
72 23         79 load_plugin_by_name( $namespace . '::' . $mod );
73             }
74             }
75              
76             sub load_plugin_by_name {
77 30     30 1 4028 my ($modname) = @_;
78              
79             # Don't try to reload.
80 30 100       99 return if exists $plugins_list{$modname};
81              
82 26         2005 eval "require $modname;"; ## no critic (ProhibitStringyEval)
83 26 100       419 if ($@) {
84 5         211 warn "Failed to load '$modname' plugin: $@\n";
85 5         20 return;
86             }
87              
88 21         133 my $register = UNIVERSAL::can( $modname, 'to_register' );
89 21 100       65 unless ( defined $register ) {
90 4         62 warn "Plugin '$modname' not registered, no 'to_register' method.\n";
91 4         15 return;
92             }
93 17         26 my $num_reg = 0;
94 17         28 my @commands;
95 17         58 foreach my $reg ( $register->() ) {
96 34 100 100     200 unless ( 'ARRAY' eq ref $reg and 2 == @{$reg} ) {
  18         84  
97 19         243 warn "Plugin '$modname': invalid registration entry\n";
98 19         49 next;
99             }
100 15 50       27 eval { cPanel::TaskQueue->register_task_processor( @{$reg} ); } or do {
  15         23  
  15         97  
101 0         0 warn "Plugin '$modname' register failed: $@\n";
102 0         0 next;
103             };
104 15         23 ++$num_reg;
105 15         48 push @commands, $reg->[0]; # Add command name to list.
106             }
107              
108 17 100       62 if ($num_reg) {
109 10         25 $plugins_list{$modname} = \@commands;
110 10         59 return 1;
111             }
112 7         22 return;
113             }
114              
115             sub list_loaded_plugins {
116 3     3 1 6412 return keys %plugins_list;
117             }
118              
119             sub get_plugins_hash {
120 4     4 1 1633 my %clone;
121 4         26 while ( my ( $module, $commands ) = each %plugins_list ) {
122 6         10 $clone{$module} = [ @{$commands} ];
  6         36  
123             }
124 4         21 return \%clone;
125             }
126              
127             1;
128              
129             __END__