diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index fbe45c51..e0394d15 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -14,6 +14,7 @@ import json import os import re import subprocess +import sys import urllib import yaml @@ -153,98 +154,120 @@ def get_json_schema_object_fields(obj, enforce_title=False, required_keys = set(obj.get("required", [])) - fields = { - "title": obj.get("title"), - "rows": [] - } - - tables = [fields] + obj_title = obj.get("title") + first_table_rows = [] + tables = [] for key_name in props: - logger.debug("Processing property %s.%s", obj.get('title'), key_name) - prop = inherit_parents(props[key_name]) + try: + logger.debug("Processing property %s.%s", obj_title, key_name) + required = key_name in required_keys + res = process_prop(key_name, props[key_name], required, + mark_required) + + first_table_rows.append(res["row"]) + tables.extend(res["tables"]) + logger.debug("Done property %s" % key_name) + + except Exception, e: + e2 = Exception("Error reading property %s.%s: %s" % + (obj_title, key_name, str(e))) + raise e2, None, sys.exc_info()[2] + - value_type = None - required = key_name in required_keys - desc = prop.get("description", "") - prop_type = prop.get('type') + tables.insert(0, { + "title": obj_title, + "rows": first_table_rows, + }) - if prop_type is None: - raise KeyError("Property '%s' of object '%s' missing 'type' field" - % (key_name, obj)) - logger.debug("%s is a %s", key_name, prop_type) + return tables + +def process_prop(key_name, prop, required, mark_required): + prop = inherit_parents(prop) + + value_type = None + desc = prop.get("description", "") + prop_type = prop.get('type') + tables = [] + + if prop_type is None: + raise KeyError("Property '%s' of object '%s' missing 'type' field" + % (key_name, obj)) + logger.debug("%s is a %s", key_name, prop_type) - if prop_type == "object": + if prop_type == "object": + nested_objects = get_json_schema_object_fields( + prop, + enforce_title=True, + mark_required=mark_required, + ) + value_type = nested_objects[0]["title"] + value_id = value_type + + tables += [x for x in nested_objects if not x.get("no-table")] + elif prop_type == "array": + items = inherit_parents(prop["items"]) + # if the items of the array are objects then recurse + if items["type"] == "object": nested_objects = get_json_schema_object_fields( - prop, + items, enforce_title=True, mark_required=mark_required, ) - value_type = nested_objects[0]["title"] - value_id = value_type - - tables += [x for x in nested_objects if not x.get("no-table")] - elif prop_type == "array": - items = inherit_parents(prop["items"]) - # if the items of the array are objects then recurse - if items["type"] == "object": - nested_objects = get_json_schema_object_fields( - items, - enforce_title=True, - mark_required=mark_required, - ) - value_id = nested_objects[0]["title"] - value_type = "[%s]" % value_id - tables += nested_objects - else: - value_type = items["type"] - if isinstance(value_type, list): - value_type = " or ".join(value_type) - value_id = value_type - value_type = "[%s]" % value_type - array_enums = items.get("enum") - if array_enums: - if len(array_enums) > 1: - value_type = "[enum]" - desc += ( - " One of: %s" % json.dumps(array_enums) - ) - else: - desc += ( - " Must be '%s'." % array_enums[0] - ) + value_id = nested_objects[0]["title"] + value_type = "[%s]" % value_id + tables += nested_objects else: - value_type = prop_type - value_id = prop_type - if prop.get("enum"): - if len(prop["enum"]) > 1: - value_type = "enum" - if desc: - desc += " " + value_type = items["type"] + if isinstance(value_type, list): + value_type = " or ".join(value_type) + value_id = value_type + value_type = "[%s]" % value_type + array_enums = items.get("enum") + if array_enums: + if len(array_enums) > 1: + value_type = "[enum]" desc += ( - "One of: %s" % json.dumps(prop["enum"]) + " One of: %s" % json.dumps(array_enums) ) else: - if desc: - desc += " " desc += ( - "Must be '%s'." % prop["enum"][0] + " Must be '%s'." % array_enums[0] ) - if isinstance(value_type, list): - value_type = " or ".join(value_type) + else: + value_type = prop_type + value_id = prop_type + if prop.get("enum"): + if len(prop["enum"]) > 1: + value_type = "enum" + if desc: + desc += " " + desc += ( + "One of: %s" % json.dumps(prop["enum"]) + ) + else: + if desc: + desc += " " + desc += ( + "Must be '%s'." % prop["enum"][0] + ) + if isinstance(value_type, list): + value_type = " or ".join(value_type) + + + if required and mark_required: + desc = "**Required.** " + desc - if required and mark_required: - desc = "**Required.** " + desc - fields["rows"].append({ + return { + "row": { "key": key_name, "type": value_type, "id": value_id, "required": required, "desc": desc, - }) - logger.debug("Done property %s" % key_name) - - return tables + }, + "tables": tables, + } def get_tables_for_schema(schema, mark_required=True): @@ -611,89 +634,100 @@ class MatrixUnits(Units): if not filename.startswith("m."): continue filepath = os.path.join(path, filename) - self.log("Reading %s" % filepath) - with open(filepath, "r") as f: - json_schema = yaml.load(f) - schema = { - "typeof": None, - "typeof_info": "", - "type": None, - "title": None, - "desc": None, - "msgtype": None, - "content_fields": [ - # { - # title: "