Config-Processor
view release on metacpan or search on metacpan
lib/Config/Processor.pm view on Meta::CPAN
open( my $fh, '<', $file_path ) || die "Can't open $file_path: $!";
my @data = ( decode_json( join( '', <$fh> ) ) );
close($fh);
return @data;
}
sub _process_tree {
my $self = shift;
my $ancs = pop;
return if readonly( $_[0] );
$_[0] = $self->_process_node( $_[0], $ancs );
if ( my $node_addr = refaddr( $_[0] ) ) {
return if $self->{_seen_nodes}{$node_addr};
$self->{_seen_nodes}{$node_addr} = 1;
}
if ( ref( $_[0] ) eq 'HASH' ) {
foreach ( values %{ $_[0] } ) {
$self->_process_tree( $_, [ $_[0], @{$ancs} ] );
}
}
elsif ( ref( $_[0] ) eq 'ARRAY' ) {
foreach ( @{ $_[0] } ) {
$self->_process_tree( $_, [ $_[0], @{$ancs} ] );
}
}
return;
}
sub _process_node {
my $self = shift;
my $node = shift;
my $ancs = shift;
return unless defined $node;
if ( !ref($node) && $self->{interpolate_variables} ) {
$node =~ s/\$((\$?)\{([^\}]*)\})/
$2 ? $1 : ( $self->_resolve_var( $3, [ @{$ancs} ] ) || '' )/ge;
}
elsif ( ref($node) eq 'HASH' && $self->{process_directives} ) {
if ( defined $node->{var} ) {
$node = $self->_resolve_var( $node->{var}, [ @{$ancs} ] );
}
elsif ( defined $node->{include} ) {
$node = $self->_build_tree( $node->{include} );
}
else {
if ( defined $node->{underlay} ) {
my $layer = delete $node->{underlay};
$layer = $self->_process_layer( $layer, $ancs );
$node = $self->{_merger}->merge( $layer, $node );
}
if ( defined $node->{overlay} ) {
my $layer = delete $node->{overlay};
$layer = $self->_process_layer( $layer, $ancs );
$node = $self->{_merger}->merge( $node, $layer );
}
}
}
return $node;
}
sub _process_layer {
my $self = shift;
my $layer = shift;
my $ancs = shift;
if ( ref($layer) eq 'HASH' ) {
$layer = $self->_process_node( $layer, $ancs );
}
elsif ( ref($layer) eq 'ARRAY' ) {
my $new_layer = {};
foreach my $node ( @{$layer} ) {
$node = $self->_process_node( $node, $ancs );
$new_layer = $self->{_merger}->merge( $new_layer, $node );
}
$layer = $new_layer;
}
return $layer;
}
sub _resolve_var {
my $self = shift;
my $name = shift;
my $ancs = shift;
my $value;
if ( $name =~ m/^\./ ) {
my $node;
my @tokens = split( /\./, $name, -1 );
while (1) {
my $token = $tokens[0];
$token =~ s/^\s+//;
$token =~ s/\s+$//;
last if length($token) > 0;
shift @tokens;
last unless @tokens;
next unless @{$ancs};
$node = shift @{$ancs};
}
$value = eval {
$self->_fetch_value( $node, $ancs, \@tokens );
};
lib/Config/Processor.pm view on Meta::CPAN
metrics: { include: metrics/* }
=item underlay
Merges specified configuration parameters with parameters located at the same
context. Configuration parameters from the context overrides parameters from
the directive. C<underlay> directive most usefull in combination with C<var>
and C<include> directives.
For example, you can use this directive to set default values of parameters.
myapp:
db:
connectors:
default:
port: "1234"
dbname: "stat"
options:
PrintWarn: 0
PrintError: 0
RaiseError: 1
stat_master:
underlay: { var: .default }
host: "stat-master.mydb.com"
username: "stat_writer"
password: "stat_writer_pass"
stat_slave:
underlay: { var: .default }
host: "stat-slave.mydb.com"
username: "stat_reader"
password: "stat_reader_pass"
You can move default parameters in separate files.
myapp:
db:
connectors:
underlay:
- { include: db_connectors/default.yml }
- { include: db_connectors/default_test.yml }
stat_master:
underlay: { var: .default }
host: "stat-master.mydb.com"
username: "stat_writer"
password: "stat_writer_pass"
stat_slave:
underlay: { var: .default }
host: "stat-slave.mydb.com"
username: "stat_reader"
password: "stat_reader_pass"
test:
underlay: { var: .default_test }
username: "test"
password: "test_pass"
=item overlay
Merges specified configuration parameters with parameters located at the same
context. Configuration parameters from the directive overrides parameters from
the context. C<overlay> directive most usefull in combination with C<var> and
C<include> directives.
For example, you can use C<overlay> directive to temporaly overriding regular
configuration parameters.
myapp:
db:
connectors:
default:
port: "1234"
dbname: "stat"
options:
PrintWarn: 0
PrintError: 0
RaiseError: 1
test:
host: "localhost"
port: "4321"
stat_master:
underlay: { var: .default }
host: "stat-master.mydb.com"
username: "stat_writer"
password: "stat_writer_pass"
overlay: { var: .test }
stat_slave:
underlay: { var: .default }
host: "stat-slave.mydb.com"
username: "stat_reader"
password: "stat_reader_pass"
overlay: { var: .test }
To disable overriding just assign to C<test> connector empty hash.
test: {}
=back
=head1 AUTHOR
Eugene Ponizovsky, E<lt>ponizovsky@gmail.comE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (c) 2016-2018, Eugene Ponizovsky, E<lt>ponizovsky@gmail.comE<gt>.
All rights reserved.
This module is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut
( run in 1.425 second using v1.01-cache-2.11-cpan-df04353d9ac )