Config::MyConfig2 is a flexible configuration file parser, that reads and writes Apache-Style configuration files, with global key/value pairs and directives <directive my_directive></directive>
It supports:
Configureable layout of configuration files, i.e. which keywords, which directives (if any), syntax checks for values
Flexible configurations, i.e. using tabs, spaces or = as delimiters between keywords and values
Apache Webserver style configuration directives: <directive my_directive>keywords & values</directive>
Keywords with multiple values, either as comma seperated list or as multiple keywords with the same name
Methods to gather loaded configuration values in Perl context, i.e. as hashtree, lists or single values
Ability to modify the configuration, after it has been loaded
Ability to store a modified configuration file back to disk
Full Perl OO access
my $myconfig = Config::MyConfig2->new ( conffile => "my_configuration_file.cfg", ); my $conftemplate; $conftemplate->{global}->{somenumber} = { required => 'true', type => 'single', match => '^\d+\.*\d*'}; $conftemplate->{global}->{somestring} = { required => 'false', type => 'single', match => '^.+'}; $conftemplate->{directive}->{foo} = { type => 'single', match => '^[true]|[false]$'}; $conftemplate->{directive}->{bar} = { type => 'single', match => '^0|1$'}; $conftemplate->{other_directive}->{far} = { type => 'list', match => '.+'}; $conftemplate->{other_directive}->{boo} = { type => 'list', match => '.+'}; $myconfig->SetupDirectives($conftemplate); my $config_hashtree = $myconfig->ReadConfig(); my $global_value = $myconfig->GetGlobalValue('foo'); $errmsg = $myconfig->SetDirectiveValue('directive_foo','identifier_baz','key_foobar','value_foo_bar_baz'); $myconfig->WriteConfig('My new config file','some_file.cfg');
This class provides methods to setup a configuration file template as well as to read and parse a configuration file, that matches to the template. The configuration can have Apache-Configuration style directives.
Furthermore, an existing configuration can be modified and written back to disk.
It supports...
Global keywords
keyword foo
keywords with lists in CSV (comma separated value) format
keyword foo, bar, boo, far
Directives with names and user-defined identifiers:
<directive foo> keyword foo other_keyword bar </directive> <other_directive bar> perl_program hello_world.pl argument foobar </other_directive>
Creates a new Config::MyConfig2 object
my $myconfig = Config::MyConfig2->new ( conffile => "my_configuration_file.cfg", );
$myconfig->SetupDirectives($conftemplate);
Where $conftemplate is a hash tree data structure.
Global values are key/value pairs, that are not living in a directive. This can be i.e.
animal = cow or animal cow
and would be templated like this:
$tmpl->{global}->{animal} = { match => '.+', type => 'single'}
Allowed delimiters are spaces, tabs and =
Directive values are values, that are living within a directive. Each diretive has a name and an identifier, i.e.
<my_directive foo> bar 100 </my_directive>
The identifiers can freely be choosen by the user. The directive names are predifined in the template.
$tmpl->{my_directive}->{bar} = {match => '.+', type = 'single'}
The keyword 'bar' would match for all directive name / directive identifier combinations with the directive 'name my_directive'.
Keyword types can be:
A single item can only be defined once and appears as a scalar in the config hash tree.
foo bar
If gathered via GetGlobalValue or GetDirectiveValue, these items will be returned as an array reference.
A multi item can be defined multiple times, either as a list of repeated keyword / value pairs or as a comma seperated list of values with one keyword
foo = 1 foo = 2 foo = 3
or
foo = 1, 2, 3
or, of course, something like this:
foo 1 ,2, 3
The match operator is a regex, where a supplied value in the configuration file is checked against. This enables the possibility of syntax checking configuration parameters.
If a check fails, an errors is thrown.
$config_hash_tree = $self->ReadConfig()
Reads and parses the configuration file. Throws an error, if a parsing error (i.e. syntax error) occurs.
Returns the configuration as a hash_tree. See the example below.
Returns a list of all directive names as an array or an empty list, if no directive names have been found.
@directives = $myconfig->GetDirectiveNames()
Expects the name of a pre-defined directive
Returns a list of all directive identifiers as an array or an empty list in case of identifiers have been found.
@identifiers = $myconfig->GetDirectiveIdentifiers('my_directive')
Returns a hash reference to the configuration, which is a nested datastructure. You might want to use
use Data::Dumper; print Dumper($config_reference)
to evaluate the details of this structure.
Because it is a reference, all modifications of this structure will also end up in configuration files, written with WriteConfig().
Returns a global value as a scalar (type = single) or a reference to an array (type = multi)
$value = $myconfig->GetGlobalValue('foo') $value_array_ref = $myconfig->GetGlobalValue('foo')
Expects the name of a directive and a keyword
$value = $myconfig->GetGlobalValue('my_directive','foo') $value_array_ref = $myconfig->GetGlobalValue('my_directive','foo')
Expects the name of a directive, directive identifier and a keyword.
Returns a directive value as a scalar (type = single) or a reference to an array (type = multi)
$value = $myconfig->GetGlobalValue('my_directive','some_identifier','foo') $value_array_ref = $myconfig->GetGlobalValue('foo')
Sets the value of a global keyword.
Expects a pre-defined global keyword and a value
Returns undef in case of success or an string with a error message. It uses the syntax-checker to verifiy if the global value meets the requirements of the checkng regex.
$errmsg = $myconfig->SetGlobalValue('some_keyword','some_value')
If the keyword is of type 'multi', the passed value will be added to a list of values.
Sets the value of a keyword within a directive.
Expects a directive-name, directive identifier, keyword and a value.
$errmsg = $myconfig->SetGlobalValue('some_directive','some_identifier','some_keyword','some_value')
If the directive identifier doesn't exist, it will be created. If the keyword is of type 'multi', the passed value will be added to a list of values.
Deletes an identifier from a directive. Expects a directive name and directive identifier Returns the removed values or undef is no values for this directive/identifiehave been deleted.
Writes the (modified) configuration file back to disk.
Expects a name-string, that is shown in the configuration file header comments and a filename where the configuration should be saved to.
$myconfig->WriteConfig('Foo Bars Configuration File','/tmp/foo.cfg');
Internal method, that is used to throw an error. The default behavior is to croack().
Configuration file for a backup script: backup.cfg
--- snip --- # # Config file # # # ---- Global Section ---- # # Path to the rsync programm rsync /usr/bin/rsync # Path to sendmail sendmail /usr/sbin/sendmail # Path to the tar utility tar /bin/tar # Path to ssh command # If not specified, rsh will be used ssh /usr/bin/ssh # Debuglevel, range (0..2) debuglevel 1 # # ---- Backup Directives ---- # <backup server-system> hostname localhost backupschedule Mon, Wed, Fri archiveschedule Sun archivemaxdays 60 add / excl /home, /proc, /sys, /dev, /mnt, /media </backup> <backup server-home> hostname localhost backupschedule Mon, Wed, Fri archiveschedule Sun archivemaxdays 30 add /home </backup> --- snap ---
Setup procedure in perl context
#!/usr/bin/perl use Config::MyConfig2; use strict; use Data::Dumper; my $myconfig = Config::MyConfig2->new( conffile => "backup.cfg" ); my $conftemplate; $conftemplate->{global}->{rsync} = { required => 'true', type => 'single', match => '.+' }; $conftemplate->{global}->{sendmail} = { required => 'true', type => 'single', match => '.+' }; $conftemplate->{global}->{tar} = { required => 'true', type => 'single', match => '.+' }; $conftemplate->{global}->{ssh} = { required => 'true', type => 'single', match => '.+' }; $conftemplate->{global}->{rsync} = { required => 'true', type => 'single', match => '.+' }; $conftemplate->{global}->{debuglevel} = { required => 'true', type => 'single', match => '^\d$' }; $conftemplate->{backup}->{hostname} = { required => 'true', type => 'single', match => '^[a-zA-Z0-9\.]+$' }; $conftemplate->{backup}->{backupschedule} = { required => 'true', type => 'list', match => '^[Mon]|[Tue]|[Wed]|[Thu]|[Fri]|[Sat]|[Sun]$' }; $conftemplate->{backup}->{archiveschedule} = { required => 'true', type => 'list', match => '^[Mon]|[Tue]|[Wed]|[Thu]|[Fri]|[Sat]|[Sun]$' }; $conftemplate->{backup}->{archivemaxdays} = { required => 'true', type => 'list', match => '^\d+$' }; $conftemplate->{backup}->{add} = { required => 'true', type => 'list', match => '.+' }; $conftemplate->{backup}->{excl} = { required => 'false', type => 'list', match => '.+' }; $myconfig->SetupDirectives($conftemplate); my $config = $myconfig->ReadConfig(); print Dumper (\$config);
Results in the following hash structure
$VAR1 = \{ 'global' => { 'tar' => '/bin/tar', 'sendmail' => '/usr/sbin/sendmail', 'rsync' => '/usr/bin/rsync', 'ssh' => '/usr/bin/ssh', 'debuglevel' => '1' }, 'backup' => { 'server-home' => { 'archivemaxdays' => [ '30' ], 'add' => [ '/home' ], 'archiveschedule' => [ 'Sun' ], 'hostname' => 'localhost', 'backupschedule' => [ 'Mon', 'Wed', 'Fri' ] }, 'server-system' => { 'excl' => [ '/home', '/proc', '/sys', '/dev', '/mnt', '/media' ], 'archivemaxdays' => [ '60' ], 'add' => [ '/' ], 'archiveschedule' => [ 'Sun' ], 'hostname' => 'localhost', 'backupschedule' => [ 'Mon', 'Wed', 'Fri' ] } } };
A more advanced example can be found in the included example program myconfig-demo.pl.
Config::MyConfig2.pm supports my DebugHelper.pm class, which provides excellent debugging and error handling methods.
$mycfg = Config::MyConfig2->new( conffile = "foo.cfg", dh = $reference_to_debughelper_class );
If you don't like, that MyConfig croaks if an error (i.e. syntax error in a configuration file) occurs, you may use MyConfig with eval:
eval { $myconfig->ReadConfig() } if ($@) ... do something
Markus Guertler, <markus at guertler.org>
<markus at guertler.org>
Please report any bugs or feature requests to bug-myconfig2 at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Config::MyConfig2. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
bug-myconfig2 at rt.cpan.org
You can find documentation for this module with the perldoc command.
perldoc Config::MyConfig2
You can also look for information at:
RT: CPAN's request tracker (report bugs here)
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Config::MyConfig2
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/Config::MyConfig2
CPAN Ratings
http://cpanratings.perl.org/d/Config::MyConfig2
Search CPAN
http://search.cpan.org/dist/Config::MyConfig2/
Copyright 2013 Markus Guertler.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
To install Config::MyConfig2, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Config::MyConfig2
CPAN shell
perl -MCPAN -e shell install Config::MyConfig2
For more information on module installation, please visit the detailed CPAN module installation guide.