Config-Model-Itself
view release on metacpan or search on metacpan
lib/Config/Model/Itself.pm view on Meta::CPAN
#
# This file is part of Config-Model-Itself
#
# This software is Copyright (c) 2007-2026 by Dominique Dumont.
#
# This is free software, licensed under:
#
# The GNU Lesser General Public License, Version 2.1, February 1999
#
package Config::Model::Itself 2.030;
use Mouse ;
use Mouse::Util::TypeConstraints;
use v5.20;
use strict;
use warnings;
use feature qw/postderef signatures/;
no warnings qw/experimental::postderef experimental::signatures/;
use Config::Model 2.157;
use IO::File ;
use Log::Log4perl 1.11;
use Carp ;
use Data::Dumper ;
use Scalar::Util qw/weaken/;
use Data::Compare ;
use Path::Tiny 0.125; # for mkdir
my $logger = Log::Log4perl::get_logger("Backend::Itself");
subtype 'ModelPathTiny' => as 'Object' => where { $_->isa('Path::Tiny') };
coerce 'ModelPathTiny' => from 'Str' => via {path($_)} ;
# find all .pl file in model_dir and load them...
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
my %args = @_;
my $legacy = delete $args{model_object};
if ($legacy) {
$args{config_model} = $legacy->instance->config_model;
$args{meta_instance} = $legacy->instance;
$args{meta_root} = $legacy;
}
return $class->$orig( %args );
};
has 'config_model' => (
is => 'ro',
isa => 'Config::Model',
lazy_build => 1,
) ;
sub _build_config_model {
my $self = shift;
# don't trigger builders below
if ($self->{meta_root}) {
return $self->meta_root->instance->config_model;
}
elsif ($self->{meta_instance}) {
return $self->meta_instance->config_model;
}
else {
return Config::Model -> new ( ) ;
}
}
has check => (is =>'ro', isa => 'Bool', default => 1) ;
has 'meta_instance' => (
is =>'ro',
isa =>'Config::Model::Instance',
lazy_build => 1,
) ;
sub _build_meta_instance {
my $self = shift;
# don't trigger builders below
if ($self->{meta_root}) {
return $self->meta_root->instance;
lib/Config/Model/Itself.pm view on Meta::CPAN
is =>'ro',
isa =>'Config::Model::Node',
lazy_build => 1,
) ;
sub _build_meta_root {
my $self = shift;
return $self->meta_instance -> config_root ;
}
has cm_lib_dir => (
is =>'ro',
isa => 'ModelPathTiny',
lazy_build => 1,
coerce => 1
) ;
sub _build_cm_lib_dir {
my $self = shift;
my $p = path('lib/Config/Model');
if (! $p->is_dir) {
$p->mkdir();
}
return $p;
}
has force_write => (is =>'ro', isa => 'Bool', default => 0) ;
has root_model => (is =>'ro', isa => 'str');
has modified_classes => (
is =>'rw',
isa =>'HashRef[Bool]',
traits => ['Hash'],
default => sub { {} } ,
handles => {
clear_classes => 'clear',
set_class => 'set',
class_was_changed => 'get' ,
class_known => 'exists',
}
) ;
has model_dir => (
is => 'ro',
isa => 'ModelPathTiny',
lazy_build => 1,
);
sub _build_model_dir {
my $self = shift;
my $md = $self->cm_lib_dir->child('models');
$md->mkdir;
return $md;
}
sub BUILD {
my $self = shift;
# avoid memory cycle
weaken($self);
my $cb = sub {
my %args = @_ ;
my $p = $args{path} || '' ;
return unless $p =~ /^class/ ;
return unless $args{index}; # may be empty when class order is changed
return if $self->class_was_changed($args{index}) ;
$logger->info("class $args{index} was modified");
$self->add_modified_class($args{index}) ;
} ;
$self->meta_instance -> on_change_cb($cb) ;
return;
}
sub add_tracked_class {
my $self = shift;
$self->set_class(shift,0) ;
return;
}
sub add_modified_class {
my $self = shift;
$self->set_class(shift,1) ;
return;
}
sub class_needs_write {
my $self = shift;
my $name = shift;
return ($self->force_write or not $self->class_known($name) or $self->class_was_changed($name)) ;
}
sub read_app_files {
my $self = shift;
my $force_load = shift || 0;
my $read_from = shift ;
my $application = shift ;
my $app_dir = $read_from || $self->model_dir->parent;
my %apps;
my %map;
$logger->info("reading app files from ".$app_dir);
foreach my $dir ( $app_dir->children(qr/\.d$/) ) {
$logger->info("reading app dir ".$dir);
foreach my $file ( $dir->children() ) {
next if $file =~ m!/README!;
next if $file =~ /(~|\.bak|\.orig)$/;
next if $application and $file->basename ne $application;
# bad categories are filtered by the model
my %data = ( category => $dir->basename('.d') );
$logger->info("reading app file ".$file);
foreach ($file->lines({ chomp => 1})) {
s/^\s+//;
s/\s+$//;
s/#.*//;
( run in 1.825 second using v1.01-cache-2.11-cpan-39bf76dae61 )