From df9df36d32a08fa99c4c133baa8f14d434f552c4 Mon Sep 17 00:00:00 2001 From: ewuerger Date: Mon, 18 Nov 2024 16:34:59 +0100 Subject: [PATCH] feat: Delete dangling representation descriptors --- capella_git_hooks/fix_links.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/capella_git_hooks/fix_links.py b/capella_git_hooks/fix_links.py index 7c29d56..0ebfc86 100644 --- a/capella_git_hooks/fix_links.py +++ b/capella_git_hooks/fix_links.py @@ -21,6 +21,7 @@ import click from capellambse import filehandler, helpers, loader +from lxml import etree LOGGER = logging.getLogger(__name__) # FIXME This isn't conventional-commits compliant, and might fail checks @@ -125,10 +126,16 @@ def fix_model(model: loader.MelodyLoader) -> bool: True if the model was modified, False otherwise. """ dirty = False + marked_for_deletion: list[etree._Element] = [] for element in model.iterall(): + try: + sourcefrag = model.find_fragment(element) + except ValueError: + continue + if element.tag == "semanticResources": if element.text == "": - element.getparent().remove(element) + marked_for_deletion.append(element) continue targetfrag = urllib.parse.unquote(element.text.rsplit("/", 1)[-1]) @@ -140,9 +147,8 @@ def fix_model(model: loader.MelodyLoader) -> bool: " https://github.com/DSD-DBS/capella-git-hooks" ) - sourcefrag = model.find_fragment(element) if sourcefrag == frags[0]: - element.getparent().remove(element) + marked_for_deletion.append(element) continue link = os.path.relpath(frags[0], sourcefrag.parent) @@ -164,11 +170,22 @@ def fix_model(model: loader.MelodyLoader) -> bool: new_links: list[str] = [] for link in links: - _, _, target_id = link.partition("#") + start, _, target_id = link.partition("#") try: target = model.follow_link(None, target_id) except KeyError: - LOGGER.error("Cannot repair dangling link: #%s", target_id) + if ( + element.tag == "ownedRepresentationDescriptors" + and start.startswith("cdo://") + ): + ft = model.trees[sourcefrag].fragment_type + if ft == loader.FragmentType.VISUAL: + marked_for_deletion.append(element) + continue + else: + LOGGER.error( + "Cannot repair dangling link: #%s", target_id + ) else: link = model.create_link( element, @@ -182,6 +199,9 @@ def fix_model(model: loader.MelodyLoader) -> bool: element.attrib[attr] = new_value dirty = True + for element in marked_for_deletion: + element.getparent().remove(element) + return dirty