File Coverage

blib/lib/Plugin/Loader.pm
Criterion Covered Total %
statement 32 32 100.0
branch 4 4 100.0
condition n/a
subroutine 7 7 100.0
pod 2 2 100.0
total 45 45 100.0


line stmt bran cond sub pod time code
1             package Plugin::Loader;
2             $Plugin::Loader::VERSION = '0.05';
3 3     3   40181 use 5.006;
  3         10  
  3         128  
4 3     3   1689 use Moo;
  3         34104  
  3         13  
5 3     3   5256 use Path::Iterator::Rule;
  3         32355  
  3         97  
6 3     3   471 use File::Spec::Functions qw/ catfile splitdir /;
  3         560  
  3         206  
7 3     3   13 use Carp qw/ croak /;
  3         3  
  3         815  
8              
9             has 'max_depth' => (is => 'rw');
10              
11             sub find_modules
12             {
13 3     3 1 3633 my ($self, $base) = @_;
14 3         14 my @baseparts = split(/::/, $base);
15 3         4 my %modules;
16              
17 3         7 foreach my $directory (@INC) {
18 36         120 my $path = catfile($directory, @baseparts);
19 36 100       433 next unless -d $path;
20              
21 3         23 my $rule = Path::Iterator::Rule->new->perl_module;
22 3 100       659 $rule->max_depth($self->max_depth) if $self->max_depth;
23              
24 3         31 foreach my $file ($rule->all($path)) {
25 8         3065 (my $modpath = $file) =~ s!^\Q$directory\E.|\.pm$!!g;
26              
27 8         25 my $module = join('::', splitdir($modpath));
28              
29             # Using a hash means that even if a module is installed
30             # in more than one place, it will only be reported once
31 8         156 $modules{ $module }++;
32             }
33             }
34              
35 3         23 return keys(%modules);
36             }
37              
38             sub load
39             {
40 2     2 1 1525 my ($self, @modules) = @_;
41              
42 2         10 require Module::Runtime;
43 2         5 foreach my $module (@modules) {
44 2         6 Module::Runtime::require_module($module);
45             }
46             }
47              
48             1;
49              
50             =encoding utf8
51              
52             =head1 NAME
53              
54             Plugin::Loader - finding and loading modules in a given namespace
55              
56             =head1 SYNOPSIS
57              
58             use Plugin::Loader;
59              
60             my $loader = Plugin::Loader->new;
61             my @plugins = $loader->find_modules('MyApp::Plugin');
62              
63             foreach my $plugin (@plugins) {
64             $loader->load($plugin);
65             }
66              
67             =head1 DESCRIPTION
68              
69             B: this module has now been renamed to L.
70             In the slim chance that you'd started using C,
71             my apologies, and please switch to using L.
72             C will eventually be removed from CPAN.
73              
74             This module provides methods for finding modules in a given namespace,
75             and then loading them. It is intended for use in situations where
76             you're looking for plugins, and then loading one or more of them.
77              
78             This module was inspired by L, which I have used in
79             a number of projects. But some people were wary of requiring L
80             just to get a module loader, which prompted me to create C.
81              
82             =head2 max_depth
83              
84             C has an optional C attribute.
85             If you set this to 1, then C will only report modules
86             that are immediately within the namespace specified.
87              
88             Let's say you have all of the CPAN plugins for the template toolkit
89             installed locally. If you don't specify C, then C
90             would return L
91             as well as L. If you set C to 1,
92             then you'd get the latter but not the former.
93              
94             Why might you want to do that?
95              
96             You might have a convention where plugins are the modules immediately
97             within the specified namespace, but that each plugin can have additional
98             modules within its own namespace.
99              
100             So typically you'll either not set C, or you'll set it to 1.
101              
102             =head1 METHODS
103              
104             =head2 find_modules
105              
106             Takes a namespace, and returns all installed modules in that namespace,
107             that were found in C<@INC>. For example:
108              
109             @plugins = $loader->find_modules('Template::Plugin');
110              
111             By default this will find all modules in the given namespace,
112             unless you've specified a maximum search depth, as described above.
113              
114             =head2 load
115              
116             Takes a module name and tries to load the module.
117             If loading fails, then we C.
118              
119             =head1 SEE ALSO
120              
121             L the new name for Plugin::Loader.
122              
123             L was the inspiration for this module, but has
124             a slightly different interface. In particular, it has C
125             hard-coded to 1.
126              
127             L is effectively a role which gives a class the ability
128             to find plugins within its namespace.
129              
130             L is similar to L,
131             but lets you control the order in which modules are loaded.
132              
133             L will load all modules in a given namespace, eg with C
134              
135             L will load all modules found in a given I
136             (as opposed to a namespace).
137              
138             L provides functions for loading modules,
139             but not for finding them.
140              
141             L provides a number of functions for finding and loading
142             modules. It provides different functions depending on whether you want
143             to limit the search depth to 1 or not: C vs C.
144              
145             L will load all modules in a given namespace,
146             and return a list of the modules found / loaded.
147             It lets you provide regexps for filtering out certain namespaces.
148              
149             L provides two functions, C
150             and C which will load all locally installed modules
151             whose name matches a pattern (specified as a regular expression
152             or glob-style pattern).
153              
154             =head1 REPOSITORY
155              
156             L
157              
158             =head1 AUTHOR
159              
160             Neil Bowers Eneilb@cpan.orgE
161              
162             =head1 COPYRIGHT AND LICENSE
163              
164             This software is copyright (c) 2014 by Neil Bowers .
165              
166             This is free software; you can redistribute it and/or modify it under
167             the same terms as the Perl 5 programming language system itself.
168              
169             =cut
170