This is a library for unified configuration management.
Essentially it provides an abstract collection data type for
looking up named values, two or more of which can be chained
together. Values from more recent collections can be preferred as
with an environment, or the values at multiple levels can be
flattened together. Convenience routines are provided from
loading these collections from files while allowing extensions
such as configurations from command-line options.
As any application grows to sufficient complexity, it acquires
options and behaviors that one may want to modify at startup or
runtime. The traditional approach is a combination of
command-line options, config files, environment variables, and/or
other specialized settings. These all have various pros and cons:
name | pros | cons |
environment variables |
implicit - no need to retype; can share between applications |
unclear when set; unexpected differences between users; limited size |
command-line options |
explicit - visible each time a command is run; |
verbose; limited size |
config files |
implicit; preserved - can be shared and version controlled |
requires a parser |
Environment variables are convenient for broad preferences, used
by many different applications, and unlikely to change per user.
Command-line options are best for settings that are likely to
change between invocations of a program. Anything else is best
stored in a config file. If there are settings that multiple
users of a group or whole system are likely to want to share, then
it makes sense to cascade multiple config files.
With any other language there is a question of config file syntax,
and a few popular choices exist such as .ini syntax. With Scheme
the obvious choice is sexps, generally as an alist. We use a
single alist for the whole file, with symbols for keys and
arbitrary sexps for values. The alists are intended primarily for
editing by hand and need not be dotted, but the interface allows
dotted values. Disambiguation is handled as with two separate
functions,
(conf-get config key)
and
(conf-get-list config key)
, which both retrieve the value
associated with
key
from
config
, in the latter case
coercing to a list. The result is determined according to the
structure of the alist cell as follows:
Cell | conf-get result | conf-get-list result |
(key) | () | () |
(key . non-list-value) | non-list-value | (non-list-value) |
(key non-list-value) | non-list-value | (non-list-value) |
(key (value1 value2 ...)) | (value1 value2 ...) | (value1 value2 ...) |
(key value1 value2 ...) | (value1 value2 ...) | (value1 value2 ...) |
Thus writing the non-dotted value will always do what you want.
Specifically, the only thing to be careful of is if you want a
single-element list value, even with
conf-get
, you should
write
(key (value))
.
Returns true iff
x
is a config object.
(make-conf alist parent source timestamp)
(read-from-file file . opt)
(assoc-get alist key [equal? [default]])
Utility analogous to
conf-get
on a pure alist. Returns
the value of the cell in
alist
whose car is
equal?
to
key
, where the value is determined as the
cadr
if the
cell is a proper list of two elements and the
cdr
otherwise.
If no cell is found, returns
default
, or
#f
if
unspecified.
(assoc-get-list alist key [default])
Equivalent to
assoc-get
but coerces its result to a list
as described in the syntax section.
Returns just the base of
config
without any parent.
Loads the config file
file
, prepending to
conf
if
provided.
(conf-load-in-path config-path file)
Search for and load any files named
file
in the
config-path
, which should be a list of strings.
(conf-load-cascaded config-path file [include-keyword])
Similar to conf-load-in-path, but also recursively loads any
"include" config files, indicated by a top-level
include-keyword
with either a string or symbol value.
Includes are loaded relative to the current file, and cycles
automatically ignored.
(conf-get config key [default])
Basic config lookup - retrieves the value from
config
associated with
key
. If not present, return
default
.
In
conf-get
and related accessors
key
can be either
a symbol, or a list of symbols. In the latter case, each symbol
is used as a key in turn, with the value taken as an alist to
further lookup values in.
(conf-get-list config key [default])
Equivalent to
conf-get
but coerces its result to a list
as described in the syntax section.
(conf-get-cdr config key . opt)
Equivalent to
conf-get
but always returns the
cdr
as-is without possibly taking its
car
.
(conf-get-multi config key)
Equivalent to
conf-get-list
but returns a list of all
cascaded configs appended together.
(conf-extend config alist [source])
Extends the config with anadditional alist.
Joins two configs.
(conf-unfold-key key value)
Utility to create an alist cell representing the chained key
key
mapped to
value
.
(conf-set config key value)
Replace a new definition into the first config alist.
(conf-specialize config key name)
Lift specialized sections to the top-level of a config.
(conf-verify spec config [warn])