From 66e16fe4a2d7903feefa92fc8ccc7ab687364059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czy=C5=BC?= Date: Wed, 9 Jul 2014 00:20:17 +0100 Subject: [PATCH] add YAML config parser --- cement/ext/ext_yaml.py | 21 +++++++++++++ tests/ext/yaml_tests.py | 65 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/cement/ext/ext_yaml.py b/cement/ext/ext_yaml.py index cb82d85a..f919ccca 100644 --- a/cement/ext/ext_yaml.py +++ b/cement/ext/ext_yaml.py @@ -1,9 +1,11 @@ """YAML Framework Extension""" +import os import sys import yaml from ..core import backend, output, hook, handler from ..utils.misc import minimal_logger +import cement.ext.ext_configparser LOG = minimal_logger(__name__) @@ -78,8 +80,27 @@ def set_output_handler(app): app._setup_output_handler() +class YamlConfigHandler(cement.ext.ext_configobj.ConfigObjConfigHandler): + class Meta: + interface = cement.core.config.IConfig + label = 'yaml' + + def parse_file(self, file_path): + file_path = os.path.abspath(os.path.expanduser(file_path)) + if os.path.exists(file_path): + LOG.debug("config file '%s' exists, loading settings..." % + file_path) + self.merge(dict(yaml.load(open(file_path)))) + return True + else: + LOG.debug("config file '%s' does not exist, skipping..." % + file_path) + return False + + def load(): """Called by the framework when the extension is 'loaded'.""" handler.register(YamlOutputHandler) + handler.register(YamlConfigHandler) hook.register('post_setup', add_yaml_option) hook.register('pre_run', set_output_handler) diff --git a/tests/ext/yaml_tests.py b/tests/ext/yaml_tests.py index 3aed7ae4..d91b8171 100644 --- a/tests/ext/yaml_tests.py +++ b/tests/ext/yaml_tests.py @@ -1,9 +1,13 @@ """Tests for cement2.ext.ext_yaml.""" +import os +import sys import yaml +from tempfile import mkstemp from cement.core import handler, hook from cement.utils import test + class YamlExtTestCase(test.CementTestCase): def setUp(self): self.app = self.make_app('tests', @@ -18,3 +22,64 @@ class YamlExtTestCase(test.CementTestCase): res = self.app.render(dict(foo='bar')) yaml_res = yaml.dump(dict(foo='bar')) self.eq(res, yaml_res) + + +class YamlConfigHandlerTestCase(test.CementTestCase): + CONFIG = ''' + section: + subsection: + list: + - item1 + - item2 + - item3 + - item4 + key: value + key1: ok1 + key2: ok2 + ''' + CONFIG_PARSED = dict( + section=dict( + subsection=dict( + list=['item1', 'item2', 'item3', 'item4'], + key='value'), + key1='ok1', + key2='ok2')) + + def setUp(self): + _, self.tmppath = mkstemp() + f = open(self.tmppath, 'w+') + f.write(self.CONFIG) + f.close() + self.app = self.make_app('myapp', + extensions=['yaml'], + config_handler='yaml', + config_files = [self.tmppath], + argv=[] + ) + + def tearDown(self): + if os.path.exists(self.tmppath): + os.remove(self.tmppath) + + def test_configobj(self): + self.app.setup() + + def test_has_section(self): + self.app.setup() + self.ok(self.app.config.has_section('section')) + + def test_keys(self): + self.app.setup() + res = 'subsection' in self.app.config.keys('section') + self.ok(res) + + def test_parse_file_bad_path(self): + self.app._meta.config_files = ['./some_bogus_path'] + self.app.setup() + + def test_parse_file(self): + self.app.setup() + self.eq(self.app.config.get('section', 'key1'), 'ok1') + + self.eq(self.app.config.get_section_dict('section'), + self.CONFIG_PARSED['section'])