File Coverage

lib/App/Conf/File.pm
Criterion Covered Total %
statement 67 90 74.4
branch 26 70 37.1
condition 7 19 36.8
subroutine 4 4 100.0
pod 1 1 100.0
total 105 184 57.0


line stmt bran cond sub pod time code
1              
2             #############################################################################
3             ## $Id: File.pm 3666 2006-03-11 20:34:10Z spadkins $
4             #############################################################################
5              
6             package App::Conf::File;
7             $VERSION = (q$Revision: 3666 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers generated by svn
8              
9 7     7   2671 use App;
  7         14  
  7         159  
10 7     7   2974 use App::Conf;
  7         24  
  7         271  
11             @ISA = ( "App::Conf" );
12              
13 7     7   34 use strict;
  7         14  
  7         9008  
14              
15             sub create {
16 6     6 1 17 my $self = shift;
17              
18 6         10 my ($options);
19 6 50 33     2199 if ($#_ >= 0 && ref($_[0]) eq "HASH") {
    0 0        
20 6         20 $options = $_[0];
21             }
22             elsif ($#_ >= 0 && $#_ % 2 == 1) {
23 0         0 $options = { @_ };
24             }
25             else {
26 0         0 $options = {};
27             }
28              
29 6         14 my @conf_file = ();
30 6         10 my ($app, $conf_type, $conf_file);
31 6         22 $conf_file = $options->{conf_file};
32 6 100       23 if (defined $conf_file) {
33 4 100       17 if ($conf_file) {
34 1         11 @conf_file = ( $conf_file );
35 1         2 $conf_type = "pl";
36 1 50       16 if ($conf_file =~ /\.([^\.]+)$/) {
37 1         2 $conf_type = $1;
38             }
39             # if a config file is specified, it must exist
40 1 50       25 if (! -r $conf_file) {
41 0         0 App::Exception::Conf->throw(
42             error => "create(): [$conf_file] $!\n"
43             );
44             }
45             }
46             }
47             else {
48             #################################################################
49             # 3. find the directory the program was run from
50             # we will use this directory to search for the
51             # initialization configuration file.
52             #################################################################
53 2         7 my $prog_dir = $0; # start with the full script path
54 2         5 $prog_dir =~ s!\\!/!g; # convert to POSIX-compliant "/" path
55 2 50       15 if ($prog_dir =~ m!^([a-z]:)?/!i) { # absolute path
56             # i.e. /usr/local/bin/app, /app
57 0         0 $prog_dir =~ s!/[^/]+$!!; # trim off the program name
58             }
59             else { # relative path
60             # i.e. app, ./app, ../bin/app, bin/app
61 2         12 $prog_dir =~ s!/?[^/]+$!!; # trim off the program name
62 2 50       8 $prog_dir = "." if (!$prog_dir); # if nothing left, directory is current dir
63             }
64              
65             #################################################################
66             # 4. find the base "prefix" directory for the entire
67             # software installation.
68             #################################################################
69 2         4 my $prefix = $options->{prefix};
70              
71             #################################################################
72             # 5. Define the standard places to look for a conf file
73             #################################################################
74 2   50     14 $app = $options->{app} || "app";
75 2   50     18 $conf_type = $options->{conf_type} || "pl";
76 2         3 my $prog_suffix = "";
77 2 50       13 if ($0 =~ /\.([a-z]+)$/i) {
78 2         7 $prog_suffix = lc($1);
79             }
80 2 50 33     16 push(@conf_file, "$ENV{HOME}/.app/$app.$conf_type") if ($ENV{HOME} && $app ne "app");
81 2 50 33     17 push(@conf_file, "$prog_dir/$app.$conf_type") if ($app ne "app" && $conf_type ne $prog_suffix);
82 2 50       6 push(@conf_file, "$prefix/etc/app/$app.$conf_type") if ($app ne "app");
83 2 50       10 push(@conf_file, "$ENV{HOME}/.app/app.$conf_type") if ($ENV{HOME});
84 2 50       16 push(@conf_file, "$prog_dir/app.$conf_type") if ($conf_type ne $prog_suffix);
85 2         45 push(@conf_file, "$prefix/etc/app/app.$conf_type");
86 2         7 push(@conf_file, "/etc/app/app.$conf_type");
87             }
88              
89             #################################################################
90             # 6. now actually read in the file
91             #################################################################
92              
93 6         15 local(*FILE);
94 6         21 my (@text, $text, $serializer_class);
95 6         48 my $conf = {};
96 6         29 while ($#conf_file > -1) {
97 5         10 $conf_file = shift(@conf_file);
98 5 50       20 print STDERR "Looking for conf_file [$conf_file]\n" if ($options->{debug_conf});
99 5 100       157 if (open(App::FILE, "< $conf_file")) {
100 3 50       17 print STDERR "Found conf_file [$conf_file]\n" if ($options->{debug_conf});
101 3         8 @conf_file = (); # don't look any farther
102 3         162 @text = ;
103 3         34 close(App::FILE);
104 3         27 $text = join("",@text);
105             #$text =~ /^(.*)/s;
106             #$text = $1;
107              
108             # Now do substitutions for {:var:} or {:var=default:} in the config file to the value in the options file
109             # (we really should do this only for text file types)
110 3 0       14 $text =~ s/\{:([a-zA-Z0-9_]+)(=?)([^:\{\}]*):\}/(defined $options->{$1} ? $options->{$1} : ($2 ? $3 : $1))/eg;
  0 0       0  
111              
112 3         6 $serializer_class = $options->{conf_serializer_class};
113              
114 3 50       10 if (!$serializer_class) {
115 3 50       11 if ($conf_type eq "pl") {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
116 3         5 $serializer_class = ""; # don't bother with a serializer
117             }
118             elsif ($conf_type eq "perl") {
119 0         0 $serializer_class = "App::Serializer::Perl";
120             }
121             elsif ($conf_type eq "stor") {
122 0         0 $serializer_class = "App::Serializer::Storable";
123             }
124             elsif ($conf_type eq "xml") {
125 0         0 $serializer_class = "App::Serializer::Xml";
126             }
127             elsif ($conf_type eq "ini") {
128 0         0 $serializer_class = "App::Serializer::Ini";
129             }
130             elsif ($conf_type eq "properties") {
131 0         0 $serializer_class = "App::Serializer::Properties";
132             }
133             elsif ($conf_type eq "conf") {
134 0         0 $serializer_class = "App::Serializer::Properties";
135             }
136             elsif ($conf_type eq "yaml") {
137 0         0 $serializer_class = "App::Serializer::Yaml";
138             }
139             elsif ($conf_type) {
140 0         0 my $serializer = ucfirst($conf_type);
141 0         0 $serializer_class = "App::Serializer::$serializer";
142             }
143             else {
144 0         0 $serializer_class = "App::Serializer";
145             }
146             }
147              
148 3 50       8 if ($serializer_class) {
149 0         0 eval "use $serializer_class;";
150 0 0       0 if ($@) {
151 0         0 App::Exception::Conf->throw(
152             error => "create(): error loading $serializer_class serializer class: $@\n"
153             );
154             }
155 0         0 $conf = $serializer_class->deserialize($text);
156 0 0       0 if (! %$conf) {
157 0         0 App::Exception::Conf->throw(
158             error => "create(): $serializer_class produced empty config\n"
159             );
160             }
161             }
162             else { # don't bother with a serializer
163 3         5 $conf = {};
164 3 50       28 if ($text =~ /^[ \t\n]*\$[a-zA-Z][a-zA-Z0-9_]* *= *(\{.*\};[ \n]*)$/s) {
165 3         12 $text = "\$conf = $1"; # untainted now
166 3         444 eval($text);
167 3 50       25 if ($@) {
168 0         0 App::Exception::Conf->throw(
169             error => "create(): [$conf_file] error eval'ing config text: $@\n"
170             );
171             }
172             }
173             else {
174 0         0 App::Exception::Conf->throw(
175             error => "create(): [$conf_file] config text doesn't match '\$var = {...};'\n"
176             );
177             }
178             }
179             }
180             }
181            
182 6 100 66     57 if ($options->{conf} && ref($options->{conf}) eq "HASH") {
183 3         24 App::Reference->overlay($conf, $options->{conf});
184             }
185              
186 6         39 $conf;
187             }
188              
189             1;
190