Config-Abstraction

 view release on metacpan or  search on metacpan

lib/Config/Abstraction.pm  view on Meta::CPAN

sub _flatten_keys
{
	my ($hash, $prefix, $seen) = @_;
	my %flat;
	_flatten_into(\%flat, $hash, $prefix // '', $seen // {});
	return %flat;
}

sub _load_config
{
	if(!UNIVERSAL::isa((caller)[0], __PACKAGE__)) {
		Carp::croak('Illegal Operation: This method can only be called by a subclass');
	}

	my $self = shift;

	# Disable Hash::Merge cloning for the duration of this method.
	# Storable::dclone (used when clone=1) cannot handle coderefs or blessed
	# objects that may appear in the 'data' argument; sharing references is
	# safe here because %merged is a fresh, method-local accumulator.
	my $saved_clone = Hash::Merge::get_clone_behavior();

lib/Config/Abstraction.pm  view on Meta::CPAN

# ---------------------------------------------------------------------------
# _load_remote_dir -- fetch and merge standard config files from one remote
# host/directory pair.
#
# Silently skips files that do not exist; warns (or logs) on parse errors.
# Merges into %$merged_ref using the same Hash::Merge LEFT_PRECEDENT strategy
# as the local pipeline, so remote values override earlier local values.
# ---------------------------------------------------------------------------
sub _load_remote_dir
{
	if(!UNIVERSAL::isa((caller)[0], __PACKAGE__)) {
		Carp::croak('Illegal Operation: This method can only be called by a subclass');
	}

	my ($self, $host, $remote_dir, $merged_ref, $file_list) = @_;
	my $logger = $self->{'logger'};

	unless($self->_load_driver('File::Slurp::Remote')) {
		my $msg = ref($self) . ": File::Slurp::Remote required for /../$host$remote_dir but is not installed";
		$logger ? $logger->warn($msg) : Carp::carp($msg);
		return;

lib/Config/Abstraction.pm  view on Meta::CPAN

# _parse_config_string -- parse a raw config string by extension.
#
# Mirrors the format-detection logic used for local files.  INI content is
# written to a File::Temp scratch file because Config::IniFiles requires a
# real filesystem path; the temp file is removed as soon as parsing returns.
#
# Returns a hashref on success, undef on failure.
# ---------------------------------------------------------------------------
sub _parse_config_string
{
	if(!UNIVERSAL::isa((caller)[0], __PACKAGE__)) {
		Carp::croak('Illegal Operation: This method can only be called by a subclass');
	}

	my ($self, $raw, $filename, $label) = @_;
	my $logger = $self->{'logger'};
	my $data;

	eval {
		if($filename =~ /\.ya?ml$/i) {
			$self->_load_driver('YAML::XS', ['Load']);

t/extended_tests.t  view on Meta::CPAN

	ok(scalar(@warns) > 0, 'logger->warn called for parse error in _parse_config_string')
		or diag('log: ' . join('; ', map { "$_->[0]: $_->[1]" } @{$log_ref}));
};

# ===========================================================================
# Access guard -- Illegal Operation croak (line 444-445)
# ===========================================================================

# Calling _load_config() (or _parse_config_string, _load_remote_dir) directly
# from a non-subclass caller should croak with 'Illegal Operation'.
# The UNIVERSAL::isa guard at line 444 checks (caller)[0] against __PACKAGE__.
subtest '_load_config() - illegal direct call from outside class croaks' => sub {
	my $cfg = Config::Abstraction->new(
		data        => { dummy => 1 },
		config_dirs => [],
	);
	# Direct call from package main (not a subclass) must croak
	my $died = 0;
	eval { $cfg->_load_config() };
	if($@) {
		$died = 1;



( run in 1.731 second using v1.01-cache-2.11-cpan-6de40a662fe )