removed NEXT stuff
[catagits/Catalyst-Plugin-ConfigLoader-Environment.git] / lib / Catalyst / Plugin / ConfigLoader / Environment.pm
1 package Catalyst::Plugin::ConfigLoader::Environment;
2
3 use warnings;
4 use strict;
5 use JSON::Any;
6 use MRO::Compat;
7 =head1 NAME
8
9 Catalyst::Plugin::ConfigLoader::Environment - Configure your
10 application with environment variables.
11
12 =head1 VERSION
13
14 Version 0.05
15
16 =cut
17
18 our $VERSION = '0.06';
19
20 =head1 SYNOPSIS
21
22 Catalyst::Plugin::ConfigLoader::Environment reads environment
23 variables and sets up the configuration in your application
24 accordingly.
25
26 Here's how you use it:
27
28     package MyApp;
29     use Catalyst qw(... ConfigLoader::Environment ...);
30     MyApp->setup;
31
32 Then, before you run your application, set some environment
33 variables:
34
35     export MYAPP_foo='Hello, world!'
36     export MYAPP_bar="foobar"
37     perl script/myapp_server.pl
38
39 Inside your application, C<< $c->config->{foo} >> will be equal to
40 C<Hello, world!>, and C<< $c->config->{bar} >> will be equal to
41 C<foobar>.
42
43 =head2 Compatibility with ConfigLoader
44
45 You can use both ConfigLoader and this module in the same application.
46 If you specify C<ConfigLoader> before C<ConfigLoader::Environment> in
47 the import list to Catalyst, the environment will override any
48 configuration files that ConfigLoader may find.  This is the
49 recommended setup.
50
51 You can reverse the order in the import list if you want static config
52 files to override the environment, but that's not recommended.
53
54 =head1 DETAILS
55
56 Here's exactly how environment variables are translated into
57 configuration.
58
59 First, your application's name is converted to ALL CAPS, any colons
60 are converted to underscores (i.e. C<My::App> is translated to
61 C<MY_APP>), and a C<_> is appended.  Then, any environment variables
62 not starting with this prefix are discarded.
63
64 The prefix is then stripped, and the remaining variables are then
65 converted to elements in the C<config> hash as follows.
66
67 Variables starting with C<Model::>, C<View::>, or C<Controller::> and
68 then any character other than C<_> are treated as configuration
69 options for the corresponding component of your application.  The
70 prefix is saved as C<prefix> and everything after the first C<_> is
71 used as a key into the C<< $c->config->{"prefix"} >> hash.
72
73 Any other variables not starting with a special prefix are added
74 directly to the C<< $c->config >> hash.
75
76 =head1 EXAMPLES
77
78 Let's translate a YAML config file:
79
80     ---
81     name: MyApp
82     title: This is My App!
83     View::Foo:
84       EXTENSION: tt
85       EVAL_PERL: 1
86     Model::Bar:
87       root: "/etc"
88     Model::DBIC:
89       connect_info: [ "dbi:Pg:dbname=foo", "username", "password" ]
90
91 into environment variables that would setup the same configuration:
92
93     MYAPP_name=MyApp
94     MYAPP_title=This is My App!
95     MYAPP_View__Foo_EXTENSION=tt
96     MYAPP_View__Foo_EVAL_PERL=1
97     MYAPP_Model__Bar_root=/etc
98     MYAPP_Model__DBIC_connect_info=["dbi:Pg:dbname=foo", "username", "password"]
99
100 Double colons are converted into double underscores.  For
101 compatibility's sake, support for the 0.01-style use of
102 bourne-incompatible variable names is retained.
103
104 Values are JSON-decoded if they look like JSON arrays or objects
105 (i.e. if they're enclosed in []s or {}s). Taking advantage of that, we
106 can write the same example this way:
107
108     MYAPP_name=MyApp
109     MYAPP_title=This is My App!
110     MYAPP_View__Foo={"EXTENSION":"tt","EVAL_PERL":1}
111     MYAPP_Model__Bar={"root":"/etc"}
112     MYAPP_Model__DBIC={"connect_info":["dbi:Pg:dbname=foo", "username", "password"]}
113
114 =head1 FUNCTIONS
115
116 =head2 setup
117
118 Overriding Catalyst' setup routine.
119
120 =cut
121
122 sub setup {
123     my $c    = shift;
124     my $prefix = Catalyst::Utils::class2env($c);
125     my %env;
126     grep { /^${prefix}[_](.+)$/ && ($env{$1}=$ENV{$_})} keys %ENV;
127
128     foreach my $var (keys %env) {
129         my $val = $env{$var};
130
131         # Decode JSON array/object 
132         if ( $val =~ m{^\[.*\]$|^\{.*\}$} ) {
133             $val = JSON::Any->jsonToObj($val);
134         }
135
136         # Special syntax Model__Foo is equivalent to Model::Foo
137         if($var =~ /(Model|View|Controller)(?:::|__)([^_]+)(?:_(.+))?$/) {
138             $var = "${1}::$2";
139
140             # Special syntax Model__Foo_bar (or Model::Foo_bar) will
141             # tweak just the 'bar' subparam for Model::Foo's
142             # config. We can accomplish this using a hash that
143             # specifies just 'bar' ($c->config will merge hashes).
144             if ( defined $3 ) {
145                 $val = { $3 => $val };
146             }
147         }
148
149         $c->config( $var => $val );
150     }
151     
152     return $c->maybe::next::method(@_);
153 }
154
155
156 =head1 AUTHOR
157
158 Jonathan Rockway, C<< <jrockway at cpan.org> >>
159
160 =head1 CONTRIBUTORS
161
162 mugwump
163
164 Ryan D Johnson, C<< <ryan at innerfence.com> >>
165
166 =head1 BUGS
167
168 Please report any bugs or feature requests to
169 C<bug-catalyst-plugin-configloader-environment at rt.cpan.org>, or through the web interface at
170 L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Catalyst-Plugin-ConfigLoader-Environment>.
171 I will be notified, and then you'll automatically be notified of progress on
172 your bug as I make changes.
173
174 =head1 SUPPORT
175
176 You can find documentation for this module with the perldoc command.
177
178     perldoc Catalyst::Plugin::ConfigLoader::Environment
179
180 You can also look for information at:
181
182 =over 4
183
184 =item * Catalyst Mailing List
185
186 L<mailto:catalyst@lists.rawmode.org>.
187
188 =item * RT: CPAN's request tracker
189
190 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Catalyst-Plugin-ConfigLoader-Environment>
191
192 =back
193
194 =head1 COPYRIGHT & LICENSE
195
196 Copyright 2006 Jonathan Rockway, all rights reserved.
197
198 This program is free software; you can redistribute it and/or modify it
199 under the same terms as Perl itself.
200
201 If you'd like to use it under a different license, that's probably OK.
202 Please contact the author.
203
204 =cut
205
206 1; # End of Catalyst::Plugin::ConfigLoader::Environment