From 92b2ebd37807f1e46343e85cb17e6257aba19b61 Mon Sep 17 00:00:00 2001 From: ewuerger Date: Fri, 1 Sep 2023 11:45:52 +0200 Subject: [PATCH 1/2] fix(model-elements)!: Fix duplication of dynamically typed work items There are serializers that change the Capella type (e.g. `SystemComponent` -> `SystemActor`) based on attributes (`is_actor`). If these types are not appearing in the config, then no work items of this type won't be fetched via the REST API and in return they are created as new work items. This commit filters work items with invalid/unconfigured types out and logs these types. --- capella2polarion/elements/element.py | 42 +++++++++++++++++++--------- tests/test_elements.py | 2 ++ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/capella2polarion/elements/element.py b/capella2polarion/elements/element.py index 616065ed..9b95df21 100644 --- a/capella2polarion/elements/element.py +++ b/capella2polarion/elements/element.py @@ -11,7 +11,12 @@ import polarion_rest_api_client as polarion_api from capellambse.model import common -from capella2polarion.elements import POL2CAPELLA_TYPES, api_helper, serialize +from capella2polarion.elements import ( + POL2CAPELLA_TYPES, + api_helper, + helpers, + serialize, +) logger = logging.getLogger(__name__) @@ -23,22 +28,33 @@ def create_work_items(ctx: dict[str, t.Any]) -> None: """Create a set of work items in Polarion.""" - - def serialize_for_create( - obj: common.GenericElement, - ) -> serialize.CapellaWorkItem | None: - logger.debug( - "Create work item for model element %r...", obj._short_repr_() - ) - return serialize.element(obj, ctx, serialize.generic_work_item) - objects = chain.from_iterable(ctx["ELEMENTS"].values()) - work_items = [ - serialize_for_create(obj) + _work_items = [ + serialize.element(obj, ctx, serialize.generic_work_item) for obj in objects if obj.uuid not in ctx["POLARION_ID_MAP"] ] - work_items = list(filter(None.__ne__, work_items)) + _work_items = list(filter(None.__ne__, _work_items)) + valid_types = set(map(helpers.resolve_element_type, set(ctx["ELEMENTS"]))) + work_items: list[polarion_api.CapellaWorkItem] = [] + missing_types: set[str] = set() + for work_item in _work_items: + assert work_item is not None + if work_item.type in valid_types: + work_items.append(work_item) + else: + missing_types.add(work_item.type) + logger.debug( + "%r are missing in the capella2polarion configuration", + ", ".join(missing_types), + ) + + for work_item in work_items: + assert work_item is not None + obj = ctx["MODEL"].by_uuid(work_item.uuid_capella) + logger.debug( + "Create work item for model element %r...", obj._short_repr_() + ) if work_items: try: ctx["API"].create_work_items(work_items) diff --git a/tests/test_elements.py b/tests/test_elements.py index cacf4fd7..b0907f7c 100644 --- a/tests/test_elements.py +++ b/tests/test_elements.py @@ -189,6 +189,8 @@ def context() -> dict[str, t.Any]: def test_create_work_items( monkeypatch: pytest.MonkeyPatch, context: dict[str, t.Any] ): + context["MODEL"] = model = mock.MagicMock() + model.by_uuid.side_effect = context["ELEMENTS"]["FakeModelObject"] monkeypatch.setattr( serialize, "generic_work_item", From b09ce59767ae2846212a8b747d708a52f86e4f92 Mon Sep 17 00:00:00 2001 From: ewuerger Date: Fri, 1 Sep 2023 11:50:25 +0200 Subject: [PATCH 2/2] fix(serializer): Improve logging message for inline image errors --- capella2polarion/elements/serialize.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/capella2polarion/elements/serialize.py b/capella2polarion/elements/serialize.py index 34f6491b..b5f5131a 100644 --- a/capella2polarion/elements/serialize.py +++ b/capella2polarion/elements/serialize.py @@ -115,7 +115,7 @@ def _generic_work_item( ) -> CapellaWorkItem: xtype = ctx["POLARION_TYPE_MAP"].get(obj.uuid, type(obj).__name__) raw_description = getattr(obj, "description", markupsafe.Markup("")) - uuids, value = _sanitize_description(raw_description, ctx) + uuids, value = _sanitize_description(obj, raw_description, ctx) ctx.setdefault("DESCR_REFERENCES", {})[obj.uuid] = uuids return CapellaWorkItem( type=helpers.resolve_element_type(xtype), @@ -128,7 +128,7 @@ def _generic_work_item( def _sanitize_description( - descr: markupsafe.Markup, ctx: dict[str, t.Any] + obj: common.GenericElement, descr: markupsafe.Markup, ctx: dict[str, t.Any] ) -> tuple[list[str], markupsafe.Markup]: referenced_uuids: list[str] = [] replaced_markup = RE_DESCR_LINK_PATTERN.sub( @@ -151,7 +151,11 @@ def repair_images(node: etree._Element) -> None: b64_img = base64.b64encode(img.read()).decode("utf8") node.attrib["src"] = f"data:{mime_type};base64,{b64_img}" except FileNotFoundError: - logger.error("Inline image can't be found from %r", file_path) + logger.error( + "Inline image can't be found from %r for %r", + file_path, + obj._short_repr_(), + ) repaired_markup = chelpers.process_html_fragments( replaced_markup, repair_images