File Coverage

blib/lib/Mojolicious/Plugin/Config.pm
Criterion Covered Total %
statement 112 112 100.0
branch 24 28 85.7
condition 15 17 88.2
subroutine 31 31 100.0
pod 3 3 100.0
total 185 191 96.8


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Config;
2 7     7   54 use Mojo::Base 'Mojolicious::Plugin';
  7         18  
  7         52  
3              
4 7     7   64 use Mojo::File qw(path);
  7         22  
  7         379  
5 7     7   50 use Mojo::Util qw(decode);
  7         24  
  7         5757  
6              
7 34     34 1 133 sub load { $_[0]->parse(decode('UTF-8', path($_[1])->slurp), @_[1, 2, 3]) }
8              
9             sub parse {
10 22     22 1 63 my ($self, $content, $file, $conf, $app) = @_;
11              
12             # Run Perl code in sandbox
13 3     3   30 my $config = eval 'package Mojolicious::Plugin::Config::Sandbox; no warnings;'
  3     3   10  
  3     3   298  
  3     3   29  
  3     2   6  
  3     2   23  
  3     2   23  
  3     2   11  
  3     2   226  
  3     2   23  
  3     2   6  
  3     2   107  
  2     2   16  
  2     2   5  
  2     2   107  
  2     2   14  
  2     2   7  
  2     2   65  
  2     2   17  
  2     2   5  
  2     2   200  
  2     2   16  
  2     2   5  
  2     2   15  
  2         21  
  2         8  
  2         172  
  2         18  
  2         13  
  2         91  
  2         13  
  2         6  
  2         93  
  2         17  
  2         5  
  2         59  
  2         14  
  2         5  
  2         217  
  2         15  
  2         6  
  2         26  
  2         14  
  2         5  
  2         164  
  2         21  
  2         8  
  2         90  
  2         15  
  2         9  
  2         98  
  2         15  
  2         4  
  2         59  
  2         16  
  2         7  
  2         196  
  2         19  
  2         4  
  2         24  
  2         17  
  2         7  
  2         142  
  2         19  
  2         7  
  2         105  
  2         17  
  2         7  
  2         97  
  2         16  
  2         4  
  2         64  
  22         2300  
14             . "sub app; local *app = sub { \$app }; use Mojo::Base -strict; $content";
15 22 50       135 die qq{Can't load configuration from file "$file": $@} if $@;
16 22 50       74 die qq{Configuration file "$file" did not return a hash reference} unless ref $config eq 'HASH';
17              
18 22         108 return $config;
19             }
20              
21             sub register {
22 27     27 1 92 my ($self, $app, $conf) = @_;
23              
24             # Override
25 27 100       157 return _plugins($app, $app->config) if $app->config->{config_override};
26              
27             # Config file
28 26   100     133 my $file = $conf->{file} || $ENV{MOJO_CONFIG};
29 26   100     145 $file ||= $app->moniker . '.' . ($conf->{ext} || 'conf');
      66        
30              
31             # Mode specific config file
32 26 100       230 my $mode = $file =~ /^(.*)\.([^.]+)$/ ? join('.', $1, $app->mode, $2) : '';
33              
34 26         100 my $home = $app->home;
35 26 100       105 $file = $home->child($file) unless path($file)->is_abs;
36 26 100 100     166 $mode = $home->child($mode) if $mode && !path($mode)->is_abs;
37 26 100 100     172 $mode = undef unless $mode && -e $mode;
38              
39             # Read config file
40 26         117 my $config = {};
41 26 100 66     117 if (-e $file) { $config = $self->load($file, $conf, $app) }
  20 100       127  
42              
43             # Check for default and mode specific config file
44 4         22 elsif (!$conf->{default} && !$mode) { die qq{Configuration file "$file" missing, maybe you need to create it?\n} }
45              
46             # Merge everything
47 20 100       97 $config = {%$config, %{$self->load($mode, $conf, $app)}} if $mode;
  14         44  
48 20 100       111 $config = {%{$conf->{default}}, %$config} if $conf->{default};
  5         38  
49 20         88 return _plugins($app, $app->config($config)->config);
50             }
51              
52             sub _plugins {
53 21     21   68 my ($app, $config) = @_;
54              
55 21 100       72 if (my $plugins = $config->{plugins}) {
56 6 50       25 die qq{Configuration value "plugins" is not an array reference} unless ref $plugins eq 'ARRAY';
57 6         15 for my $plugin (@$plugins) {
58 12 50       38 die qq{Configuration value "plugins" contains an entry that is not a hash reference} unless ref $plugin eq 'HASH';
59 12         63 $app->plugin((keys %$plugin)[0], (values %$plugin)[0]);
60             }
61             }
62              
63 21         68 return $app->config;
64             }
65              
66             1;
67              
68             =encoding utf8
69              
70             =head1 NAME
71              
72             Mojolicious::Plugin::Config - Perl-ish configuration plugin
73              
74             =head1 SYNOPSIS
75              
76             # myapp.conf (it's just Perl returning a hash)
77             {
78             # Just a value
79             foo => "bar",
80              
81             # Nested data structures are fine too
82             baz => ['♥'],
83              
84             # You have full access to the application
85             music_dir => app->home->child('music')
86             };
87              
88             # Mojolicious
89             my $config = $app->plugin('Config');
90             say $config->{foo};
91              
92             # Mojolicious::Lite
93             my $config = plugin 'Config';
94             say $config->{foo};
95              
96             # foo.html.ep
97             %= config->{foo}
98              
99             # The configuration is available application-wide
100             my $config = app->config;
101             say $config->{foo};
102              
103             # Everything can be customized with options
104             my $config = plugin Config => {file => '/etc/myapp.stuff'};
105              
106             =head1 DESCRIPTION
107              
108             L is a Perl-ish configuration plugin.
109              
110             The application object can be accessed via C<$app> or the C function, L, L, L and Perl
111             5.16 L are automatically enabled. A default configuration filename in the application home directory
112             will be generated from the value of L (C<$moniker.conf>). You can extend the normal
113             configuration file C<$moniker.conf> with C specific ones like C<$moniker.$mode.conf>, which will be detected
114             automatically.
115              
116             These configuration values are currently reserved:
117              
118             =over 2
119              
120             =item C
121              
122             If this configuration value has been set in L when this plugin is loaded, it will not do anything
123             besides loading deployment specific plugins.
124              
125             =item C
126              
127             plugins => [{SetUserGroup => {user => 'sri', group => 'staff'}}]
128              
129             One or more deployment specific plugins that should be loaded right after this plugin has been loaded.
130              
131             =back
132              
133             The code of this plugin is a good example for learning to build new plugins, you're welcome to fork it.
134              
135             See L for a list of plugins that are available by default.
136              
137             =head1 OPTIONS
138              
139             L supports the following options.
140              
141             =head2 default
142              
143             # Mojolicious::Lite
144             plugin Config => {default => {foo => 'bar'}};
145              
146             Default configuration, making configuration files optional.
147              
148             =head2 ext
149              
150             # Mojolicious::Lite
151             plugin Config => {ext => 'stuff'};
152              
153             File extension for generated configuration filenames, defaults to C.
154              
155             =head2 file
156              
157             # Mojolicious::Lite
158             plugin Config => {file => 'myapp.conf'};
159             plugin Config => {file => '/etc/foo.stuff'};
160              
161             Path to configuration file, absolute or relative to the application home directory, defaults to the value of the
162             C environment variable or C<$moniker.conf> in the application home directory.
163              
164             =head1 METHODS
165              
166             L inherits all methods from L and implements the following new ones.
167              
168             =head2 load
169              
170             $plugin->load($file, $conf, $app);
171              
172             Loads configuration file and passes the content to L.
173              
174             sub load ($self, $file, $conf, $app) {
175             ...
176             return $self->parse($content, $file, $conf, $app);
177             }
178              
179             =head2 parse
180              
181             $plugin->parse($content, $file, $conf, $app);
182              
183             Parse configuration file.
184              
185             sub parse ($self, $content, $file, $conf, $app) {
186             ...
187             return $hash;
188             }
189              
190             =head2 register
191              
192             my $config = $plugin->register(Mojolicious->new);
193             my $config = $plugin->register(Mojolicious->new, {file => '/etc/app.conf'});
194              
195             Register plugin in L application and merge configuration.
196              
197             =head1 SEE ALSO
198              
199             L, L, L.
200              
201             =cut