Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-dunamai for openSUSE:Factory checked in at 2026-08-11 17:09:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-dunamai (Old) and /work/SRC/openSUSE:Factory/.python-dunamai.new.17972 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-dunamai" Tue Aug 11 17:09:16 2026 rev:15 rq:1370273 version:1.26.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-dunamai/python-dunamai.changes 2026-04-07 16:48:11.406757594 +0200 +++ /work/SRC/openSUSE:Factory/.python-dunamai.new.17972/python-dunamai.changes 2026-08-11 17:09:19.590194343 +0200 @@ -1,0 +2,11 @@ +Fri Aug 7 18:52:18 UTC 2026 - Richard Rahl <[email protected]> + +- Update to version 1.26.2: + + Fixed: With highest_tag enabled, a pattern/pattern_prefix that + only some tags matched could select a non-matching tag and fall + back to the default version (e.g. 0.0.0) instead of the highest + matching tag + + Fixed: Integration with Fossil 2.28 failed due to a SQL + formatting mode change + +------------------------------------------------------------------- Old: ---- python-dunamai-1.26.1.tar.gz New: ---- python-dunamai-1.26.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-dunamai.spec ++++++ --- /var/tmp/diff_new_pack.dGgixH/_old 2026-08-11 17:09:20.334225835 +0200 +++ /var/tmp/diff_new_pack.dGgixH/_new 2026-08-11 17:09:20.338226004 +0200 @@ -17,24 +17,27 @@ %{?sle15_python_module_pythons} +%bcond_without libalternatives +%define modname dunamai Name: python-dunamai -Version: 1.26.1 +Version: 1.26.2 Release: 0 Summary: Dynamic version generation License: MIT -Group: Development/Libraries/Python URL: https://github.com/mtkennerly/dunamai Source0: https://files.pythonhosted.org/packages/source/d/dunamai/dunamai-%{version}.tar.gz#/%{name}-%{version}.tar.gz +BuildRequires: %{python_module packaging} BuildRequires: %{python_module pip} BuildRequires: %{python_module poetry-core >= 1.0.0} +BuildRequires: %{python_module pytest} +BuildRequires: alts +BuildRequires: dos2unix BuildRequires: fdupes +BuildRequires: git-core BuildRequires: python-rpm-macros -Requires(post): update-alternatives -Requires(postun): update-alternatives +Requires: alts +Requires: python-packaging BuildArch: noarch -## needed for tests -BuildRequires: %{python_module pytest} -BuildRequires: git %python_subpackages %description @@ -45,22 +48,16 @@ simply by creating a tag. %prep -%autosetup -p1 -n dunamai-%{version} +%autosetup -p1 -n %{modname}-%{version} +dos2unix CHANGELOG.md %build %pyproject_wheel %install %pyproject_install -%python_clone -a %{buildroot}%{_bindir}/dunamai +%python_clone -a %{buildroot}%{_bindir}/%{modname} %python_expand %fdupes %{buildroot}%{$python_sitelib} -%prepare_alternative dunamai - -%post -%python_install_alternative dunamai - -%postun -%python_uninstall_alternative dunamai %check donttest="git" @@ -69,7 +66,7 @@ %files %{python_files} %doc CHANGELOG.md README.md %license LICENSE -%python_alternative %{_bindir}/dunamai -%{python_sitelib}/dunamai -%{python_sitelib}/dunamai-%{version}.dist-info +%python_alternative %{_bindir}/%{modname} +%{python_sitelib}/%{modname} +%{python_sitelib}/%{modname}-%{version}.dist-info ++++++ python-dunamai-1.26.1.tar.gz -> python-dunamai-1.26.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dunamai-1.26.1/CHANGELOG.md new/dunamai-1.26.2/CHANGELOG.md --- old/dunamai-1.26.1/CHANGELOG.md 1970-01-01 01:00:00.000000000 +0100 +++ new/dunamai-1.26.2/CHANGELOG.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +1,12 @@ +## v1.26.2 (2026-08-01) + +* Fixed: With `highest_tag` enabled, a `pattern`/`pattern_prefix` that only some + tags matched could select a non-matching tag and fall back to the default + version (e.g. `0.0.0`) instead of the highest matching tag. + ([Contributed by Flourish3](https://github.com/mtkennerly/dunamai/pull/112)) +* Fixed: Integration with Fossil 2.28 failed due to a SQL formatting mode change. + ([Contributed by rosset](https://github.com/mtkennerly/dunamai/issues/113)) + ## v1.26.1 (2026-04-04) * Fixed: The `highest_tag` argument was ignored in `Version.from_any_vcs()`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dunamai-1.26.1/PKG-INFO new/dunamai-1.26.2/PKG-INFO --- old/dunamai-1.26.1/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/dunamai-1.26.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: dunamai -Version: 1.26.1 +Version: 1.26.2 Summary: Dynamic version generation License: MIT License-File: LICENSE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dunamai-1.26.1/dunamai/__init__.py new/dunamai-1.26.2/dunamai/__init__.py --- old/dunamai-1.26.1/dunamai/__init__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/dunamai-1.26.2/dunamai/__init__.py 1970-01-01 01:00:00.000000000 +0100 @@ -270,6 +270,13 @@ selected_source = None selected_parsed = None for source in sources: + # Only rank tags that actually match the pattern/prefix. Otherwise a + # tag for a different prefix could be selected and then fail to match, + # collapsing the result to the fallback version. + match = re.search(pattern, source) + if match is None: + continue + parsed = Version.parse(source, pattern) try: if selected_parsed is None or parsed > selected_parsed: @@ -1813,18 +1820,18 @@ code, msg = _run_cmd("fossil branch current", path) branch = msg - code, msg = _run_cmd("fossil sql \"SELECT value FROM vvar WHERE name = 'checkout-hash' LIMIT 1\"", path) + code, msg = _run_cmd("fossil sql --quote \"SELECT value FROM vvar WHERE name = 'checkout-hash' LIMIT 1\"", path) commit = msg.strip("'")[:commit_length] code, msg = _run_cmd( - 'fossil sql "' + 'fossil sql --quote "' "SELECT DATETIME(mtime) FROM event JOIN blob ON event.objid=blob.rid WHERE type = 'ci'" " AND uuid = (SELECT value FROM vvar WHERE name = 'checkout-hash' LIMIT 1) LIMIT 1\"", path, ) timestamp = dt.datetime.strptime(msg.strip("'") + "+0000", "%Y-%m-%d %H:%M:%S%z") - code, msg = _run_cmd("fossil sql \"SELECT count() FROM event WHERE type = 'ci'\"", path) + code, msg = _run_cmd("fossil sql --quote \"SELECT count() FROM event WHERE type = 'ci'\"", path) # The repository creation itself counts as a commit. total_commits = int(msg) - 1 if total_commits <= 0: @@ -1863,7 +1870,7 @@ WHERE tagxref.tagtype = 1 ORDER BY event.mtime DESC, tagxref.mtime DESC; """ - code, msg = _run_cmd('fossil sql "{}"'.format(" ".join(query.splitlines())), path) + code, msg = _run_cmd('fossil sql --quote "{}"'.format(" ".join(query.splitlines())), path) if not msg: try: distance = int(total_commits) @@ -1879,9 +1886,13 @@ vcs=vcs, ) - tags_to_distance = [ - (line.rsplit(",", 1)[0][5:-1], int(line.rsplit(",", 1)[1]) - 1) for line in msg.splitlines() - ] + tags_to_distance = [] + for line in msg.splitlines(): + # Lines look like: 'sym-v0.1.0',1 + parts = line.rsplit(",", 1) + tag = parts[0][5:-1] + distance = int(parts[1]) - 1 + tags_to_distance.append((tag, distance)) matched_pattern = _match_version_pattern( pattern, [t for t, d in tags_to_distance], latest_tag, highest_tag, strict, pattern_prefix diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dunamai-1.26.1/pyproject.toml new/dunamai-1.26.2/pyproject.toml --- old/dunamai-1.26.1/pyproject.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/dunamai-1.26.2/pyproject.toml 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ [tool.poetry] name = "dunamai" -version = "1.26.1" +version = "1.26.2" description = "Dynamic version generation" license = "MIT" authors = ["Matthew T. Kennerly <[email protected]>"] @@ -48,7 +48,7 @@ [tool.ruff] line-length = 120 -extend-select = ["W605", "N"] +extend-select = ["ARG", "N", "W605"] ignore = ["E501"] [build-system] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dunamai-1.26.1/tests/integration/test_dunamai.py new/dunamai-1.26.2/tests/integration/test_dunamai.py --- old/dunamai-1.26.1/tests/integration/test_dunamai.py 1970-01-01 01:00:00.000000000 +0100 +++ new/dunamai-1.26.2/tests/integration/test_dunamai.py 1970-01-01 01:00:00.000000000 +0100 @@ -12,6 +12,16 @@ from dunamai import Version, Vcs, Concern, _get_git_version, _run_cmd [email protected](scope="session", autouse=True) +def set_env_vars(): + os.environ["GIT_AUTHOR_NAME"] = "foo" + os.environ["GIT_AUTHOR_EMAIL"] = "[email protected]" + os.environ["GIT_COMMITTER_NAME"] = "foo" + os.environ["GIT_COMMITTER_EMAIL"] = "[email protected]" + os.environ["DARCS_EMAIL"] = "foo <[email protected]>" + os.environ["BZR_EMAIL"] = "foo <[email protected]>" + + def avoid_identical_ref_timestamps() -> None: time.sleep(1.2) @@ -53,6 +63,8 @@ def make_run_callback(where: Path) -> Callable: def inner(command, expected_code: int = 0, env: Optional[dict] = None): + if env is not None: + env = {**os.environ, **env} _, out = _run_cmd(command, where=where, codes=[expected_code], env=env) return out @@ -312,6 +324,100 @@ @pytest.mark.skipif(shutil.which("git") is None, reason="Requires Git") +def test__version__from_git__highest_tag_with_pattern_prefix(tmp_path) -> None: + # Regression test: with `highest_tag=True` and a `pattern_prefix`, the + # highest matching tag must be selected even when a tag with a different + # (non-matching) prefix is the most recent tag and sorts higher numerically. + run = make_run_callback(tmp_path) + from_vcs = make_from_callback(Version.from_git) + b = "master" + + def from_foo(**kwargs): + return from_vcs(pattern="default-unprefixed", pattern_prefix="foo-", **kwargs) + + with chdir(tmp_path): + run("git init") + (tmp_path / "foo.txt").write_text("1") + run("git add .") + run('git commit --no-gpg-sign -m "First"') + run("git tag --no-sign foo-1.0.0 -m Annotated") + + (tmp_path / "foo.txt").write_text("2") + run("git add .") + avoid_identical_ref_timestamps() + run('git commit --no-gpg-sign -m "Second"') + run("git tag --no-sign foo-1.1.0 -m Annotated") + + # A higher-numbered tag with a different prefix, applied most recently so + # it is the newest tag chronologically. + (tmp_path / "foo.txt").write_text("3") + run("git add .") + avoid_identical_ref_timestamps() + run('git commit --no-gpg-sign -m "Third"') + run("git tag --no-sign bar-9.9.9 -m Annotated") + + (tmp_path / "foo.txt").write_text("4") + run("git add .") + avoid_identical_ref_timestamps() + run('git commit --no-gpg-sign -m "Fourth"') + + # The closest matching tag is foo-1.1.0, two commits back. + assert from_foo() == Version("1.1.0", distance=2, dirty=False, branch=b) + # The highest matching tag is also foo-1.1.0; bar-9.9.9 must be ignored. + assert from_foo(highest_tag=True) == Version("1.1.0", distance=2, dirty=False, branch=b) + + [email protected](shutil.which("git") is None, reason="Requires Git") +def test__version__from_git__highest_tag_picks_numerically_highest(tmp_path) -> None: + # With a single prefix, `highest_tag=True` must pick the numerically highest + # tag even when a later commit carries a lower tag number. + run = make_run_callback(tmp_path) + from_vcs = make_from_callback(Version.from_git) + b = "master" + + def from_foo(**kwargs): + return from_vcs(pattern="default-unprefixed", pattern_prefix="foo-", **kwargs) + + with chdir(tmp_path): + run("git init") + (tmp_path / "foo.txt").write_text("1") + run("git add .") + run('git commit --no-gpg-sign -m "First"') + run("git tag --no-sign foo-2.0.0 -m Annotated") + + (tmp_path / "foo.txt").write_text("2") + run("git add .") + avoid_identical_ref_timestamps() + run('git commit --no-gpg-sign -m "Second"') + run("git tag --no-sign foo-1.5.0 -m Annotated") + + # latest_tag follows chronology, highest_tag follows version ordering. + assert from_foo(latest_tag=True) == Version("1.5.0", dirty=False, branch=b) + assert from_foo(highest_tag=True) == Version("2.0.0", distance=1, dirty=False, branch=b) + + [email protected](shutil.which("git") is None, reason="Requires Git") +def test__version__from_git__highest_tag_with_no_matching_tags(tmp_path) -> None: + run = make_run_callback(tmp_path) + from_vcs = make_from_callback(Version.from_git) + + def from_missing(**kwargs): + return from_vcs(pattern="default-unprefixed", pattern_prefix="missing-", **kwargs) + + with chdir(tmp_path): + run("git init") + (tmp_path / "foo.txt").write_text("1") + run("git add .") + run('git commit --no-gpg-sign -m "First"') + run("git tag --no-sign foo-1.0.0 -m Annotated") + + # No tag matches the prefix: fall back without raising when not strict. + assert from_missing(highest_tag=True).base == "0.0.0" + with pytest.raises(ValueError): + from_missing(highest_tag=True, strict=True) + + [email protected](shutil.which("git") is None, reason="Requires Git") def test__version__from_git__with_nonchronological_commits(tmp_path) -> None: run = make_run_callback(tmp_path) from_vcs = make_from_callback(Version.from_git, chronological=False) @@ -327,7 +433,6 @@ env={ "GIT_COMMITTER_DATE": "2000-01-02T01:00:00", "GIT_AUTHOR_DATE": "2000-01-02T01:00:00", - **os.environ, }, ) @@ -340,7 +445,6 @@ env={ "GIT_COMMITTER_DATE": "2000-01-01T01:00:00", "GIT_AUTHOR_DATE": "2000-01-01T01:00:00", - **os.environ, }, )
