Badger
view release on metacpan or search on metacpan
lib/Badger/Config/Filesystem.pm view on Meta::CPAN
@_
);
}
sub item {
my ($self, $name) = @_;
$self->debug_data("looking for $name in items: ", $self->{ item }) if DEBUG;
return $self->{ item }->{ $name }
||= $self->lookup_item($name);
}
sub lookup_item {
# hook for subclasses
return undef;
}
sub item_schema {
my ($self, $name, $schema) = @_;
my $data = $self->item($name);
if (DEBUG) {
$self->debug_data("$name item schema data: ", $data);
$self->debug_data("$name file schema: ", $schema);
}
if ($schema) {
$data = extend({ }, $data, $schema);
}
# the schema we got may have been for a parent via lookup_item.
$self->{ item }->{ $name } = $data;
$self->debug_data("set new item $name data", $data) if DEBUG;
return $data;
}
sub item_schema_from_data {
my ($self, $name, $data) = @_;
my $more;
if ($data && ref $data eq HASH) {
# In the event that someone needs to store a 'schema' item in the *real*
# configuration data, we look for '_schema_' first and delete that,
# leaving 'schema' untouched
$more = delete $data->{_schema_}
|| delete $data->{ schema };
}
return$self->item_schema($name, $more);
}
sub has_item {
my $self = shift->prototype;
my $name = shift;
my $item = $self->{ item }->{ $name };
# This is all the same as in the base class up to the final test which
# looks for $self->config_file($name) as a last-ditch attempt
if (defined $item) {
# A 1/0 entry in the item tells us if an item categorically does or
# doesn't exist in the config data set (or allowable set - it might
# be a valid configuration option that simply hasn't been set yet)
return $item;
}
else {
# Otherwise the existence (or not) of an item in the data set is
# enough to satisfy us one way or another
return 1
if exists $self->{ data }->{ $name };
# Special case for B::C::Filesystem which looks to see if there's a
# matching config file. We cache the existence in $self->{ item }
# so we know if it's there (or not) for next time
return $self->{ item }->{ $name }
= $self->config_file($name);
}
}
1;
__END__
=head1 NAME
Badger::Config::Filesystem - reads configuration files in a directory
=head1 SYNOPSIS
use Badger::Config::Filesystem;
my $config = Badger::Config::Filesystem->new(
root => 'path/to/some/dir'
);
# Fetch the data in user.[yaml|json] in above dir
my $user = $config->get('user')
|| die "user: not found";
# Fetch sub-data items using dotted syntax
print $config->get('user.name');
print $config->get('user.emails.0');
=head1 DESCRIPTION
This module is a subclass of L<Badger::Config> for reading data from
configuration files in a directory.
Consider a directory that contains the following files and sub-directories:
config/
site.yaml
style.yaml
pages.yaml
pages/
admin.yaml
developer.yaml
We can create a L<Badger::Config::Filesystem> object to read the configuration
data from the files in this directory like so:
my $config = Badger::Config::Filesystem->new(
root => 'config'
);
Reading the data from C<site.yaml> is as simple as this:
my $site = $config->get('site');
Note that the file extension is B<not> required. You can have either a
C<site.yaml> or a C<site.json> file in the directory and the module will
lib/Badger/Config/Filesystem.pm view on Meta::CPAN
=head3 join
Joins data paths together using the C<tree_joint> string which is C<_> by
default.
=head3 uri
Joins data paths together using slash characters to create URI paths.
An item in a sub-directory can have a leading slash (i.e. an absolute path)
and it will be promoted to the top-level data hash.
e.g.
foo/bar + baz = foo/bar/baz
foo/bar + /bam = /bam
=head3 none
No tree is created. No sub-directories are scanned. You never saw me.
I wasn't here.
=head2 tree_joint
This option can be used to set the default character sequence for joining
paths
=head2 uri_paths
This option can be used to set the default C<uri_paths> option for joining
paths as URIs. It should be set to C<relative> or C<absolute>. It can
be over-ridden in a C<schema> section of a top-level configuration file.
=head1 METHODS
The module inherits all methods defined in the L<Badger::Config> and
L<Badger::Workplace> base classes.
=head1 INTERNAL METHODS
The following methods are defined for internal use.
=head2 init($config)
This overrides the default initialisation method inherited from
L<Badger::Config>. It calls the L<init_config()|Badger::Config/init_config()>
method to perform the base class L<Badger::Config> initialisation and then
the L<init_filesystem()> method to perform initialisation specific to the
L<Badger::Config::Filesystem> module.
=head2 init_filesystem($config)
This performs the initialisation of the object specific to the filesystem
object.
=head2 head($item)
This redefines the L<head()|Badger::Config/head()> method in the
L<Badger::Config> base class. The method is called by
L<get()|Badger::Config/get()> to fetch a top-level data item
(e.g. C<user> in C<$config-E<gt>get('user.name')>). This implementation
looks for existing data items as usual, but additionally falls back on a
call to L<fetch($item)> to load additional data (or attempt to load it).
=head2 tail($item, $data)
This is a do-nothing stub for subclasses to redefine. It is called after
a successful call to L<fetch()>.
=head2 fetch($item)
This is the main method called to load a configuration file (or tree of
files) from the filesystem. It looks to see if a configuration file
(with one of the known L<extensions> appended, e.g. C<"$item.yaml">,
C<"$item.json">, etc) exists and/or a directory named C<$item>.
If the file exists but the directory doesn't then the configuration data
is read from the file. If the directory exists
=head2 config_tree($item, $file, $dir)
This scans a configuration tree comprising of a configuration file and/or
a directory. The C<$file> and C<$dir> arguments are optional and are only
supported as an internal optimisation. The method can safely be called with
a single C<$item> argument and the relevant file and directory will be
determined automatically.
The configuration file is loaded (via L<scan_config_file()>). If the
directory exists then it is also scanned (via L<scan_config_dir()>) and the
files contained therein are loaded.
=head2 scan_config_file($file, $data, $path, $schema, $binder)
Loads the data in a configuration C<$file> and merges it into the common
C<$data> hash under the C<$path> prefix (a reference to an array). The
C<$schema> contains any schema rules for this data item. The C<$binder>
is a reference to a L<tree_binder()> method to handle the data merge.
=head2 scan_config_dir($dir, $data, $path, $schema, $binder)
Scans the diles in a configuration directory, C<$dir> and recursively calls
L<scan_config_dir()> for each sub-directory found, and L<scan_config_file()>
for each file.
=head2 tree_binder($name)
This method returns a reference to one of the binder methods below based
on the C<$name> parameter provided.
# returns a reference to the nest_binder() method
my $binder = $config->tree_binder('nest');
If no C<$name> is specified then it uses the default C<tree_type> of C<nest>.
This can be changed via the L<tree_type> configuration option.
=head2 nest_tree_binder($parent, $path, $child, $schema)
This handles the merging of data for the L<nest> L<tree_type>.
=head2 flat_tree_binder($parent, $path, $child, $schema)
This handles the merging of data for the L<flat> L<tree_type>.
=head2 uri_tree_binder($parent, $path, $child, $schema)
This handles the merging of data for the L<uri> L<tree_type>.
=head2 join_tree_binder($parent, $path, $child, $schema)
This handles the merging of data for the L<join> L<tree_type>.
=head2 config_file($name)
( run in 1.802 second using v1.01-cache-2.11-cpan-364913b4093 )