52 lines
1.5 KiB
Python
52 lines
1.5 KiB
Python
from collections import OrderedDict
|
|
|
|
import cimodel.lib.miniutils as miniutils
|
|
|
|
|
|
LIST_MARKER = "- "
|
|
INDENTATION_WIDTH = 2
|
|
|
|
|
|
def is_dict(data):
|
|
return type(data) in [dict, OrderedDict]
|
|
|
|
|
|
def is_collection(data):
|
|
return is_dict(data) or type(data) is list
|
|
|
|
|
|
def render(fh, data, depth, is_list_member=False):
|
|
"""
|
|
PyYaml does not allow precise control over the quoting
|
|
behavior, especially for merge references.
|
|
Therefore, we use this custom YAML renderer.
|
|
"""
|
|
|
|
indentation = " " * INDENTATION_WIDTH * depth
|
|
|
|
if is_dict(data):
|
|
tuples = list(data.items())
|
|
if type(data) is not OrderedDict:
|
|
tuples.sort()
|
|
|
|
for i, (k, v) in enumerate(tuples):
|
|
if not v:
|
|
continue
|
|
# If this dict is itself a list member, the first key gets prefixed with a list marker
|
|
list_marker_prefix = LIST_MARKER if is_list_member and not i else ""
|
|
|
|
trailing_whitespace = "\n" if is_collection(v) else " "
|
|
fh.write(indentation + list_marker_prefix + k + ":" + trailing_whitespace)
|
|
|
|
render(fh, v, depth + 1 + int(is_list_member))
|
|
|
|
elif type(data) is list:
|
|
for v in data:
|
|
render(fh, v, depth, True)
|
|
|
|
else:
|
|
# use empty quotes to denote an empty string value instead of blank space
|
|
modified_data = miniutils.quote(data) if data == "" else data
|
|
list_member_prefix = indentation + LIST_MARKER if is_list_member else ""
|
|
fh.write(list_member_prefix + str(modified_data) + "\n")
|