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 )