Skip to content

Commit 80f373a

Browse files
committed
Initial implementation of rightmost bumps
Adds new magic comments supported in commits: [bump_rightmost: 3] [start_rightmost] This should implement missing z-stream type bumps used mainly in RHEL already released branches fixes. It is needed to ensure latest branch build is always preferred after upgrade to higher version. In Fedora regular mass rebuilds mitigates the need for something similar. But it could be still used when doing rebase in multiple branches, where only rawhide build should always have highest release. This is attempt to provide user-friendly alternative to manual calls of rpmdev-bumpspec -r command. Signed-off-by: Petr Menšík <pemensik@redhat.com>
1 parent d36d3f6 commit 80f373a

2 files changed

Lines changed: 74 additions & 19 deletions

File tree

rpmautospec/magic_comments.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
import re
2-
from typing import NamedTuple
2+
import typing
33

44
magic_comment_re = re.compile(r"^\s*\[(?P<magic>.*)\]\s*$")
5-
skip_changelog_re = re.compile(r"\s*skip\s+changelog\s*")
6-
bump_release_re = re.compile(r"\s*bump\s+release\s*(?::\s*)?(?P<bump_value>\d+)\s*")
5+
intvalue_re = re.compile(r"\s*(?P<keyname>[a-z]+([\s_]+[a-z]+)*)\s*(?::\s*)?(?P<value>\d+)\s*")
76

87

9-
class MagicCommentResult(NamedTuple):
10-
skip_changelog: bool
11-
bump_release: int
8+
class MagicCommentResult(typing.NamedTuple):
9+
"""Do not include this commit in changelog."""
10+
skip_changelog: bool = False
11+
"""Start increasing number on the right of release string, not left."""
12+
start_rightmost: bool = False
13+
"""Bump release to specified number."""
14+
bump_release: int = 0
15+
"""Bump rightmost of the release to specified number."""
16+
bump_rightmost: int = 0
1217

1318

1419
def parse_magic_comments(message: str) -> MagicCommentResult:
15-
skip_changelog = False
16-
bump_release = 0
20+
types = typing.get_type_hints(MagicCommentResult)
21+
values = dict()
1722

1823
for line in message.split("\n"):
1924
if l_match := magic_comment_re.match(line):
2025
for part in l_match.group("magic").split(","):
21-
if skip_changelog_re.match(part):
22-
skip_changelog = True
23-
if br_match := bump_release_re.match(part):
24-
bump_release = max(bump_release, int(br_match.group("bump_value")))
26+
part = part.strip().replace(" ", "_")
27+
if part in types and types[part] is bool:
28+
values[part] = True
29+
elif br_match := intvalue_re.match(part):
30+
keyname = br_match.group("keyname")
31+
if keyname in types and types[keyname] is int:
32+
values[keyname] = int(br_match.group("value"))
33+
else:
34+
raise ValueError(f"Parameter \"{keyname}\" "
35+
"is not recognized int type magic")
2536

26-
return MagicCommentResult(skip_changelog=skip_changelog, bump_release=bump_release)
37+
return MagicCommentResult(**values)

rpmautospec/pkg_history.py

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ def __init__(self, spec_or_path: Union[str, Path]):
8787
self.repo = None
8888

8989
self._rpmverflags_for_commits = {}
90+
self.rightmost_bumps = False
9091

9192
@staticmethod
9293
def _get_rpm_packager() -> str:
@@ -217,10 +218,13 @@ def release_number_visitor(self, commit: pygit2.Commit, child_info: dict[str, An
217218
base = verflags["base"]
218219
if base is None:
219220
base = 1
221+
right_base = verflags.get("right_base", 1)
222+
if right_base is None:
223+
right_base = 1
220224
tag_string = "".join(f".{t}" for t in (verflags["extraver"], verflags["snapinfo"]) if t)
221225
else:
222226
epoch_version = prerelease = None
223-
base = 1
227+
base = right_base = 1
224228
tag_string = ""
225229

226230
if not epoch_version:
@@ -247,13 +251,22 @@ def release_number_visitor(self, commit: pygit2.Commit, child_info: dict[str, An
247251

248252
commit_result["verflags"] = commit_verflags
249253
commit_result["epoch-version"] = epoch_version
250-
commit_result["magic-comment-result"] = parse_magic_comments(commit.message)
254+
magic_comments = parse_magic_comments(commit.message)
255+
commit_result["magic-comment-result"] = magic_comments
256+
257+
if magic_comments.start_rightmost:
258+
log.debug("\tstarting rightmost bumps")
259+
self.rightmost_bumps = True
251260

252261
log.debug("\tepoch_version: %s", epoch_version)
253262
log.debug(
254263
"\tparent rel numbers: %s",
255264
", ".join(str(res["release-number"]) if res else "none" for res in parent_results),
256265
)
266+
log.debug(
267+
"\tparent rightmost numbers: %s",
268+
", ".join(str(res["rightmost-number"]) if res else "none" for res in parent_results),
269+
)
257270

258271
# Find the maximum applicable parent release number and increment by one if the
259272
# epoch-version can be parsed from the spec file.
@@ -272,20 +285,51 @@ def release_number_visitor(self, commit: pygit2.Commit, child_info: dict[str, An
272285
)
273286
for res in parent_results
274287
)
288+
275289
release_number = max(parent_release_numbers, default=0)
276290

291+
parent_rightmost_numbers = tuple(
292+
(
293+
res["rightmost-number"]
294+
if res
295+
and (
296+
# Now increase rightmost only until epoch-version or release-number changes
297+
epoch_version is None
298+
or res["epoch-version"] is None
299+
or epoch_version == res["epoch-version"]
300+
or res["release-number"] == release_number
301+
)
302+
else 0
303+
)
304+
for res in parent_results
305+
)
306+
307+
rightmost_number = max(parent_rightmost_numbers, default=0)
308+
277309
if self.specfile.name in commit.tree:
278-
release_number += 1
310+
if self.rightmost_bumps:
311+
rightmost_number += 1
312+
else:
313+
release_number += 1
279314

280-
release_number = max(release_number, commit_result["magic-comment-result"].bump_release)
315+
release_number = max(release_number, magic_comments.bump_release)
316+
rightmost_number = max(rightmost_number, magic_comments.bump_rightmost)
281317

282318
commit_result["release-number"] = release_number
319+
commit_result["rightmost-number"] = rightmost_number
283320

284-
log.debug("\trelease_number: %s", release_number)
321+
log.debug("\trelease_number: %s (r%s)", release_number, rightmost_number)
285322

286323
prerel_str = "0." if prerelease else ""
287324
release_number_with_base = release_number + base - 1
288-
commit_result["release-complete"] = f"{prerel_str}{release_number_with_base}{tag_string}"
325+
rightmost_with_base = rightmost_number + right_base - 1
326+
rightmost_str = "" # hide rightmost unless used
327+
if rightmost_with_base > 0:
328+
rightmost_str = "." + str(rightmost_with_base)
329+
330+
commit_result["release-complete"] = (
331+
f"{prerel_str}{release_number_with_base}{tag_string}{rightmost_str}"
332+
)
289333

290334
yield commit_result
291335

0 commit comments

Comments
 (0)