From a2fb1c0b27223e8e93e3257e76a4e2ca105fbf82 Mon Sep 17 00:00:00 2001 From: Yuriy Taraday Date: Wed, 28 Sep 2016 17:21:52 +0300 Subject: [PATCH] Add 'ccp config dump' command This command dumps current config with all default vaules omitted from original config Change-Id: I4fda39903330452780c898be0cfae1c249e5f527 --- fuel_ccp/cli.py | 14 ++++++++++++++ fuel_ccp/config/__init__.py | 4 ++++ fuel_ccp/config/_yaml.py | 14 ++++++++++++++ fuel_ccp/tests/test_config_yaml.py | 29 +++++++++++++++++++++++++++++ setup.cfg | 1 + 5 files changed, 62 insertions(+) diff --git a/fuel_ccp/cli.py b/fuel_ccp/cli.py index 7c9c53e3..fd3d3ec7 100644 --- a/fuel_ccp/cli.py +++ b/fuel_ccp/cli.py @@ -161,6 +161,20 @@ class ShowDep(BaseCommand): dependencies.show_dep(parsed_args.components) +class ConfigDump(BaseCommand): + """Dump full current configuration to stdout""" + + def get_parser(self, *args, **kwargs): + parser = super(ConfigDump, self).get_parser(*args, **kwargs) + return parser + + def take_action(self, parsed_args): + if CONF.repositories.clone: + do_fetch() + config.load_component_defaults() + config.dump_yaml(self.app.stdout) + + def signal_handler(signo, frame): sys.exit(-signo) diff --git a/fuel_ccp/config/__init__.py b/fuel_ccp/config/__init__.py index fe98e10a..9471d58f 100644 --- a/fuel_ccp/config/__init__.py +++ b/fuel_ccp/config/__init__.py @@ -106,3 +106,7 @@ def load_component_defaults(): global _REAL_CONF new_config._merge(_REAL_CONF) _REAL_CONF = new_config + + +def dump_yaml(stream): + _yaml.dump(_REAL_CONF, stream) diff --git a/fuel_ccp/config/_yaml.py b/fuel_ccp/config/_yaml.py index 97a2a2da..51e46489 100644 --- a/fuel_ccp/config/_yaml.py +++ b/fuel_ccp/config/_yaml.py @@ -115,6 +115,20 @@ def load_with_includes(filename): return res +class Dumper(yaml.SafeDumper): + pass + + +def represent_attr_dict(dumper, data): + return dumper.represent_dict(data._dict) + +Dumper.add_representer(AttrDict, represent_attr_dict) + + +def dump(obj, stream): + yaml.dump(obj, stream, Dumper=Dumper, default_flow_style=False) + + class UnwrapAttrDict(dict): def __init__(self, attr_dict): return super(UnwrapAttrDict, self).__init__(attr_dict._dict) diff --git a/fuel_ccp/tests/test_config_yaml.py b/fuel_ccp/tests/test_config_yaml.py index 2049611b..83501389 100644 --- a/fuel_ccp/tests/test_config_yaml.py +++ b/fuel_ccp/tests/test_config_yaml.py @@ -1,4 +1,5 @@ import fixtures +import io import mock import six import testscenarios @@ -101,3 +102,31 @@ class TestLoadWithIncludes(testscenarios.WithScenarios, base.TestCase): res = _yaml.load_with_includes('config') self.assertEqual(res, self.expected_result) + + +class TestLoadDump(testscenarios.WithScenarios, base.TestCase): + scenarios = [ + ('simple', {'yaml': 'a: b\n', 'parsed': {'a': 'b'}}), + ('nested', { + 'yaml': 'a:\n b: c\n', + 'parsed': {'a': {'b': 'c'}}, + }), + ] + + yaml = None + parsed = None + + def test_load(self): + res = _yaml.load(self.yaml) + self.assertIsInstance(res, _yaml.AttrDict) + self.assertEqual(self.parsed, res) + + def test_dump(self): + obj = _yaml.AttrDict() + obj._merge(self.parsed) + if str is bytes: + stream = io.BytesIO() + else: + stream = io.StringIO() + _yaml.dump(obj, stream) + self.assertEqual(self.yaml, stream.getvalue()) diff --git a/setup.cfg b/setup.cfg index 108c6d2c..1288a5c1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,6 +33,7 @@ ccp.cli = fetch = fuel_ccp.cli:Fetch show-dep = fuel_ccp.cli:ShowDep validate = fuel_ccp.cli:Validate + config_dump = fuel_ccp.cli:ConfigDump [build_sphinx] source-dir = doc/source