Skip to content

Commit

Permalink
fix(model): Round namespace versions
Browse files Browse the repository at this point in the history
Fixes #417.
  • Loading branch information
Wuestengecko committed May 3, 2024
1 parent aaf8241 commit d87e4c7
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
14 changes: 14 additions & 0 deletions capellambse/_namespaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ class Plugin:
version: str | tuple[str, str] | None = None
viewpoint: str | None = None

version_precision: int = 1
"""Number of significant parts in the version number for namespaces.
When generating a versioned namespace URL from a Plugin, only this
many digits will be taken from the activated viewpoint. This allows
reusing the same namespace across subsequent minor plugin releases.
Example: A version of "1.2.3" with precision set to 2 will result in
the namespace version "1.2.0" being used.
Note that the used version number will always be padded with zeroes
to as many parts as there are in the original version number.
"""

def __post_init__(self) -> None:
if self.version is not None and self.viewpoint is None:
raise TypeError("Versioned plugins require a viewpoint")
Expand Down
31 changes: 31 additions & 0 deletions capellambse/loader/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,34 @@ def _unquote_ref(ref: str) -> str:
return ref


def _round_version(v: str, prec: int) -> str:
"""Round a version number.
Parameters
----------
v
The version number.
prec
Precision to round to, i.e. the number of leading non-zero
parts. Remaining parts will be set to zero.
Returns
-------
str
The rounded version number.
"""
assert prec > 0
pos = dots = 0
while pos < len(v) and dots < prec:
try:
pos = v.index(".", pos) + 1
except ValueError:
return v
else:
dots += 1
return v[:pos] + re.sub(r"[^.]+", "0", v[pos:])


class FragmentType(enum.Enum):
"""The type of an XML fragment."""

Expand Down Expand Up @@ -319,6 +347,9 @@ def update_namespaces(self, viewpoints: cabc.Mapping[str, str]) -> None:
raise CorruptModelError(
f"Viewpoint not activated: {plugin.viewpoint}"
)
vp_version = _round_version(
vp_version, plugin.version_precision
)
uri += f"/{vp_version}"

assert new_nsmap.get(ns) in (None, uri)
Expand Down
12 changes: 12 additions & 0 deletions tests/test_model_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,3 +595,15 @@ def test_model_diagram_visible_nodes_can_be_accessed_when_a_cache_was_specified(
model = capellambse.MelodyModel(TEST_MODEL_5_0, diagram_cache=tmp_path)

assert model.diagrams[0].nodes


def test_updated_namespaces_use_rounded_versions(
model_5_2: capellambse.MelodyModel,
):
model_5_2._loader.update_namespaces()

assert model_5_2.info.capella_version == "5.2.0"
nsver = model_5_2._element.nsmap[
"org.polarsys.capella.core.data.capellacommon"
].rsplit("/", 1)[-1]
assert nsver == "5.0.0"

0 comments on commit d87e4c7

Please sign in to comment.