Just * do it: a catalyst::plugin::configloader-style layer over config::any
version 0.065
Config::JFDI is an implementation of Catalyst::Plugin::ConfigLoader that exists outside of Catalyst.
Essentially, Config::JFDI will scan a directory for files matching a certain name. If such a file is found which also matches an extension that Config::Any can read, then the configuration from that file will be loaded.
Config::JFDI will also look for special files that end with a \*(L"_local\*(R" suffix. Files with this special suffix will take precedence over any other existing configuration file, if any. The precedence takes place by merging the local configuration with the \*(L"standard\*(R" configuration via Hash::Merge::Simple.
Finally, you can override/modify the path search from outside your application, by setting the <\s-1NAME\s0>_CONFIG variable outside your application (where <\s-1NAME\s0> is the uppercase version of what you passed to Config::JFDI->new).
use Config::JFDI; my $config = Config::JFDI->new(name => "my_application", path => "path/to/my/application"); my $config_hash = $config->get;
This will look for something like (depending on what Config::Any will find):
path/to/my/application/my_application_local.{yml,yaml,cnf,conf,jsn,json,...} AND
path/to/my/application/my_application.{yml,yaml,cnf,conf,jsn,json,...}
... and load the found configuration information appropiately, with _local taking precedence.
You can also specify a file directly:
my $config = Config::JFDI->new(file => "/path/to/my/application/my_application.cnf");
To later reload your configuration, fresh from disk:
$config->reload;
We are currently kicking around ideas for a next-generation configuration loader. The goals are:
* A universal platform for configuration slurping and post-processing * Use Config::Any to do configuration loading * A sane API so that developers can roll their own loader according to the needs of their application * A friendly interface so that users can have it just DWIM * Host/application/instance specific configuration via _local and %ENV
Find more information and contribute at:
Roadmap: <http://sites.google.com/site/configloader/>
Mailing list: <http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/config-loader>
In previous versions, Config::JFDI would treat the file parameter as a path parameter, stripping off the extension (ignoring it) and globbing what remained against all the extensions that Config::Any could provide. That is, it would do this:
Config::JFDI->new( file => 'xyzzy.cnf' ); # Transform 'xyzzy.cnf' into 'xyzzy.pl', 'xyzzy.yaml', 'xyzzy_local.pl', ... (depending on what Config::Any could parse)
This is probably not what people intended. Config::JFDI will now squeak a warning if you pass 'file' through, but you can suppress the warning with 'no_06_warning' or 'quiet_deprecation'
Config::JFDI->new( file => 'xyzzy.cnf', no_06_warning => 1 ); Config::JFDI->new( file => 'xyzzy.cnf', quiet_deprecation => 1 ); # More general
If you *do* want the original behavior, simply pass in the file parameter as the path parameter instead:
Config::JFDI->new( path => 'xyzzy.cnf' ); # Will work as before
You can configure the $config object by passing the following to new:
name The name specifying the prefix of the configuration file to look for and the ENV variable to read. This can be a package name. In any case, :: will be substituted with _ in <name> and the result will be lowercased.
To prevent modification of <name>, pass it in as a scalar reference.
path The directory to search in
file Directly read the configuration from this file. Config::Any must recognize the extension. Setting this will override path
no_local Disable lookup of a local configuration. The 'local_suffix' option will be ignored. Off by default
local_suffix The suffix to match when looking for a local configuration. "local" By default ("config_local_suffix" will also work so as to be drop-in compatible with C::P::CL)
no_env Set this to 1 to disregard anything in the ENV. The 'env_lookup' option will be ignored. Off by default
env_lookup Additional ENV to check if $ENV{<NAME>...} is not found
driver A hash consisting of Config:: driver information. This is passed directly through to Config::Any
install_accessor Set this to 1 to install a Catalyst-style accessor as <name>::config You can also specify the package name directly by setting install_accessor to it (e.g. install_accessor => "My::Application")
substitute A hash consisting of subroutines called during the substitution phase of configuration preparation. ("substitutions" will also work so as to be drop-in compatible with C::P::CL) A substitution subroutine has the following signature: ($config, [ $argument1, $argument2, ... ])
path_to The path to dir to use for the _\|_path_to(...)_\|_ substitution. If nothing is given, then the 'home' config value will be used ($config->get->{home}). Failing that, the current directory will be used.
default A hash filled with default keys/values
Returns a new Config::JFDI object As an alternative way to load a config, ->open will pass given arguments to ->new( ... ), then attempt to do ->load
Unlike ->get or ->load, if no configuration files are found, ->open will return undef (or the empty list)
This is so you can do something like:
my $config_hash = Config::JFDI->open( "/path/to/application.cnf" ) or croak "Couldn't find config file!"
In scalar context, ->open will return the config hash, \s-1NOT\s0 the config object. If you want the config object, call ->open in list context:
my ($config_hash, $config) = Config::JFDI->open( ... )
You can pass any arguments to ->open that you would to ->new Load a config as specified by ->new( ... ) and \s-1ENV\s0 and return a hash
These will only load the configuration once, so it's safe to call them multiple times without incurring any loading-time penalty Returns a list of files found
If the list is empty, then no files were loaded/read Return a clone of the configuration hash using Clone
This will load the configuration first, if it hasn't already Reload the configuration, examining \s-1ENV\s0 and scanning the path anew
Returns a hash of the configuration For each given <value>, if <value> looks like a substitution specification, then run the substitution macro on <value> and store the result.
There are three default substitutions (the same as Catalyst::Plugin::ConfigLoader)
\*(C`_\|_HOME_\|_\*(C' - replaced with \*(C`$c->path_to('')\*(C'
\*(C`_\|_path_to(foo/bar)_\|_\*(C' - replaced with \*(C`$c->path_to('foo/bar')\*(C'
\*(C`_\|_literal(_\|_FOO_\|_)_\|_\*(C' - leaves _\|_FOO_\|_ alone (allows you to use \*(C`_\|_DATA_\|_\*(C' as a config value, for example)
The parameter list is split on comma (\*(C`,\*(C').
You can define your own substitutions by supplying the substitute option to ->new
Catalyst::Plugin::ConfigLoader
Config::Any
Catalyst
Config::Merge
Config::General
Robert Krimen <[email protected]>
This software is copyright (c) 2011 by Robert Krimen.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.