File Coverage

blib/lib/Config/Yak/OrderedPlugins.pm
Criterion Covered Total %
statement 11 13 84.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 16 18 88.8


line stmt bran cond sub pod time code
1             package Config::Yak::OrderedPlugins;
2             {
3             $Config::Yak::OrderedPlugins::VERSION = '0.23';
4             }
5             BEGIN {
6 1     1   1398 $Config::Yak::OrderedPlugins::AUTHORITY = 'cpan:TEX';
7             }
8             # ABSTRACT: a role to provide handling of ordered plugins
9              
10 1     1   18 use 5.010_000;
  1         3  
  1         36  
11 1     1   5 use mro 'c3';
  1         1  
  1         5  
12 1     1   42 use feature ':5.10';
  1         1  
  1         81  
13              
14 1     1   384 use Moose::Role;
  0            
  0            
15             use namespace::autoclean;
16              
17             # use IO::Handle;
18             # use autodie;
19             # use MooseX::Params::Validate;
20             # use Carp;
21             use English qw( -no_match_vars );
22             use Try::Tiny;
23             use Module::Pluggable::Object;
24              
25             # extends ...
26             # has ...
27             has '_finder' => (
28             'is' => 'rw',
29             'isa' => 'Module::Pluggable::Object',
30             'lazy' => 1,
31             'builder' => '_init_finder',
32             'accessor' => 'finder',
33             );
34              
35             has '_plugins' => (
36             'is' => 'rw',
37             'isa' => 'ArrayRef',
38             'lazy' => 1,
39             'builder' => '_init_plugins',
40             'accessor' => 'plugins',
41             );
42              
43             has '_finder_search_path' => (
44             'is' => 'rw',
45             'isa' => 'ArrayRef[Str]',
46             'lazy' => 1,
47             'builder' => '_init_finder_search_path',
48             );
49              
50             # with ...
51             with qw(Config::Yak::RequiredConfig Log::Tree::RequiredLogger);
52             # initializers ...
53             sub _init_finder_search_path {
54             my $self = shift;
55              
56             return [$self->_plugin_base_class()];
57             }
58              
59             sub _init_finder {
60             my $self = shift;
61              
62             # The finder is the class that finds our available plugins
63             my $Finder = Module::Pluggable::Object::->new( 'search_path' => $self->_finder_search_path() );
64              
65             return $Finder;
66             } ## end sub _init_finder
67              
68             sub _init_plugins {
69             my $self = shift;
70              
71             # Allow the plugins to be sorted by prio in the config with the Priority
72             # key in each plugin section. Why priorities? It may make sense or even
73             # be a strict requirement to run some plugins before or after
74             # another one.
75             my $order_ref = {};
76              
77             PLUGIN: foreach my $plugin_name ( $self->finder()->plugins() ) {
78             ## no critic (ProhibitStringyEval)
79             my $eval_status = eval "require $plugin_name;";
80             ## use critic
81             if ( !$eval_status ) {
82             $self->logger()->log( message => 'Failed to require ' . $plugin_name . ': ' . $EVAL_ERROR, level => 'warning', );
83             next;
84             }
85             my $arg_ref = $self->config()->get($plugin_name);
86             $arg_ref->{'logger'} = $self->logger();
87             $arg_ref->{'config'} = $self->config();
88             $arg_ref->{'parent'} = $self;
89             $arg_ref->{'name'} ||= $plugin_name;
90             if ( $arg_ref->{'disabled'} ) {
91             $self->logger()->log( message => 'Skipping disabled plugin: ' . $plugin_name, level => 'debug', );
92             next PLUGIN;
93             }
94             try {
95             my $Plugin = $plugin_name->new($arg_ref);
96             my $prio = $Plugin->priority();
97              
98             # disabled/abstract plugins will set a prio of 0
99             if ( $prio > 0 ) {
100             push( @{ $order_ref->{$prio} }, $Plugin );
101             $self->logger()->log( message => 'Loaded plugin '.ref($Plugin).' w/ priority '.$prio, level => 'debug', );
102             } else {
103             $self->logger()->log( message => 'Skipped loaded plugin '.ref($Plugin).' w/ priority '.$prio, level => 'debug', );
104             }
105             } ## end try
106             catch {
107             $self->logger()->log( message => 'Failed to initialize plugin ' . $plugin_name . ' w/ error: ' . $_, level => 'warning', );
108             };
109             } ## end foreach my $plugin_name ( $self...)
110              
111             my @plugins = ();
112              
113             # this basically merges the pre-sorted sub-arrays (which, if you follow
114             # my advice, should each contain only one element ... but we must
115             # plan for the unexptected, of course)
116             foreach my $prio ( sort { $a <=> $b } keys %{$order_ref} ) {
117             #$self->logger()->log( message => 'Adding Plugins '.join(',',map { ref($_) } @{$order_ref->{$prio}}).' w/ prio '.$prio, level => 'debug', );
118             push( @plugins, @{ $order_ref->{$prio} } );
119             }
120              
121             return \@plugins;
122             } ## end sub _init_plugins
123              
124             # requires ...
125             requires qw(_plugin_base_class);
126              
127             # your code here ...
128              
129             no Moose::Role;
130              
131             1;
132              
133             __END__
134              
135             =pod
136              
137             =encoding utf-8
138              
139             =head1 NAME
140              
141             Config::Yak::OrderedPlugins - a role to provide handling of ordered plugins
142              
143             =head1 SYNOPSIS
144              
145             use Moose;
146             with 'Config::Yak::OrderedPlugins';
147              
148             =head1 DESCRIPTION
149              
150             This Moose role provides an plugin hanlder for plugins ordered by priority.
151              
152             Upon access to the plugins() method this role will search
153             for all plugins within the search path defined by _plugin_base_class().
154              
155             It will also require an Config::Yak instance and a Log::Tree instance.
156              
157             =head1 NAME
158              
159             Config::Yak::OrderedPlugins - This role provides an handler for ordered plugins.
160              
161             =head1 AUTHOR
162              
163             Dominik Schulz <dominik.schulz@gauner.org>
164              
165             =head1 COPYRIGHT AND LICENSE
166              
167             This software is copyright (c) 2012 by Dominik Schulz.
168              
169             This is free software; you can redistribute it and/or modify it under
170             the same terms as the Perl 5 programming language system itself.
171              
172             =cut