Add ConfigObj's validate.py and construct a config specification and use it to validate the configuration. Most crucially this causes ConfigObj to know about the correct types it should be converting the different entries into

This commit is contained in:
Chris Jones 2009-12-28 22:06:23 +00:00
parent f690cd6e5f
commit dc9ae3363d
2 changed files with 1533 additions and 2 deletions

View File

@ -44,9 +44,10 @@ import os
import sys import sys
from copy import copy from copy import copy
from configobj import ConfigObj from configobj import ConfigObj
from validate import Validator
from borg import Borg from borg import Borg
from factory import Factory from factory import Factory
from util import dbg, get_config_dir, dict_diff from util import dbg, err, DEBUG, get_config_dir, dict_diff
DEFAULTS = { DEFAULTS = {
'global_config': { 'global_config': {
@ -254,6 +255,64 @@ class ConfigBase(Borg):
if self.layouts is None: if self.layouts is None:
self.layouts = copy(DEFAULTS['layouts']) self.layouts = copy(DEFAULTS['layouts'])
def defaults_to_configspec(self):
"""Convert our tree of default values into a ConfigObj validation
specification"""
configspecdata = {}
section = {}
for key in DEFAULTS['global_config']:
keytype = DEFAULTS['global_config'][key].__class__.__name__
value = DEFAULTS['global_config'][key]
if keytype == 'int':
keytype = 'integer'
elif keytype == 'str':
keytype = 'string'
elif keytype == 'bool':
keytype = 'boolean'
elif keytype == 'list':
value = 'list(%s)' % ','.join(value)
keytype = '%s(default=%s)' % (keytype, value)
section[key] = keytype
configspecdata['global_config'] = section
section = {}
for key in DEFAULTS['keybindings']:
value = DEFAULTS['keybindings'][key]
if value is None:
continue
elif isinstance(value, tuple):
value = value[0]
section[key] = 'string(default=%s)' % value
configspecdata['keybindings'] = section
section = {}
for key in DEFAULTS['profiles']['default']:
keytype = DEFAULTS['profiles']['default'][key].__class__.__name__
value = DEFAULTS['profiles']['default'][key]
if keytype == 'int':
keytype = 'integer'
elif keytype == 'bool':
keytype = 'boolean'
elif keytype == 'str':
keytype = 'string'
value = '"%s"' % value
elif keytype == 'list':
value = 'list(%s)' % ','.join(value)
keytype = '%s(default=%s)' % (keytype, value)
section[key] = keytype
configspecdata['profiles'] = {}
configspecdata['profiles']['__many__'] = section
configspec = ConfigObj(configspecdata)
if DEBUG == True:
configspec.write(open('/tmp/configspec', 'w'))
return(configspec)
def load(self): def load(self):
"""Load configuration data from our various sources""" """Load configuration data from our various sources"""
if self.loaded is True: if self.loaded is True:
@ -267,7 +326,14 @@ class ConfigBase(Borg):
dbg('ConfigBase::load: Unable to open %s (%s)' % (filename, ex)) dbg('ConfigBase::load: Unable to open %s (%s)' % (filename, ex))
return return
parser = ConfigObj(configfile) configspec = self.defaults_to_configspec()
parser = ConfigObj(configfile, configspec=configspec)
validator = Validator()
result = parser.validate(validator, preserve_errors=True)
if result != True:
err('ConfigBase::load: config format is not valid')
for section_name in self.sections: for section_name in self.sections:
dbg('ConfigBase::load: Processing section: %s' % section_name) dbg('ConfigBase::load: Processing section: %s' % section_name)
section = getattr(self, section_name) section = getattr(self, section_name)

1465
terminatorlib/validate.py Normal file

File diff suppressed because it is too large Load Diff