1Config::Model::Backend:U:sAenry(C3o)ntributed Perl DocumCeonntfaitgi:o:nModel::Backend::Any(3)
2
3
4

NAME

6       Config::Model::Backend::Any - Virtual class for other backends
7

VERSION

9       version 2.150
10

SYNOPSIS

12        package Config::Model::Backend::Foo ;
13        use Mouse ;
14
15        extends 'Config::Model::Backend::Any';
16
17        # mandatory
18        sub read {
19           my $self = shift ;
20           my %args = @_ ;
21
22           # args are:
23           # root       => './my_test',  # fake root directory, used for tests
24           # config_dir => /etc/foo',    # absolute path
25           # file       => 'foo.conf',   # file name
26           # file_path  => Path::Tiny object for './my_test/etc/foo/foo.conf'
27           # check      => yes|no|skip
28
29           return 0 unless $args{file_path}->exists ; # or die, your choice
30
31           # read the file line by line
32           # we assume the file contain lines like 'key=value'
33           foreach ($args{file_path}->lines_utf8) {
34               chomp ;   # remove trailing \n
35               s/#.*// ; # remove any comment
36               next unless /\S/; # skip blank line
37
38               # $data is 'foo=bar' which is compatible with load
39               $self->node->load(steps => $_, check => $args{check} ) ;
40           }
41           return 1 ;
42        }
43
44        # mandatory
45        sub write {
46           my $self = shift ;
47           my %args = @_ ;
48
49           # args are:
50           # root       => './my_test',  # fake root directory, used for tests
51           # config_dir => /etc/foo',    # absolute path
52           # file       => 'foo.conf',   # file name
53           # file_path  => Path::Tiny object for './my_test/etc/foo/foo.conf'
54           # check      => yes|no|skip
55
56           # read the content of the configuration tree
57           my @lines;
58           foreach my $elt ($self->node->children) {
59               # read the value from element $elt
60               my $v = $self->node->grab_value($elt) ;
61
62               # write value in file
63               push @lines,qq!$elt="$v"\n! if defined $v ;
64           }
65
66           $args{file_path}->spew_utf8(@lines);
67           return 1;
68        }
69

DESCRIPTION

71       Some application have configuration files with a syntax which is not
72       supported by existing "Config::Model::Backend::*" classes.
73
74       In this case a new backend must be written.
75       "Config::Model::Backend::Any" was created to facilitate this task.
76
77       The new backend class must use Mouse and must extends (inherit)
78       "Config::Model::Backend::Any".
79

How to write your own backend

81   Declare the new backend in a node of the model
82       As explained in "Backend specification" in Config::Model::BackendMgr,
83       the new backend must be declared as an attribute of a
84       Config::Model::Node specification.
85
86       Let's say your new backend is "Config::Model::Backend::Foo". This new
87       backend can be specified with:
88
89        rw_config  => {
90           backend    => 'Foo' , # can also be 'foo'
91           config_dir => '/etc/cfg_dir'
92           file       => 'foo.conf', # optional
93        }
94
95       (The backend class name is constructed with "ucfirst($backend_name)")
96
97       "rw_config" can also have custom parameters that are passed verbatim to
98       "Config::Model::Backend::Foo" methods:
99
100        rw_config  => {
101           backend    => 'Foo' , # can also be 'foo'
102           config_dir => '/etc/cfg_dir'
103           file       => 'foo.conf', # optional
104           my_param   => 'my_value',
105        }
106
107       "Config::Model::Backend::Foo" class must inherit (extend)
108       Config::Model::Backend::Any and is expected to provide the following
109       methods:
110
111       read
112           "read" is called with the following parameters:
113
114            %custom_parameters,       # e.g. my_param   => 'my_value' in the example above
115            object     => $obj,         # Config::Model::Node object
116            root       => $root_dir,  # fake root directory, used for tests
117            backend    => $backend,   # backend name
118            config_dir => $read_dir,  # path below root
119            file       => 'foo.conf', # file name
120            file_path  => $full_name, # Path::Tiny object
121            check      => [yes|no|skip]
122
123           The IO::File object is undef if the file cannot be read.
124
125           This method must return 1 if the read was successful, 0 otherwise.
126
127           Following the "my_param" example above, %custom_parameters contains
128           " ( 'my_param' , 'my_value' ) ", so "read()" is called with "root",
129           "config_dir", "file_path" and "my_param   => 'my_value'".
130
131       write
132           "write" is called with the following parameters:
133
134            %$custom_parameters,         # e.g. my_param   => 'my_value' in the example above
135            object      => $obj,         # Config::Model::Node object
136            root        => $root_dir,    # fake root directory, used for tests
137            auto_create => $auto_create, # boolean specified in backend declaration
138            auto_delete => $auto_delete, # boolean specified in backend declaration
139            backend     => $backend,     # backend name
140            config_dir  => $write_dir,   # override from instance
141            file        => 'foo.conf',   # file name
142            file_path   => $full_name, # full file name (root+path+file)
143            write       => 1,            # always
144            check       => [ yes|no|skip] ,
145            backup      => [ undef || '' || suffix ] # backup strategy required by user
146
147           The IO::File object is undef if the file cannot be written to.
148
149           This method must return 1 if the write was successful, 0 otherwise
150
151   How to test your new backend
152       Using Config::Model::Tester, you can test your model with your backend
153       following the instructions given in Config::Model::Tester.
154
155       You can also test your backend with a minimal model (and
156       Config::Model::Tester). In this case, you need to specify a small model
157       to test in a "*-test-conf.pl" file.  See the IniFile backend test
158       <https://github.com/dod38fr/config-
159       model/blob/master/t/model_tests.d/backend-ini-test-conf.pl> for an
160       example and its examples files <https://github.com/dod38fr/config-
161       model/tree/master/t/model_tests.d/backend-ini-examples>.
162

CONSTRUCTOR

164   new
165       The constructor should be used only by Config::Model::Node.
166
167       Parameter:
168
169       node
170           Calling node object. Node ref is weakened,
171
172       name
173           Backend name
174
175       auto_create
176           Boolean. Set to true to create the configuration file if this one
177           is missing (default 0)
178
179       auto_delete
180           Boolean. Set to true to remove the configuration file if this one
181           no longer contain configuration information. (default 0)
182

Methods to override

184   annotation
185       Whether the backend supports reading and writing annotation (a.k.a
186       comments). Default is 0. Override this method to return 1 if your
187       backend supports annotations.
188
189   read
190       Read the configuration file. This method must be overridden.
191
192   write
193       Write the configuration file. This method must be overridden.
194

Methods

196   node
197       Return the node (a Config::Model::Node) holding this backend.
198
199   instance
200       Return the instance (a Config::Model::Instance) holding this
201       configuration.
202
203   show_message
204       Parameters: "( string )"
205
206       Show a message to STDOUT (unless overridden).  Delegated to
207       "show_message" in Config::Model::Instance.
208
209   read_global_comments
210       Parameters:
211
212       •   array ref of string containing the lines to be parsed
213
214       •   A string to specify how a comment is started. Each character is
215           recognized as a comment starter (e.g '"#;"' allow a comment to
216           begin with '"#"' or '";"')
217
218       Read the global comments (i.e. the first block of comments until the
219       first blank or non comment line) and store them as root node
220       annotation. Note that the global comment must be separated from the
221       first data line by a blank line.
222
223       Example:
224
225        $self->read_global_comments( \@lines, ';');
226        $self->read_global_comments( \@lines, '#;');
227
228   associates_comments_with_data
229       Parameters:
230
231       •   array ref of string containing the lines to be parsed
232
233       •   A string to specify how a comment is started. Each character is
234           recognized as a comment starter (e.g '"#;"' allow a comment to
235           begin with '"#"' or '";"')
236
237       This method extracts comments from the passed lines and associate them
238       with actual data found in the file lines. Data is associated with
239       comments preceding or on the same line as the data. Returns a list of [
240       data, comment ].
241
242       Example:
243
244         my @lines = (
245           '# Foo comments',
246           'foo= 1',
247           'Baz = 0 # Baz comments'
248         );
249         my @res = $self->associates_comments_with_data( \@lines, '#')
250         # @res is:
251         # ( [ 'foo= 1', 'Foo comments' ] , [ 'Baz = 0' , 'Baz comments' ] )
252
253   write_global_comments
254       Return a string containing global comments using data from
255       configuration root annotation.
256
257       Requires one parameter: comment_char (e.g "#" or '//' )
258
259       Example:
260
261         my $str = $self->write_global_comments('#')
262
263   write_data_and_comments
264       Returns a string containing comments (stored in annotation) and
265       corresponding data. Comments are written before the data. If a data is
266       undef, the comment is written on its own line.
267
268       Positional parameters are "( comment_char , data1, comment1, data2,
269       comment2 ...)"
270
271       Example:
272
273        print $self->write_data_and_comments('#', 'foo', 'foo comment', undef, 'lone comment','bar')
274        # returns "# foo comment\nfoo\n#lon
275
276       Use "undef" as comment char if comments are not supported by the syntax
277       of the configuration file. Comments will then be dropped.
278

Replacing a custom backend

280       Custom backend are now deprecated and must be replaced with a class
281       inheriting this module.
282
283       Please:
284
285       •   Rename your class to begin with "Config::Model::Backend::"
286
287       •   Add "use Mouse ;" and "extends 'Config::Model::Backend::Any';" in
288           the header of your custom class.
289
290       •   Add "my $self = shift;" as the beginning of "read" and "write"
291           functions... well... methods.
292
293       Here's an example of such a change <https://github.com/dod38fr/config-
294       model/commit/c3b7007ad386cb2356c5ac1499fe51bdf492b19a>.
295

AUTHOR

297       Dominique Dumont, (ddumont at cpan dot org)
298

SEE ALSO

300       Config::Model, Config::Model::BackendMgr, Config::Model::Node,
301

AUTHOR

303       Dominique Dumont
304
306       This software is Copyright (c) 2005-2022 by Dominique Dumont.
307
308       This is free software, licensed under:
309
310         The GNU Lesser General Public License, Version 2.1, February 1999
311
312
313
314perl v5.34.1                      2022-05-09    Config::Model::Backend::Any(3)
Impressum