File Coverage

blib/lib/Config/Model/Value/LayeredInclude.pm
Criterion Covered Total %
statement 29 29 100.0
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 39 39 100.0


line stmt bran cond sub pod time code
1             #
2             # This file is part of Config-Model
3             #
4             # This software is Copyright (c) 2005-2022 by Dominique Dumont.
5             #
6             # This is free software, licensed under:
7             #
8             # The GNU Lesser General Public License, Version 2.1, February 1999
9             #
10             package Config::Model::Value::LayeredInclude 2.153; # TRIAL
11              
12 1     1   22 use v5.20;
  1         6  
13 1     1   8 use Mouse;
  1         3  
  1         21  
14 1     1   631 use strict;
  1         5  
  1         29  
15 1     1   5 use warnings;
  1         2  
  1         35  
16 1     1   5 use Log::Log4perl qw(get_logger :levels);
  1         2  
  1         13  
17              
18 1     1   172 use base qw/Config::Model::Value/;
  1         4  
  1         115  
19              
20 1     1   7 use feature qw/postderef signatures/;
  1         2  
  1         131  
21 1     1   8 no warnings qw/experimental::postderef experimental::signatures/;
  1         2  
  1         169  
22              
23             my $logger = get_logger("Tree::Element::Value::LayeredInclude");
24              
25             # should we clear all layered value when include value is changed ?
26             # If yes, beware of recursive includes. Clear should only be done once.
27              
28             around _store => sub ($orig, $self, %args) {
29             my ( $value, $check, $silent, $notify_change, $ok, $callback ) =
30             @args{qw/value check silent notify_change ok callback/};
31              
32             my $old_value = $self->_fetch_no_check;
33              
34             $orig->($self, %args);
35             {
36             ## no critic (TestingAndDebugging::ProhibitNoWarnings)
37 1     1   9 no warnings 'uninitialized';
  1         4  
  1         122  
38             return $value if $value eq $old_value;
39             }
40              
41             my $i = $self->instance;
42             my $already_in_layered = $i->layered;
43              
44             # layered stuff here
45             if ( not $already_in_layered ) {
46             $i->layered_clear;
47             $i->layered_start;
48             }
49              
50             {
51             ## no critic (TestingAndDebugging::ProhibitNoWarnings)
52 1     1   9 no warnings 'uninitialized';
  1         2  
  1         182  
53             $logger->debug("Loading layered config from $value (old_data is $old_value)");
54             }
55              
56             # load included file in layered mode
57             $self->root->read_config_data(
58             # check => 'no',
59             config_file => $value,
60             auto_create => 0, # included file must exist
61             );
62              
63             if ( not $already_in_layered ) {
64             $i->layered_stop;
65             }
66              
67             # test if already in layered mode -> if no, clear layered,
68             $logger->debug("Done loading layered config from $value");
69              
70             return $value;
71             };
72              
73             1;
74              
75             # ABSTRACT: Include a sub layer configuration
76              
77             __END__
78              
79             =pod
80              
81             =encoding UTF-8
82              
83             =head1 NAME
84              
85             Config::Model::Value::LayeredInclude - Include a sub layer configuration
86              
87             =head1 VERSION
88              
89             version 2.153
90              
91             =head1 SYNOPSIS
92              
93             # in a model declaration:
94             'element' => [
95             'include' => {
96             'class' => 'Config::Model::Value::LayeredInclude',
97              
98             # usual Config::Model::Value parameters
99             'type' => 'leaf',
100             'value_type' => 'uniline',
101             'convert' => 'lc',
102             'summary' => 'Include file for cascaded configuration',
103             'description' => 'To support multiple variants of ...'
104             },
105             ]
106              
107             =head1 DESCRIPTION
108              
109             This class inherits from L<Config::Model::Value>. It overrides
110             L<_store> to trigger a refresh of layered value when a value is
111             changed. I.e. changing this value trigger a reload of the referred configuration
112             file which values are used as default value. This class was designed to
113             cope with L<multistrap|http://wiki.debian.org/Multistrap> configuration.
114              
115             =head2 CAUTION
116              
117             A configuration file can support 2 kinds of include:
118              
119             =over
120              
121             =item *
122              
123             Layered include which sets default values like multistrap or ssh. These includes are
124             read-only.
125              
126             =item *
127              
128             Real includes like C<apache>. In this cases modified configuration items can be written to
129             included files.
130              
131             =back
132              
133             This class works only with the first type
134              
135             =head1 AUTHOR
136              
137             Dominique Dumont
138              
139             =head1 COPYRIGHT AND LICENSE
140              
141             This software is Copyright (c) 2005-2022 by Dominique Dumont.
142              
143             This is free software, licensed under:
144              
145             The GNU Lesser General Public License, Version 2.1, February 1999
146              
147             =cut