diff --git a/pretty_print.py b/pretty_print.py new file mode 100644 index 0000000..494d976 --- /dev/null +++ b/pretty_print.py @@ -0,0 +1,58 @@ +import click +import yaml +from jinja2 import Environment, FileSystemLoader +from diff_match_patch import diff_match_patch + + +def html_constructor(loader, node): + return str(node.value) + + +yaml.add_constructor("!html", html_constructor, Loader=yaml.FullLoader) + + +def generate_diff(previous, current): + dmp = diff_match_patch() + diff = dmp.diff_main("\n".join(previous), "\n".join(current)) + dmp.diff_cleanupSemantic(diff) + return dmp.diff_prettyHtml(diff) + +def traverse_and_diff(data): + """For every key "name" or "description" if it has + child keys "previous" and "current" we perform HtmlDiff + and store result in a new child key "diff". + """ + updates = {} + for key, value in data.items(): + if key in ["name", "description"] \ + and isinstance(value, dict) \ + and "previous" in value \ + and "current" in value: + diff = generate_diff( + value["previous"].splitlines(), + value["current"].splitlines() + ) + updates[key] = {"diff": diff} + elif isinstance(value, list): + for item in value: + traverse_and_diff(item) + elif isinstance(value, dict): + traverse_and_diff(value) + for key, value in updates.items(): + data[key].update(value) + return data + + +@click.command() +@click.argument("filename") +def main(filename): + with open(filename) as f: + data = yaml.load(f, Loader=yaml.FullLoader) + env = Environment(loader=FileSystemLoader(".")) + template = env.get_template("report.html.j2") + html = template.render(data=traverse_and_diff(data)) + with open("report.html", "w") as f: + f.write(html) + +if __name__ == "__main__": + main() diff --git a/report.html.j2 b/report.html.j2 new file mode 100644 index 0000000..3ce3d97 --- /dev/null +++ b/report.html.j2 @@ -0,0 +1,93 @@ + + + + + +

Object Changes

+
+ {% set LAYER = {"oa": "Operational Analysis", "sa": "System Analysis", "la": "Logical Architecture", "pa": "Physical Architecture"}%} + {% for layer in ["oa", "sa", "la", "pa"] %} +

{{LAYER[layer]}}

+
+ {% for obj_type in data["objects"][layer] %} + {% set obj_type_items = data["objects"][layer][obj_type] %} +

{{obj_type}}

+
+ {% if "created" in obj_type_items %} +

Created

+
+
    + {% for obj in obj_type_items["created"] %} +
  • {{obj["name"]}}
  • + {% endfor %} +
+
+ {% endif %} + + {% if "modified" in obj_type_items %} +

Modified

+
+ {% for obj in obj_type_items["modified"] %} +

{{ obj["display_name"] }}

+
    + {% for change in obj["changes"] %} +
  • {{ change }}: + {% if "diff" in obj["changes"][change] %} + {{ obj["changes"][change]["diff"] }} + {% else %} + {{ obj["changes"][change]["previous"] }} -> {{ obj["changes"][change]["current"] }} + {% endif %} +
  • + {% endfor %} +
+ {% endfor %} +
+ {% endif %} + + {% if "deleted" in obj_type_items %} +

Deleted

+
+
    + {% for obj in obj_type_items["deleted"] %} +
  • {{obj["name"]}}
  • + {% endfor %} +
+
+ {% endif %} +
+ {% endfor %} +
+ {% endfor %} +
+ + \ No newline at end of file