line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Application::Config; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
36781
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
35
|
|
4
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
32
|
|
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
1309
|
use Config::Tiny; |
|
1
|
|
|
|
|
1052
|
|
|
1
|
|
|
|
|
27
|
|
7
|
1
|
|
|
1
|
|
480382
|
use File::HomeDir; |
|
1
|
|
|
|
|
10309
|
|
|
1
|
|
|
|
|
153
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
our $VERSION = '0.5'; |
10
|
|
|
|
|
|
|
our $CONFIG = {}; |
11
|
|
|
|
|
|
|
our $FILE = {}; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub import { |
14
|
4
|
|
|
4
|
|
24
|
my $class = shift; |
15
|
4
|
|
|
|
|
5
|
my $cfgfile = shift; |
16
|
4
|
|
|
|
|
5
|
my $pkg = shift; |
17
|
|
|
|
|
|
|
|
18
|
4
|
100
|
|
|
|
11
|
if (!$pkg) { |
19
|
3
|
|
|
|
|
11
|
($pkg, undef, undef) = caller(); |
20
|
|
|
|
|
|
|
} |
21
|
|
|
|
|
|
|
|
22
|
4
|
100
|
|
|
|
9
|
if (!$cfgfile) { |
23
|
2
|
|
|
|
|
8
|
my $cfgpkg = substr($pkg, rindex($pkg, ':') + 1); |
24
|
2
|
|
|
|
|
6
|
$cfgfile = lc($cfgpkg) . ".conf" ; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
{ |
28
|
1
|
|
|
1
|
|
7
|
no strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
226
|
|
|
4
|
|
|
|
|
6
|
|
29
|
|
|
|
|
|
|
|
30
|
4
|
|
|
|
|
23
|
*{$pkg."::config"} = sub { |
31
|
5
|
100
|
|
5
|
|
5666
|
return $CONFIG{$pkg} if $CONFIG{$pkg}; |
32
|
4
|
|
|
|
|
44
|
my @paths = ( |
33
|
|
|
|
|
|
|
File::Spec->catfile( File::HomeDir->my_home, ".$cfgfile" ), |
34
|
|
|
|
|
|
|
".$cfgfile", |
35
|
|
|
|
|
|
|
"./etc/$cfgfile", |
36
|
|
|
|
|
|
|
"/etc/$cfgfile" |
37
|
|
|
|
|
|
|
); |
38
|
4
|
|
|
|
|
220
|
foreach my $path (@paths) { |
39
|
12
|
100
|
|
|
|
126
|
if (-e $path) { |
40
|
4
|
|
|
|
|
9
|
$FILE{$pkg} = $path; |
41
|
4
|
|
|
|
|
22
|
return $CONFIG{$pkg} = Config::Tiny->read( $path ); |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
} |
44
|
0
|
|
|
|
|
0
|
return {}; |
45
|
4
|
|
|
|
|
25
|
}; |
46
|
|
|
|
|
|
|
|
47
|
4
|
|
|
|
|
17
|
*{$pkg.'::configfile'} = sub { |
48
|
0
|
|
|
0
|
|
0
|
return $FILE{$pkg}; |
49
|
4
|
|
|
|
|
9
|
}; |
50
|
|
|
|
|
|
|
|
51
|
4
|
|
|
|
|
1941
|
*{$pkg."::pkgconfig"} = sub { |
52
|
1
|
|
|
1
|
|
971
|
my ($package, $filename, $line) = caller; |
53
|
1
|
|
50
|
|
|
5
|
return $pkg->config->{$package} || {}; |
54
|
4
|
|
|
|
|
14
|
}; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=head1 NAME |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
Application::Config - configuration for applications that makes less work |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=head1 SYNOPSIS |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
package Foo; |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
use Application::Config; |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
package Some::Other::Package; |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
my $config = Foo->config; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=head1 DESCRIPTION |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
I find myself writing methods that fetch a config file for an application from |
76
|
|
|
|
|
|
|
disk and return it all the time. I come from the small-tools loosely joined school of thought, |
77
|
|
|
|
|
|
|
which means I'm writing little applications all the time. This really sucks. Application::Config solves that problem |
78
|
|
|
|
|
|
|
for me. It might solve it for you. Who knows. |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=head1 USAGE |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
When Application::Config is imported into a package it creates a two class |
83
|
|
|
|
|
|
|
methods for the package. The first, config, returns a Config::Tiny object |
84
|
|
|
|
|
|
|
for the entire config file. The second, pkgconfig, returns a hash reference |
85
|
|
|
|
|
|
|
that contains the part of the config file relevent to the calling package. For |
86
|
|
|
|
|
|
|
example the config file: |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
foo=bar |
89
|
|
|
|
|
|
|
baz=bash |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
[My::Test::Class] |
92
|
|
|
|
|
|
|
foo=baz |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
Would result in the config method returning a data structure that looks |
95
|
|
|
|
|
|
|
something like: |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
{ |
98
|
|
|
|
|
|
|
'_' => { |
99
|
|
|
|
|
|
|
'foo' => 'bar', |
100
|
|
|
|
|
|
|
'baz' => 'bash' |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
'My::Test::Class' => { |
103
|
|
|
|
|
|
|
'foo' => 'baz' |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
Calling pkgconfig from the My::Test::Class package would return only the |
108
|
|
|
|
|
|
|
structure under the C key. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=head1 WHERE ARE THE CONFIG FILES ON DISK? |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
Application config looks, in this order, for a config file: |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=over 4 |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=item ~/. |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=item ./. |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=item ./etc/ |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=item /etc/ |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=back |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
The actual filename varies based on the name of the package requiring the |
127
|
|
|
|
|
|
|
Application::Config module. For example the code: |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
package MyPackage; |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
use Application::Config; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
would look for the filename mypackage.conf (or .mypackage.conf in the first |
134
|
|
|
|
|
|
|
instance). |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
package Another::MyPackage; |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
use Application::Config; |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
Would look for the same config file. This can be altered by providing an |
141
|
|
|
|
|
|
|
argument to the Application::Config require line: |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
package Another::MyPackage; |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
use Application::Config 'myconfigfile.conf'; |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=head1 INSTALLING THE METHODS INTO ANOTHER PACKAGE |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
All three of these uses would install the C and C methods |
150
|
|
|
|
|
|
|
into the requiring package. If you'd like the methods to be installed |
151
|
|
|
|
|
|
|
somewhere else, you can simply add a second argument to the require line that |
152
|
|
|
|
|
|
|
is the package to install the methods in. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=head1 SEE ALSO |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
L |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=head1 AUTHOR |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
James A. Duncan |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
Contributions from Scott McWhirter |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=head1 LICENSE |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
This module is released under the MIT license |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=cut |