Skip Menu |

This queue is for tickets about the Catalyst-Plugin-ConfigLoader-Environment CPAN distribution.

Report information
The Basics
Id: 33539
Status: resolved
Worked: 15 min
Priority: 0/
Queue: Catalyst-Plugin-ConfigLoader-Environment

People
Owner: jrockway [...] cpan.org
Requestors: ryan [...] innerfence.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: [PATCH] Extended JSON support, merge_hashes support
Date: Sat, 23 Feb 2008 16:53:50 -0800
To: bug-catalyst-plugin-configloader-environment [...] rt.cpan.org
From: Ryan D Johnson <ryan [...] innerfence.com>
* Allow any parameter to be a JSON structure (formerly only MVC__Foo_bar) could be JSON. * Allow top-level MVC__Foo params * Use $c->config() instead of $c->config->{} to change the config, that way we get merge_hashes for free --- Changes | 5 ++ lib/Catalyst/Plugin/ConfigLoader/Environment.pm | 52 ++++++++++++++++------- t/01-live.t | 18 +++++++- t/lib/TestApp/Controller/Root.pm | 8 +++- t/lib/TestApp/Model/TestModel.pm | 7 +++ 5 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 t/lib/TestApp/Model/TestModel.pm diff --git a/Changes b/Changes index ea10f15..21ea463 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,10 @@ Revision history for Catalyst-Plugin-ConfigLoader-Environment +0.05 Unreleased + - Allow top-level ::-params (Model__Foo, not just Model__Foo_bar) + - Allow JSON for all values (not just Model__Foo_bar) + - Use $c->config() instead of tweaking config directly (get merge_hashes for free) + 0.04 14 January 2008 - YAML is causing weird errors; killing it in favor of making JSON::Any mandatory diff --git a/lib/Catalyst/Plugin/ConfigLoader/Environment.pm b/lib/Catalyst/Plugin/ConfigLoader/Environment.pm index e380052..e82f61a 100644 --- a/lib/Catalyst/Plugin/ConfigLoader/Environment.pm +++ b/lib/Catalyst/Plugin/ConfigLoader/Environment.pm @@ -2,7 +2,6 @@ package Catalyst::Plugin::ConfigLoader::Environment; use warnings; use strict; -use Catalyst::Utils; use JSON::Any; =head1 NAME @@ -16,7 +15,7 @@ Version 0.04 =cut -our $VERSION = '0.04'; +our $VERSION = '0.04_01'; =head1 SYNOPSIS @@ -102,7 +101,15 @@ Double colons are converted into double underscores. For compatibility's sake, support for the 0.01-style use of bourne-incompatible variable names is retained. -The last one should only be passed JSON. +Values are JSON-decoded if they look like JSON arrays or objects +(i.e. if they're enclosed in []s or {}s). Taking advantage of that, we +can write the same example this way: + + MYAPP_name=MyApp + MYAPP_title=This is My App! + MYAPP_View__Foo={"EXTENSION":"tt","EVAL_PERL":1} + MYAPP_Model__Bar={"root":"/etc"} + MYAPP_Model__DBIC={"connect_info":["dbi:Pg:dbname=foo", "username", "password"]} =head1 FUNCTIONS @@ -119,18 +126,27 @@ sub setup { grep { /^${prefix}[_](.+)$/ && ($env{$1}=$ENV{$_})} keys %ENV; foreach my $var (keys %env) { - if($var =~ /(Model|View|Controller)(?:::|__)([^_]+)_(.+)$/){ - my $comp = "${1}::$2"; - my $item = $3; - my $val = $env{"$var"}; - if ($val =~ m{^[\[\{]}) { - $val = JSON::Any->jsonToObj($val); - } - $c->config->{$comp}{$item} = $val; - } - else { - $c->config->{$var} = $env{$var}; - } + my $val = $env{$var}; + + # Decode JSON array/object + if ( $val =~ m{^\[.*\]$|^\{.*\}$} ) { + $val = JSON::Any->jsonToObj($val); + } + + # Special syntax Model__Foo is equivalent to Model::Foo + if($var =~ /(Model|View|Controller)(?:::|__)([^_]+)(?:_(.+))?$/) { + $var = "${1}::$2"; + + # Special syntax Model__Foo_bar (or Model::Foo_bar) will + # tweak just the 'bar' subparam for Model::Foo's + # config. We can accomplish this using a hash that + # specifies just 'bar' ($c->config will merge hashes). + if ( defined $3 ) { + $val = { $3 => $val }; + } + } + + $c->config( $var => $val ); } return $c->NEXT::setup(@_); @@ -141,6 +157,12 @@ sub setup { Jonathan Rockway, C<< <jrockway at cpan.org> >> +=head1 CONTRIBUTORS + +mugwump + +Ryan D Johnson, C<< <ryan at innerfence.com> >> + =head1 BUGS Please report any bugs or feature requests to diff --git a/t/01-live.t b/t/01-live.t index 7c8a3e8..7214660 100644 --- a/t/01-live.t +++ b/t/01-live.t @@ -2,16 +2,18 @@ # 01-live.t # Copyright (c) 2006 Jonathan Rockway <jrockway@cpan.org> -use Test::More tests => 9; +use Test::More tests => 12; use FindBin qw($Bin); use lib "$Bin/lib"; BEGIN { $ENV{TESTAPP_foo} = 'foo'; $ENV{TESTAPP_bar} = 'bar'; $ENV{TESTAPP_foo_bar_baz} = 'quux'; + $ENV{TESTAPP_quux} = q%[1,2,3,4]%; $ENV{TESTAPP_View::TestView_foo} = "Test View's foo!"; $ENV{TESTAPP_View::TestView_quux} = q%[1,2,3,"Test View's quux!",{"foo":"bar"}]%; $ENV{TESTAPP_View__TestView_bar} = "Test View's bar!"; + $ENV{TESTAPP_Model__TestModel} = q%{"bar":"baz"}%; } @@ -26,6 +28,7 @@ ok(ref $config, 'got config'); is($config->{foo}, 'foo', 'got foo'); is($config->{bar}, 'bar', 'got bar'); is($config->{foo_bar_baz}, 'quux', 'got foo_bar_baz'); +is_deeply($config->{quux}, [1,2,3,4], 'JSON for simple param'); my $view = get('/foo/foo'); is($view, "Test View's foo!", 'got View::TestView->foo'); @@ -35,7 +38,16 @@ is($view, "Test View's bar!", 'got View::TestView->bar'); $view = get('/foo/quux'); eval $view; -warn $view; no warnings 'once'; is_deeply($quux, [1,2,3,"Test View's quux!",{ foo => 'bar'}], - 'got View::TestView->quux'); + 'JSON for :: sub-param'); + +$r = request('/model'); +ok($r->is_success, 'got /model'); +my $model_attributes = eval $r->content; +is_deeply($model_attributes, + { + foo => 'bar', # From __PACKAGE__ default config + bar => 'baz', # Merged from my environment hash + }, + 'JSON for top-level :: param with hash merge'); diff --git a/t/lib/TestApp/Controller/Root.pm b/t/lib/TestApp/Controller/Root.pm index cefbd82..d42c9a8 100644 --- a/t/lib/TestApp/Controller/Root.pm +++ b/t/lib/TestApp/Controller/Root.pm @@ -13,7 +13,7 @@ sub default : Private { $c->res->body(Dumper($c->config)); } -sub foo : Local { +sub foo : Local { my ($self, $c, $varname) = @_; my $result = $c->view('TestView')->$varname; if (ref $result) { @@ -25,5 +25,11 @@ sub foo : Local { } $c->res->body($result); } + +sub model : Local { + my ( $self, $c, $varname ) = @_; + $c->res->body(Dumper(\%{$c->model('TestModel')})); +} + 1; diff --git a/t/lib/TestApp/Model/TestModel.pm b/t/lib/TestApp/Model/TestModel.pm new file mode 100644 index 0000000..a465340 --- /dev/null +++ b/t/lib/TestApp/Model/TestModel.pm @@ -0,0 +1,7 @@ +package TestApp::Model::TestModel; +use base 'Catalyst::Model'; + +__PACKAGE__->config( foo => 'bar', + bar => 'quux' ); + +1; -- 1.5.2.5
Subject: Re: [rt.cpan.org #33539] [PATCH] Extended JSON support, merge_hashes support
Date: Tue, 26 Feb 2008 11:06:06 -0800
To: bug-Catalyst-Plugin-ConfigLoader-Environment [...] rt.cpan.org
From: Ryan D Johnson <ryan [...] innerfence.com>
Looks like RT butchered the git format-email. Here it is as an attachment.
From 41cb5105d5034c7753076d8c6f854fde3d97c4ab Mon Sep 17 00:00:00 2001 From: Ryan D Johnson <ryan@innerfence.com> Date: Fri, 22 Feb 2008 17:52:44 -0800 Subject: [PATCH] Extended JSON support, merge_hashes support * Allow any parameter to be a JSON structure (formerly only MVC__Foo_bar) could be JSON. * Allow top-level MVC__Foo params * Use $c->config() instead of $c->config->{} to change the config, that way we get merge_hashes for free --- Changes | 5 ++ lib/Catalyst/Plugin/ConfigLoader/Environment.pm | 52 ++++++++++++++++------- t/01-live.t | 18 +++++++- t/lib/TestApp/Controller/Root.pm | 8 +++- t/lib/TestApp/Model/TestModel.pm | 7 +++ 5 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 t/lib/TestApp/Model/TestModel.pm diff --git a/Changes b/Changes index ea10f15..21ea463 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,10 @@ Revision history for Catalyst-Plugin-ConfigLoader-Environment +0.05 Unreleased + - Allow top-level ::-params (Model__Foo, not just Model__Foo_bar) + - Allow JSON for all values (not just Model__Foo_bar) + - Use $c->config() instead of tweaking config directly (get merge_hashes for free) + 0.04 14 January 2008 - YAML is causing weird errors; killing it in favor of making JSON::Any mandatory diff --git a/lib/Catalyst/Plugin/ConfigLoader/Environment.pm b/lib/Catalyst/Plugin/ConfigLoader/Environment.pm index e380052..e82f61a 100644 --- a/lib/Catalyst/Plugin/ConfigLoader/Environment.pm +++ b/lib/Catalyst/Plugin/ConfigLoader/Environment.pm @@ -2,7 +2,6 @@ package Catalyst::Plugin::ConfigLoader::Environment; use warnings; use strict; -use Catalyst::Utils; use JSON::Any; =head1 NAME @@ -16,7 +15,7 @@ Version 0.04 =cut -our $VERSION = '0.04'; +our $VERSION = '0.04_01'; =head1 SYNOPSIS @@ -102,7 +101,15 @@ Double colons are converted into double underscores. For compatibility's sake, support for the 0.01-style use of bourne-incompatible variable names is retained. -The last one should only be passed JSON. +Values are JSON-decoded if they look like JSON arrays or objects +(i.e. if they're enclosed in []s or {}s). Taking advantage of that, we +can write the same example this way: + + MYAPP_name=MyApp + MYAPP_title=This is My App! + MYAPP_View__Foo={"EXTENSION":"tt","EVAL_PERL":1} + MYAPP_Model__Bar={"root":"/etc"} + MYAPP_Model__DBIC={"connect_info":["dbi:Pg:dbname=foo", "username", "password"]} =head1 FUNCTIONS @@ -119,18 +126,27 @@ sub setup { grep { /^${prefix}[_](.+)$/ && ($env{$1}=$ENV{$_})} keys %ENV; foreach my $var (keys %env) { - if($var =~ /(Model|View|Controller)(?:::|__)([^_]+)_(.+)$/){ - my $comp = "${1}::$2"; - my $item = $3; - my $val = $env{"$var"}; - if ($val =~ m{^[\[\{]}) { - $val = JSON::Any->jsonToObj($val); - } - $c->config->{$comp}{$item} = $val; - } - else { - $c->config->{$var} = $env{$var}; - } + my $val = $env{$var}; + + # Decode JSON array/object + if ( $val =~ m{^\[.*\]$|^\{.*\}$} ) { + $val = JSON::Any->jsonToObj($val); + } + + # Special syntax Model__Foo is equivalent to Model::Foo + if($var =~ /(Model|View|Controller)(?:::|__)([^_]+)(?:_(.+))?$/) { + $var = "${1}::$2"; + + # Special syntax Model__Foo_bar (or Model::Foo_bar) will + # tweak just the 'bar' subparam for Model::Foo's + # config. We can accomplish this using a hash that + # specifies just 'bar' ($c->config will merge hashes). + if ( defined $3 ) { + $val = { $3 => $val }; + } + } + + $c->config( $var => $val ); } return $c->NEXT::setup(@_); @@ -141,6 +157,12 @@ sub setup { Jonathan Rockway, C<< <jrockway at cpan.org> >> +=head1 CONTRIBUTORS + +mugwump + +Ryan D Johnson, C<< <ryan at innerfence.com> >> + =head1 BUGS Please report any bugs or feature requests to diff --git a/t/01-live.t b/t/01-live.t index 7c8a3e8..7214660 100644 --- a/t/01-live.t +++ b/t/01-live.t @@ -2,16 +2,18 @@ # 01-live.t # Copyright (c) 2006 Jonathan Rockway <jrockway@cpan.org> -use Test::More tests => 9; +use Test::More tests => 12; use FindBin qw($Bin); use lib "$Bin/lib"; BEGIN { $ENV{TESTAPP_foo} = 'foo'; $ENV{TESTAPP_bar} = 'bar'; $ENV{TESTAPP_foo_bar_baz} = 'quux'; + $ENV{TESTAPP_quux} = q%[1,2,3,4]%; $ENV{TESTAPP_View::TestView_foo} = "Test View's foo!"; $ENV{TESTAPP_View::TestView_quux} = q%[1,2,3,"Test View's quux!",{"foo":"bar"}]%; $ENV{TESTAPP_View__TestView_bar} = "Test View's bar!"; + $ENV{TESTAPP_Model__TestModel} = q%{"bar":"baz"}%; } @@ -26,6 +28,7 @@ ok(ref $config, 'got config'); is($config->{foo}, 'foo', 'got foo'); is($config->{bar}, 'bar', 'got bar'); is($config->{foo_bar_baz}, 'quux', 'got foo_bar_baz'); +is_deeply($config->{quux}, [1,2,3,4], 'JSON for simple param'); my $view = get('/foo/foo'); is($view, "Test View's foo!", 'got View::TestView->foo'); @@ -35,7 +38,16 @@ is($view, "Test View's bar!", 'got View::TestView->bar'); $view = get('/foo/quux'); eval $view; -warn $view; no warnings 'once'; is_deeply($quux, [1,2,3,"Test View's quux!",{ foo => 'bar'}], - 'got View::TestView->quux'); + 'JSON for :: sub-param'); + +$r = request('/model'); +ok($r->is_success, 'got /model'); +my $model_attributes = eval $r->content; +is_deeply($model_attributes, + { + foo => 'bar', # From __PACKAGE__ default config + bar => 'baz', # Merged from my environment hash + }, + 'JSON for top-level :: param with hash merge'); diff --git a/t/lib/TestApp/Controller/Root.pm b/t/lib/TestApp/Controller/Root.pm index cefbd82..d42c9a8 100644 --- a/t/lib/TestApp/Controller/Root.pm +++ b/t/lib/TestApp/Controller/Root.pm @@ -13,7 +13,7 @@ sub default : Private { $c->res->body(Dumper($c->config)); } -sub foo : Local { +sub foo : Local { my ($self, $c, $varname) = @_; my $result = $c->view('TestView')->$varname; if (ref $result) { @@ -25,5 +25,11 @@ sub foo : Local { } $c->res->body($result); } + +sub model : Local { + my ( $self, $c, $varname ) = @_; + $c->res->body(Dumper(\%{$c->model('TestModel')})); +} + 1; diff --git a/t/lib/TestApp/Model/TestModel.pm b/t/lib/TestApp/Model/TestModel.pm new file mode 100644 index 0000000..a465340 --- /dev/null +++ b/t/lib/TestApp/Model/TestModel.pm @@ -0,0 +1,7 @@ +package TestApp::Model::TestModel; +use base 'Catalyst::Model'; + +__PACKAGE__->config( foo => 'bar', + bar => 'quux' ); + +1; -- 1.5.2.5
Thanks. This is now on CPAN as 0.05. If there are any problems, let me know and I'll pull from your git repository. -- Jonathan Rockway <jrockway@cpan.org>