Copied and adapted tests from Catalyst::Plugin::ConfigLoader
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Container.pm
CommitLineData
b4a6fa62 1package Catalyst::Container;
2use Bread::Board;
3use Moose;
4use Config::Any;
5use Data::Visitor::Callback;
6use Catalyst::Utils ();
7
8extends 'Bread::Board::Container';
9
10has config_local_suffix => (
11 is => 'rw',
12 isa => 'Str',
13 default => 'local',
14);
15
16has driver => (
17 is => 'rw',
18 isa => 'HashRef',
19 default => sub { +{} },
20);
21
22has file => (
23 is => 'rw',
24 isa => 'Str',
25 default => '',
26);
27
28has substitutions => (
29 is => 'rw',
30 isa => 'HashRef',
31 default => sub { +{} },
32);
33
34has name => (
35 is => 'rw',
36 isa => 'Str',
37 default => 'TestApp',
38);
39
40sub BUILD {
41 my $self = shift;
42
43 container $self => as {
44 service name => $self->name;
45 service driver => $self->driver;
46 service file => $self->file;
47 service substitutions => $self->substitutions;
48
49 service extensions => (
50 block => sub {
51 return \@{Config::Any->extensions};
52 },
53 );
54
55 service prefix => (
56 block => sub {
57 return Catalyst::Utils::appprefix( shift->param('name') );
58 },
59 dependencies => [ depends_on('name') ],
60 );
61
62 service path => (
63 block => sub {
64 my $s = shift;
65
66 return Catalyst::Utils::env_value( $s->param('name'), 'CONFIG' )
67 || $s->param('file')
68 || $s->param('name')->path_to( $s->param('prefix') );
69 },
70 dependencies => [ depends_on('file'), depends_on('name'), depends_on('prefix') ],
71 );
72
73 service config => (
74 block => sub {
75 my $s = shift;
76
77 my $v = Data::Visitor::Callback->new(
78 plain_value => sub {
79 return unless defined $_;
80 return $self->_config_substitutions( $s->param('name'), $s->param('substitutions'), $_ );
81 }
82
83 );
84 $v->visit( $s->param('raw_config') );
85 },
86 dependencies => [ depends_on('name'), depends_on('raw_config'), depends_on('substitutions') ],
87 );
88
89 service raw_config => (
90 block => sub {
91 my $s = shift;
92
93 my @global = @{$s->param('global_config')};
94 my @locals = @{$s->param('local_config')};
95
96 my $config = {};
97 for my $cfg (@global, @locals) {
98 for (keys %$cfg) {
99 $config = Catalyst::Utils::merge_hashes( $config, $cfg->{$_} );
100 }
101 }
102 return $config;
103 },
104 dependencies => [ depends_on('global_config'), depends_on('local_config') ],
105 );
106
107 service global_files => (
108 block => sub {
109 my $s = shift;
110
111 my ( $path, $extension ) = @{$s->param('config_path')};
112
113 my @extensions = @{$s->param('extensions')};
114
115 my @files;
116 if ( $extension ) {
117 die "Unable to handle files with the extension '${extension}'" unless grep { $_ eq $extension } @extensions;
118 push @files, $path;
119 } else {
120 @files = map { "$path.$_" } @extensions;
121 }
122 return \@files;
123 },
124 dependencies => [ depends_on('extensions'), depends_on('config_path') ],
125 );
126
127 service local_files => (
128 block => sub {
129 my $s = shift;
130
131 my ( $path, $extension ) = @{$s->param('config_path')};
132 my $suffix = $s->param('config_local_suffix');
133
134 my @extensions = @{$s->param('extensions')};
135
136 my @files;
137 if ( $extension ) {
138 die "Unable to handle files with the extension '${extension}'" unless grep { $_ eq $extension } @extensions;
139 $path =~ s{\.$extension}{_$suffix.$extension};
140 push @files, $path;
141 } else {
142 @files = map { "${path}_${suffix}.$_" } @extensions;
143 }
144 return \@files;
145 },
146 dependencies => [ depends_on('extensions'), depends_on('config_path'), depends_on('config_local_suffix') ],
147 );
148
149 service global_config => (
150 block => sub {
151 my $s = shift;
9ea11efb 152
f228c263 153 return Config::Any->load_files({
154 files => $s->param('global_files'),
b4a6fa62 155 filter => \&_fix_syntax,
156 use_ext => 1,
157 driver_args => $s->param('driver'),
158 });
b4a6fa62 159 },
160 dependencies => [ depends_on('global_files') ],
161 );
162
163 service local_config => (
164 block => sub {
165 my $s = shift;
166
f228c263 167 return Config::Any->load_files({
168 files => $s->param('local_files'),
b4a6fa62 169 filter => \&_fix_syntax,
170 use_ext => 1,
171 driver_args => $s->param('driver'),
172 });
b4a6fa62 173 },
174 dependencies => [ depends_on('local_files') ],
175 );
176
177 service config_path => (
178 block => sub {
179 my $s = shift;
180
181 my $path = $s->param('path');
182 my $prefix = $s->param('prefix');
183
184 my ( $extension ) = ( $path =~ m{\.(.{1,4})$} );
185
186 if ( -d $path ) {
187 $path =~ s{[\/\\]$}{};
188 $path .= "/$prefix";
189 }
190
191 return [ $path, $extension ];
192 },
193 dependencies => [ depends_on('prefix'), depends_on('path') ],
194 );
195
196 service config_local_suffix => (
197 block => sub {
198 my $s = shift;
199 my $suffix = Catalyst::Utils::env_value( $s->param('name'), 'CONFIG_LOCAL_SUFFIX' ) || $self->config_local_suffix;
200
201 return $suffix;
202 },
203 dependencies => [ depends_on('name') ],
204 );
205
206 };
207}
208
209sub _fix_syntax {
210 my $config = shift;
211 my @components = (
212 map +{
213 prefix => $_ eq 'Component' ? '' : $_ . '::',
214 values => delete $config->{ lc $_ } || delete $config->{ $_ }
215 },
216 grep { ref $config->{ lc $_ } || ref $config->{ $_ } }
217 qw( Component Model M View V Controller C Plugin )
218 );
219
220 foreach my $comp ( @components ) {
221 my $prefix = $comp->{ prefix };
222 foreach my $element ( keys %{ $comp->{ values } } ) {
223 $config->{ "$prefix$element" } = $comp->{ values }->{ $element };
224 }
225 }
226}
227
228sub _config_substitutions {
f228c263 229 my ($self, $name, $subs) = @_;
b4a6fa62 230
231 $subs->{ HOME } ||= sub { shift->path_to( '' ); };
232 $subs->{ ENV } ||=
233 sub {
234 my ( $c, $v ) = @_;
235 if (! defined($ENV{$v})) {
236 Catalyst::Exception->throw( message =>
237 "Missing environment variable: $v" );
238 return "";
239 } else {
240 return $ENV{ $v };
241 }
242 };
243 $subs->{ path_to } ||= sub { shift->path_to( @_ ); };
244 $subs->{ literal } ||= sub { return $_[ 1 ]; };
245 my $subsre = join( '|', keys %$subs );
246
247 for ( @_ ) {
248 my $arg = $_;
249 $arg =~ s{__($subsre)(?:\((.+?)\))?__}{ $subs->{ $1 }->( $name, $2 ? split( /,/, $2 ) : () ) }eg;
250 return $arg;
251 }
252}
253
2541;