Skip to content

Commit

Permalink
Merge branch 'main' into fix-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ewuerger authored Oct 1, 2024
2 parents 6330de6 + 998320a commit 350808d
Show file tree
Hide file tree
Showing 13 changed files with 332 additions and 158 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

Synchronise Capella models with Polarion projects.

![image](https://github.com/DSD-DBS/capella-polarion/blob/gh-pages/_static/c2p-uc1.GIF)
![image](./docs/source/_static/c2p-uc1.gif)

Use cases covered:

Expand Down
85 changes: 67 additions & 18 deletions capella2polarion/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,46 @@


@click.group()
@click.option("--debug", is_flag=True, default=False)
@click.option(
"--capella-model",
type=cli_helpers.ModelCLI(),
required=True,
envvar="CAPELLA2POLARION_CAPELLA_MODEL",
)
@click.option(
"--polarion-project-id",
type=str,
required=False,
default=None,
envvar="POLARION_PROJECT_ID",
required=True,
envvar="CAPELLA2POLARION_PROJECT_ID",
)
@click.option(
"--polarion-url",
envvar="POLARION_HOST",
type=str,
required=True,
envvar="POLARION_HOST",
)
@click.option("--polarion-pat", type=str, required=True, envvar="POLARION_PAT")
@click.option(
"--polarion-delete-work-items",
is_flag=True,
default=False,
envvar="CAPELLA2POLARION_DELETE_WORK_ITEMS",
)
@click.option(
"--debug", is_flag=True, envvar="CAPELLA2POLARION_DEBUG", default=False
)
@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.pass_context
def cli(
ctx: click.core.Context,
debug: bool,
capella_model: capellambse.MelodyModel | None,
polarion_project_id: str,
polarion_url: str,
polarion_pat: str,
polarion_delete_work_items: bool,
capella_model: capellambse.MelodyModel,
debug: bool,
) -> None:
"""Synchronise data from Capella to Polarion."""
if capella_model.diagram_cache is None:
if capella_model is not None and capella_model.diagram_cache is None:
logger.warning("It's highly recommended to define a diagram cache!")

capella2polarion_cli = Capella2PolarionCli(
Expand All @@ -76,18 +88,41 @@ def print_cli_state(capella2polarion_cli: Capella2PolarionCli) -> None:
@click.option(
"--synchronize-config",
type=click.File(mode="r", encoding="utf8"),
default=None,
required=True,
envvar="CAPELLA2POLARION_SYNCHRONIZE_CONFIG",
)
@click.option(
"--force-update",
is_flag=True,
envvar="CAPELLA2POLARION_FORCE_UPDATE",
default=False,
)
@click.option(
"--type-prefix",
type=str,
envvar="CAPELLA2POLARION_TYPE_PREFIX",
default="",
)
@click.option(
"--role-prefix",
type=str,
envvar="CAPELLA2POLARION_ROLE_PREFIX",
default="",
)
@click.option(
"--grouped-links-custom-fields / --no-grouped-links-custom-fields",
envvar="CAPELLA2POLARION_GROUPED_LINKS_CUSTOM_FIELDS",
is_flag=True,
default=True,
)
@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,
synchronize_config: typing.TextIO,
force_update: bool,
type_prefix: str,
role_prefix: str,
grouped_links_custom_fields: bool,
) -> None:
"""Synchronise model elements."""
capella_to_polarion_cli: Capella2PolarionCli = ctx.obj
Expand All @@ -100,6 +135,7 @@ def synchronize(
)
capella_to_polarion_cli.force_update = force_update

assert capella_to_polarion_cli.capella_model is not None
converter = model_converter.ModelConverter(
capella_to_polarion_cli.capella_model,
capella_to_polarion_cli.polarion_params.project_id,
Expand All @@ -124,6 +160,7 @@ def synchronize(
polarion_worker.polarion_data_repo,
generate_links=True,
generate_attachments=True,
generate_grouped_links_custom_fields=grouped_links_custom_fields,
)

polarion_worker.compare_and_update_work_items(converter.converter_session)
Expand All @@ -133,10 +170,21 @@ def synchronize(
@click.option(
"--document-rendering-config",
type=click.File(mode="r", encoding="utf8"),
default=None,
required=True,
envvar="CAPELLA2POLARION_DOCUMENT_CONFIG",
)
@click.option(
"--overwrite-layouts",
is_flag=True,
default=False,
envvar="CAPELLA2POLARION_OVERWRITE_LAYOUTS",
)
@click.option(
"--overwrite-numbering",
is_flag=True,
default=False,
envvar="CAPELLA2POLARION_OVERWRITE_NUMBERING",
)
@click.option("--overwrite-layouts", is_flag=True, default=False)
@click.option("--overwrite-numbering", is_flag=True, default=False)
@click.pass_context
def render_documents(
ctx: click.core.Context,
Expand All @@ -160,6 +208,7 @@ def render_documents(
configs.iterate_documents()
)

assert capella_to_polarion_cli.capella_model is not None
renderer = document_renderer.DocumentRenderer(
polarion_worker.polarion_data_repo,
capella_to_polarion_cli.capella_model,
Expand Down
2 changes: 1 addition & 1 deletion capella2polarion/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(
polarion_url: str,
polarion_pat: str,
polarion_delete_work_items: bool,
capella_model: capellambse.MelodyModel,
capella_model: capellambse.MelodyModel | None,
force_update: bool = False,
) -> None:
self.debug = debug
Expand Down
49 changes: 26 additions & 23 deletions capella2polarion/converters/link_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ def __init__(
converter_config.DIAGRAM_ELEMENTS_SERIALIZER: self._handle_diagram_reference_links, # pylint: disable=line-too-long
}

self._link_field_groups: dict[str, list[polarion_api.WorkItemLink]] = (
defaultdict(list)
)

def create_links_for_work_item(
self, uuid: str
) -> list[polarion_api.WorkItemLink]:
Expand All @@ -58,6 +62,7 @@ def create_links_for_work_item(
work_item = converter_data.work_item
assert work_item is not None
assert work_item.id is not None
self._link_field_groups.clear()
new_links: list[polarion_api.WorkItemLink] = []
link_errors: list[str] = []
for link_config in converter_data.type_config.links:
Expand All @@ -66,9 +71,7 @@ def create_links_for_work_item(
try:
assert work_item.id is not None
if serializer:
new_links.extend(
serializer(obj, work_item.id, role_id, {})
)
links = serializer(obj, work_item.id, role_id, {})
else:
refs = _resolve_attribute(obj, link_config.capella_attr)
new: cabc.Iterable[str]
Expand All @@ -88,9 +91,10 @@ def create_links_for_work_item(
new = set(
self._get_work_item_ids(work_item.id, new, role_id)
)
new_links.extend(
self._create(work_item.id, role_id, new, {})
)
links = self._create(work_item.id, role_id, new, {})

new_links.extend(links)
self._link_field_groups[link_config.link_field].extend(links)
except Exception as error:
error_message = make_link_logging_message(
f"{type(error).__name__} {str(error)}",
Expand Down Expand Up @@ -223,23 +227,22 @@ def create_grouped_link_fields(
assert work_item is not None
wi = f"[{work_item.id}]({work_item.type} {work_item.title})"
logger.debug("Building grouped links for work item %r...", wi)
for role, grouped_links in _group_by(
"role", work_item.linked_work_items
).items():
if (config := find_link_config(data, role)) is not None:
if back_links is not None and config.reverse_field:
for link in grouped_links:
back_links.setdefault(
link.secondary_work_item_id, {}
).setdefault(config.reverse_field, []).append(link)

if config.link_field:
self._create_link_fields(
work_item,
config.link_field,
grouped_links,
config=config,
)
for link_config in data.type_config.links:
grouped_links = self._link_field_groups[link_config.link_field]

if back_links is not None and link_config.reverse_field:
for link in grouped_links:
back_links.setdefault(
link.secondary_work_item_id, {}
).setdefault(link_config.reverse_field, []).append(link)

if grouped_links:
self._create_link_fields(
work_item,
link_config.link_field,
grouped_links,
config=link_config,
)

def _create_link_fields(
self,
Expand Down
16 changes: 12 additions & 4 deletions capella2polarion/converters/model_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def generate_work_items(
polarion_data_repo: polarion_repo.PolarionDataRepository,
generate_links: bool = False,
generate_attachments: bool = False,
generate_grouped_links_custom_fields: bool = False,
) -> dict[str, data_models.CapellaWorkItem]:
"""Return a work items mapping from model elements for Polarion.
Expand All @@ -100,6 +101,9 @@ def generate_work_items(
generate_attachments
A boolean flag to control attachments generation. For SVG
attachments, PNGs are generated and attached automatically.
generate_grouped_links_custom_fields
A boolean flag to control grouped links custom fields
generation.
"""
serializer = element_converter.CapellaWorkItemSerializer(
self.model,
Expand All @@ -113,13 +117,16 @@ def generate_work_items(
assert work_item.type is not None

if generate_links:
self.generate_work_item_links(polarion_data_repo)
self.generate_work_item_links(
polarion_data_repo, generate_grouped_links_custom_fields
)

return {wi.uuid_capella: wi for wi in work_items}

def generate_work_item_links(
self,
polarion_data_repo: polarion_repo.PolarionDataRepository,
generate_grouped_links_custom_fields: bool,
):
"""Generate links for all work items and add custom fields for them."""
back_links: dict[str, dict[str, list[polarion_api.WorkItemLink]]] = {}
Expand All @@ -140,9 +147,10 @@ def generate_work_item_links(
links = link_serializer.create_links_for_work_item(uuid)
converter_data.work_item.linked_work_items = links

link_serializer.create_grouped_link_fields(
converter_data, back_links
)
if generate_grouped_links_custom_fields:
link_serializer.create_grouped_link_fields(
converter_data, back_links
)

for uuid, converter_data in self.converter_session.items():
if converter_data.work_item is None:
Expand Down
20 changes: 10 additions & 10 deletions ci-templates/gitlab/render_documents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@

variables:
CAPELLA2POLARION_DEBUG: "0"
# Remember to set the following environment variables:
# POLARION_HOST
# POLARION_PAT
# CAPELLA2POLARION_PROJECT_ID
# CAPELLA2POLARION_CAPELLA_MODEL
# CAPELLA2POLARION_DOCUMENT_CONFIG
# Optional flags:
# CAPELLA2POLARION_OVERWRITE_LAYOUTS - Overwrite default Live-Doc layouts
# CAPELLA2POLARION_OVERWRITE_NUMBERING - Overwrite default heading numbering

capella2polarion_render_documents:
needs:
Expand All @@ -12,13 +21,4 @@ capella2polarion_render_documents:

script:
- pip install "capella2polarion${CAPELLA2POLARION_VERSION:+==$CAPELLA2POLARION_VERSION}"
- >
python \
-m capella2polarion \
$([[ $CAPELLA2POLARION_DEBUG -eq 1 ]] && echo '--debug') \
--polarion-project-id=${CAPELLA2POLARION_PROJECT_ID:?} \
--capella-model="${CAPELLA2POLARION_MODEL_JSON:?}" \
render-documents \
$([[ $CAPELLA2POLARION_OVERWRITE_LAYOUTS -eq 1 ]] && echo '--overwrite-layouts') \
$([[ $CAPELLA2POLARION_OVERWRITE_NUMBERING -eq 1 ]] && echo '--overwrite-numbering') \
--document-rendering-config="${CAPELLA2POLARION_DOCUMENT_CONFIG:?}"
- capella2polarion render-documents
22 changes: 11 additions & 11 deletions ci-templates/gitlab/synchronise_elements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@

variables:
CAPELLA2POLARION_DEBUG: "1"
# Remember to set the following environment variables:
# POLARION_HOST
# POLARION_PAT
# CAPELLA2POLARION_PROJECT_ID
# CAPELLA2POLARION_CAPELLA_MODEL
# CAPELLA2POLARION_SYNCHRONIZE_CONFIG
# Optional flags:
# CAPELLA2POLARION_FORCE_UPDATE - Simulate initial run
# CAPELLA2POLARION_TYPE_PREFIX - Prefix for work item types
# CAPELLA2POLARION_ROLE_PREFIX - Prefix for work item link roles

capella2polarion_synchronise_elements:
needs:
Expand All @@ -11,14 +21,4 @@ capella2polarion_synchronise_elements:

script:
- pip install "capella2polarion${CAPELLA2POLARION_VERSION:+==$CAPELLA2POLARION_VERSION}"
- >
python \
-m capella2polarion \
$([[ $CAPELLA2POLARION_DEBUG -eq 1 ]] && echo '--debug') \
--polarion-project-id=${CAPELLA2POLARION_PROJECT_ID:?} \
--capella-model="${CAPELLA2POLARION_MODEL_JSON:?}" \
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 synchronize
19 changes: 19 additions & 0 deletions docs/.readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
# SPDX-License-Identifier: CC0-1.0

# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

version: 2

build:
os: ubuntu-22.04
tools:
python: "3.12"

sphinx:
configuration: docs/source/conf.py

python:
install:
- requirements: docs/requirements.txt
Loading

0 comments on commit 350808d

Please sign in to comment.