File Coverage

blib/lib/App/CELL/Config.pm
Criterion Covered Total %
statement 57 78 73.0
branch 28 62 45.1
condition n/a
subroutine 12 15 80.0
pod 5 5 100.0
total 102 160 63.7


line stmt bran cond sub pod time code
1             # *************************************************************************
2             # Copyright (c) 2014-2020, SUSE LLC
3             #
4             # All rights reserved.
5             #
6             # Redistribution and use in source and binary forms, with or without
7             # modification, are permitted provided that the following conditions are met:
8             #
9             # 1. Redistributions of source code must retain the above copyright notice,
10             # this list of conditions and the following disclaimer.
11             #
12             # 2. Redistributions in binary form must reproduce the above copyright
13             # notice, this list of conditions and the following disclaimer in the
14             # documentation and/or other materials provided with the distribution.
15             #
16             # 3. Neither the name of SUSE LLC nor the names of its contributors may be
17             # used to endorse or promote products derived from this software without
18             # specific prior written permission.
19             #
20             # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21             # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22             # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23             # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24             # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25             # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26             # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27             # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28             # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29             # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30             # POSSIBILITY OF SUCH DAMAGE.
31             # *************************************************************************
32              
33             package App::CELL::Config;
34              
35 14     14   911 use strict;
  14         33  
  14         316  
36 14     14   55 use warnings;
  14         25  
  14         237  
37 14     14   187 use 5.012;
  14         46  
38              
39 14     14   4859 use App::CELL::Log qw( $log );
  14         29  
  14         1263  
40 14     14   5196 use App::CELL::Status;
  14         37  
  14         428  
41             #use Data::Dumper;
42 14     14   79 use Scalar::Util qw( blessed );
  14         23  
  14         691  
43              
44             =head1 NAME
45              
46             App::CELL::Config -- load, store, and dispense meta parameters, core
47             parameters, and site parameters
48              
49              
50              
51             =head1 SYNOPSIS
52            
53             use App::CELL::Config qw( $meta $core $site );
54              
55             # get a parameter value (returns value or undef)
56             my $value;
57             $value = $meta->MY_PARAM;
58             $value = $core->MY_PARAM;
59             $value = $site->MY_PARAM;
60              
61             # set a meta parameter
62             $meta->set( 'MY_PARAM', 42 );
63              
64             # set an as-yet undefined core/site parameter
65             $core->set( 'MY_PARAM', 42 );
66             $site->set( 'MY_PARAM', 42 );
67              
68              
69              
70             =head1 DESCRIPTION
71              
72             The purpose of the L module is to maintain and provide
73             access to three package variables, C<$meta>, C<$core>, and C<$site>, which
74             are actually singleton objects, containing configuration parameters loaded
75             by L from files in the distro sharedir and the site
76             configuration directory, if any.
77              
78             For details, read L.
79              
80              
81              
82             =head1 EXPORTS
83              
84             This module exports three scalars: the 'singleton' objects C<$meta>,
85             C<$core>, and C<$site>.
86              
87             =cut
88              
89 14     14   74 use Exporter qw( import );
  14         19  
  14         13176  
90             our @EXPORT_OK = qw( $meta $core $site );
91              
92             our $meta = bless { CELL_CONFTYPE => 'meta' }, __PACKAGE__;
93             our $core = bless { CELL_CONFTYPE => 'core' }, __PACKAGE__;
94             our $site = bless { CELL_CONFTYPE => 'site' }, __PACKAGE__;
95              
96              
97              
98             =head1 SUBROUTINES
99              
100              
101             =head2 AUTOLOAD
102              
103             The C routine handles calls that look like this:
104             $meta->MY_PARAM
105             $core->MY_PARAM
106             $site->MY_PARAM
107              
108             =cut
109              
110             our $AUTOLOAD;
111             sub AUTOLOAD {
112 519     519   6622 my $self = shift;
113 519         2078 ( my $param ) = $AUTOLOAD =~ m/.*::(.*)$/;
114 519 50       1061 return SUPER->DESTROY if $param eq 'DESTROY'; # for Perl <= 5.012
115 519         1107 my ( undef, $file, $line ) = caller;
116 519 50       1371 die "Bad call to Config.pm \$$param at $file line $line!" if not blessed $self;
117 519         936 return _retrieve_param( $self->{'CELL_CONFTYPE'}, $param );
118             }
119              
120             sub _retrieve_param {
121 521     521   825 my ( $type, $param ) = @_;
122 521 100       825 if ( $type eq 'meta' ) {
    100          
    50          
123             return (exists $meta->{$param})
124             ? $meta->{$param}->{Value}
125 496 100       2719 : undef;
126             } elsif ( $type eq 'core' ) {
127             return (exists $core->{$param})
128             ? $core->{$param}->{Value}
129 4 50       22 : undef;
130             } elsif ( $type eq 'site' ) {
131 21 100       58 if (exists $site->{$param}) {
    100          
132 11         45 return $site->{$param}->{Value};
133             } elsif (exists $core->{$param}) {
134 9         40 return $core->{$param}->{Value};
135             }
136             }
137 1         5 return;
138             }
139              
140              
141             =head2 DESTROY
142              
143             For some reason, Perl 5.012 seems to want a DESTROY method
144              
145             =cut
146              
147             sub DESTROY {
148 0     0   0 my $self = shift;
149 0 0       0 $self->SUPER::DESTROY if $self->can("SUPER::DESTROY");
150             }
151              
152              
153             =head2 exists
154              
155             Determine parameter existence.
156              
157             =cut
158              
159             sub exists {
160 2     2 1 584 my ( $self, $param ) = @_;
161 2         5 my $type = $self->{'CELL_CONFTYPE'};
162              
163 2         3 my $bool;
164 2 50       7 if ( $type eq 'meta' ) {
    0          
    0          
165 2         5 $bool = exists $meta->{ $param };
166             } elsif ( $type eq 'core' ) {
167 0         0 $bool = exists $core->{ $param };
168             } elsif ( $type eq 'site' ) {
169 0         0 $bool = exists $site->{ $param };
170 0 0       0 if ( ! $bool ) {
171 0         0 $bool = exists $core->{ $param };
172             }
173             } else {
174 0         0 die "AAAAAAAAAAGGAHHAGHHG! improper param type in exists routine";
175             }
176 2         8 return $bool;
177             }
178              
179              
180             =head2 get
181              
182             Wrapper for get_param
183              
184             =cut
185              
186             sub get {
187 0     0 1 0 my ( $self, $param ) = @_;
188 0         0 return $self->get_param( $param );
189             }
190              
191              
192             =head2 get_param
193              
194             Get value of config param provided in the argument.
195              
196             =cut
197              
198             sub get_param {
199 2     2 1 239 my ( $self, $param ) = @_;
200 2         8 my ( undef, $file, $line ) = caller;
201 2 50       12 die "Bad call to Config.pm \$$param at $file line $line!" if not blessed $self;
202 2         7 return _retrieve_param( $self->{'CELL_CONFTYPE'}, $param );
203             }
204              
205              
206             =head2 get_param_metadata
207              
208             Routine to provide access not only to the value, but also to the metadata
209             (file and line number where parameter was defined) associated with a
210             given parameter.
211              
212             Takes: parameter name. Returns: reference to the hash associated with the
213             given parameter, or undef if no parameter found.
214              
215             =cut
216              
217             sub get_param_metadata {
218 0     0 1 0 my ( $self, $param ) = @_;
219 0         0 my ( undef, $file, $line ) = caller;
220 0 0       0 die "Bad call to Config.pm \$$param at $file line $line!" if not blessed $self;
221 0         0 my $type = $self->{'CELL_CONFTYPE'};
222 0 0       0 if ( $type eq 'meta' ) {
    0          
    0          
223             return (exists $meta->{$param})
224 0 0       0 ? $meta->{$param}
225             : undef;
226             } elsif ( $type eq 'core' ) {
227             return (exists $core->{$param})
228 0 0       0 ? $core->{$param}
229             : undef;
230             } elsif ( $type eq 'site' ) {
231 0 0       0 if (exists $site->{$param}) {
    0          
232 0         0 return $site->{$param};
233             } elsif (exists $core->{$param}) {
234 0         0 return $core->{$param};
235             }
236             }
237 0         0 return;
238             }
239              
240              
241             =head2 set
242              
243             Use this function to set new params (meta/core/site) or change existing
244             ones (meta only). Takes two arguments: parameter name and new value.
245             Returns a status object.
246              
247             =cut
248              
249             sub set {
250 42     42 1 1915 my ( $self, $param, $value ) = @_;
251 42 50       169 return App::CELL::Status->not_ok if not blessed $self;
252 42         184 my %ARGS = (
253             level => 'OK',
254             caller => [ CORE::caller() ],
255             );
256 42 100       225 if ( $self->{'CELL_CONFTYPE'} eq 'meta' ) {
    100          
    50          
257 22 100       72 if ( exists $meta->{$param} ) {
258 11 50       61 %ARGS = (
259             %ARGS,
260             code => 'CELL_OVERWRITE_META_PARAM',
261             args => [ $param, ( defined( $value ) ? $value : 'undef' ) ],
262             );
263             #$log->debug( "Overwriting \$meta->$param with ->$value<-", cell => 1 );
264             } else {
265             #$log->debug( "Setting new \$meta->$param to ->$value<-", cell => 1 );
266             }
267 22         133 $meta->{$param} = {
268             'File' => (caller)[1],
269             'Line' => (caller)[2],
270             'Value' => $value,
271             };
272             } elsif ( $self->{'CELL_CONFTYPE'} eq 'core' ) {
273 1 50       4 if ( exists $core->{$param} ) {
274 1         8 %ARGS = (
275             %ARGS,
276             level => 'ERR',
277             code => 'CELL_PARAM_EXISTS_IMMUTABLE',
278             args => [ 'Core', $param ],
279             );
280             } else {
281 0         0 $core->{$param} = {
282             'File' => (caller)[1],
283             'Line' => (caller)[2],
284             'Value' => $value,
285             };
286             }
287             } elsif ( $self->{'CELL_CONFTYPE'} eq 'site' ) {
288 19 100       58 if ( exists $site->{$param} ) {
289 1         7 %ARGS = (
290             %ARGS,
291             level => 'ERR',
292             code => 'CELL_PARAM_EXISTS_IMMUTABLE',
293             args => [ 'Site', $param ],
294             );
295             } else {
296 18         115 $site->{$param} = {
297             'File' => (caller)[1],
298             'Line' => (caller)[2],
299             'Value' => $value,
300             };
301             }
302             }
303 42         223 return App::CELL::Status->new( %ARGS );
304             }
305              
306             # END OF App::CELL::Config MODULE
307             1;