.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{
. if \nF \{
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "Poet::Conf 3pm"
.TH Poet::Conf 3pm "2014-02-26" "perl v5.18.2" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Poet::Conf \-\- Poet configuration
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 2
\& # In a script...
\& use Poet::Script qw($conf);
\&
\& # In a module...
\& use Poet qw($conf);
\&
\& # $conf is automatically available in Mason components
\&
\& # then...
\& my $value = $conf\->get(\*(Aqkey\*(Aq, \*(Aqdefault\*(Aq);
\& my $value = $conf\->get_or_die(\*(Aqkey\*(Aq);
\&
\& my $listref = $conf\->get_list(\*(Aqkey\*(Aq, [\*(Aqdefault\*(Aq]);
\& my $hashref = $conf\->get_hash(\*(Aqkey\*(Aq, {\*(Aqdefault\*(Aq => 5});
\& my $bool = $conf\->get_boolean(\*(Aqkey\*(Aq);
\&
\& my @keys = grep { /^foo\e./ } $conf\->get_keys;
\&
\& my $hash = $conf\->as_hash;
\& print $conf\->as_string;
\&
\& {
\& my $lex = $conf\->set_local({\*(Aqkey\*(Aq => \*(Aqnew_value\*(Aq});
\& # key has new_value inside this scope only
\& }
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
The Poet::Conf object gives access to the current environment's configuration,
read from configuration files in the conf/ subdirectory.
.SH "CONFIGURATION FILES"
.IX Header "CONFIGURATION FILES"
Poet configuration files are found in the conf/ subdirectory of the environment
root:
.PP
.Vb 12
\& conf/
\& global.cfg
\& global/
\& something.cfg
\& something_else.cfg
\& ...
\& layer/
\& development.cfg
\& production.cfg
\& ...
\& local.cfg
\& $ENV{POET_EXTRA_CONF_FILE}
.Ve
.PP
The files are read and merged in the following order, with later files taking
precedence over earlier files. None of the files have to exist except
\&\f(CW\*(C`local.cfg\*(C'\fR.
.IP "\(bu" 4
\&\f(CW\*(C`global.cfg\*(C'\fR contains various settings for the environment, typically checked
into version control. Having a single file is fine for a simple site and a
single developer, but if this gets too unwieldy, see global/ below.
.IP "\(bu" 4
The \f(CW\*(C`global/\*(C'\fR directory contains multiple .cfg files, all of which are read in
alphabetical order. This is an alternative to \f(CW\*(C`global.cfg\*(C'\fR when the latter
gets too crowded and you have multiple developers making simultaneous changes.
It is an error for two global files to set the same key.
.IP "\(bu" 4
The \f(CW\*(C`layer/\*(C'\fR directory contains version-controlled files specific to layers,
e.g. \f(CW\*(C`development.cfg\*(C'\fR and \f(CW\*(C`production.cfg\*(C'\fR. Only one of these files will be
active at a time, depending on the current layer (as set in \f(CW\*(C`local.cfg\*(C'\fR).
.IP "\(bu" 4
\&\f(CW\*(C`local.cfg\*(C'\fR contains settings for this particular instance of the environment.
It is not checked into version control. local.cfg must exist and must contain
at least the layer, e.g.
.Sp
.Vb 1
\& layer: development
.Ve
.IP "\(bu" 4
If \f(CW$ENV{POET_EXTRA_CONF_FILE}\fR is defined when configuration initializes, it
is read as an extra conf file whose values override all others.
.SH "CONFIGURATION FORMAT"
.IX Header "CONFIGURATION FORMAT"
Basic conf file format is \s-1YAML\s0 , e.g.
.PP
.Vb 4
\& cache:
\& defaults:
\& driver: Memcached
\& servers: ["10.0.0.15:11211", "10.0.0.15:11212"]
\&
\& log:
\& defaults:
\& level: info
\& output: poet.log
\& layout: "%d{dd/MMM/yyyy:HH:mm:ss.SS} [%p] %c \- %m \- %F:%L \- %P%n"
.Ve
.SS "Interpolation \- referring to other entries"
.IX Subsection "Interpolation - referring to other entries"
Conf entries can refer to other entries via the syntax \f(CW\*(C`${key}\*(C'\fR. For example:
.PP
.Vb 1
\& # conf file
\&
\& foo: 5
\& bar: "The number ${foo}"
\& baz: ${bar}00
\&
\& # then
\&
\& $conf\->get(\*(Aqfoo\*(Aq)
\& => 5
\& $conf\->get(\*(Aqbar\*(Aq)
\& => "The number 5"
\& $conf\->get(\*(Aqbaz\*(Aq)
\& => "The number 500"
.Ve
.PP
The key must exist or a fatal error will occur.
.PP
There is a single built-in entry, \f(CW\*(C`root_dir\*(C'\fR, containing the root directory of
the environment that you can use in other entries, e.g.
.PP
.Vb 4
\& cache:
\& defaults:
\& driver: File
\& root_dir: ${root_dir}/data/cache
.Ve
.SS "Dot notation for hash access"
.IX Subsection "Dot notation for hash access"
Conf entries can use dot (\*(L".\*(R") notation to refer to hash entries. e.g. this
.PP
.Vb 1
\& foo.bar.baz: 5
.Ve
.PP
is the same as
.PP
.Vb 3
\& foo:
\& bar:
\& baz: 5
.Ve
.PP
The dot notation is especially useful for \fIoverriding\fR individual hash
elements from higher precedence config files. For example, if in
\&\f(CW\*(C`global/cache.cfg\*(C'\fR you have
.PP
.Vb 5
\& cache:
\& defaults:
\& driver: File
\& root_dir: $root/data/cache
\& depth: 3
.Ve
.PP
and in local.cfg you have
.PP
.Vb 1
\& cache.defaults.depth: 2
.Ve
.PP
then only \f(CW\*(C`depth\*(C'\fR will be overridden; the \f(CW\*(C`driver\*(C'\fR and \f(CW\*(C`root_dir\*(C'\fR will
remain as they were set in \f(CW\*(C`global/cache.cfg\*(C'\fR. If instead local.cfg had
.PP
.Vb 3
\& cache:
\& defaults:
\& depth: 3
.Ve
.PP
then this would completely replace the entire hash under \f(CW\*(C`cache\*(C'\fR.
.ie n .SH "OBTAINING $conf SINGLETON"
.el .SH "OBTAINING \f(CW$conf\fP SINGLETON"
.IX Header "OBTAINING $conf SINGLETON"
In a script:
.PP
.Vb 1
\& use Poet::Script qw($conf);
.Ve
.PP
In a module:
.PP
.Vb 1
\& use Poet qw($conf);
.Ve
.PP
\&\f(CW$conf\fR is automatically available in components.
.PP
You can also get it via
.PP
.Vb 1
\& my $conf = Poet::Environment\->current_env\->conf;
.Ve
.SH "METHODS"
.IX Header "METHODS"
.SS "Methods for getting conf values"
.IX Subsection "Methods for getting conf values"
.IP "get (key[, default])" 4
.IX Item "get (key[, default])"
.Vb 1
\& my $value = $conf\->get(\*(Aqkey\*(Aq => \*(Aqdefault\*(Aq);
.Ve
.Sp
Get \fIkey\fR from configuration. If \fIkey\fR is unavailable, return the \fIdefault\fR,
or undef if no default is given.
.Sp
The return value may be a scalar, list reference, or hash reference, though we
recommend using \*(L"get_list\*(R" and \*(L"get_hash\*(R" if you expect a list or hash.
.Sp
\&\fIkey\fR can contain dot notation to refer to hash entries. e.g. these are
equivalent:
.Sp
.Vb 1
\& $conf\->get(\*(Aqfoo.bar.baz\*(Aq);
\&
\& $conf\->get_hash(\*(Aqfoo\*(Aq)\->{bar}\->{baz};
.Ve
.IP "get_or_die (key)" 4
.IX Item "get_or_die (key)"
.Vb 1
\& my $value = $conf\->get_or_die(\*(Aqkey\*(Aq);
.Ve
.Sp
Get \fIkey\fR from configuration. If \fIkey\fR is unavailable, throw a fatal error.
.IP "get_list (key[, default])" 4
.IX Item "get_list (key[, default])"
.Vb 1
\& my $listref = $conf\->get_list(\*(Aqkey\*(Aq, [\*(Aqdefault\*(Aq]);
.Ve
.Sp
Get \fIkey\fR from configuration. If the value is not a list reference, throw an
error.
.Sp
If \fIkey\fR is unavailable, return the \fIdefault\fR, or an empty list reference if
no default is given.
.IP "get_hash (key[, default])" 4
.IX Item "get_hash (key[, default])"
.Vb 1
\& my $hashref = $conf\->get_hash(\*(Aqkey\*(Aq, {\*(Aqdefault\*(Aq => 5});
.Ve
.Sp
Get \fIkey\fR from configuration. If the value is not a hash reference, throw an
error.
.Sp
If \fIkey\fR is unavailable, return the \fIdefault\fR, or an empty hash reference if
no default is given.
.IP "get_boolean (key)" 4
.IX Item "get_boolean (key)"
.Vb 1
\& my $bool = $conf\->get_boolean(\*(Aqkey\*(Aq);
.Ve
.Sp
Get \fIkey\fR from configuration. Return 1 if the value represents true (\*(L"1\*(R", \*(L"t\*(R",
\&\*(L"true\*(R", \*(L"y\*(R", \*(L"yes\*(R") and 0 if the value represents false (\*(L"0\*(R", \*(L"f\*(R", \*(L"false\*(R",
\&\*(L"n\*(R", \*(L"no\*(R") or is not present in configuration. These are case insensitive
matches. Throws an error if there is a value that is a reference or does not
match one of the valid options.
.IP "get_secure (key)" 4
.IX Item "get_secure (key)"
.Vb 1
\& my $password = $conf\->get_secure(\*(Aqsecret_password\*(Aq);
.Ve
.Sp
Get \fIkey\fR from a separate, non-version-controlled, secure config file; if it
cannot be found, then fallback to normal config. Useful for passwords,
encryption keys, etc. that might be ok in normal config on development, but
ought to be secure on production.
.Sp
The location of the secure config file is determined by config entry
conf.secure_conf_file; it defaults to \f(CW\*(C`conf/secure.cfg\*(C'\fR. The file is in plain
\&\s-1YAML\s0 format, with no interpolation or dot notation.
.SS "Other methods"
.IX Subsection "Other methods"
.IP "layer" 4
.IX Item "layer"
Returns the current layer, as determined from \f(CW\*(C`local.cfg\*(C'\fR.
.IP "is_development" 4
.IX Item "is_development"
Boolean; returns true iff the current layer is 'development'.
.IP "is_live" 4
.IX Item "is_live"
Boolean; the opposte of \*(L"is_development\*(R".
.IP "get_keys" 4
.IX Item "get_keys"
.Vb 1
\& my @keys = sort $conf\->get_keys;
.Ve
.Sp
Return a list of all keys in configuration.
.IP "as_hash" 4
.IX Item "as_hash"
.Vb 1
\& my $hash = $conf\->as_hash;
.Ve
.Sp
Return a hash reference mapping keys to their value as returned by \f(CW\*(C`$conf\->get\*(C'\fR.
.IP "as_string" 4
.IX Item "as_string"
.Vb 1
\& print $conf\->as_string;
.Ve
.Sp
Return a printable representation of the keys and values.
.IP "set_local" 4
.IX Item "set_local"
.Vb 1
\& my $lex = $conf\->set_local({key => \*(Aqvalue\*(Aq, ...});
.Ve
.Sp
Temporarily set each \fIkey\fR to \fIvalue\fR. The original value will be restored
when \f(CW$lex\fR goes out of scope.
.Sp
This is intended for specialized use in unit tests and development tools, \s-1NOT\s0
for production code. Setting and resetting of configuration values will make it
much more difficult to read and debug code!
.IP "generate_dynamic_config" 4
.IX Item "generate_dynamic_config"
.Vb 1
\& $conf\->generate_dynamic_config();
.Ve
.Sp
This method can be used to dynamically generate configuration files for
external software (e.g. Apache, nginx, logrotate). It uses
MasonX::ProcessDir to process Mason templates in
\&\f(CW\*(C`conf/dynamic\*(C'\fR and generate destination files in \f(CW\*(C`data/conf/dynamic\*(C'\fR.
.Sp
For example, if \f(CW\*(C`conf/dynamic/httpd.conf.mc\*(C'\fR contains an Apache configuration
file with Mason dynamic elements, this method will generate a static
configuration file in \f(CW\*(C`data/conf/dynamic/httpd.conf.mc\*(C'\fR, which you can then
feed directly into Apache.
.SH "MODIFIABLE METHODS"
.IX Header "MODIFIABLE METHODS"
These methods are not intended to be called externally, but may be useful to
override or modify with method modifiers in
subclasses. Their APIs will be kept as stable as
possible.
.IP "read_conf_data" 4
.IX Item "read_conf_data"
This is the main method that finds and parses conf files and returns a hash of
conf keys to values. You can modify this to dynamically compute certain conf
keys:
.Sp
.Vb 5
\& override \*(Aqread_conf_data\*(Aq => sub {
\& my $hash = super();
\& $hash\->{complex_key} = ...;
\& return $hash;
\& };
.Ve
.Sp
or to completely override how Poet gets its configuration:
.Sp
.Vb 6
\& override \*(Aqread_conf_data\*(Aq => sub {
\& return {
\& some_conf_key => \*(Aqsome conf value\*(Aq,
\& ...
\& };
\& };
.Ve
.IP "initial_conf_data" 4
.IX Item "initial_conf_data"
Returns a hash with initial configuration data before any conf files have been
merged in. By default, just contains
.Sp
.Vb 1
\& ( root => \*(Aq/path/to/root\*(Aq )
.Ve
.IP "_build_layer" 4
.IX Item "_build_layer"
Determines the current layer before \*(L"read_conf\*(R" is called. By default, looks
for a \f(CW\*(C`layer\*(C'\fR key in \f(CW\*(C`local.cfg\*(C'\fR.
.IP "_build_is_development" 4
.IX Item "_build_is_development"
Determines the value of \*(L"is_development\*(R", and subsequently its opposite
\&\*(L"is_live\*(R". By default, true iff layer == 'development'.
.IP "ordered_conf_files" 4
.IX Item "ordered_conf_files"
Returns a list of conf files to read in order from lowest to highest
precedence. You can modify this to insert an additional file, e.g.
.Sp
.Vb 4
\& override \*(Aqordered_conf_files\*(Aq => sub {
\& my @list = super();
\& return (@list, \*(Aq/path/to/important.cfg\*(Aq);
\& };
.Ve
.IP "read_conf_file ($file)" 4
.IX Item "read_conf_file ($file)"
Read a single conf \fI\f(CI$file\fI\fR and return its hash representation. You can modify
this to use a conf format other than \s-1YAML,\s0 e.g.
.Sp
.Vb 1
\& use Config::INI;
\&
\& override \*(Aqread_conf_file\*(Aq => sub {
\& my ($self, $file) = @_;
\& return Config::INI::Reader\->read_file($file);
\& };
.Ve
.ie n .IP "merge_conf_data ($current_data, $new_data, $file)" 4
.el .IP "merge_conf_data ($current_data, \f(CW$new_data\fR, \f(CW$file\fR)" 4
.IX Item "merge_conf_data ($current_data, $new_data, $file)"
Merge \fI\f(CI$new_data\fI\fR from \fI\f(CI$file\fI\fR into \fI\f(CI$current_data\fI\fR. \fI\f(CI$new_data\fI\fR and
\&\fI\f(CI$current_data\fI\fR are both hashrefs, and \fI\f(CI$current_data\fI\fR will be the empty hash
for the first file. By default, this just uses Perl's built-in hash merging
with values from \fI\f(CI$new_data\fI\fR taking precedence.
.SH "CREDITS"
.IX Header "CREDITS"
The ideas of merging multiple conf files and variable interpolation came from
YAML::AppConfig.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
Poet
.SH "AUTHOR"
.IX Header "AUTHOR"
Jonathan Swartz
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
This software is copyright (c) 2012 by Jonathan Swartz.
.PP
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.