Skip to content

Version strategy contracts

VersionStrategy.compare_versions(current, *, target) compares the current version with a target. The result is -1 for older, 0 for equal and 1 for newer. Comparison does not read a file, select an upgrade or mutate a system.

Semantic versioning

SemanticVersioningStrategy() compares semantic-version strings. It does not expose the former examples’ get_version, set_version, or compare methods and takes no version_field or default_version configuration.

>>> from r2x_core import SemanticVersioningStrategy
>>> strategy = SemanticVersioningStrategy()
>>> # Expected: ordering follows semantic versions, not lexical string order.
>>> strategy.compare_versions("1.9.0", target="1.10.0")
-1
>>> strategy.compare_versions("2.0.0", target="1.0.0")
1
>>> strategy.compare_versions("1.0.0", target="1.0.0")
0

Git history order

GitVersioningStrategy(commit_history) accepts a nonempty list ordered oldest to newest. Comparisons use positions in that supplied history, not timestamps or lexical ordering. Unknown commits and a missing current version raise ValueError. The labels below stand in for known identifiers in a supplied history; no Git repository or network request is needed to test ordering.

>>> from r2x_core import GitVersioningStrategy
>>> strategy = GitVersioningStrategy(["older", "middle", "newer"])
>>> # Expected: the first supplied history entry precedes the last.
>>> strategy.compare_versions("older", target="newer")
-1
>>> strategy.compare_versions("newer", target="middle")
1
>>> try:
...     strategy.compare_versions("unknown", target="newer")
... except ValueError as error:
...     assert "not found in history" in str(error)
...     print(type(error).__name__)
ValueError

Version readers

VersionReader.read_version(folder_path: Path) is a protocol returning a version string or None. A model package implements its own file/layout convention. This complete example reads an actual temporary VERSION file:

>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> from r2x_core import VersionReader
>>> class TextVersionReader:
...     def read_version(self, folder_path: Path) -> str | None:
...         path = folder_path / "VERSION"
...         return path.read_text(encoding="utf-8").strip() if path.is_file() else None
>>> reader: VersionReader = TextVersionReader()
>>> with TemporaryDirectory() as directory:
...     root = Path(directory)
...     before = reader.read_version(root)
...     _ = (root / "VERSION").write_text("1.2.3\n", encoding="utf-8")
...     after = reader.read_version(root)
>>> # Expected: absence is distinct from the version read from the created file.
>>> before, after
(None, '1.2.3')

Use manage versions for selection guidance, upgrade steps for transformation/error contracts, and the generated API for signatures and pinned source.