consolidate yaml configuration

workaround ruamel.yaml issue 255,
where once an empty dict or list has been written,
'flow' style is used thereafter, using dense `{key: value}` form
instead of traditional yaml block style.
This commit is contained in:
Min RK
2018-11-01 11:34:16 +01:00
parent d79155380a
commit d331936812
4 changed files with 61 additions and 13 deletions

19
tests/test_yaml.py Normal file
View File

@@ -0,0 +1,19 @@
from tljh.yaml import yaml
def test_no_empty_flow(tmpdir):
path = tmpdir.join("config.yaml")
with path.open("w") as f:
f.write("{}")
# load empty config file
with path.open("r") as f:
config = yaml.load(f)
# set a value
config["key"] = "value"
# write to a file
with path.open("w") as f:
yaml.dump(config, f)
# verify that it didn't use compact '{}' flow-style
with path.open("r") as f:
content = f.read()
assert content.strip() == "key: value"

View File

@@ -13,14 +13,13 @@ tljh-config show firstlevel.second_level
"""
import argparse
from collections import Sequence, Mapping
from copy import deepcopy
import os
import re
import sys
from ruamel.yaml import YAML
from ruamel.yaml.comments import CommentedMap, CommentedSeq
yaml = YAML(typ='rt')
from .yaml import yaml
INSTALL_PREFIX = os.environ.get('TLJH_INSTALL_PREFIX', '/opt/tljh')
@@ -211,11 +210,11 @@ def parse_value(value_str):
def _is_dict(item):
return isinstance(item, (dict, CommentedMap))
return isinstance(item, Mapping)
def _is_list(item):
return isinstance(item, (list, CommentedSeq))
return isinstance(item, Sequence)
def main(argv=None):

View File

@@ -12,7 +12,6 @@ from urllib.error import HTTPError
from urllib.request import urlopen, URLError
import pluggy
from ruamel.yaml import YAML
from tljh import (
apt,
@@ -23,8 +22,7 @@ from tljh import (
traefik,
user,
)
from tljh.config import (
from .config import (
CONFIG_DIR,
CONFIG_FILE,
HUB_ENV_PREFIX,
@@ -32,10 +30,10 @@ from tljh.config import (
STATE_DIR,
USER_ENV_PREFIX,
)
from .yaml import yaml
HERE = os.path.abspath(os.path.dirname(__file__))
rt_yaml = YAML()
logger = logging.getLogger(__name__)
@@ -263,7 +261,7 @@ def ensure_admins(admins):
config_path = CONFIG_FILE
if os.path.exists(config_path):
with open(config_path, 'r') as f:
config = rt_yaml.load(f)
config = yaml.load(f)
else:
config = {}
@@ -271,7 +269,7 @@ def ensure_admins(admins):
config['users']['admin'] = list(admins)
with open(config_path, 'w+') as f:
rt_yaml.dump(config, f)
yaml.dump(config, f)
def ensure_jupyterhub_running(times=4):
@@ -388,7 +386,7 @@ def ensure_config_yaml(plugin_manager):
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, 'r') as f:
config = rt_yaml.load(f)
config = yaml.load(f)
else:
config = {}
@@ -396,7 +394,7 @@ def ensure_config_yaml(plugin_manager):
hook.tljh_config_post_install(config=config)
with open(CONFIG_FILE, 'w+') as f:
rt_yaml.dump(config, f)
yaml.dump(config, f)
def main():

32
tljh/yaml.py Normal file
View File

@@ -0,0 +1,32 @@
"""consolidated yaml API
ensures the same yaml settings for reading/writing
throughout tljh
"""
from ruamel.yaml.composer import Composer
from ruamel.yaml import YAML
class _NoEmptyFlowComposer(Composer):
"""yaml composer that avoids setting flow_style on empty
containers.
workaround ruamel.yaml issue #255
"""
def compose_mapping_node(self, anchor):
node = super().compose_mapping_node(anchor)
if not node.value:
node.flow_style = False
return node
def compose_sequence_node(self, anchor):
node = super().compose_sequence_node(anchor)
if not node.value:
node.flow_style = False
return node
# create the global yaml object:
yaml = YAML(typ="rt")
yaml.Composer = _NoEmptyFlowComposer