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.129
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 ( node => $node_obj, name => backend_name )
165       The constructor should be used only by Config::Model::Node.
166

Methods to override

168   annotation
169       Whether the backend supports reading and writing annotation (a.k.a
170       comments). Default is 0. Override this method to return 1 if your
171       backend supports annotations.
172
173   read
174       Read the configuration file. This method must be overridden.
175
176   write
177       Write the configuration file. This method must be overridden.
178

Methods

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

Replacing a custom backend

264       Custom backend are now deprecated and must be replaced with a class
265       inheriting this module.
266
267       Please:
268
269       ·   Rename your class to begin with "Config::Model::Backend::"
270
271       ·   Add "use Mouse ;" and "extends 'Config::Model::Backend::Any';" in
272           the header of your custom class.
273
274       ·   Add "my $self = shift;" as the beginning of "read" and "write"
275           functions... well... methods.
276
277       Here's an example of such a change <https://github.com/dod38fr/config-
278       model/commit/c3b7007ad386cb2356c5ac1499fe51bdf492b19a>.
279

AUTHOR

281       Dominique Dumont, (ddumont at cpan dot org)
282

SEE ALSO

284       Config::Model, Config::Model::BackendMgr, Config::Model::Node,
285       Config::Model::Backend::Yaml,
286

AUTHOR

288       Dominique Dumont
289
291       This software is Copyright (c) 2005-2018 by Dominique Dumont.
292
293       This is free software, licensed under:
294
295         The GNU Lesser General Public License, Version 2.1, February 1999
296
297
298
299perl v5.28.1                      2018-12-07    Config::Model::Backend::Any(3)
Impressum