From 17e2e684f6642e51c106dd9ce10b5cdc73e695fa Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Mar 04 2022 17:20:39 +0000 Subject: Ignore locale when formatting dates Dates in RPM changelogs must use a set format with abbreviated English names of weekdays and months. Previously, we used datetime.strftime() which always honours locale settings, so when run under e.g. `fedpkg local` with a locale that uses another format or language, this generated invalid RPM changelog entries. Because the CLI didn't initialize locale, this never caught anyone's eye before. Fixes: #104 Signed-off-by: Nils Philippsen --- diff --git a/ci/pytest.yaml b/ci/pytest.yaml index 6442218..0bac22b 100644 --- a/ci/pytest.yaml +++ b/ci/pytest.yaml @@ -9,6 +9,9 @@ become: yes package: name: + - glibc-langpack-de + - glibc-langpack-en + - python3-babel - python3-koji - python3-pygit2 - python3-pytest diff --git a/python-rpmautospec.spec b/python-rpmautospec.spec index 942eaf8..7d08191 100644 --- a/python-rpmautospec.spec +++ b/python-rpmautospec.spec @@ -20,6 +20,9 @@ URL: https://pagure.io/fedora-infra/rpmautospec Source0: https://releases.pagure.org/fedora-infra/rpmautospec/rpmautospec-%{version}.tar.gz BuildArch: noarch +# the langpacks are needed for tests +BuildRequires: glibc-langpack-de +BuildRequires: glibc-langpack-en BuildRequires: python3-devel >= 3.6.0 BuildRequires: python3-setuptools %if %{with epel_le_7} @@ -30,6 +33,7 @@ BuildRequires: python2-devel # python3-koji %if ! %{with epel_le_7} BuildRequires: koji +BuildRequires: python%{python3_pkgversion}-babel BuildRequires: python3-koji BuildRequires: python3-pygit2 BuildRequires: python%{python3_pkgversion}-pytest @@ -52,6 +56,7 @@ Summary: %{summary} %{?python_provide:%python_provide python3-%{srcname}} Requires: koji +Requires: python3-babel Requires: python3-koji Requires: python3-pygit2 Requires: rpm @@ -141,6 +146,9 @@ install -m 644 rpm/macros.d/macros.rpmautospec %{buildroot}%{rpmmacrodir}/ %endif %changelog +* Sun Nov 07 2021 Nils Philippsen +- require python3-babel and glibc langpacks (the latter for testing) + * Fri Aug 06 2021 Nils Philippsen - 0.2.5-1 - Update to 0.2.5 diff --git a/requirements.txt b/requirements.txt index 23dc10f..0395e16 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ +babel>=2.9 koji pygit2>=1.2.1 diff --git a/rpmautospec/pkg_history.py b/rpmautospec/pkg_history.py index 4490bb6..768c31e 100644 --- a/rpmautospec/pkg_history.py +++ b/rpmautospec/pkg_history.py @@ -12,6 +12,7 @@ from textwrap import TextWrapper from typing import Any, Dict, Optional, Sequence, Union import pygit2 +from babel.dates import format_datetime from .misc import AUTORELEASE_MACRO @@ -302,7 +303,12 @@ class PkgHistoryProcessor: } changelog_author = f"{commit.author.name} <{commit.author.email}>" - changelog_date = dt.datetime.utcfromtimestamp(commit.commit_time).strftime("%a %b %d %Y") + changelog_date = format_datetime( + dt.datetime.utcfromtimestamp(commit.commit_time), + format="EEE MMM dd Y", + locale="en", + ) + changelog_evr = f"{commit_result['epoch-version']}-{commit_result['release-complete']}" changelog_header = f"* {changelog_date} {changelog_author} {changelog_evr}" @@ -634,7 +640,9 @@ class PkgHistoryProcessor: changelog_author = f"{signature.name} <{signature.email}>" except KeyError: changelog_author = "Unknown User " - changelog_date = dt.datetime.utcnow().strftime("%a %b %d %Y") + changelog_date = format_datetime( + dt.datetime.utcnow(), format="EEE MMM dd Y", locale="en" + ) changelog_evr = f"{epoch_version}-{release_complete}" changelog_header = f"* {changelog_date} {changelog_author} {changelog_evr}" diff --git a/tests/rpmautospec/test_pkg_history.py b/tests/rpmautospec/test_pkg_history.py index 0a81281..16b63b2 100644 --- a/tests/rpmautospec/test_pkg_history.py +++ b/tests/rpmautospec/test_pkg_history.py @@ -1,6 +1,9 @@ +import datetime as dt +import locale import os import re import stat +from calendar import LocaleTextCalendar from shutil import rmtree from unittest.mock import patch @@ -16,6 +19,21 @@ def processor(repo): return processor +@pytest.fixture +def setlocale(): + """Allow temporary modification of locale settings.""" + saved_locale_settings = { + category: locale.getlocale(getattr(locale, category)) + for category in dir(locale) + if category.startswith("LC_") and category != "LC_ALL" + } + + yield locale.setlocale + + for category, locale_settings in saved_locale_settings.items(): + locale.setlocale(getattr(locale, category), locale_settings) + + class TestPkgHistoryProcessor: version_re = re.compile(r"^Version: .*$", flags=re.MULTILINE) @@ -128,8 +146,13 @@ class TestPkgHistoryProcessor: else: assert processor._get_rpmverflags_for_commit(head_commit)["epoch-version"] == "1.0" - @pytest.mark.parametrize("testcase", ("without commit", "with commit", "all results")) - def test_run(self, testcase, repo, processor): + @pytest.mark.parametrize( + "testcase", ("without commit", "with commit", "all results", "locale set") + ) + def test_run(self, testcase, repo, processor, setlocale): + if testcase == "locale set": + setlocale(locale.LC_ALL, "de_DE.UTF-8") + all_results = "all results" in testcase head_commit = repo[repo.head.target] @@ -166,4 +189,16 @@ class TestPkgHistoryProcessor: ): assert snippet in top_entry["data"] + cal = LocaleTextCalendar(firstweekday=0, locale="C.UTF-8") + commit_time = dt.datetime.utcfromtimestamp(head_commit.commit_time) + weekdayname = cal.formatweekday(day=commit_time.weekday(), width=3) + monthname = cal.formatmonthname( + theyear=commit_time.year, + themonth=commit_time.month, + width=1, + withyear=False, + )[:3] + expected_date_blurb = f"* {weekdayname} {monthname} {commit_time.day:02} {commit_time.year}" + assert top_entry["data"].startswith(expected_date_blurb) + assert all("error" not in entry for entry in changelog)