File Coverage

blib/lib/Mason/PluginManager.pm
Criterion Covered Total %
statement 73 73 100.0
branch 19 22 86.3
condition n/a
subroutine 18 18 100.0
pod n/a
total 110 113 97.3


line stmt bran cond sub pod time code
1             package Mason::PluginManager;
2             $Mason::PluginManager::VERSION = '2.23';
3 20     85   136 use Carp;
  20         33  
  20         1699  
4 20     50   107 use Log::Any qw($log);
  20         29  
  20         167  
5 20     50   1917 use Mason::Moose;
  20         30  
  20         158  
6 20     50   37861 use Mason::Util qw(can_load uniq);
  20         39  
  20         2379  
7              
8             my ( %apply_plugins_cache, %final_subclass_seen );
9              
10             # CLASS METHODS
11             #
12              
13             our $depth;
14             our %visited;
15             my $max_depth = 16;
16              
17 20     50   7987 method process_top_plugin_specs ($class: $plugin_specs) {
  111     111   247  
  111         229  
  111         171  
18 111         285 local $depth = 0;
19 111         313 local %visited = ();
20              
21 111         311 my @positive_plugin_specs = grep { !/^\-/ } @$plugin_specs;
  17         101  
22 111         343 my @negative_plugin_specs = map { substr( $_, 1 ) } grep { /^\-/ } @$plugin_specs;
  3         11  
  17         50  
23 111         282 push( @positive_plugin_specs, '@Default' );
24 7         12 my %exclude_plugin_modules =
25 111         545 map { ( $_, 1 ) } $class->process_plugin_specs( \@negative_plugin_specs );
26              
27 242         541 my @modules =
28 111         398 grep { !$exclude_plugin_modules{$_} } $class->process_plugin_specs( \@positive_plugin_specs );
29              
30 109         525 return @modules;
31             }
32              
33 20     50   9964 method process_plugin_specs ($class: $plugin_specs) {
  600     600   847  
  600         810  
  600         588  
34 600         1339 local $depth = $depth + 1;
35 600         2085 local %visited = %visited;
36 600 50       1566 die ">$max_depth levels deep in process_plugins_list (plugin cycle?)" if $depth >= $max_depth;
37 600 50       1598 croak 'plugins must be an array reference' unless ref($plugin_specs) eq 'ARRAY';
38 600         1696 my @modules = ( uniq( map { $class->process_plugin_spec($_) } @$plugin_specs ) );
  382         1041  
39 598         1857 return @modules;
40             }
41              
42 20     50   8419 method process_plugin_spec ($class: $plugin_spec) {
  382     382   629  
  382         496  
  382         412  
43 382         1014 my $module = $class->plugin_spec_to_module($plugin_spec);
44 380 100       3100 my @modules = !$visited{$module}++ ? $module->expand_to_plugins : ();
45 380         1218 return @modules;
46             }
47              
48 20     20   7420 method plugin_spec_to_module ($class: $plugin_spec) {
  382     382   563  
  382         484  
  382         416  
49 382 100       1986 my $module =
    100          
50             substr( $plugin_spec, 0, 1 ) eq '+' ? ( substr( $plugin_spec, 1 ) )
51             : substr( $plugin_spec, 0, 1 ) eq '@'
52             ? ( "Mason::PluginBundle::" . substr( $plugin_spec, 1 ) )
53             : "Mason::Plugin::$plugin_spec";
54 382 100       897 return can_load($module)
55             ? $module
56             : die "could not load '$module' for plugin spec '$plugin_spec'";
57             }
58              
59 20     20   8668 method apply_plugins_to_class ($class: $base_subclass, $name, $plugins) {
  734     734   1500  
  734         1435  
  734         895  
60 734         957 my $subclass;
61 734         2322 my $key = join( ",", $base_subclass, @$plugins );
62 734 100       14009 return $apply_plugins_cache{$key} if defined( $apply_plugins_cache{$key} );
63              
64 206         338 my $final_subclass;
65 206         662 my @roles = map { $_->get_roles_for_mason_class($name) } @$plugins;
  467         3170  
66 206 100       643 if (@roles) {
67 74         984 my $meta = Moose::Meta::Class->create_anon_class(
68             superclasses => [$base_subclass],
69             roles => \@roles,
70             cache => 1
71             );
72 74         358332 $final_subclass = $meta->name;
73 180     180   1052 $meta->add_method( 'meta' => sub { $meta } )
        180      
        178      
        178      
74 74 100       880 if !$final_subclass_seen{$final_subclass}++;
75             }
76             else {
77 132         266 $final_subclass = $base_subclass;
78             }
79 206 50       5451 $log->debugf( "apply_plugins - base_subclass=%s, name=%s, plugins=%s, roles=%s - %s",
80             $base_subclass, $name, $plugins, \@roles, $final_subclass )
81             if $log->is_debug;
82              
83 206 100       4129 $final_subclass->meta->make_immutable if $final_subclass->can('meta');
84              
85 206         26521 $apply_plugins_cache{$key} = $final_subclass;
86 206         7012 return $final_subclass;
87             }
88              
89             __PACKAGE__->meta->make_immutable();
90              
91             1;