line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package XT::Files; |
2
|
|
|
|
|
|
|
|
3
|
32
|
|
|
32
|
|
2142813
|
use 5.006; |
|
32
|
|
|
|
|
343
|
|
4
|
32
|
|
|
32
|
|
165
|
use strict; |
|
32
|
|
|
|
|
61
|
|
|
32
|
|
|
|
|
748
|
|
5
|
32
|
|
|
32
|
|
165
|
use warnings; |
|
32
|
|
|
|
|
53
|
|
|
32
|
|
|
|
|
1638
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.001'; |
8
|
|
|
|
|
|
|
|
9
|
32
|
|
|
32
|
|
13653
|
use Class::Tiny 1; |
|
32
|
|
|
|
|
49905
|
|
|
32
|
|
|
|
|
156
|
|
10
|
|
|
|
|
|
|
|
11
|
32
|
|
|
32
|
|
15258
|
use Role::Tiny::With (); |
|
32
|
|
|
|
|
154962
|
|
|
32
|
|
|
|
|
885
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
Role::Tiny::With::with 'XT::Files::Role::Logger'; |
14
|
|
|
|
|
|
|
|
15
|
32
|
|
|
32
|
|
201
|
use Carp (); |
|
32
|
|
|
|
|
67
|
|
|
32
|
|
|
|
|
429
|
|
16
|
32
|
|
|
32
|
|
149
|
use File::Basename (); |
|
32
|
|
|
|
|
54
|
|
|
32
|
|
|
|
|
409
|
|
17
|
32
|
|
|
32
|
|
142
|
use File::Find (); |
|
32
|
|
|
|
|
60
|
|
|
32
|
|
|
|
|
401
|
|
18
|
32
|
|
|
32
|
|
14725
|
use Module::Load (); |
|
32
|
|
|
|
|
33783
|
|
|
32
|
|
|
|
|
646
|
|
19
|
32
|
|
|
32
|
|
216
|
use Scalar::Util (); |
|
32
|
|
|
|
|
57
|
|
|
32
|
|
|
|
|
595
|
|
20
|
32
|
|
|
32
|
|
12393
|
use version 0.77 (); |
|
32
|
|
|
|
|
58437
|
|
|
32
|
|
|
|
|
968
|
|
21
|
|
|
|
|
|
|
|
22
|
32
|
|
|
32
|
|
12798
|
use XT::Files::File; |
|
32
|
|
|
|
|
93
|
|
|
32
|
|
|
|
|
1878
|
|
23
|
|
|
|
|
|
|
|
24
|
32
|
|
|
32
|
|
220
|
use constant MODULE_NAME_RX => qr{ ^ [A-Za-z_] [0-9A-Za-z_]* (?: :: [0-9A-Za-z_]+ )* $ }xs; ## no critic (RegularExpressions::RequireLineBoundaryMatching) |
|
32
|
|
|
|
|
61
|
|
|
32
|
|
|
|
|
72110
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# |
27
|
|
|
|
|
|
|
# CLASS METHODS |
28
|
|
|
|
|
|
|
# |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub BUILD { |
31
|
48
|
|
|
48
|
0
|
39694
|
my ( $self, $args ) = @_; |
32
|
|
|
|
|
|
|
|
33
|
48
|
|
|
|
|
224
|
$self->{_excludes} = []; |
34
|
48
|
|
|
|
|
163
|
$self->{_file} = {}; |
35
|
|
|
|
|
|
|
|
36
|
48
|
100
|
|
|
|
173
|
if ( exists $args->{'-config'} ) { |
37
|
41
|
100
|
|
|
|
167
|
if ( defined $args->{'-config'} ) { |
38
|
11
|
|
|
|
|
29
|
$self->_load_config( $args->{'-config'} ); |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# -config exists but is not defined, no configuration requested |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
else { |
44
|
|
|
|
|
|
|
# We did not get "config => undef" and therefore try to load the |
45
|
|
|
|
|
|
|
# default config file |
46
|
7
|
|
|
|
|
29
|
$self->_load_default_config(); |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
40
|
|
|
|
|
105
|
return; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
{ |
53
|
|
|
|
|
|
|
# The XT::Files singleton |
54
|
|
|
|
|
|
|
my $xtf; |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub initialize { |
57
|
5
|
|
|
5
|
1
|
97
|
my $class = shift; |
58
|
|
|
|
|
|
|
|
59
|
5
|
100
|
|
|
|
13
|
Carp::croak( __PACKAGE__ . q{ is already initialized} ) if $class->_is_initialized; |
60
|
|
|
|
|
|
|
|
61
|
4
|
|
|
|
|
43
|
$xtf = $class->new(@_); |
62
|
4
|
|
|
|
|
21
|
return $xtf; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub instance { |
66
|
4
|
|
|
4
|
1
|
11
|
my ($class) = @_; |
67
|
|
|
|
|
|
|
|
68
|
4
|
100
|
|
|
|
13
|
if ( !$class->_is_initialized ) { |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
# ignore args |
71
|
3
|
|
|
|
|
9
|
$class->initialize; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
4
|
|
|
|
|
14
|
return $xtf; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub _is_initialized { |
78
|
45
|
|
|
45
|
|
18745
|
my ($class) = @_; |
79
|
|
|
|
|
|
|
|
80
|
45
|
100
|
|
|
|
437
|
return 1 if defined $xtf; |
81
|
40
|
|
|
|
|
253
|
return; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# |
86
|
|
|
|
|
|
|
# OBJECT METHODS |
87
|
|
|
|
|
|
|
# |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub plugin { |
90
|
28
|
|
|
28
|
1
|
21651
|
my ( $self, $plugin_name, $plugin_version, $keyvals_ref ) = @_; |
91
|
|
|
|
|
|
|
|
92
|
28
|
|
|
|
|
78
|
my $plugin_pkg = $self->_expand_config_plugin_name($plugin_name); |
93
|
|
|
|
|
|
|
|
94
|
27
|
|
|
|
|
115
|
Module::Load::load($plugin_pkg); |
95
|
|
|
|
|
|
|
|
96
|
26
|
100
|
|
|
|
673
|
if ( defined $plugin_version ) { |
97
|
6
|
100
|
|
|
|
20
|
$self->log_fatal("Not a valid version '$plugin_version'") if !version::is_lax($plugin_version); |
98
|
5
|
100
|
|
|
|
192
|
$self->log_fatal( "$plugin_pkg version $plugin_version required--this is only version " . $plugin_pkg->VERSION ) if version->parse( $plugin_pkg->VERSION ) < version->parse($plugin_version); |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
24
|
100
|
|
|
|
294
|
$self->log_fatal("$plugin_pkg doesn't have a run method") if !$plugin_pkg->can('run'); |
102
|
23
|
100
|
|
|
|
145
|
$self->log_fatal("$plugin_pkg doesn't have a new method") if !$plugin_pkg->can('new'); |
103
|
|
|
|
|
|
|
|
104
|
22
|
|
|
|
|
92
|
my $plugin = $plugin_pkg->new( xtf => $self ); |
105
|
|
|
|
|
|
|
|
106
|
22
|
|
|
|
|
179
|
$plugin->run($keyvals_ref); |
107
|
|
|
|
|
|
|
|
108
|
22
|
|
|
|
|
117
|
return; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub files { |
112
|
20
|
|
|
20
|
1
|
4860
|
my ($self) = @_; |
113
|
|
|
|
|
|
|
|
114
|
20
|
|
|
|
|
41
|
my $exclude_regex; |
115
|
20
|
|
|
|
|
31
|
my @excludes = @{ $self->{_excludes} }; |
|
20
|
|
|
|
|
70
|
|
116
|
20
|
100
|
|
|
|
66
|
if (@excludes) { |
117
|
6
|
|
|
|
|
17
|
$exclude_regex = join q{|}, @excludes; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
20
|
|
|
|
|
38
|
my @result; |
121
|
|
|
|
|
|
|
RESULT_FILE: |
122
|
20
|
|
|
|
|
31
|
for my $name ( sort keys %{ $self->{_file} } ) { |
|
20
|
|
|
|
|
103
|
|
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# skip ignored files |
125
|
54
|
100
|
|
|
|
110
|
next RESULT_FILE if !defined $self->{_file}->{$name}; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# skip excluded files |
128
|
50
|
100
|
100
|
|
|
593
|
next RESULT_FILE if defined $exclude_regex && File::Basename::fileparse($name) =~ $exclude_regex; |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# skip non-existing files |
131
|
43
|
100
|
|
|
|
502
|
next RESULT_FILE if !-e $name; |
132
|
|
|
|
|
|
|
|
133
|
42
|
|
|
|
|
138
|
push @result, $self->{_file}->{$name}; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
20
|
|
|
|
|
175
|
return @result; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# |
140
|
|
|
|
|
|
|
# File |
141
|
|
|
|
|
|
|
# |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
sub bin_file { |
144
|
26
|
|
|
26
|
1
|
1518
|
my ( $self, $name ) = @_; |
145
|
|
|
|
|
|
|
|
146
|
26
|
|
|
|
|
207
|
my $file = XT::Files::File->new( name => $name, is_script => 1 ); |
147
|
26
|
|
|
|
|
167
|
$self->file( $name, $file ); |
148
|
26
|
|
|
|
|
53
|
return; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
sub file { |
152
|
93
|
|
|
93
|
1
|
395
|
my ( $self, $name, $file ) = @_; |
153
|
|
|
|
|
|
|
|
154
|
93
|
100
|
|
|
|
246
|
if ( @_ > 2 ) { |
155
|
71
|
100
|
|
|
|
150
|
if ( defined $file ) { |
156
|
67
|
100
|
66
|
|
|
577
|
$self->log_fatal(q{File is not of class 'XT::Files::File'}) if !defined Scalar::Util::blessed($file) || !$file->isa('XT::Files::File'); |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
70
|
|
|
|
|
215
|
$self->{_file}->{$name} = $file; |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
92
|
|
|
|
|
234
|
return $self->{_file}->{$name}; |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub ignore_file { |
166
|
3
|
|
|
3
|
1
|
4835
|
my ( $self, $name ) = @_; |
167
|
|
|
|
|
|
|
|
168
|
3
|
|
|
|
|
13
|
$self->file( $name, undef ); |
169
|
3
|
|
|
|
|
9
|
return; |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
sub module_file { |
173
|
21
|
|
|
21
|
1
|
54
|
my ( $self, $name ) = @_; |
174
|
|
|
|
|
|
|
|
175
|
21
|
|
|
|
|
129
|
my $file = XT::Files::File->new( name => $name, is_module => 1 ); |
176
|
21
|
|
|
|
|
161
|
$self->file( $name, $file ); |
177
|
21
|
|
|
|
|
49
|
return; |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub pod_file { |
181
|
10
|
|
|
10
|
1
|
37
|
my ( $self, $name ) = @_; |
182
|
|
|
|
|
|
|
|
183
|
10
|
|
|
|
|
65
|
my $file = XT::Files::File->new( name => $name, is_pod => 1 ); |
184
|
10
|
|
|
|
|
77
|
$self->file( $name, $file ); |
185
|
10
|
|
|
|
|
28
|
return; |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
sub remove_file { |
189
|
1
|
|
|
1
|
1
|
370
|
my ( $self, $name ) = @_; |
190
|
|
|
|
|
|
|
|
191
|
1
|
|
|
|
|
3
|
delete $self->{_file}->{$name}; |
192
|
1
|
|
|
|
|
4
|
return; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
sub test_file { |
196
|
8
|
|
|
8
|
1
|
34
|
my ( $self, $name ) = @_; |
197
|
|
|
|
|
|
|
|
198
|
8
|
|
|
|
|
65
|
my $file = XT::Files::File->new( name => $name, is_test => 1, is_script => 1 ); |
199
|
8
|
|
|
|
|
65
|
$self->file( $name, $file ); |
200
|
8
|
|
|
|
|
31
|
return; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# |
204
|
|
|
|
|
|
|
# Directory |
205
|
|
|
|
|
|
|
# |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
sub bin_dir { |
208
|
14
|
|
|
14
|
1
|
58
|
my ( $self, $name ) = @_; |
209
|
|
|
|
|
|
|
|
210
|
14
|
|
|
|
|
42
|
for my $file ( $self->_find_new_files($name) ) { |
211
|
21
|
|
|
|
|
52
|
$self->bin_file( $file, $name ); |
212
|
|
|
|
|
|
|
} |
213
|
|
|
|
|
|
|
|
214
|
14
|
|
|
|
|
44
|
return; |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub module_dir { |
218
|
9
|
|
|
9
|
1
|
26
|
my ( $self, $name ) = @_; |
219
|
|
|
|
|
|
|
|
220
|
9
|
|
|
|
|
26
|
for my $file ( $self->_find_new_files($name) ) { |
221
|
30
|
100
|
|
|
|
149
|
if ( $file =~ m{ [.] pm $ }xsm ) { |
|
|
100
|
|
|
|
|
|
222
|
17
|
|
|
|
|
50
|
$self->module_file( $file, $name ); |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
elsif ( $file =~ m{ [.] pod $ }xsm ) { |
225
|
6
|
|
|
|
|
22
|
$self->pod_file( $file, $name ); |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
|
229
|
9
|
|
|
|
|
30
|
return; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub test_dir { |
233
|
4
|
|
|
4
|
1
|
12
|
my ( $self, $name ) = @_; |
234
|
|
|
|
|
|
|
|
235
|
4
|
|
|
|
|
11
|
for my $file ( $self->_find_new_files($name) ) { |
236
|
6
|
100
|
|
|
|
26
|
if ( $file =~ m{ [.] t $ }xsm ) { |
237
|
3
|
|
|
|
|
12
|
$self->test_file( $file, $name ); |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
4
|
|
|
|
|
14
|
return; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
# |
245
|
|
|
|
|
|
|
# Excludes |
246
|
|
|
|
|
|
|
# |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
sub exclude { |
249
|
21
|
|
|
21
|
1
|
5438
|
my ( $self, $exclude ) = @_; |
250
|
|
|
|
|
|
|
|
251
|
21
|
|
|
|
|
33
|
push @{ $self->{_excludes} }, $exclude; |
|
21
|
|
|
|
|
52
|
|
252
|
21
|
|
|
|
|
41
|
return; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
# |
256
|
|
|
|
|
|
|
# PRIVATE METHODS |
257
|
|
|
|
|
|
|
# |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
sub _expand_config_plugin_name { |
260
|
31
|
|
|
31
|
|
153
|
my ( $self, $plugin_name ) = @_; |
261
|
|
|
|
|
|
|
|
262
|
31
|
|
|
|
|
53
|
my $package_name = $plugin_name; |
263
|
31
|
100
|
|
|
|
167
|
if ( $package_name !~ s{ ^ = }{}xsm ) { |
264
|
17
|
|
|
|
|
63
|
$package_name = "XT::Files::Plugin::$plugin_name"; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
31
|
100
|
|
|
|
209
|
$self->log_fatal("'$plugin_name' is not a valid plugin name") if $package_name !~ MODULE_NAME_RX; |
268
|
|
|
|
|
|
|
|
269
|
29
|
|
|
|
|
139
|
return $package_name; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
sub _find_new_files { |
273
|
32
|
|
|
32
|
|
5568
|
my ( $self, $dir ) = @_; |
274
|
|
|
|
|
|
|
|
275
|
32
|
|
|
|
|
49
|
my @files; |
276
|
|
|
|
|
|
|
|
277
|
32
|
100
|
|
|
|
607
|
if ( !-d $dir ) { |
278
|
10
|
|
|
|
|
76
|
$self->log_debug("Directory $dir does not exist or is not a directory"); |
279
|
10
|
|
|
|
|
31
|
return; |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
File::Find::find( |
283
|
|
|
|
|
|
|
{ |
284
|
|
|
|
|
|
|
no_chdir => 1, |
285
|
|
|
|
|
|
|
wanted => sub { |
286
|
97
|
100
|
100
|
97
|
|
3794
|
return if -l $File::Find::name || !-f _; |
287
|
64
|
|
|
|
|
809
|
push @files, $File::Find::name; |
288
|
|
|
|
|
|
|
}, |
289
|
|
|
|
|
|
|
}, |
290
|
22
|
|
|
|
|
1978
|
$dir, |
291
|
|
|
|
|
|
|
); |
292
|
|
|
|
|
|
|
|
293
|
22
|
|
|
|
|
120
|
@files = grep { !exists $self->{_file}->{$_} } @files; |
|
64
|
|
|
|
|
175
|
|
294
|
|
|
|
|
|
|
|
295
|
22
|
|
|
|
|
73
|
return @files; |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
sub _global_keyval { ## no critic (Subroutines::RequireFinalReturn) |
299
|
7
|
|
|
7
|
|
6429
|
my ( $self, $key, $value ) = @_; |
300
|
|
|
|
|
|
|
|
301
|
7
|
100
|
|
|
|
18
|
if ( $key eq ':version' ) { |
302
|
6
|
100
|
|
|
|
20
|
$self->log_fatal("Not a valid version '$value'") if !version::is_lax($value); |
303
|
4
|
100
|
|
|
|
259
|
$self->log_fatal( __PACKAGE__ . " version $value required--this is only version " . __PACKAGE__->VERSION ) if version->parse( __PACKAGE__->VERSION ) < version->parse($value); |
304
|
2
|
|
|
|
|
12
|
return; |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
|
307
|
1
|
|
|
|
|
7
|
$self->log_fatal("Invalid entry '$key = $value'"); |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
sub _load_config { |
311
|
18
|
|
|
18
|
|
1901
|
my ( $self, $config ) = @_; |
312
|
|
|
|
|
|
|
|
313
|
18
|
|
|
|
|
32
|
my $type_section = 1; |
314
|
18
|
|
|
|
|
23
|
my $type_keyval = 2; |
315
|
|
|
|
|
|
|
|
316
|
18
|
100
|
|
5
|
|
474
|
open my $fh, '<', $config or $self->log_fatal("Cannot read file '$config': $!"); |
|
5
|
|
|
|
|
35
|
|
|
5
|
|
|
|
|
7
|
|
|
5
|
|
|
|
|
33
|
|
317
|
|
|
|
|
|
|
|
318
|
16
|
|
|
|
|
3405
|
my $in_global_section = 1; |
319
|
16
|
|
|
|
|
32
|
my @lines; |
320
|
16
|
|
|
|
|
28
|
my $line_counter = 0; |
321
|
|
|
|
|
|
|
LINE: |
322
|
16
|
|
|
|
|
131
|
while ( defined( my $line = <$fh> ) ) { |
323
|
48
|
|
|
|
|
75
|
$line_counter++; |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# skip empty lines or comment |
326
|
48
|
100
|
|
|
|
182
|
next LINE if $line =~ m{ ^ \s* (?: [#;] | $ ) }xsm; |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
# remove leading whitespace |
329
|
40
|
|
|
|
|
188
|
$line =~ s{ ^ \s* }{}xsm; |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
# remove tailing whitespace |
332
|
40
|
|
|
|
|
190
|
$line =~ s{ \s* $ }{}xsm; |
333
|
|
|
|
|
|
|
|
334
|
40
|
100
|
|
|
|
113
|
if ( $line =~ m{ ^ \[ }xsm ) { |
335
|
12
|
100
|
|
|
|
66
|
$self->log_fatal("Syntax error in config on line $line_counter") if $line !~ m{ ^ \[ ( .+ ) \] $ }xsm; |
336
|
11
|
|
|
|
|
36
|
my $section = $1; ## no critic (RegularExpressions::ProhibitCaptureWithoutTest) |
337
|
11
|
|
|
|
|
33
|
push @lines, [ $type_section, $line_counter, $section ]; |
338
|
11
|
|
|
|
|
22
|
$in_global_section = 0; |
339
|
11
|
|
|
|
|
45
|
next LINE; |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
28
|
|
|
|
|
122
|
my ( $key, $value ) = split /\s*=\s*/xsm, $line, 2; |
343
|
28
|
100
|
66
|
|
|
196
|
$self->log_fatal("Syntax error in config on line $line_counter") if !defined $key || !defined $value || $key eq q{} || $value eq q{}; |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
344
|
|
|
|
|
|
|
# |
345
|
25
|
100
|
|
|
|
45
|
if ($in_global_section) { |
346
|
3
|
|
|
|
|
9
|
$self->_global_keyval( $key, $value ); |
347
|
1
|
|
|
|
|
4
|
next LINE; |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
22
|
|
|
|
|
131
|
push @lines, [ $type_keyval, $line_counter, $key, $value ]; |
351
|
|
|
|
|
|
|
} |
352
|
10
|
50
|
|
|
|
59
|
close $fh or $self->logger->log_fatal("Cannot read file '$config': $!"); |
353
|
|
|
|
|
|
|
|
354
|
10
|
|
|
|
|
32
|
while (@lines) { |
355
|
11
|
|
|
|
|
52
|
my $section = ${ $lines[0] }[2]; |
|
11
|
|
|
|
|
35
|
|
356
|
11
|
|
|
|
|
21
|
shift @lines; |
357
|
|
|
|
|
|
|
|
358
|
11
|
|
|
|
|
25
|
my @keyvals; |
359
|
|
|
|
|
|
|
my $plugin_version; |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
LINE_KEYVAL: |
362
|
11
|
|
|
|
|
34
|
while (@lines) { |
363
|
24
|
100
|
|
|
|
55
|
last LINE_KEYVAL if $lines[0][0] == $type_section; |
364
|
|
|
|
|
|
|
|
365
|
22
|
100
|
|
|
|
45
|
if ( $lines[0][2] eq ':version' ) { |
366
|
3
|
|
|
|
|
8
|
$plugin_version = $lines[0][3]; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
else { |
369
|
19
|
|
|
|
|
26
|
push @keyvals, [ @{ $lines[0] }[ 2, 3 ] ]; |
|
19
|
|
|
|
|
44
|
|
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
22
|
|
|
|
|
51
|
shift @lines; |
373
|
|
|
|
|
|
|
} |
374
|
|
|
|
|
|
|
|
375
|
11
|
|
|
|
|
49
|
$self->plugin( $section, $plugin_version, \@keyvals ); |
376
|
|
|
|
|
|
|
} |
377
|
|
|
|
|
|
|
|
378
|
10
|
|
|
|
|
161
|
return; |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
sub _load_default_config { |
382
|
7
|
|
|
7
|
|
18
|
my ($self) = @_; |
383
|
|
|
|
|
|
|
|
384
|
7
|
|
|
|
|
12
|
my $config; |
385
|
|
|
|
|
|
|
FILE: |
386
|
7
|
|
|
|
|
18
|
for my $file ( '.xtfilesrc', 'xtfiles.ini' ) { |
387
|
14
|
100
|
|
|
|
296
|
next FILE if !-e $file; |
388
|
4
|
100
|
|
|
|
33
|
$self->log_fatal("Multiple default config files found: '$config' and '$file'") if defined $config; |
389
|
3
|
|
|
|
|
10
|
$config = $file; |
390
|
|
|
|
|
|
|
} |
391
|
|
|
|
|
|
|
|
392
|
6
|
100
|
|
|
|
27
|
if ( !defined $config ) { |
393
|
4
|
|
|
|
|
8
|
my $default_config = '[Default]'; |
394
|
4
|
|
|
|
|
9
|
$config = \$default_config; |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
|
397
|
6
|
|
|
|
|
26
|
return $self->_load_config($config); |
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
1; |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
__END__ |