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