build.ini, getting configuration
from
"Ethan Jucovy"
on Mar 10, 2008 09:21 PM
Spurred on by opencore's locally-failing vacuum.txt tests (they depend on
external configuration from build.ini which isn't guaranteed in the test
setup but is provided by fassembler) and inspired by a suggestion Robert
made last week about putting configuration behind an interface, I've written
a basic configuration parsing package for build.ini, fassembler.configparser,
which you can find here:
https://svn.openplans.org/svn/fassembler/configparser
It should allow somewhat easier and more uniform fetching of configuration
options from fassembler's build.ini format. When the package is installed,
you can use it within any application like
{{{
from fassembler.configparser.configparser import get_config
get_config(OPTION_I_WANT)
}}}
which will find the value of a key in build.ini that looks like
{{{
[applications]
MY_APPLICATION OPTION_I_WANT = key
}}}
or, failing that, will look for an `OPTION_I_WANT` key in the [general]
section.
Under the hood it just relies on a few assumptions to find the
MY_APPLICATION prefix based on the activated virtualenv. So note that it
does assume a certain application layout on the filesystem and the use of
virtualenv. As a fassembler-specific utility these seem like reasonable
assumptions to me.
It does mean though that our current rather ad-hoc build.ini layout would
have to be unified -- always prefix app-specific keys with the application
name and in [applications], and put non-app-specific keys in the [general]
section -- which I think is valuable in its own right. (Or of course we
could settle on any other configuration spelling and rewrite this utility
function. I'm kind of confused about our current setup actually -- what
goes in build.ini under [applications] and what goes in an
application-specific ini file like deliverance.ini? And what about the
options in the *-req.txt files?)
I've also begun to wrap this function behind an interface, so those of us in
zopeland can hook it up (which, with ZCMLLoader, should just be a matter of
easy_installing the package -- though I haven't tried this myself yet) and
say
{{{
from opencore.utility.interfaces import IProvideSiteConfig
getUtility(IProvideSiteConfig).get(OPTION_I_WANT)
}}}
As I see it, there are two major benefits here: it decouples the software
from the build tool (provided you go through the interfaces you don't need
to know anything about where the configuration options are coming from or
how and where they're stored) and it allows us to mock the configuration for
tests. Setting up a mock configuration utility in opencore should be pretty
easy now; if anyone wants to implement one before I get around to it (which
will be soon, I think, so that I can have a fully passing test suite...) my
thought is to extend IProvideSiteConfig.get with an optional `default`
parameter. The mock utility's implementation would just always return that
default.
There are a few more details I'm not quite sure about. I've deliberately
avoided putting this utility in opencore itself or making opencore depend on
it, since that would defeat the purpose of the decoupling. (For my own
unfassembled build I think I'm going to write another simple implementation
of the utility which I suppose I'll throw in SVN somewhere as well.)
However, if we do start using the IProvideSiteConfig utility universally in
opencore, we will need *some* implementation to be available. It may be
reasonable to leave it unimplemented by default and clarify that it's up to
the user to install one, or it might be better to implement a default
utility and hook up alternative ones as overrides. Either way I don't think
it's a big issue, though, and if we end up adopting this for opencore
fassembler's opencore-req.txt should eventually specify
fassembler.configparser so that the proper utility is available for
fassembled sites.
egj