Developer-Dashboard
view release on metacpan or search on metacpan
lib/Developer/Dashboard/EnvLoader.pm view on Meta::CPAN
package Developer::Dashboard::EnvLoader;
use strict;
use warnings;
our $VERSION = '4.16';
use Cwd qw(abs_path cwd);
use File::Basename qw(dirname);
use File::Spec;
use Developer::Dashboard::EnvAudit;
# load_runtime_layers(%args)
# Loads every participating plain-directory and DD-OOP-LAYER runtime env file
# from the configured root toward the current working directory.
# Input: hash with paths => Developer::Dashboard::PathRegistry object.
# Output: ordered array reference of loaded env file paths.
sub load_runtime_layers {
my ( $class, %args ) = @_;
my $paths = $args{paths} or die "Missing paths\n";
return $class->load_files(
files => [
$class->_plain_directory_env_files($paths),
$class->_runtime_layer_env_files($paths),
],
);
}
# load_skill_layers(%args)
# Loads every participating skill-root env file from home skill layer to the
# deepest effective skill layer.
# Input: hash with skill_layers => array reference of skill root paths.
# Output: ordered array reference of loaded env file paths.
sub load_skill_layers {
my ( $class, %args ) = @_;
return $class->_load_skill_layer_specs(
specs => $class->_skill_layer_specs( @{ $args{skill_layers} || [] } ),
);
}
# load_skill_layers_into_hash(%args)
# Loads the ordered nested skill env chain into an isolated temporary
# environment and returns only the added or changed keys.
# Input: hash with skill_layers => array reference of skill root paths and
# optional base_env => hash reference of starting environment values.
# Output: hash reference with loaded file list and env overlay hash.
sub load_skill_layers_into_hash {
my ( $class, %args ) = @_;
my $base_env = ref( $args{base_env} ) eq 'HASH' ? { %{ $args{base_env} } } : { %ENV };
my %before = %{$base_env};
local %ENV = %{$base_env};
local $ENV{DEVELOPER_DASHBOARD_ENV_AUDIT};
local %Developer::Dashboard::EnvAudit::AUDIT;
my $loaded = $class->_load_skill_layer_specs(
specs => $class->_skill_layer_specs( @{ $args{skill_layers} || [] } ),
);
my %overlay;
for my $key ( sort keys %ENV ) {
next
if exists $before{$key}
&& (
( !defined $before{$key} && !defined $ENV{$key} )
|| ( defined $before{$key} && defined $ENV{$key} && $before{$key} eq $ENV{$key} )
);
$overlay{$key} = $ENV{$key};
}
return {
files => $loaded,
env => \%overlay,
};
}
# load_files(%args)
# Loads a specific ordered list of .env and .env.pl files, updating both %ENV
# and the shared EnvAudit inventory.
# Input: hash with files => array reference of candidate file paths.
# Output: ordered array reference of the env files that were actually loaded.
sub load_files {
my ( $class, %args ) = @_;
my @files = @{ $args{files} || [] };
my @loaded;
my %seen;
for my $file (@files) {
next if !defined $file || $file eq '';
my $identity = $class->_path_identity($file);
next if $seen{$identity}++;
next if !-f $file;
if ( $file =~ /\.env\.pl\z/ ) {
$class->_load_env_pl_file($file);
push @loaded, $file;
next;
}
$class->_load_env_file($file);
push @loaded, $file;
}
return \@loaded;
}
# load_files_into_hash(%args)
# Loads a specific ordered list of env files into an isolated temporary
# environment and returns only the added or changed keys.
# Input: hash with files => array reference of candidate file paths and
# optional base_env => hash reference of starting environment values.
# Output: hash reference with loaded file list and env overlay hash.
sub load_files_into_hash {
my ( $class, %args ) = @_;
my $base_env = ref( $args{base_env} ) eq 'HASH' ? { %{ $args{base_env} } } : { %ENV };
my %before = %{$base_env};
local %ENV = %{$base_env};
local $ENV{DEVELOPER_DASHBOARD_ENV_AUDIT};
local %Developer::Dashboard::EnvAudit::AUDIT;
my $loaded = $class->load_files( files => $args{files} );
my %overlay;
for my $key ( sort keys %ENV ) {
next
if exists $before{$key}
&& (
( !defined $before{$key} && !defined $ENV{$key} )
|| ( defined $before{$key} && defined $ENV{$key} && $before{$key} eq $ENV{$key} )
);
$overlay{$key} = $ENV{$key};
}
return {
files => $loaded,
env => \%overlay,
};
}
# _plain_directory_env_files($paths)
# Builds the env file list contributed by ancestor directories from the active
# root toward the current working directory.
# Input: path registry object.
# Output: ordered list of plain directory env file paths.
sub _plain_directory_env_files {
my ( $class, $paths ) = @_;
my @files;
for my $dir ( $class->_plain_directory_layers($paths) ) {
push @files, $class->_env_file_candidates($dir);
}
return @files;
}
# _runtime_layer_env_files($paths)
# Builds the env file list contributed by participating DD-OOP-LAYER runtime
# roots from home runtime to deepest child runtime.
# Input: path registry object.
# Output: ordered list of runtime env file paths.
sub _runtime_layer_env_files {
my ( $class, $paths ) = @_;
my @files;
for my $runtime_root ( $paths->runtime_layers ) {
push @files, $class->_env_file_candidates($runtime_root);
}
return @files;
}
# _plain_directory_layers($paths)
# Resolves the ancestor directory chain whose plain .env files participate in
# env loading for the current working directory.
# Input: path registry object.
# Output: ordered list of directory paths from root to cwd.
sub _plain_directory_layers {
my ( $class, $paths ) = @_;
my $cwd = $paths->current_working_directory;
return () if !defined $cwd || $cwd eq '';
my $home = $paths->home;
my $project_root = eval { $paths->current_project_root } || '';
my $stop_dir = '';
if ( $class->_same_or_descendant_path( $cwd, $home ) ) {
$stop_dir = $home;
}
elsif ( $project_root ne '' && $class->_same_or_descendant_path( $cwd, $project_root ) ) {
$stop_dir = $project_root;
}
else {
return ();
}
my @layers;
my $dir = $cwd;
while ($dir) {
push @layers, $dir;
last if $class->_path_identity($dir) eq $class->_path_identity($stop_dir);
my $parent = dirname($dir);
last if !defined $parent || $parent eq '' || $parent eq $dir;
( run in 0.907 second using v1.01-cache-2.11-cpan-df04353d9ac )