1Config::Model::Backend:U:sAenry(C3o)ntributed Perl DocumCeonntfaitgi:o:nModel::Backend::Any(3)
2
3
4
6 Config::Model::Backend::Any - Virtual class for other backends
7
9 version 2.142
10
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
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
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
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
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
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
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
297 Dominique Dumont, (ddumont at cpan dot org)
298
300 Config::Model, Config::Model::BackendMgr, Config::Model::Node,
301
303 Dominique Dumont
304
306 This software is Copyright (c) 2005-2021 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.0 2021-07-22 Config::Model::Backend::Any(3)