App-Chronicle

 view release on metacpan or  search on metacpan

lib/Chronicle/Config/Reader.pm  view on Meta::CPAN


=item Command-execution and expansion

If backticks are found in configuration values they will be replaced with the output of the specified command.

=back

The following snippet demonstrates these features:

=for example begin

    # The path variable will be set to /bin:/sbin:...
    path = $PATH

    # Our hostname will be set
    hostname = `hostname`

=for example end

=cut


=head1 METHODS

Now follows documentation on the available methods.

=cut

package Chronicle::Config::Reader;

use strict;
use warnings;



our $VERSION = "5.1.7";


=head2 new

This is the constructor, no arguments are required or expected.

=cut

sub new
{
    my ($proto) = (@_);
    my $class = ref($proto) || $proto;
    my $self = {};
    bless( $self, $class );
    return $self;
}



=head2 parseFile

Parse a configuration file, and insert any values into the provided
hash-reference.

The two parameters required are a hash-reference, which will be updated
with the configuration-values, and the name of the configuration file
to parse.

If the file specified does not exist no action is taken.

Sample usage:

=for example begin

      $cfg->parse( \%config, "/etc/foo/config" );

=for example end

=cut

sub parseFile
{
    my ( $self, $ref, $file ) = (@_);

    #
    #  If it doesn't exist ignore it.
    #
    return if ( !-e $file );

    open my $handle, "<:encoding(utf-8)", $file or
      die "Cannot read file '$file' - $!";

    #
    #  Process each line.
    #
    while ( defined( my $line = <$handle> ) )
    {
        chomp $line;
        if ( $line =~ s/\\$// )
        {
            $line .= <FILE>;
            redo unless eof(FILE);
        }

        $self->parseLine( $ref, $line );
    }

    close($handle);
}



=head2 parseLine

Parse a single line.

This method is called internally, but it is exposed in case it might
be useful to other callers.

The two parameters required are a hash-reference, which will be updated
with the configuration-values, and a line of configuration-file content
which should be parsed.

If the line is missing, or consistes entirely of a comment, this is
not a problem. (e.g. C<"# this is a comment"> will result in no update
to the hash-reference, but also raise no error.)

Sample usage:

=for example begin

     $cfg->parseLine( \%config, 'user = $USER' );

=for example end

=cut

sub parseLine
{
    my ( $self, $ref, $line ) = (@_);

    # Skip lines beginning with comments
    return if ( $line =~ /^([ \t]*)\#/ );

    # Skip blank lines
    return if ( length($line) < 1 );

    # Strip trailing comments.
    if ( $line =~ /(.*)\#(.*)/ )
    {
        $line = $1;
    }

    # Find variable settings
    if ( $line =~ /([^=]+)=([^\n]*)/ )
    {
        my $key = $1;
        my $val = $2;

        # Strip leading and trailing whitespace.
        $key =~ s/^\s+//;
        $key =~ s/\s+$//;
        $val =~ s/^\s+// if ($val);
        $val =~ s/\s+$// if ($val);

        # environment expansion?
        $val =~ s/\$(\w+)/$ENV{$1}/g if ( $val && ( $val =~ /\$/ ) );

        # command expansion?
        if ( $val && ( $val =~ /(.*)`([^`]+)`(.*)/ ) )
        {

            # store
            my $pre  = $1;
            my $cmd  = $2;
            my $post = $3;

            # get output
            my $output = `$cmd`;
            chomp($output);



( run in 0.503 second using v1.01-cache-2.11-cpan-39bf76dae61 )