diff env/lib/python3.9/site-packages/planemo/shed/diff.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.9/site-packages/planemo/shed/diff.py	Mon Mar 22 18:12:50 2021 +0000
@@ -0,0 +1,66 @@
+"""Utilities for calculating effective repository diffs.
+
+Some intelligence is required because the tool shed updates attributes that it
+is beneficial to ignore.
+"""
+from __future__ import print_function
+
+import os
+import sys
+from xml.etree import ElementTree
+
+from planemo.xml import diff
+
+
+def diff_and_remove(working, label_a, label_b, f):
+    """Remove tool shed XML files and use a smart XML diff on them.
+
+    Return 0 if and only if the XML content is the sam after stripping
+    attirbutes the tool shed updates.
+    """
+    assert label_a != label_b
+    special = ["tool_dependencies.xml", "repository_dependencies.xml"]
+    deps_diff = 0
+    # Could walk either A or B; will only compare if in same relative location
+    for dirpath, dirnames, filenames in os.walk(os.path.join(working, label_a)):
+        for filename in filenames:
+            if filename in special:
+                a = os.path.join(dirpath, filename)
+                b = os.path.join(working, label_b, os.path.relpath(a, os.path.join(working, label_a)))
+                files_exist = os.path.exists(a) and os.path.exists(b)
+                if files_exist:
+                    deps_diff |= _shed_diff(a, b, f)
+                    os.remove(a)
+                    os.remove(b)
+    return deps_diff
+
+
+def _shed_diff(file_a, file_b, f=sys.stdout):
+    """Strip attributes the tool shed writes and do smart XML diff.
+
+    Returns 0 if and only if the XML content is the same after stripping
+    ``tool_shed`` and ``changeset_revision`` attributes.
+    """
+    xml_a = ElementTree.parse(file_a).getroot()
+    xml_b = ElementTree.parse(file_b).getroot()
+    _strip_shed_attributes(xml_a)
+    _strip_shed_attributes(xml_b)
+    return diff.diff(xml_a, xml_b, reporter=f.write)
+
+
+def _strip_shed_attributes(xml_element):
+    if xml_element.tag == "repository":
+        _remove_attribs(xml_element)
+    for child in xml_element:
+        _strip_shed_attributes(child)
+
+
+def _remove_attribs(xml_element):
+    for attrib in ["changeset_revision", "toolshed"]:
+        if attrib in xml_element.attrib:
+            del xml_element.attrib[attrib]
+
+
+__all__ = (
+    "diff_and_remove",
+)