File Coverage

blib/lib/Catalyst/Plugin/PickComponents.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Catalyst::Plugin::PickComponents;
2              
3 1     1   24526 use strict;
  1         3  
  1         38  
4 1     1   6 use warnings;
  1         2  
  1         30  
5 1     1   6 use vars qw/$VERSION/;
  1         6  
  1         51  
6             $VERSION = '0.02';
7 1     1   23002 use Module::Pluggable::Object;
  1         15836  
  1         38  
8 1     1   529 use Catalyst::Utils ();
  0            
  0            
9             use MRO::Compat;
10              
11             sub setup_components {
12             my $class = shift;
13            
14             my $config = $class->config->{ pick_components };
15              
16             unless ($config) {
17             return $class->maybe::next::method(@_);
18             }
19            
20             my @paths = exists $config->{paths} ? @{ delete $config->{paths} } : ();
21             my @modules = exists $config->{modules} ? @{ delete $config->{modules} } : ();
22             my @expect_paths = exists $config->{expect_paths} ? @{ delete $config->{expect_paths} } : ();
23             my @expect_modules = exists $config->{expect_modules} ? @{ delete $config->{expect_modules} } : ();
24            
25             my (@plugins, @expect_plugins);
26             if (scalar @paths) {
27             my $locator = Module::Pluggable::Object->new(
28             search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
29             %$config
30             );
31             @plugins = $locator->plugins;
32             }
33             if (scalar @modules) {
34             push @plugins, @modules;
35             }
36             if (scalar @expect_paths) {
37             my $locator = Module::Pluggable::Object->new(
38             search_path => [ map { s/^(?=::)/$class/; $_; } @expect_paths ],
39             );
40             @expect_plugins = $locator->plugins;
41             }
42             if (scalar @expect_modules) {
43             push @expect_plugins, @expect_modules;
44             }
45             my %has = map { $_ => 1 } @plugins;
46             $has{$_} = 0 foreach @expect_plugins;
47             @plugins = grep { $has{$_} == 1 } keys %has;
48            
49             # below code is copied from Catalyst.pm sub setup_components
50            
51             my @comps = sort { length $a <=> length $b } @plugins;
52             my %comps = map { $_ => 1 } @comps;
53            
54             for my $component ( @comps ) {
55              
56             # We pass ignore_loaded here so that overlay files for (e.g.)
57             # Model::DBI::Schema sub-classes are loaded - if it's in @comps
58             # we know M::P::O found a file on disk so this is safe
59              
60             Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
61              
62             my $module = $class->setup_component( $component );
63             my %modules = (
64             $component => $module,
65             map {
66             $_ => $class->setup_component( $_ )
67             } grep {
68             not exists $comps{$_}
69             } Devel::InnerPackage::list_packages( $component )
70             );
71            
72             for my $key ( keys %modules ) {
73             $class->components->{ $key } = $modules{ $key };
74             }
75             }
76             }
77              
78             1;
79             __END__
80              
81             =pod
82              
83             =head1 NAME
84              
85             Catalyst::Plugin::PickComponents - Pick up the components for Catalyst.
86              
87             =head1 SYNOPSIS
88              
89             use Catalyst qw/
90             PickComponents
91             /;
92              
93             # configure which dir and modules to be loaded
94             __PACKAGE__->config->{pick_components} = {
95             paths => [ '::Controller', '::Model' ],
96             modules => [ 'MyApp::View::TT' ],
97             expect_paths => [ '::Controller::Admin', '::Controller::Search' ],
98             expect_modules => [ 'MyApp::Controller::Admin', 'MyApp::Controller::Search' ],
99             }
100            
101             # after ConfigLoader or something else, in YAML myapp.yml or myapp_local.yml
102             pick_components:
103             paths:
104             - ::Controller
105             - ::Model
106             modules:
107             - MyApp::View::TT
108             expect_paths:
109             - ::Controller::Admin
110             - ::Controller::Search
111             expect_modules:
112             - MyApp::Controller::Admin
113             - MyApp::Controller::Search
114              
115             =head1 DESCRIPTION
116              
117             This plugin gives you the rights to pick up what modules loaded for a certain application instance.
118              
119             When source perl modules expand quickly, we might want to load different modules into different servers. For sure we can remove useless modules in different servers, but I'm afraid that it's hard to maintain and configure.
120              
121             example:
122              
123             # http://www.myapp.com/, myapp_local.yml
124             pick_components:
125             paths:
126             - ::Controller
127             - ::Model
128             modules:
129             - MyApp::View::TT
130             expect_paths:
131             - ::Controller::Admin
132             - ::Controller::Search
133             expect_modules:
134             - MyApp::Controller::Admin
135             - MyApp::Controller::Search
136            
137             # http://search.myapp.com/, myapp_local.yml
138             pick_components:
139             paths:
140             - ::Controller::Search
141             - ::Model
142             modules:
143             - MyApp::View::TT
144             - MyApp::Controller::Search
145             - MyApp::Controller::Root
146             expect_paths:
147             - ::Controller::Admin
148             expect_modules:
149             - MyApp::Controller::Admin
150            
151             # http://admin.myapp.com/, myapp_local.yml
152             pick_components:
153             paths:
154             - ::Controller::Admin
155             - ::Model
156             modules:
157             - MyApp::View::TT
158             - MyApp::Controller::Admin
159             - MyApp::Controller::Root
160             expect_paths:
161             - ::Controller::Search
162             expect_modules:
163             - MyApp::Controller::Search
164              
165             =head1 SEE ALSO
166              
167             L<Catalyst::Runtime>
168              
169             =head1 AUTHOR
170              
171             Fayland Lam, C<< <fayland at gmail.com> >>
172              
173             =head1 COPYRIGHT & LICENSE
174              
175             Copyright 2007 Fayland Lam, all rights reserved.
176              
177             This program is free software; you can redistribute it and/or modify it
178             under the same terms as Perl itself.
179              
180             =cut