Skip to content

Commit

Permalink
Implement high-level manipulation of version and release
Browse files Browse the repository at this point in the history
Signed-off-by: Nikola Forró <nforro@redhat.com>
  • Loading branch information
nforro committed Apr 26, 2022
1 parent 727564c commit 60c18b7
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
93 changes: 93 additions & 0 deletions specfile/specfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import contextlib
import datetime
import re
import subprocess
import types
from pathlib import Path
Expand Down Expand Up @@ -266,3 +267,95 @@ def add_changelog_entry(
elif email is not None:
author += f" <{email}>"
changelog.append(ChangelogEntry.assemble(timestamp, author, entry, evr))

@property
def version(self) -> str:
"""Version string as stored in the spec file."""
with self.tags() as tags:
return tags.version.value

@version.setter
def version(self, value: str) -> None:
with self.tags() as tags:
tags.version.value = value

@property
def expanded_version(self) -> str:
"""Version string with macros expanded."""
with self.tags() as tags:
return tags.version.expanded_value

@staticmethod
def _split_raw_release(raw_release: str) -> Tuple[str, str]:
"""
Splits raw release string into release and dist parts.
Args:
raw_release: Raw release string.
Returns:
Tuple of (release, dist).
"""
tokens = re.split(r"(%(?P<m>\{\??)?dist(?(m)\}))$", raw_release, maxsplit=1)[:2]
if len(tokens) == 2:
return tokens[0], tokens[1]
return tokens[0], ""

@classmethod
def _get_updated_release(cls, raw_release: str, release: str) -> str:
"""
Returns the specified raw release string updated with the specified release.
Args:
raw_release: Raw release string.
release: New release.
Returns:
Updated raw release string.
"""
_, dist = cls._split_raw_release(raw_release)
return f"{release}{dist}"

@property
def release(self) -> str:
"""Release string without the dist suffix."""
release, _ = self._split_raw_release(self.raw_release)
return release

@release.setter
def release(self, value: str) -> None:
self.raw_release = self._get_updated_release(self.raw_release, value)

@property
def raw_release(self) -> str:
"""Release string as stored in the spec file."""
with self.tags() as tags:
return tags.release.value

@raw_release.setter
def raw_release(self, value: str) -> None:
with self.tags() as tags:
tags.release.value = value

@property
def expanded_release(self) -> str:
"""Release string without the dist suffix with macros expanded."""
return self.expand(self.release)

@property
def expanded_raw_release(self) -> str:
"""Release string with macros expanded."""
with self.tags() as tags:
return tags.release.expanded_value

def set_version_and_release(self, version: str, release: str = "1") -> None:
"""
Sets both version and release at the same time.
Args:
version: Version string.
release: Release string, defaults to '1'.
"""
with self.tags() as tags:
tags.version.value = version
tags.release.value = self._get_updated_release(tags.release.value, release)
26 changes: 26 additions & 0 deletions tests/integration/test_specfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import subprocess

import pytest
import rpm
from flexmock import flexmock

from specfile.exceptions import SpecfileException
Expand Down Expand Up @@ -172,3 +173,28 @@ def test_add_changelog_entry(
spec.add_changelog_entry(entry, author, email, timestamp)
with spec.sections() as sections:
assert sections.changelog[: len(result)] == result


@pytest.mark.parametrize(
"version, release",
[
("0.2", "3"),
("67", "1"),
("1.4.6", "0.1rc5"),
],
)
def test_set_version_and_release(spec_minimal, version, release):
spec = Specfile(spec_minimal)
spec.set_version_and_release(version, release)
assert spec.version == version
assert spec.release == release
assert spec.raw_release.startswith(release)
with spec.tags() as tags:
assert tags.version.value == spec.version
assert tags.release.value == spec.raw_release
assert spec._spec.sourceHeader[rpm.RPMTAG_VERSION] == spec.expanded_version
assert spec._spec.sourceHeader[rpm.RPMTAG_RELEASE] == spec.expanded_raw_release
spec.raw_release = release
with spec.tags() as tags:
assert tags.release.value == release
assert spec._spec.sourceHeader[rpm.RPMTAG_RELEASE] == spec.expanded_raw_release
32 changes: 32 additions & 0 deletions tests/unit/test_specfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright Contributors to the Packit project.
# SPDX-License-Identifier: MIT

import pytest

from specfile.specfile import Specfile


@pytest.mark.parametrize(
"raw_release, release, dist",
[
("1%{?dist}", "1", "%{?dist}"),
("0.1%{prerelease}%{dist}", "0.1%{prerelease}", "%{dist}"),
("28%dist", "28", "%dist"),
("%{release_string}", "%{release_string}", ""),
],
)
def test_split_raw_release(raw_release, release, dist):
assert Specfile._split_raw_release(raw_release) == (release, dist)


@pytest.mark.parametrize(
"raw_release, release, result",
[
("1%{?dist}", "28", "28%{?dist}"),
("0.1%{prerelease}%{dist}", "1", "1%{dist}"),
("28%dist", "0.1", "0.1%dist"),
("%{release_string}", "1", "1"),
],
)
def test_get_updated_release(raw_release, release, result):
assert Specfile._get_updated_release(raw_release, release) == result

0 comments on commit 60c18b7

Please sign in to comment.