Skip to content

Commit

Permalink
refactor: Add prefixes in ConverterConfig
Browse files Browse the repository at this point in the history
Instead of adding them during the serialization
  • Loading branch information
ewuerger committed Aug 21, 2024
1 parent f1000c6 commit 3c2950d
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 62 deletions.
13 changes: 6 additions & 7 deletions capella2polarion/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
@click.option("--polarion-pat", envvar="POLARION_PAT", type=str)
@click.option("--polarion-delete-work-items", is_flag=True, default=False)
@click.option("--capella-model", type=cli_helpers.ModelCLI(), default=None)
@click.option("--type-prefix", type=str, default="")
@click.option("--role-prefix", type=str, default="")
@click.pass_context
def cli(
ctx: click.core.Context,
Expand All @@ -47,6 +49,8 @@ def cli(
polarion_pat: str,
polarion_delete_work_items: bool,
capella_model: capellambse.MelodyModel,
type_prefix: str,
role_prefix: str,
) -> None:
"""Synchronise data from Capella to Polarion."""
if capella_model.diagram_cache is None:
Expand All @@ -59,6 +63,8 @@ def cli(
polarion_pat,
polarion_delete_work_items,
capella_model,
type_prefix=type_prefix,
role_prefix=role_prefix,
)
capella2polarion_cli.setup_logger()
ctx.obj = capella2polarion_cli
Expand All @@ -79,15 +85,11 @@ def print_cli_state(capella2polarion_cli: Capella2PolarionCli) -> None:
default=None,
)
@click.option("--force-update", is_flag=True, default=False)
@click.option("--type-prefix", type=str, default="")
@click.option("--role-prefix", type=str, default="")
@click.pass_context
def synchronize(
ctx: click.core.Context,
force_update: bool,
synchronize_config: typing.TextIO,
type_prefix: str,
role_prefix: str,
) -> None:
"""Synchronise model elements."""
capella_to_polarion_cli: Capella2PolarionCli = ctx.obj
Expand All @@ -97,13 +99,10 @@ def synchronize(
)
capella_to_polarion_cli.load_synchronize_config(synchronize_config)
capella_to_polarion_cli.force_update = force_update
capella_to_polarion_cli.type_prefix = type_prefix
capella_to_polarion_cli.role_prefix = role_prefix

converter = model_converter.ModelConverter(
capella_to_polarion_cli.capella_model,
capella_to_polarion_cli.polarion_params.project_id,
type_prefix=capella_to_polarion_cli.type_prefix,
role_prefix=capella_to_polarion_cli.role_prefix,
)

Expand Down
80 changes: 47 additions & 33 deletions capella2polarion/converters/converter_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ def _default_type_conversion(c_type: str) -> str:
class ConverterConfig:
"""The overall Config for capella2polarion."""

def __init__(self):
def __init__(self, type_prefix: str = "", role_prefix: str = ""):
self.type_prefix = type_prefix
self.role_prefix = role_prefix

self._layer_configs: dict[str, dict[str, list[CapellaTypeConfig]]] = {}
self._global_configs: dict[str, CapellaTypeConfig] = {}
self.polarion_types = set[str]()
Expand All @@ -77,7 +80,7 @@ def read_config_file(self, synchronize_config: t.TextIO):
global_config_dict = config_dict.pop("*", {})
all_type_config = global_config_dict.pop("*", {})
global_links = all_type_config.get("links", [])
self.__global_config.links = _force_link_config(global_links)
self.__global_config.links = self._force_link_config(global_links)

if "Diagram" in global_config_dict:
diagram_config = global_config_dict.pop("Diagram") or {}
Expand Down Expand Up @@ -122,21 +125,21 @@ def set_layer_config(
# As we set up all types this way, we can expect that all
# non-compliant links are coming from global context here
closest_links = _filter_links(c_type, closest_config.links, True)
p_type = (
type_config.get("polarion_type")
or closest_config.p_type
or _default_type_conversion(c_type)
p_type = add_prefix(
(
type_config.get("polarion_type")
or closest_config.p_type
or _default_type_conversion(c_type)
),
self.type_prefix,
)
self.polarion_types.add(p_type)
links = self._force_link_config(type_config.get("links", []))
self._layer_configs[layer][c_type].append(
CapellaTypeConfig(
p_type,
type_config.get("serializer") or closest_config.converters,
_filter_links(
c_type,
_force_link_config(type_config.get("links", [])),
)
+ closest_links,
_filter_links(c_type, links) + closest_links,
type_config.get("is_actor", _C2P_DEFAULT),
type_config.get("nature", _C2P_DEFAULT),
)
Expand All @@ -152,7 +155,7 @@ def set_global_config(self, c_type: str, type_config: dict[str, t.Any]):
p_type,
type_config.get("serializer"),
_filter_links(
c_type, _force_link_config(type_config.get("links", []))
c_type, self._force_link_config(type_config.get("links", []))
)
+ self._get_global_links(c_type),
type_config.get("is_actor", _C2P_DEFAULT),
Expand All @@ -165,14 +168,39 @@ def set_diagram_config(self, diagram_config: dict[str, t.Any]):
p_type = diagram_config.get("polarion_type") or "diagram"
self.polarion_types.add(p_type)
links = _filter_links(
c_type, _force_link_config(diagram_config.get("links", []))
c_type, self._force_link_config(diagram_config.get("links", []))
)
self.diagram_config = CapellaTypeConfig(
p_type,
add_prefix(p_type, self.type_prefix),
diagram_config.get("serializer") or "diagram",
links + self._get_global_links(c_type),
)

def _force_link_config(self, links: t.Any) -> list[LinkConfig]:
result: list[LinkConfig] = []
for link in links:
if isinstance(link, str):
config = LinkConfig(
capella_attr=link,
polarion_role=add_prefix(link, self.role_prefix),
)
elif isinstance(link, dict):
config = LinkConfig(
capella_attr=(lid := link["capella_attr"]),
polarion_role=add_prefix(
link.get("polarion_role", lid), self.role_prefix
),
include=link.get("include", {}),
)
else:
logger.error(
"Link not configured correctly: %r",
link,
)
continue
result.append(config)
return result

def get_type_config(
self, layer: str, c_type: str, **attributes: t.Any
) -> CapellaTypeConfig | None:
Expand Down Expand Up @@ -252,25 +280,11 @@ def _force_dict(
raise TypeError("Unsupported Type")


def _force_link_config(links: t.Any) -> list[LinkConfig]:
result: list[LinkConfig] = []
for link in links:
if isinstance(link, str):
config = LinkConfig(capella_attr=link, polarion_role=link)
elif isinstance(link, dict):
config = LinkConfig(
capella_attr=(lid := link["capella_attr"]),
polarion_role=link.get("polarion_role", lid),
include=link.get("include", {}),
)
else:
logger.error(
"Link not configured correctly: %r",
link,
)
continue
result.append(config)
return result
def add_prefix(polarion_type: str, prefix: str) -> str:
"""Add a prefix to the given ``polarion_type``."""
if prefix:
return f"{prefix}_{polarion_type}"
return polarion_type


def _filter_links(
Expand Down
7 changes: 0 additions & 7 deletions capella2polarion/converters/element_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,11 @@ def __init__(
capella_polarion_mapping: polarion_repo.PolarionDataRepository,
converter_session: data_session.ConverterSession,
generate_attachments: bool,
type_prefix: str = "",
):
self.model = model
self.capella_polarion_mapping = capella_polarion_mapping
self.converter_session = converter_session
self.generate_attachments = generate_attachments
self.type_prefix = type_prefix
self.jinja_envs: dict[str, jinja2.Environment] = {}

def serialize_all(self) -> list[data_models.CapellaWorkItem]:
Expand Down Expand Up @@ -125,11 +123,6 @@ def serialize(self, uuid: str) -> data_models.CapellaWorkItem | None:
)
converter_data.work_item = None

if self.type_prefix and converter_data.work_item is not None:
converter_data.work_item.type = (
f"{self.type_prefix}_{converter_data.work_item.type}"
)

if converter_data.errors:
log_args = (
converter_data.capella_element._short_repr_(),
Expand Down
6 changes: 2 additions & 4 deletions capella2polarion/converters/link_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ def create_links_for_work_item(
for link_config in converter_data.type_config.links:
serializer = self.serializers.get(link_config.capella_attr)
role_id = link_config.polarion_role
if self.role_prefix:
role_id = f"{self.role_prefix}_{role_id}"
try:
if serializer:
new_links.extend(
Expand Down Expand Up @@ -225,13 +223,13 @@ def create_grouped_link_fields(
key = link.secondary_work_item_id
back_links.setdefault(key, []).append(link)

role_id = self._remove_prefix(role)
config: converter_config.LinkConfig | None = None
for link_config in data.type_config.links:
if link_config.polarion_role == role_id:
if link_config.polarion_role == role:
config = link_config
break

role_id = self._remove_prefix(role)
self._create_link_fields(
work_item, role_id, grouped_links, config=config
)
Expand Down
3 changes: 0 additions & 3 deletions capella2polarion/converters/model_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,10 @@ def __init__(
self,
model: capellambse.MelodyModel,
project_id: str,
type_prefix: str = "",
role_prefix: str = "",
):
self.model = model
self.project_id = project_id
self.type_prefix = type_prefix
self.role_prefix = role_prefix

self.converter_session: data_session.ConverterSession = {}
Expand Down Expand Up @@ -110,7 +108,6 @@ def generate_work_items(
polarion_data_repo,
self.converter_session,
generate_attachments,
self.type_prefix,
)
work_items = serializer.serialize_all()
for work_item in work_items:
Expand Down
6 changes: 3 additions & 3 deletions ci-templates/gitlab/synchronise_elements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ capella2polarion_synchronise_elements:
$([[ $CAPELLA2POLARION_DEBUG -eq 1 ]] && echo '--debug') \
--polarion-project-id=${CAPELLA2POLARION_PROJECT_ID:?} \
--capella-model="${CAPELLA2POLARION_MODEL_JSON:?}" \
${CAPELLA2POLARION_TYPE_PREFIX:+--type-prefix="$CAPELLA2POLARION_TYPE_PREFIX"} \
${CAPELLA2POLARION_ROLE_PREFIX:+--role-prefix="$CAPELLA2POLARION_ROLE_PREFIX"} \
synchronize \
--synchronize-config=${CAPELLA2POLARION_CONFIG:?} \
$([[ $CAPELLA2POLARION_FORCE_UPDATE -eq 1 ]] && echo '--force-update') \
${CAPELLA2POLARION_TYPE_PREFIX:+--type-prefix="$CAPELLA2POLARION_TYPE_PREFIX"} \
${CAPELLA2POLARION_ROLE_PREFIX:+--role-prefix="$CAPELLA2POLARION_ROLE_PREFIX"}
$([[ $CAPELLA2POLARION_FORCE_UPDATE -eq 1 ]] && echo '--force-update')
13 changes: 8 additions & 5 deletions tests/test_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -718,8 +718,10 @@ def test_create_link_from_single_attribute_with_role_prefix(
)

base_object.pw.polarion_data_repo.update_work_items([work_item_2])
base_object.mc.converter_session["uuid2"].work_item = work_item_2

converter_data = base_object.mc.converter_session["uuid2"]
converter_data.work_item = work_item_2
link_config = converter_data.type_config.links[0]
link_config.polarion_role = f"_C2P_{link_config.polarion_role}"
expected = polarion_api.WorkItemLink(
"Obj-2",
"Obj-1",
Expand All @@ -733,6 +735,7 @@ def test_create_link_from_single_attribute_with_role_prefix(
base_object.c2pcli.capella_model,
role_prefix="_C2P",
)

links = link_serializer.create_links_for_work_item("uuid2")

assert links == [expected]
Expand Down Expand Up @@ -1725,7 +1728,7 @@ def test_add_jinja_to_description(self, model: capellambse.MelodyModel):
def test_multiple_serializers(model: capellambse.MelodyModel, prefix: str):
cap = model.by_uuid(TEST_OCAP_UUID)
type_config = converter_config.CapellaTypeConfig(
"test",
f"{prefix}_test" if prefix else "test",
["include_pre_and_post_condition", "add_context_diagram"],
[],
)
Expand All @@ -1738,12 +1741,12 @@ def test_multiple_serializers(model: capellambse.MelodyModel, prefix: str):
)
},
True,
prefix,
)

work_item = serializer.serialize(TEST_OCAP_UUID)

assert work_item is not None
assert work_item.type is not None
assert work_item.type.startswith(prefix)
assert "preCondition" in work_item.additional_attributes
assert "postCondition" in work_item.additional_attributes
Expand Down Expand Up @@ -1810,13 +1813,13 @@ def test_generic_work_item_with_type_prefix(
}
type_config = config.get_type_config(layer, c_type, **attributes)
assert type_config is not None
type_config.p_type = f"{prefix}_{type_config.p_type}"
ework_item = data_models.CapellaWorkItem(id=f"{prefix}_TEST")
serializer = element_converter.CapellaWorkItemSerializer(
model,
polarion_repo.PolarionDataRepository([ework_item]),
{uuid: data_session.ConverterData(layer, type_config, obj)},
False,
prefix,
)

work_item = serializer.serialize(uuid)
Expand Down

0 comments on commit 3c2950d

Please sign in to comment.