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.129
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 ( node => $node_obj, name => backend_name )
165 The constructor should be used only by Config::Model::Node.
166
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
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
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
281 Dominique Dumont, (ddumont at cpan dot org)
282
284 Config::Model, Config::Model::BackendMgr, Config::Model::Node,
285 Config::Model::Backend::Yaml,
286
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)