| Filename | /appl/netdisco/perl5/lib/perl5/Dancer/Config.pm |
| Statements | Executed 2139 statements in 2.97ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 599 | 4 | 2 | 1.42ms | 2.34ms | Dancer::Config::setting |
| 599 | 1 | 1 | 918µs | 918µs | Dancer::Config::_get_setting |
| 342 | 1 | 1 | 362µs | 362µs | Dancer::Config::settings |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::BEGIN |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:36] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:40] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:45] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:50] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:55] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:60] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:70] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:74] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:78] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::__ANON__[:96] |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::_set_setting |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::_trigger_hooks |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::conffile |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::environment_file |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::init_confdir |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::init_envdir |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::load |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::load_default_settings |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::load_settings_from_yaml |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::load_yaml_module |
| 0 | 0 | 0 | 0s | 0s | Dancer::Config::normalize_setting |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Dancer::Config; | ||||
| 2 | our $AUTHORITY = 'cpan:SUKRIA'; | ||||
| 3 | #ABSTRACT: how to configure Dancer to suit your needs | ||||
| 4 | $Dancer::Config::VERSION = '1.3512'; | ||||
| 5 | use strict; | ||||
| 6 | use warnings; | ||||
| 7 | use base 'Exporter'; | ||||
| 8 | use vars '@EXPORT_OK'; | ||||
| 9 | |||||
| 10 | use Hash::Merge::Simple; | ||||
| 11 | use Dancer::Config::Object 'hashref_to_object'; | ||||
| 12 | use Dancer::Deprecation; | ||||
| 13 | use Dancer::Template; | ||||
| 14 | use Dancer::ModuleLoader; | ||||
| 15 | use Dancer::FileUtils 'path'; | ||||
| 16 | use Carp; | ||||
| 17 | use Dancer::Exception qw(:all); | ||||
| 18 | |||||
| 19 | use Encode; | ||||
| 20 | |||||
| 21 | @EXPORT_OK = qw(setting); | ||||
| 22 | |||||
| 23 | my $SETTINGS = {}; | ||||
| 24 | |||||
| 25 | # mergeable settings | ||||
| 26 | my %MERGEABLE = map { ($_ => 1) } qw( plugins handlers ); | ||||
| 27 | my %_LOADED; | ||||
| 28 | |||||
| 29 | 342 | 402µs | # spent 362µs within Dancer::Config::settings which was called 342 times, avg 1µs/call:
# 342 times (362µs+0s) by Dancer::config at line 137 of Dancer.pm, avg 1µs/call | ||
| 30 | |||||
| 31 | my $setters = { | ||||
| 32 | logger => sub { | ||||
| 33 | my ($setting, $value) = @_; | ||||
| 34 | require Dancer::Logger; | ||||
| 35 | Dancer::Logger->init($value, settings()); | ||||
| 36 | }, | ||||
| 37 | log_file => sub { | ||||
| 38 | require Dancer::Logger; | ||||
| 39 | Dancer::Logger->init(setting("logger"), settings()); | ||||
| 40 | }, | ||||
| 41 | session => sub { | ||||
| 42 | my ($setting, $value) = @_; | ||||
| 43 | require Dancer::Session; | ||||
| 44 | Dancer::Session->init($value, settings()); | ||||
| 45 | }, | ||||
| 46 | template => sub { | ||||
| 47 | my ($setting, $value) = @_; | ||||
| 48 | require Dancer::Template; | ||||
| 49 | Dancer::Template->init($value, settings()); | ||||
| 50 | }, | ||||
| 51 | route_cache => sub { | ||||
| 52 | my ($setting, $value) = @_; | ||||
| 53 | require Dancer::Route::Cache; | ||||
| 54 | Dancer::Route::Cache->reset(); | ||||
| 55 | }, | ||||
| 56 | serializer => sub { | ||||
| 57 | my ($setting, $value) = @_; | ||||
| 58 | require Dancer::Serializer; | ||||
| 59 | Dancer::Serializer->init($value); | ||||
| 60 | }, | ||||
| 61 | # This setting has been deprecated in favor of global_warnings. | ||||
| 62 | import_warnings => sub { | ||||
| 63 | my ($setting, $value) = @_; | ||||
| 64 | |||||
| 65 | Dancer::Deprecation->deprecated( | ||||
| 66 | message => "import_warnings has been deprecated, please use global_warnings instead." | ||||
| 67 | ); | ||||
| 68 | |||||
| 69 | $^W = $value ? 1 : 0; | ||||
| 70 | }, | ||||
| 71 | global_warnings => sub { | ||||
| 72 | my ($setting, $value) = @_; | ||||
| 73 | $^W = $value ? 1 : 0; | ||||
| 74 | }, | ||||
| 75 | traces => sub { | ||||
| 76 | my ($setting, $traces) = @_; | ||||
| 77 | $Dancer::Exception::Verbose = $traces ? 1 : 0; | ||||
| 78 | }, | ||||
| 79 | }; | ||||
| 80 | $setters->{log_path} = $setters->{log_file}; | ||||
| 81 | |||||
| 82 | my $normalizers = { | ||||
| 83 | charset => sub { | ||||
| 84 | my ($setting, $charset) = @_; | ||||
| 85 | length($charset || '') | ||||
| 86 | or return $charset; | ||||
| 87 | my $encoding = Encode::find_encoding($charset); | ||||
| 88 | defined $encoding | ||||
| 89 | or raise core_config => "Charset defined in configuration is wrong : couldn't identify '$charset'"; | ||||
| 90 | my $name = $encoding->name; | ||||
| 91 | # Perl makes a distinction between the usual perl utf8, and the strict | ||||
| 92 | # utf8 charset. But we don't want to make this distinction | ||||
| 93 | $name eq 'utf-8-strict' | ||||
| 94 | and $name = 'utf-8'; | ||||
| 95 | return $name; | ||||
| 96 | }, | ||||
| 97 | }; | ||||
| 98 | |||||
| 99 | sub normalize_setting { | ||||
| 100 | my ($class, $setting, $value) = @_; | ||||
| 101 | |||||
| 102 | $value = $normalizers->{$setting}->($setting, $value) | ||||
| 103 | if exists $normalizers->{$setting}; | ||||
| 104 | |||||
| 105 | return $value; | ||||
| 106 | } | ||||
| 107 | |||||
| 108 | # public accessor for get/set | ||||
| 109 | # spent 2.34ms (1.42+918µs) within Dancer::Config::setting which was called 599 times, avg 4µs/call:
# 467 times (1000µs+624µs) by Dancer::setting at line 215 of Dancer.pm, avg 3µs/call
# 66 times (92µs+80µs) by Dancer::Logger::Abstract::format_message at line 66 of Dancer/Logger/Abstract.pm, avg 3µs/call
# 33 times (260µs+151µs) by Dancer::Logger::Abstract::_should at line 52 of Dancer/Logger/Abstract.pm, avg 12µs/call
# 33 times (70µs+62µs) by Dancer::Logger::Abstract::_log_format at line 39 of Dancer/Logger/Abstract.pm, avg 4µs/call | ||||
| 110 | 599 | 1.22ms | 599 | 918µs | if (@_ == 1) { # spent 918µs making 599 calls to Dancer::Config::_get_setting, avg 2µs/call |
| 111 | return _get_setting(shift @_); | ||||
| 112 | } | ||||
| 113 | else { | ||||
| 114 | # can be useful for debug! Use Logger, instead? | ||||
| 115 | die "Odd number in 'set' assignment" unless scalar @_ % 2 == 0; | ||||
| 116 | |||||
| 117 | my $count = 0; | ||||
| 118 | while (@_) { | ||||
| 119 | my $setting = shift; | ||||
| 120 | my $value = shift; | ||||
| 121 | |||||
| 122 | _set_setting ($setting, $value); | ||||
| 123 | |||||
| 124 | # At the moment, with any kind of hierarchical setter, | ||||
| 125 | # there is no case where the same trigger will be run more | ||||
| 126 | # than once. If/when a hierarchical setter is implemented, | ||||
| 127 | # we should create a list of the hooks that should be run, | ||||
| 128 | # and run them at the end of this while, only (efficiency | ||||
| 129 | # purposes). | ||||
| 130 | _trigger_hooks($setting, $value); | ||||
| 131 | $count++ | ||||
| 132 | } | ||||
| 133 | return $count; # just to return anything, the number of items set. | ||||
| 134 | } | ||||
| 135 | } | ||||
| 136 | |||||
| 137 | sub _trigger_hooks { | ||||
| 138 | my ($setting, $value) = @_; | ||||
| 139 | |||||
| 140 | $setters->{$setting}->(@_) if defined $setters->{$setting}; | ||||
| 141 | } | ||||
| 142 | |||||
| 143 | sub _set_setting { | ||||
| 144 | my ($setting, $value) = @_; | ||||
| 145 | |||||
| 146 | return unless @_ == 2; | ||||
| 147 | |||||
| 148 | # normalize the value if needed | ||||
| 149 | $value = Dancer::Config->normalize_setting($setting, $value); | ||||
| 150 | $SETTINGS->{$setting} = $value; | ||||
| 151 | return $value; | ||||
| 152 | } | ||||
| 153 | |||||
| 154 | # spent 918µs within Dancer::Config::_get_setting which was called 599 times, avg 2µs/call:
# 599 times (918µs+0s) by Dancer::Config::setting at line 110, avg 2µs/call | ||||
| 155 | 599 | 198µs | my $setting = shift; | ||
| 156 | |||||
| 157 | 599 | 1.15ms | return $SETTINGS->{$setting}; | ||
| 158 | } | ||||
| 159 | |||||
| 160 | sub conffile { path(setting('confdir') || setting('appdir'), 'config.yml') } | ||||
| 161 | |||||
| 162 | sub environment_file { | ||||
| 163 | my $env = setting('environment'); | ||||
| 164 | # XXX for compatibility reason, we duplicate the code from `init_envdir` here | ||||
| 165 | # we don't know how if some application don't already do some weird stuff like | ||||
| 166 | # the test in `t/15_plugins/02_config.t`. | ||||
| 167 | my $envdir = setting('envdir') || path(setting('appdir'), 'environments'); | ||||
| 168 | return path($envdir, "$env.yml"); | ||||
| 169 | } | ||||
| 170 | |||||
| 171 | sub init_confdir { | ||||
| 172 | return setting('confdir') if setting('confdir'); | ||||
| 173 | setting confdir => $ENV{DANCER_CONFDIR} || setting('appdir'); | ||||
| 174 | } | ||||
| 175 | |||||
| 176 | sub init_envdir { | ||||
| 177 | return setting('envdir') if setting('envdir'); | ||||
| 178 | my $appdirpath = defined setting('appdir') ? | ||||
| 179 | path( setting('appdir'), 'environments' ) : | ||||
| 180 | path('environments'); | ||||
| 181 | |||||
| 182 | setting envdir => $ENV{DANCER_ENVDIR} || $appdirpath; | ||||
| 183 | } | ||||
| 184 | |||||
| 185 | sub load { | ||||
| 186 | init_confdir(); | ||||
| 187 | init_envdir(); | ||||
| 188 | |||||
| 189 | # look for the conffile | ||||
| 190 | return 1 unless -f conffile; | ||||
| 191 | |||||
| 192 | # load YAML | ||||
| 193 | my $module = load_yaml_module(); | ||||
| 194 | |||||
| 195 | unless ($_LOADED{conffile()}) { | ||||
| 196 | load_settings_from_yaml(conffile, $module); | ||||
| 197 | $_LOADED{conffile()}++; | ||||
| 198 | } | ||||
| 199 | |||||
| 200 | my $env = environment_file; | ||||
| 201 | |||||
| 202 | # don't load the same env twice | ||||
| 203 | unless( $_LOADED{$env} ) { | ||||
| 204 | if (-f $env ) { | ||||
| 205 | load_settings_from_yaml($env, $module); | ||||
| 206 | $_LOADED{$env}++; | ||||
| 207 | } | ||||
| 208 | elsif (setting('require_environment')) { | ||||
| 209 | # failed to load the env file, and the main config said we needed it. | ||||
| 210 | confess "Could not load environment file '$env', and require_environment is set"; | ||||
| 211 | } | ||||
| 212 | } | ||||
| 213 | |||||
| 214 | foreach my $key (grep { $setters->{$_} } keys %$SETTINGS) { | ||||
| 215 | $setters->{$key}->($key, $SETTINGS->{$key}); | ||||
| 216 | } | ||||
| 217 | if ( $SETTINGS->{strict_config} ) { | ||||
| 218 | $SETTINGS = hashref_to_object($SETTINGS); | ||||
| 219 | } | ||||
| 220 | |||||
| 221 | return 1; | ||||
| 222 | } | ||||
| 223 | |||||
| 224 | sub load_settings_from_yaml { | ||||
| 225 | my ($file, $module) = @_; | ||||
| 226 | |||||
| 227 | $module ||= load_yaml_module(); | ||||
| 228 | |||||
| 229 | my $config; | ||||
| 230 | { | ||||
| 231 | no strict 'refs'; | ||||
| 232 | $config = eval { &{ $module . '::LoadFile' }($file) } | ||||
| 233 | or confess "Unable to parse the configuration file: $file: $@"; | ||||
| 234 | } | ||||
| 235 | |||||
| 236 | $SETTINGS = Hash::Merge::Simple::merge( $SETTINGS, { | ||||
| 237 | map { | ||||
| 238 | $_ => Dancer::Config->normalize_setting( $_, $config->{$_} ) | ||||
| 239 | } keys %$config | ||||
| 240 | } ); | ||||
| 241 | |||||
| 242 | return scalar keys %$config; | ||||
| 243 | } | ||||
| 244 | |||||
| 245 | sub load_yaml_module { | ||||
| 246 | my ($module) = @_; | ||||
| 247 | |||||
| 248 | $module ||= $SETTINGS->{engines}{YAML}{module} || 'YAML'; | ||||
| 249 | |||||
| 250 | my ( $result, $error ) = Dancer::ModuleLoader->load($module); | ||||
| 251 | confess "Could not load $module: $error" | ||||
| 252 | unless $result; | ||||
| 253 | |||||
| 254 | return $module; | ||||
| 255 | } | ||||
| 256 | |||||
| 257 | sub load_default_settings { | ||||
| 258 | $SETTINGS->{server} ||= $ENV{DANCER_SERVER} || '0.0.0.0'; | ||||
| 259 | $SETTINGS->{port} ||= $ENV{DANCER_PORT} || '3000'; | ||||
| 260 | $SETTINGS->{content_type} ||= $ENV{DANCER_CONTENT_TYPE} || 'text/html'; | ||||
| 261 | $SETTINGS->{charset} ||= $ENV{DANCER_CHARSET} || ''; | ||||
| 262 | $SETTINGS->{startup_info} ||= !$ENV{DANCER_NO_STARTUP_INFO}; | ||||
| 263 | $SETTINGS->{daemon} ||= $ENV{DANCER_DAEMON} || 0; | ||||
| 264 | $SETTINGS->{apphandler} ||= $ENV{DANCER_APPHANDLER} || 'Standalone'; | ||||
| 265 | $SETTINGS->{warnings} ||= $ENV{DANCER_WARNINGS} || 0; | ||||
| 266 | $SETTINGS->{auto_reload} ||= $ENV{DANCER_AUTO_RELOAD} || 0; | ||||
| 267 | $SETTINGS->{traces} ||= $ENV{DANCER_TRACES} || 0; | ||||
| 268 | $SETTINGS->{server_tokens} ||= !$ENV{DANCER_NO_SERVER_TOKENS}; | ||||
| 269 | $SETTINGS->{logger} ||= $ENV{DANCER_LOGGER} || 'file'; | ||||
| 270 | $SETTINGS->{environment} ||= | ||||
| 271 | $ENV{DANCER_ENVIRONMENT} | ||||
| 272 | || $ENV{PLACK_ENV} | ||||
| 273 | || 'development'; | ||||
| 274 | |||||
| 275 | setting $_ => {} for keys %MERGEABLE; | ||||
| 276 | setting template => 'simple'; | ||||
| 277 | } | ||||
| 278 | |||||
| 279 | load_default_settings(); | ||||
| 280 | |||||
| 281 | 1; | ||||
| 282 | |||||
| 283 | __END__ |