Aion-Env

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN


eval 'use Aion::Env NN_TEST => ()'; $@; # ^-> NN_TEST is'nt defined!
eval 'use Aion::Env NN_TEST => (nouname => 1)'; $@; # ^-> Unknown aspect: nouname
eval 'use Aion::Env NN_TEST => (nouname1 => 1, nouname2 => 2)'; $@; # ^-> Unknown aspects: nouname1, nouname2
```

# DESCRIPTION

Ð’ проектах используется конфигурационный файл `.env` для конфигурации проекта, в `Makefile`, для `docker` и `docker compose`. Данный модуль позволяет оформÐ...

Константы инициализируются из `%ENV`, если там нет значения или оно `undef`, то из файла `.env`, а если и там его не будет – из опции `default`.

При парсинге файла, ошибка синтаксиса приведёт к исключению.

Тип переменной окружения можно проверять с помощью опции `isa`. Она принимает подпрограмму или объект с перегруженным оператором `${}`. Ð’ этÐ...

Рекомендуется называть переменные окружения используя название модуля в котором она объявлена. Например, пакет `Aion::Type`, тогда имена перÐ...

# SUBROUTINES

## import ($cls, $name, %kw)

i18n/Aion/Env.ru-en.po  view on Meta::CPAN

msgid "Aion::Env - создаёт константу связанную со значением из .env"
msgstr "Aion::Env - creates a constant associated with the value from .env"

msgid "Файл .env:"
msgstr ".env file:"

msgid "В проектах используется конфигурационный файл `.env` для конфигурации проекта, в `Makefile`, для `docker` и `docker compose`. Данный модуль позволяет оф...
msgstr "Projects use the `.env` configuration file for project configuration, in `Makefile`, for `docker` and `docker compose`. This module allows you to design environment variables as constants of `perl` modules."

msgid "Константы инициализируются из `%ENV`, если там нет значения или оно `undef`, то из файла `.env`, а если и там его не будет – из опции `default`."
msgstr "Constants are initialized from `%ENV`, if there is no value there or it is `undef`, then from the `.env` file, and if it is not there, from the `default` option."

msgid "При парсинге файла, ошибка синтаксиса приведёт к исключению."
msgstr "When parsing a file, a syntax error will result in an exception."

msgid "Тип переменной окружения можно проверять с помощью опции `isa`. Она принимает подпрограмму или объект с перегруженным оператором `${}`. Ð...
msgstr "The type of an environment variable can be checked using the `isa` option. It accepts a subroutine or object with the `${}` operator overloaded. In this case, the value will be passed to `$_`. If the object has a `validate` method, like `Aion...

msgid "Рекомендуется называть переменные окружения используя название модуля в котором она объявлена. Например, пакет `Aion::Type`, тогда имена ...
msgstr "It is recommended to name environment variables using the name of the module in which it is declared. For example, the package is `Aion::Type`, then the names of the environment variables in it are `AION_TYPE_*`."

lib/Aion/Env.md  view on Meta::CPAN


eval 'use Aion::Env NN_TEST => ()'; $@; # ^-> NN_TEST is'nt defined!
eval 'use Aion::Env NN_TEST => (nouname => 1)'; $@; # ^-> Unknown aspect: nouname
eval 'use Aion::Env NN_TEST => (nouname1 => 1, nouname2 => 2)'; $@; # ^-> Unknown aspects: nouname1, nouname2
```

# DESCRIPTION

Ð’ проектах используется конфигурационный файл `.env` для конфигурации проекта, в `Makefile`, для `docker` и `docker compose`. Данный модуль позволяет оформÐ...

Константы инициализируются из `%ENV`, если там нет значения или оно `undef`, то из файла `.env`, а если и там его не будет – из опции `default`.

При парсинге файла, ошибка синтаксиса приведёт к исключению.

Тип переменной окружения можно проверять с помощью опции `isa`. Она принимает подпрограмму или объект с перегруженным оператором `${}`. Ð’ этÐ...

Рекомендуется называть переменные окружения используя название модуля в котором она объявлена. Например, пакет `Aion::Type`, тогда имена перÐ...

# SUBROUTINES

## import ($cls, $name, %kw)

lib/Aion/Env.pm  view on Meta::CPAN

	BB_TEST; # -> 1
	
	eval 'use Aion::Env NN_TEST => ()'; $@; # ^-> NN_TEST is'nt defined!
	eval 'use Aion::Env NN_TEST => (nouname => 1)'; $@; # ^-> Unknown aspect: nouname
	eval 'use Aion::Env NN_TEST => (nouname1 => 1, nouname2 => 2)'; $@; # ^-> Unknown aspects: nouname1, nouname2

=head1 DESCRIPTION

Projects use the C<.env> configuration file for project configuration, in C<Makefile>, for C<docker> and C<docker compose>. This module allows you to design environment variables as constants of C<perl> modules.

Constants are initialized from C<%ENV>, if there is no value there or it is C<undef>, then from the C<.env> file, and if it is not there, from the C<default> option.

When parsing a file, a syntax error will result in an exception.

The type of an environment variable can be checked using the C<isa> option. It accepts a subroutine or object with the C<${}> operator overloaded. In this case, the value will be passed to C<$_>. If the object has a C<validate> method, like C<Aion::T...

It is recommended to name environment variables using the name of the module in which it is declared. For example, the package is C<Aion::Type>, then the names of the environment variables in it are C<AION_TYPE_*>.

=head1 SUBROUTINES

=head2 import ($cls, $name, %kw)

lib/Aion/Env/Etc.md  view on Meta::CPAN

Получить значение по ключу из хеша.

```perl
my ($val, $key_exists) = Aion::Env::Etc::by_key({x => {y => {z => 3}}}, "x.y.z");

$val # -> 3
$key_exists # -> 1

($val, $key_exists) = Aion::Env::Etc::by_key({x => {y => {t => 10}}}, "x.y.z");

$val # -> undef
$key_exists # -> 0
```

# AUTHOR

Yaroslav O. Kosmina <dart@cpan.org>

# LICENSE

âš– **Perl5**

lib/Aion/Env/Etc.pm  view on Meta::CPAN

	my ($path) = @_;

	my $etc;
	my @S = $path;
	while(@S) {
		my $path = shift @S;
		open my $f, '<:utf8', $path or die "$path :$!";
		read $f, my $buf, -s $f;
		close $f;
		$buf =~ s!\$\{([a-z_]\w*)\}! val($ENV{$1} // $Aion::Env::env{$1}) !gie;
		my $include = YAML::Syck::Load($buf); undef $buf;
		push @S, @{$include->{includes}};
		%$include = (%$include, %{$include->{'when@' . APP_ENV}});
		$etc = merge_hashes($path, undef, $etc, $include);
	}

	$etc
}

# Рекурсивное объединение двух хешей
sub merge_hashes {
	my ($file, $path, $x, $y) = @_;

	my %val = %$x;

lib/Aion/Env/Etc.pm  view on Meta::CPAN

	$s =~ s/[\\"']/\\$&/g;
	$s =~ s/\n/\\n/g;
	$s =~ s/\r/\\r/g;
	$s =~ s/\t/\\t/g;
	$s
}

# Получить значение по ключу
sub by_key($$) {
	my ($hash, $path) = @_;
	exists $hash->{$_}? $hash = $hash->{$_}: return undef, 0 for split /\./, $path;
	return $hash, 1;
}

1;

__END__

=encoding utf-8

=head1 NAME

lib/Aion/Env/Etc.pm  view on Meta::CPAN


Get the value by key from the hash.

	my ($val, $key_exists) = Aion::Env::Etc::by_key({x => {y => {z => 3}}}, "x.y.z");
	
	$val # -> 3
	$key_exists # -> 1
	
	($val, $key_exists) = Aion::Env::Etc::by_key({x => {y => {t => 10}}}, "x.y.z");
	
	$val # -> undef
	$key_exists # -> 0

=head1 AUTHOR

Yaroslav O. Kosmina L<mailto:dart@cpan.org>

=head1 LICENSE

âš– B<Perl5>

t/aion/env.t  view on Meta::CPAN

use common::sense; use open qw/:std :utf8/;  use Carp qw//; use Cwd qw//; use File::Basename qw//; use File::Find qw//; use File::Slurper qw//; use File::Spec qw//; use File::Path qw//; use Scalar::Util qw//;  use Test::More 0.98;  use String::Diff q...
# # NAME
# 
# Aion::Env - создаёт константу связанную со значением из .env
# 
# # VERSION
# 
# 0.1
# 
# # SYNOPSIS
# 

t/aion/env.t  view on Meta::CPAN

	$ENV{UNI_TEST} = 30;
}

sub Int { sub { /^-?\d+$/ } }

use Aion::Env BIN_TEST => (isa => Int);
use Aion::Env OCT_TEST => (isa => Int);
use Aion::Env UNI_TEST => (isa => Int);
use Aion::Env BB_TEST => (isa => Int, default => 1);

local ($::_g0 = do {BIN_TEST;}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'BIN_TEST; # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {OCT_TEST;}, $::_e0 = do {1020}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'OCT_TEST; # -> 1020' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {UNI_TEST;}, $::_e0 = do {30}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'UNI_TEST; # -> 30' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {BB_TEST;}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'BB_TEST; # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {eval 'use Aion::Env NN_TEST => ()'; $@;}, $::_e0 = 'NN_TEST is\'nt defined!'); ::ok $::_g0 =~ /^${\quotemeta $::_e0}/, 'eval \'use Aion::Env NN_TEST => ()\'; $@; # ^-> NN_TEST is\'nt defined!' or ::diag ::_string_diff($::_g0, $::_...
local ($::_g0 = do {eval 'use Aion::Env NN_TEST => (nouname => 1)'; $@;}, $::_e0 = 'Unknown aspect: nouname'); ::ok $::_g0 =~ /^${\quotemeta $::_e0}/, 'eval \'use Aion::Env NN_TEST => (nouname => 1)\'; $@; # ^-> Unknown aspect: nouname' or ::diag ::_...
local ($::_g0 = do {eval 'use Aion::Env NN_TEST => (nouname1 => 1, nouname2 => 2)'; $@;}, $::_e0 = 'Unknown aspects: nouname1, nouname2'); ::ok $::_g0 =~ /^${\quotemeta $::_e0}/, 'eval \'use Aion::Env NN_TEST => (nouname1 => 1, nouname2 => 2)\'; $@; ...

# 
# # DESCRIPTION
# 
# Ð’ проектах используется конфигурационный файл `.env` для конфигурации проекта, в `Makefile`, для `docker` и `docker compose`. Данный модуль позволяет офорÐ...
# 
# Константы инициализируются из `%ENV`, если там нет значения или оно `undef`, то из файла `.env`, а если и там его не будет – из опции `default`.
# 
# При парсинге файла, ошибка синтаксиса приведёт к исключению.
# 
# Тип переменной окружения можно проверять с помощью опции `isa`. Она принимает подпрограмму или объект с перегруженным оператором `${}`. Ð’ эÑ...
# 
# Рекомендуется называть переменные окружения используя название модуля в котором она объявлена. Например, пакет `Aion::Type`, тогда имена пеÑ...
# 
# # SUBROUTINES
# 
# ## import ($cls, $name, %kw)

t/aion/env/etc.pm  view on Meta::CPAN

use common::sense; use open qw/:std :utf8/;  use Carp qw//; use Cwd qw//; use File::Basename qw//; use File::Find qw//; use File::Slurper qw//; use File::Spec qw//; use File::Path qw//; use Scalar::Util qw//;  use Test::More 0.98;  use String::Diff q...
# 
# use common::sense;
# 
# use YAML::Syck qw//;
# 
# use Aion::Env AION_ENV_ETC_PATH => (default => 'etc/include.yml');
# use Aion::Env APP_ENV => (default => 'prod');
# 
# our %ETC = -e AION_ENV_ETC_PATH? _parse(AION_ENV_ETC_PATH): ();
# 

t/aion/env/etc.t  view on Meta::CPAN

use common::sense; use open qw/:std :utf8/;  use Carp qw//; use Cwd qw//; use File::Basename qw//; use File::Find qw//; use File::Slurper qw//; use File::Spec qw//; use File::Path qw//; use Scalar::Util qw//;  use Test::More 0.98;  use String::Diff q...
# # NAME
# 
# Aion::Env::Etc - создаёт константу связанную с ключом из конфигурационных файлов
# 
# # SYNOPSIS
# 
# Файл etc/include.yml:
#@> etc/include.yml
#>> includes:
#>>   - etc/test.yml

t/aion/env/etc.t  view on Meta::CPAN

#@< EOF
# 
subtest 'SYNOPSIS' => sub { 
BEGIN { $ENV{APP_ENV} = 'dev' }

sub Int { sub { /^-?\d+$/ } }

use Aion::Env::Etc TEST_ABC => (isa => Int);
use Aion::Env::Etc VAL => (isa => Int, key => 'test.val');

local ($::_g0 = do {TEST_ABC}, $::_e0 = do {-12}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'TEST_ABC # -> -12' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {VAL}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'VAL # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# # DESCRIPTION
# 
# Парсит конфигурационный файл. Путь к нему задан энвиронмент-переменной `AION_ENV_ETC_PATH`.
# 
# В нём может быть ключ `includes` c включением других конфигурационных файлов, а у тех – других.
# Для простоты `includes` срабатывают от текущего каталога, который должен соответствовать корню проекта (таково соглашение).
# 
# Ключи вида `when@ID` будут перекрывать своими ключами ключи конфигурационного файла, если `ID` из них соответствует `APP_ENV`.

t/aion/env/etc.t  view on Meta::CPAN

# ## merge_hashes ($file, $path, $x, $y)
# 
# Обединяет два хеша рекурсивно. Если в совпадающих ключах не хеши, то выбрасывает ошибку с `$file` и `$path`, где `$file` – подключающийся файл, а `$p...
# 
# ## val ($s)
# 
# Добавляет бэкслеши. Используется для эскейпинга энвиронментов.
# 
::done_testing; }; subtest 'val ($s)' => sub { 
my $escape_string = "\\\"\\'\\\\\\t\\r\\n";
local ($::_g0 = do {Aion::Env::Etc::val("\"'\\\t\r\n")}, $::_e0 = do {$escape_string}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Aion::Env::Etc::val("\"\'\\\t\r\n") # -> $escape_string' or ::diag ::_struct_diff($::_g0, $::_e0); u...

# 
# ## by_key ($hash, $path)
# 
# Получить значение по ключу из хеша.
# 
::done_testing; }; subtest 'by_key ($hash, $path)' => sub { 
my ($val, $key_exists) = Aion::Env::Etc::by_key({x => {y => {z => 3}}}, "x.y.z");

local ($::_g0 = do {$val}, $::_e0 = do {3}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$val # -> 3' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$key_exists}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$key_exists # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

($val, $key_exists) = Aion::Env::Etc::by_key({x => {y => {t => 10}}}, "x.y.z");

local ($::_g0 = do {$val}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$val # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$key_exists}, $::_e0 = do {0}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$key_exists # -> 0' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# # AUTHOR
# 
# Yaroslav O. Kosmina <dart@cpan.org>
# 
# # LICENSE
# 
# âš– **Perl5**
# 



( run in 1.938 second using v1.01-cache-2.11-cpan-d80b1682f3f )