From 1517a87983c4bf9ef4511474a68c603d6d639758 Mon Sep 17 00:00:00 2001 From: Tomas Tomecek Date: Wed, 14 Jan 2026 16:28:10 +0100 Subject: [PATCH] changelog: fixup entries that have wrong padding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I had to fix the regex to correctly account for double-digit days (only first digit was parsed before this change). This commit also ignores extra padding for double-digit days. Signed-off-by: Tomas Tomecek Assisted-by: Claude Co-authored-by: Nikola Forró --- specfile/changelog.py | 16 ++++++++++++---- specfile/specfile.py | 8 ++++++-- tests/integration/test_specfile.py | 27 +++++++++++++++++++++++++++ tests/unit/test_changelog.py | 9 +++++++-- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/specfile/changelog.py b/specfile/changelog.py index 8b37fa99..33e39d9b 100644 --- a/specfile/changelog.py +++ b/specfile/changelog.py @@ -167,10 +167,14 @@ def extended_timestamp(self) -> bool: return m is not None @property - def day_of_month_padding(self) -> str: - """Padding of day of month in the entry header timestamp""" + def sanitized_day_of_month_padding(self) -> str: + """ + Padding of day of month in the entry header timestamp. Nonsensical padding + (i.e. multiple spaces before double-digit day of month) is corrected. + """ weekdays = "|".join(WEEKDAYS) months = "|".join(MONTHS) + m = re.search( rf""" ({weekdays}) # weekday @@ -178,14 +182,18 @@ def day_of_month_padding(self) -> str: ({months}) # month [ ] (?P[ ]*) # optional whitespace padding - ((?P0)?\d|[12]\d|3[01]) # possibly zero-padded day of month + (?P0)? # optional zero-padding + (?P[12]\d|3[01]|[1-9]) # day of month (1-31) """, self.header, re.VERBOSE, ) if not m: return "" - return m.group("wsp") + (m.group("zp") or "") + # remove extra padding for double-digit day numbers + whitespace_padding = "" if len(m.group("day")) == 2 else m.group("wsp") + zero_padding = m.group("zp") or "" + return whitespace_padding + zero_padding @property def style(self) -> ChangelogStyle: diff --git a/specfile/specfile.py b/specfile/specfile.py index 1a05c65d..112f29f9 100644 --- a/specfile/specfile.py +++ b/specfile/specfile.py @@ -641,9 +641,13 @@ def add_changelog_entry( elif email is not None: author += f" <{email}>" if changelog: - # try to preserve padding of day of month + # compute day of month padding from the longest valid entry + # incorrect padding is stripped; invalid entries are ignored padding = max( - (e.day_of_month_padding for e in reversed(changelog)), + ( + e.sanitized_day_of_month_padding + for e in reversed(changelog) + ), key=len, ) else: diff --git a/tests/integration/test_specfile.py b/tests/integration/test_specfile.py index 97b16e38..fd69c3a7 100644 --- a/tests/integration/test_specfile.py +++ b/tests/integration/test_specfile.py @@ -226,6 +226,33 @@ def test_add_changelog_entry( assert sections.changelog[: len(result)] == result +def test_add_changelog_entry_ignores_invalid_padding(specfile_factory, spec_minimal): + """Test that add_changelog_entry ignores entries with invalid day padding (issue #216).""" + spec = specfile_factory(spec_minimal) + + # Simulate scipy scenario: malformed entry with space before double-digit day + with spec.sections() as sections: + sections.changelog.data = [ + "* Mon Dec 11 2021 Author - 0.5.1-5", # INVALID + "- Initial version", + "", + "* Tue May 04 2020 Another - 0.1-0", # VALID (zero-padded) + "- First version", + ] + + # Add new entry with single-digit day - should use zero-padding from valid entry + flexmock(specfile.specfile).should_receive("guess_packager").and_return( + "Test User " + ).once() + spec.add_changelog_entry("test entry", timestamp=datetime.date(2024, 1, 5)) + + with spec.sections() as sections: + new_entry = sections.changelog[0] + # Should use zero-padding style "Jan 05", not space-padding "Jan 5" + assert "Jan 05" in new_entry + assert "Jan 5" not in new_entry + + @pytest.mark.parametrize( "version, release", [ diff --git a/tests/unit/test_changelog.py b/tests/unit/test_changelog.py index ba74dc4b..030060b6 100644 --- a/tests/unit/test_changelog.py +++ b/tests/unit/test_changelog.py @@ -92,12 +92,17 @@ def test_entry_has_extended_timestamp(header, extended): ), ( "* Mon Oct 18 12:34:45 CEST 2021 Nikola Forró - 0.2-1", - " ", + "", # Invalid: double-digit day with space padding, returns "" ), + ( + "* Mon Dec 11 2006 Author - 1.0", + "", + ), # Invalid: space before double-digit + ("* Invalid header", ""), # Invalid: unparsable ], ) def test_entry_day_of_month_padding(header, padding): - assert ChangelogEntry(header, [""]).day_of_month_padding == padding + assert ChangelogEntry(header, [""]).sanitized_day_of_month_padding == padding @pytest.mark.parametrize(