Skip to content

Commit

Permalink
refactor: Massive restructuring, move all polarion/capella mappings i…
Browse files Browse the repository at this point in the history
…n a new repository class
  • Loading branch information
micha91 committed Jan 4, 2024
1 parent b7dfc66 commit bc90df6
Show file tree
Hide file tree
Showing 12 changed files with 734 additions and 691 deletions.
10 changes: 5 additions & 5 deletions capella2polarion/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
import click
from capellambse import cli_helpers

from capella2polarion import capella_work_item
from capella2polarion import polarion_worker as pw
from capella2polarion.capella2polarioncli import Capella2PolarionCli
from capella2polarion.elements import serialize
from capella2polarion.capella_polarion_conversion import element_converter

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -108,21 +109,21 @@ def synchronize(ctx: click.core.Context) -> None:
capella_to_polarion_cli.load_capella_diagramm_cache_index()
polarion_worker = pw.PolarionWorker(
capella_to_polarion_cli.polarion_params,
serialize.resolve_element_type,
capella_to_polarion_cli.capella_model,
element_converter.resolve_element_type,
)
assert (
capella_to_polarion_cli.capella_diagram_cache_index_content is not None
)
polarion_worker.load_elements_and_type_map(
capella_to_polarion_cli.synchronize_config_content,
capella_to_polarion_cli.capella_model,
capella_to_polarion_cli.capella_diagram_cache_index_content,
)

polarion_worker.fill_xtypes()
polarion_worker.load_polarion_work_item_map()
description_references: typing.Any = {}
new_work_items: dict[str, serialize.CapellaWorkItem]
new_work_items: dict[str, capella_work_item.CapellaWorkItem]
new_work_items = polarion_worker.create_work_items(
capella_to_polarion_cli.capella_diagram_cache_folder_path,
capella_to_polarion_cli.capella_model,
Expand All @@ -136,7 +137,6 @@ def synchronize(ctx: click.core.Context) -> None:
description_references,
)
polarion_worker.patch_work_items(
capella_to_polarion_cli.capella_model,
new_work_items,
description_references,
capella_to_polarion_cli.synchronize_config_roles,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@

import capellambse
import markupsafe
import polarion_rest_api_client as polarion_api
from capellambse import helpers as chelpers
from capellambse.model import common
from capellambse.model import diagram as diagr
from capellambse.model.crosslayer import capellacore, cs, interaction
from capellambse.model.layers import oa, pa
from lxml import etree

from capella2polarion.polarion_connector import polarion_repo

from .. import capella_work_item

RE_DESCR_LINK_PATTERN = re.compile(r"<a href=\"hlink://([^\"]+)\">([^<]+)</a>")
RE_DESCR_DELETED_PATTERN = re.compile(
f"<deleted element ({chelpers.RE_VALID_UUID.pattern})>"
Expand Down Expand Up @@ -54,20 +57,6 @@
logger = logging.getLogger(__name__)


class CapellaWorkItem(polarion_api.WorkItem):
"""A custom WorkItem class with additional capella related attributes."""

class Condition(t.TypedDict):
"""A class to describe a pre or post condition."""

type: str
value: str

uuid_capella: str
preCondition: Condition | None
postCondition: Condition | None


def resolve_element_type(type_: str) -> str:
"""Return a valid Type ID for polarion for a given ``obj``."""
return type_[0].lower() + type_[1:]
Expand Down Expand Up @@ -135,7 +124,9 @@ def _get_requirement_types_text(
return _format_texts(type_texts)


def _condition(html: bool, value: str) -> CapellaWorkItem.Condition:
def _condition(
html: bool, value: str
) -> capella_work_item.CapellaWorkItem.Condition:
_type = "text/html" if html else "text/plain"
return {"type": _type, "value": value}

Expand All @@ -145,11 +136,15 @@ class CapellaWorkItemSerializer:

diagram_cache_path: pathlib.Path
polarion_type_map: dict[str, str]
capella_polarion_mapping: polarion_repo.PolarionDataRepository
model: capellambse.MelodyModel
polarion_id_map: dict[str, str]
descr_references: dict[str, list[str]]

serializers: dict[
str, cabc.Callable[[common.GenericElement], CapellaWorkItem]
str,
cabc.Callable[
[common.GenericElement], capella_work_item.CapellaWorkItem
],
]
serializer_mapping: dict[str, str]

Expand All @@ -158,14 +153,14 @@ def __init__(
diagram_cache_path: pathlib.Path,
polarion_type_map: dict[str, str],
model: capellambse.MelodyModel,
polarion_id_map: dict[str, str],
capella_polarion_mapping: polarion_repo.PolarionDataRepository,
descr_references: dict[str, list[str]],
serializer_mapping: dict[str, str] | None = None,
):
self.diagram_cache_path = diagram_cache_path
self.polarion_type_map = polarion_type_map
self.model = model
self.polarion_id_map = polarion_id_map
self.capella_polarion_mapping = capella_polarion_mapping
self.descr_references = descr_references
self.serializers = {
"include_pre_and_post_condition": self.include_pre_and_post_condition,
Expand All @@ -177,7 +172,7 @@ def __init__(

def serialize(
self, obj: diagr.Diagram | common.GenericElement
) -> CapellaWorkItem | None:
) -> capella_work_item.CapellaWorkItem | None:
"""Return a CapellaWorkItem for the given diagram or element."""
try:
if isinstance(obj, diagr.Diagram):
Expand All @@ -195,7 +190,9 @@ def serialize(
logger.error("Serializing model element failed. %s", error.args[0])
return None

def diagram(self, diag: diagr.Diagram) -> CapellaWorkItem:
def diagram(
self, diag: diagr.Diagram
) -> capella_work_item.CapellaWorkItem:
"""Serialize a diagram for Polarion."""
diagram_path = self.diagram_cache_path / f"{diag.uuid}.svg"
src = _decode_diagram(diagram_path)
Expand All @@ -205,7 +202,7 @@ def diagram(self, diag: diagr.Diagram) -> CapellaWorkItem:
description = (
f'<html><p><img style="{style}" src="{src}" /></p></html>'
)
return CapellaWorkItem(
return capella_work_item.CapellaWorkItem(
type="diagram",
title=diag.name,
description_type="text/html",
Expand All @@ -216,13 +213,13 @@ def diagram(self, diag: diagr.Diagram) -> CapellaWorkItem:

def _generic_work_item(
self, obj: common.GenericElement
) -> CapellaWorkItem:
) -> capella_work_item.CapellaWorkItem:
xtype = self.polarion_type_map.get(obj.uuid, type(obj).__name__)
raw_description = getattr(obj, "description", markupsafe.Markup(""))
uuids, value = self._sanitize_description(obj, raw_description)
self.descr_references[obj.uuid] = uuids
requirement_types = _get_requirement_types_text(obj)
return CapellaWorkItem(
return capella_work_item.CapellaWorkItem(
type=resolve_element_type(xtype),
title=obj.name,
description_type="text/html",
Expand Down Expand Up @@ -286,15 +283,15 @@ def replace_markup(
except KeyError:
logger.error("Found link to non-existing model element: %r", uuid)
return strike_through(match.group(default_group))
if pid := self.polarion_id_map.get(uuid):
if pid := self.capella_polarion_mapping.get_work_item_id(uuid):
referenced_uuids.append(uuid)
return POLARION_WORK_ITEM_URL.format(pid=pid)
logger.warning("Found reference to non-existing work item: %r", uuid)
return match.group(default_group)

def include_pre_and_post_condition(
self, obj: PrePostConditionElement
) -> CapellaWorkItem:
) -> capella_work_item.CapellaWorkItem:
"""Return generic attributes and pre- and post-condition."""

def get_condition(cap: PrePostConditionElement, name: str) -> str:
Expand Down Expand Up @@ -328,14 +325,18 @@ def get_linked_text(
self.descr_references[obj.uuid] = uuids
return value

def constraint(self, obj: capellacore.Constraint) -> CapellaWorkItem:
def constraint(
self, obj: capellacore.Constraint
) -> capella_work_item.CapellaWorkItem:
"""Return attributes for a ``Constraint``."""
work_item = self._generic_work_item(obj)
# pylint: disable-next=attribute-defined-outside-init
work_item.description = self.get_linked_text(obj)
return work_item

def _include_actor_in_type(self, obj: cs.Component) -> CapellaWorkItem:
def _include_actor_in_type(
self, obj: cs.Component
) -> capella_work_item.CapellaWorkItem:
"""Return attributes for a ``Component``."""
work_item = self._generic_work_item(obj)
if obj.is_actor:
Expand All @@ -348,7 +349,7 @@ def _include_actor_in_type(self, obj: cs.Component) -> CapellaWorkItem:

def _include_nature_in_type(
self, obj: pa.PhysicalComponent
) -> CapellaWorkItem:
) -> capella_work_item.CapellaWorkItem:
"""Return attributes for a ``PhysicalComponent``."""
work_item = self._include_actor_in_type(obj)
xtype = work_item.type
Expand Down
Loading

0 comments on commit bc90df6

Please sign in to comment.