File Coverage

lib/Dancer/Plugin/DynamicConfig.pm
Criterion Covered Total %
statement 63 66 95.4
branch 17 22 77.2
condition 3 3 100.0
subroutine 14 14 100.0
pod 1 3 33.3
total 98 108 90.7


line stmt bran cond sub pod time code
1             package Dancer::Plugin::DynamicConfig;
2 1     1   1055 use strict;
  1         3  
  1         45  
3 1     1   7 use warnings;
  1         2  
  1         42  
4 1     1   17 use Dancer ':syntax';
  1         1  
  1         9  
5 1     1   564 use Dancer::FileUtils qw(read_file_content);
  1         2  
  1         64  
6 1     1   6 use Dancer::ModuleLoader;
  1         2  
  1         24  
7 1     1   1087 use Dancer::Plugin;
  1         2300  
  1         97  
8 1     1   6 use Encode qw(encode);
  1         3  
  1         56  
9 1     1   2409 use JSON::XS qw(decode_json);
  1         8069  
  1         89  
10 1     1   10 use Time::HiRes;
  1         2  
  1         8  
11 1     1   112 use Try::Tiny;
  1         2  
  1         995  
12              
13             our $VERSION = '0.07';
14              
15             my @file_types = ({
16             type => 'json',
17             re => qr{\.json$},
18             parser => sub {
19             my ($filename) = @_;
20             my $json;
21             try {
22             read_file_content($filename) =~ /(.*)/s; # untaint
23             try {
24             $json = decode_json(encode('UTF-8', $1));
25             } catch {
26             warning "couldn't parse json file ($filename): $_\n";
27             };
28             } catch {
29             warning "couldn't find file to parse ($filename): $_\n";
30             };
31             return $json;
32             },
33             });
34              
35             my $dynamic_config;
36              
37             register dynamic_config => sub {
38 9     9   1411 my ($file_key) = @_;
39              
40 9 100       39 initialize() unless $dynamic_config;
41              
42 9 100       40 if (my $fileinfo = $dynamic_config->{$file_key}) {
43 8         29 my $mtime = (dc_stat($fileinfo->{path}))[9];
44              
45 8 100 100     60 if (not defined $fileinfo->{data} or $mtime > $fileinfo->{mtime}) {
46 7         30 my $parsed = $fileinfo->{parser}->($fileinfo->{path});
47              
48 7 50       24 if (defined $parsed) {
49 7         17 $fileinfo->{mtime} = $mtime;
50 7 100       51 $fileinfo->{data} = $fileinfo->{rewrite_class} ? $fileinfo->{rewrite_class}->rewrite($parsed) : $parsed;
51             } else {
52 0         0 warning "could not parse $fileinfo->{path}";
53 0 0       0 warning "$@" if $@;
54             }
55             }
56              
57 8         248 return $fileinfo->{data};
58             } else {
59 1         8 warning "unknown dynamic_config key [$file_key]";
60             }
61              
62 1         77 return '';
63             };
64              
65 3     3 1 4157629 sub reinitialize { undef $dynamic_config; initialize() }
  3         72  
66              
67             sub initialize {
68 4     4 0 12 SETTING: while (my ($file_key, $etc) = each %{ plugin_setting() }) {
  23         79  
69 19         739 my ($path, $rewrite_class);
70 19 100       143 if (ref $etc) {
71 8         19 $path = $etc->{path};
72 8         17 $rewrite_class = $etc->{rewrite_class};
73             } else {
74 11         21 $path = $etc;
75             }
76              
77 19         33 foreach my $ft (@file_types) {
78 19 100       190 if ($path =~ $ft->{re}) {
79 18         229 $dynamic_config->{$file_key} = {
80             path => $path,
81             mtime => undef,
82             data => undef,
83             type => $ft->{type},
84             parser => $ft->{parser},
85             rewrite_class => $rewrite_class,
86             };
87              
88 18 100       44 if ($rewrite_class) {
89 8 50       66 Dancer::ModuleLoader->load($rewrite_class) or die "Could not load $rewrite_class";
90             }
91 18         1510 next SETTING;
92             } else {
93 1         12 warning "ignoring config key [$file_key]: unknown filetype for [$path]";
94 1         132 warn "ignoring config key [$file_key]: unknown filetype for [$path]";
95             # should this die? your config is so broken we can't start up
96             }
97             }
98             }
99              
100 4         131 return;
101             }
102              
103             sub dc_stat {
104 8     8 0 16 my ($filething) = @_;
105              
106 8 50       29 if (defined &Time::HiRes::stat) {
107 8         214 return Time::HiRes::stat($filething);
108             } else {
109 0           return stat($filething);
110             }
111             }
112              
113             register_plugin;
114              
115             1;
116              
117             __END__