From d5a5919a27cc8d57f9231c5ea874b78b2657cc7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Fri, 26 May 2023 19:10:37 +0200 Subject: [PATCH] Fix literal % handling in %{pyproject_files} on RPM 4.19 RPM 4.19 now requires 2 %s to escape a single literal % in the filelist. The test has been adjusted to actually run our code instead of only verifying the assumptions. Related: rhbz#2208971 --- macros.pyproject | 7 +++++ pyproject-rpm-macros.spec | 1 + pyproject_save_files.py | 14 ++++----- tests/escape_percentages.spec | 56 ++++++++++++++++++++++++++++++----- tests/tests.yml | 2 +- 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/macros.pyproject b/macros.pyproject index 402f730..9b29b73 100644 --- a/macros.pyproject +++ b/macros.pyproject @@ -104,7 +104,14 @@ fi %pyproject_extras_subpkg(n:i:f:F) %{expand:%{?python_extras_subpkg:%{python_extras_subpkg%{?!-i:%{?!-f:%{?!-F: -f %{_pyproject_ghost_distinfo}}}} %**}}} +# Escaping an actual percentage sign in path by 8 signs has been verified in RPM 4.16 and 4.17. +# See this thread http://lists.rpm.org/pipermail/rpm-list/2021-June/002048.html +# Since RPM 4.19, 2 signs are needed instead. +# On the CI, we build tests/escape_percentages.spec to verify the assumptions. +# We should check RPM version here instead of Fedora/RHEL, but it's hard; +# see https://github.com/rpm-software-management/rpm/issues/2523 %pyproject_save_files() %{expand:\\\ +%{expr:0%{?fedora} >= 39 || 0%{?rhel} >= 10 ? "RPM_PERCENTAGES_COUNT=2" : "RPM_PERCENTAGES_COUNT=8" } \\ %{__python3} %{_rpmconfigdir}/redhat/pyproject_save_files.py \\ --output-files "%{pyproject_files}" \\ --output-modules "%{_pyproject_modules}" \\ diff --git a/pyproject-rpm-macros.spec b/pyproject-rpm-macros.spec index 28890ef..e53aca4 100644 --- a/pyproject-rpm-macros.spec +++ b/pyproject-rpm-macros.spec @@ -163,6 +163,7 @@ export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856 %changelog * Wed May 31 2023 Miro Hrončok - 1.8.1-1 - On Python older than 3.11, use tomli instead of deprecated toml +- Fix literal %% handling in %%{pyproject_files} on RPM 4.19 * Tue May 23 2023 Miro Hrončok - 1.8.0-2 - Rebuilt for ELN dependency changes diff --git a/pyproject_save_files.py b/pyproject_save_files.py index 00d706d..551a876 100644 --- a/pyproject_save_files.py +++ b/pyproject_save_files.py @@ -12,6 +12,9 @@ from importlib.metadata import Distribution # From RPM's build/files.c strtokWithQuotes delim argument RPM_FILES_DELIMETERS = ' \n\t' +# See the comment in the macro that wraps this script +RPM_PERCENTAGES_COUNT = int(os.getenv('RPM_PERCENTAGES_COUNT', '2')) + # RPM hardcodes the lists of manpage extensions and directories, # so we have to maintain separate ones :( # There is an issue for RPM to provide the lists as macros: @@ -441,13 +444,13 @@ def escape_rpm_path(path): '"/usr/lib/python3.9/site-packages/setuptools/script (dev).tmpl"' >>> escape_rpm_path('/usr/share/data/100%valid.path') - '/usr/share/data/100%%%%%%%%valid.path' + '/usr/share/data/100%%valid.path' >>> escape_rpm_path('/usr/share/data/100 % valid.path') - '"/usr/share/data/100 %%%%%%%% valid.path"' + '"/usr/share/data/100 %% valid.path"' >>> escape_rpm_path('/usr/share/data/1000 %% valid.path') - '"/usr/share/data/1000 %%%%%%%%%%%%%%%% valid.path"' + '"/usr/share/data/1000 %%%% valid.path"' >>> escape_rpm_path('/usr/share/data/spaces and "quotes"') Traceback (most recent call last): @@ -461,10 +464,7 @@ def escape_rpm_path(path): """ orig_path = path = str(path) if "%" in path: - # Escaping by 8 %s has been verified in RPM 4.16 and 4.17, but probably not stable - # See this thread http://lists.rpm.org/pipermail/rpm-list/2021-June/002048.html - # On the CI, we build tests/escape_percentages.spec to verify this assumption - path = path.replace("%", "%" * 8) + path = path.replace("%", "%" * RPM_PERCENTAGES_COUNT) if any(symbol in path for symbol in RPM_FILES_DELIMETERS): if '"' in path: # As far as we know, RPM cannot list such file individually diff --git a/tests/escape_percentages.spec b/tests/escape_percentages.spec index 5ebf13f..be64156 100644 --- a/tests/escape_percentages.spec +++ b/tests/escape_percentages.spec @@ -1,5 +1,5 @@ Name: escape_percentages -Version: 0 +Version: 0.1 Release: 0 Summary: ... License: MIT @@ -7,19 +7,59 @@ BuildArch: noarch %description This spec file verifies that escaping percentage signs in paths is possible via -exactly 8 percentage signs in a filelist and directly in the %%files section. +exactly 2 (or 8) percentage signs in a filelist and directly in the %%files section. It serves as a regression test for pyproject_save_files:escape_rpm_path(). When this breaks, the function needs to be adapted. -%install + +%prep +cat > pyproject.toml << EOF +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" +EOF + +cat > setup.cfg << EOF +[metadata] +name = escape_percentages +version = 0.1 +[options] +packages = + escape_percentages +[options.package_data] +escape_percentages = + * +EOF + +mkdir -p escape_percentages +touch escape_percentages/__init__.py # the paths on disk will have 1 percentage sign if we type 2 in the spec # we use the word 'version' after the sign, as that is a known existing macro -touch '%{buildroot}/one%%version' +touch 'escape_percentages/one%%version' + + +%generate_buildrequires +%pyproject_buildrequires + + +%build +%pyproject_wheel + + +%install +%pyproject_install +%pyproject_save_files escape_percentages touch '%{buildroot}/two%%version' -# the filelist will contain 8 percentage signs when we type 16 in spec -echo '/one%%%%%%%%%%%%%%%%version' > filelist -test $(wc -c filelist | cut -f1 -d' ') -eq 20 # 8 signs + /one (4) + version (7) + newline (1) -%files -f filelist +%check +grep '/escape_percentages/one' %{pyproject_files} + + + +%files -f %{pyproject_files} +%if 0%{?fedora} >= 39 || 0%{?rhel} >= 10 +/two%%version +%else /two%%%%%%%%version +%endif diff --git a/tests/tests.yml b/tests/tests.yml index 3a6652a..bab37eb 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -97,7 +97,7 @@ run: ./mocktest.sh python-virtualenv - escape_percentages: dir: . - run: rpmbuild -ba escape_percentages.spec + run: ./mocktest.sh escape_percentages required_packages: - 'https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm' - 'https://dl.fedoraproject.org/pub/epel/epel-next-release-latest-9.noarch.rpm'