File Coverage

blib/lib/EB/Config.pm
Criterion Covered Total %
statement 91 157 57.9
branch 21 70 30.0
condition 8 15 53.3
subroutine 16 23 69.5
pod 0 1 0.0
total 136 266 51.1


line stmt bran cond sub pod time code
1             #! perl -- -*- coding: utf-8 -*-
2              
3 6     6   2819 use utf8;
  6         22  
  6         29  
4              
5             # Config.pm -- Configuration files.
6             # Author : Johan Vromans
7             # Created On : Fri Jan 20 17:57:13 2006
8             # Last Modified By: Johan Vromans
9             # Last Modified On: Fri Mar 18 20:31:19 2011
10             # Update Count : 251
11             # Status : Unknown, Use with caution!
12              
13             package main;
14              
15             our $cfg;
16             our $dbh;
17              
18             package EB::Config;
19              
20 6     6   332 use strict;
  6         7  
  6         102  
21 6     6   16 use warnings;
  6         9  
  6         142  
22 6     6   18 use Carp;
  6         12  
  6         391  
23 6     6   20 use File::Spec;
  6         12  
  6         3117  
24              
25             sub init_config {
26 6     6 0 11 my ($pkg, $opts) = @_;
27 6         5 my $app;
28              
29             Carp::croak("Internal error -- missing package arg for __PACKAGE__\n")
30 6 50       29 unless $app = delete $opts->{app};
31              
32 6         12 $app = lc($app);
33              
34 6 0 33     20 return if $::cfg && $app && $::cfg->{app} eq lc($app);
      33        
35              
36             # Pre-parse @ARGV for "-f configfile".
37 6         9 my $extraconf = $opts->{config};
38 6         7 my $skipconfig = $opts->{nostdconf};
39              
40             # Resolve extraconf to a file name. It must exist.
41 6 50       16 if ( $extraconf ) {
42 0 0       0 if ( -d $extraconf ) {
43 0         0 my $f = File::Spec->catfile( $extraconf,
44             EB::Config::Handler::std_config($app) );
45 0 0       0 if ( -e $f ) {
46 0         0 $extraconf = $f;
47             }
48             else {
49 0         0 $extraconf = File::Spec->catfile($extraconf,
50             EB::Config::Handler::std_config_alt($app));
51             }
52             }
53 0 0       0 die("$extraconf: $!\n") unless -f $extraconf;
54             }
55              
56             # Build the list of config files.
57 6         7 my @cfgs;
58 6 100       17 if ( !$skipconfig ) {
59 2         7 @cfgs = ( File::Spec->catfile( "etc", $app,
60             EB::Config::Handler::std_config($app) ),
61             EB::Config::Handler::user_dir
62             ( $app, EB::Config::Handler::std_config($app) ),
63             );
64 2 50       8 unless ( $extraconf ) {
65 2         7 push(@cfgs, EB::Config::Handler::std_config($app));
66 2 50       29 $cfgs[-1] = EB::Config::Handler::std_config_alt($app) unless -e $cfgs[-1];
67             }
68             }
69 6 50       15 push(@cfgs, $extraconf) if $extraconf;
70              
71             # Load configs.
72 6         24 my $cfg = EB::Config::Handler->new($app);
73 6         13 for my $file ( @cfgs ) {
74 6 50       81 next unless -s $file;
75 0         0 $cfg->load($file);
76             }
77              
78 6 50       17 if ( $opts->{define} ) {
79 0         0 while ( my ($k, $v) = each( %{ $opts->{define} } ) ) {
  0         0  
80 0 0       0 if ( $k =~ /^(\w+(?:::\w+)*)::?(\w+)/ ) {
81 0         0 $cfg->newval($1, $2, $v);
82             }
83             else {
84 0         0 warn("define error: \"$k\" = \"$v\"\n");
85             }
86             }
87             }
88              
89             $ENV{EB_LANG} = $cfg->val('locale','lang',
90             $ENV{EB_LANG}||$ENV{LANG}||
91 6   66     63 ($^O =~ /^(ms)?win/i ? "nl_NL.utf8" : "nl_NL"));
92              
93 6         18 $cfg->_plug(qw(locale lang EB_LANG));
94 6         13 $ENV{LANG} = $cfg->val(qw(locale lang));
95              
96 6         15 $cfg->_plug(qw(database name EB_DB_NAME));
97              
98 6 50       13 if ( my $db = $cfg->val(qw(database name), undef) ) {
99 0         0 $db =~ s/^eekboek_//; # legacy
100 0         0 $cfg->newval(qw(database name), $db);
101 0         0 $ENV{EB_DB_NAME} = $db;
102             }
103              
104 6         13 $cfg->_plug(qw(database host EB_DB_HOST));
105 6         11 $cfg->_plug(qw(database port EB_DB_PORT));
106 6         10 $cfg->_plug(qw(database user EB_DB_USER));
107 6         10 $cfg->_plug(qw(database password EB_DB_PASSWORD));
108              
109 6         8 $cfg->_plug(qw(csv separator EB_CSV_SEPARATOR));
110              
111 6         10 $cfg->_plug(qw(internal now EB_SQL_NOW));
112              
113 6         10 $cfg->_plug("internal sql", qw(trace EB_SQL_TRACE));
114 6         11 $cfg->_plug("internal sql", qw(prepstats EB_SQL_PREP_STATS));
115 6         10 $cfg->_plug("internal sql", qw(replayout EB_SQL_REP_LAYOUT));
116              
117 6 50       22 if ( $cfg->val(__PACKAGE__, "showfiles", 0) ) {
118 0         0 warn("Config files:\n ",
119             join( "\n ", $cfg->files ), "\n");
120             }
121              
122 6 50       13 if ( $cfg->val(__PACKAGE__, "dumpcfg", 0) ) {
123 6     6   1119 use Data::Dumper;
  6         9671  
  6         6073  
124 0         0 warn(Dumper($cfg));
125             }
126 6         16 $::cfg = $cfg;
127             }
128              
129             sub import {
130 2     2   18 my ($self, $app) = @_;
131 2 50       24 return unless defined $app;
132 0         0 die("PROGRAM ERROR: EB::Config cannot import anything");
133             }
134              
135             package EB::Config::Handler;
136              
137             # Very simple inifile handler (read-only).
138              
139             sub _key {
140 109     109   90 my ($section, $parameter) = @_;
141 109         278 $section.'::'.$parameter;
142             }
143              
144             sub val {
145 103     103   130 my ($self, $section, $parameter, $default) = @_;
146 103         75 my $res;
147 103         167 $res = $self->{data}->{ _key($section, $parameter) };
148 103 100       189 $res = $default unless defined $res;
149 103 50 66     231 Carp::cluck("=> missing config: \"" . _key($section, $parameter) . "\"\n")
150             unless defined $res || @_ > 3;
151 103         258 $res;
152             }
153              
154             sub newval {
155 6     6   9 my ($self, $section, $parameter, $value) = @_;
156 6         12 $self->{data}->{ _key($section, $parameter) } = $value;
157             }
158              
159             sub setval {
160 0     0   0 my ($self, $section, $parameter, $value) = @_;
161 0         0 my $key = _key( $section, $parameter );
162             Carp::cluck("=> missing config: \"$key\"\n")
163 0 0       0 unless exists $self->{data}->{ $key };
164 0         0 $self->{data}->{ $key } = $value;
165             }
166              
167             sub _plug {
168 66     66   60 my ($self, $section, $parameter, $env) = @_;
169             $self->newval($section, $parameter, $ENV{$env})
170 66 100 66     134 if $ENV{$env} && !$self->val($section, $parameter, undef);
171             }
172              
173             sub files {
174 0     0   0 my ($self) = @_;
175 0 0       0 return $self->{files}->[-1] unless wantarray;
176 0         0 return @{ $self->{files} };
  0         0  
177             }
178              
179             sub file {
180 0     0   0 goto &files; # for convenience
181             }
182              
183             sub set_file {
184 0     0   0 my ( $self, $file ) = @_;
185 0 0       0 if ( $self->{files}->[0] eq '' ) {
186 0         0 $self->{files} = [];
187             }
188 0         0 push( @{ $self->{files} }, $file );
  0         0  
189             }
190              
191             sub app {
192 0     0   0 my ($self) = @_;
193 0         0 $self->{app};
194             }
195              
196             sub new {
197 6     6   37 my ($package, $app, $file) = @_;
198 6         12 my $self = bless {}, $package;
199 6         44 $self->{files} = [ '' ];
200 6         13 $self->{data} = {};
201 6         8 $self->{app} = $app;
202 6 50       21 $self->load($file) if defined $file;
203 6         11 return $self;
204             }
205              
206             sub load {
207 0     0   0 my ($self, $file) = @_;
208              
209 0 0       0 open( my $fd, "<:encoding(utf-8)", $file )
210             or Carp::croak("Error opening config $file: $!\n");
211              
212 0         0 $self->set_file($file);
213              
214 0         0 my $section = "global";
215 0         0 my $fail;
216 0         0 while ( <$fd> ) {
217 0         0 chomp;
218 0 0       0 next unless /\S/;
219 0 0       0 next if /^[#;]/;
220 0 0       0 if ( /^\s*\[\s*(.*?)\s*\]\s*$/ ) {
221 0         0 $section = lc $1;
222 0         0 next;
223             }
224 0 0       0 if ( /^\s*(.*?)\s*=\s*(.*?)\s*$/ ) {
225 0         0 $self->{data}->{ _key($section, lc($1)) } = $2;
226 0         0 next;
227             }
228 0         0 Carp::cluck("Error in config $file, line $.:\n$_\n");
229 0         0 $fail++;
230             }
231 0 0       0 Carp::croak("Error processing config $file, aborted\n")
232             if $fail;
233              
234 0         0 $self;
235             }
236              
237             sub printconf {
238 0     0   0 my ( $self, $list ) = @_;
239 0 0       0 return unless @$list > 0;
240 0         0 foreach my $conf ( @$list ) {
241 0 0       0 unless ( $conf =~ /^(.+?):([^:]+)/ ) {
242 0         0 print STDOUT ("\n");
243 0         0 next;
244             }
245 0         0 my ($sec, $conf) = ($1, $2);
246 0         0 $sec =~ s/:+$//;
247 0         0 my $val = $self->val($sec, $conf, undef);
248 0 0       0 print STDOUT ($val) if defined $val;
249 0         0 print STDOUT ("\n");
250             }
251             }
252              
253             sub user_dir {
254 2     2   3 my ( $app, $item ) = @_;
255             {
256 2         3 local $SIG{__WARN__};
  2         4  
257 2         2 local $SIG{__DIE__};
258 2         3 eval { $app = $app->app };
  2         13  
259             }
260              
261 2 50       12 if ( $^O =~ /^mswin/i ) {
262             my $f = File::Spec->catpath( $ENV{HOMEDRIVE}, $ENV{HOMEPATH},
263 0         0 File::Spec->catfile( $app, $item ));
264              
265 0         0 return $f;
266             }
267 2 50       105 File::Spec->catfile( glob("~"),
268             "." . lc( $app),
269             defined($item) ? $item : (),
270             );
271             }
272              
273             sub std_config {
274 8     8   8 my ( $app ) = @_;
275             {
276 8         7 local $SIG{__WARN__};
  8         17  
277 8         10 local $SIG{__DIE__};
278 8         8 eval { $app = $app->app };
  8         69  
279             }
280 8         65 lc($app) . ".conf";
281             }
282              
283             sub std_config_alt {
284 2     2   4 "." . &std_config;
285             }
286              
287             1;