[Rpm-maint] [rpm-software-management/rpm] RFE: A native %foreach approach (Discussion #4158)
Miro Hrončok
notifications at github.com
Wed Mar 18 15:39:06 UTC 2026
Hi. In the past, I found myself in a position where I had to do [something](https://src.fedoraproject.org/rpms/python3-rpm/blob/epel9/f/python3-rpm.spec) like this:
```specfile
%global python3_pkgversion 3.11
%py3_build
%global python3_pkgversion 3.12
%py3_build
%global python3_pkgversion 3.13
%py3_build
%global python3_pkgversion 3.14
%py3_build
```
For more complex spec snippets, I defined a helper macro:
```specfile
%define python3x_package %{?name:%package -n python%{python3_pkgversion}-rpm
Summary: Python %{python3_pkgversion} bindings for apps which will manipulate RPM packages
BuildRequires: python%{python3_pkgversion}-devel
%if v"%{python3_pkgversion}" >= v"3.12"
BuildRequires: python%{python3_pkgversion}-setuptools
%endif
...
%description -n python%{python3_pkgversion}-rpm
The python%{python3_pkgversion}-rpm package contains...}
%global python3_pkgversion 3.11
%python3x_package
%global python3_pkgversion 3.12
%python3x_package
%global python3_pkgversion 3.13
%python3x_package
%global python3_pkgversion 3.14
%python3x_package
```
Yet this seemed horrible so later I [went with](https://src.fedoraproject.org/rpms/python3-rpm/blob/bd64780478c4b52ffe2c3ae50b898335b6591c33/f/macros.foreach) something like this:
Macros:
```lua
%foreach(m:) %{lua:
if opt.m == nil or opt.m == "" then
rpm.expand("%{error:%%foreach requires -m <macro_name>}")
end
if #arg < 2 then
rpm.expand("%{error:%%foreach requires at least one macro value and a template string}")
end
-- The string template is the last argument
local template = arg[#arg]
for i = 1, #arg-1 do
rpm.define(opt.m .. " " .. arg[i])
print(rpm.expand(template))
print("\\n")
rpm.undefine(opt.m)
end
}
%foreachpy() %{foreach -m python3_pkgversion %{python3_pkgversions} %{quote:%1}}
```
Usage:
```specfile
%global python3_pkgversions 3.13 3.14
%{foreachpy %{quote:
%package -n python%%{python3_pkgversion}-rpm
Summary: Python %%{python3_pkgversion} bindings for apps which will manipulate RPM packages
BuildRequires: python%%{python3_pkgversion}-devel
...
%description -n python%%{python3_pkgversion}-rpm
The python%%{python3_pkgversion}-rpm package contains...
}}
...
%{foreachpy %{quote:
%files -n python%%{python3_pkgversion}-rpm
%%%%license COPYING
%dir %%{python3_sitearch}/rpm
%%{python3_sitearch}/rpm-%{rpmver}*.egg-info
%%{python3_sitearch}/rpm/__init__.py
%%{python3_sitearch}/rpm/transaction.py
%%{python3_sitearch}/rpm/_rpm.so
%artifact %%{python3_sitearch}/rpm/__pycache__/
}}
```
It works, but it's a bit tedious to use. Particularly, the need to `%%%%`-escape the `%license` declaration in files is :exploding_head: (or else it expands to the License value).
----
I was wondering if we could have some native mechanism of a foreach block in RPM, that would:
- eliminate the need to pass everything in `%quote`
- eliminate the need to escape everything within
E.g. I would love to be able to do:
```specfile
%global python3_pkgversions 3.13 3.14
...
%foreach python3_pkgversion %{python3_pkgversions}
%files -n python%{python3_pkgversion}-rpm
%license COPYING
%dir %{python3_sitearch}/rpm
%{python3_sitearch}/rpm-%{rpmver}*.egg-info
%{python3_sitearch}/rpm/__init__.py
%{python3_sitearch}/rpm/transaction.py
%{python3_sitearch}/rpm/_rpm.so
%artifact %{python3_sitearch}/rpm/__pycache__/
%endforeach
```
--
Reply to this email directly or view it on GitHub:
https://github.com/rpm-software-management/rpm/discussions/4158
You are receiving this because you are subscribed to this thread.
Message ID: <rpm-software-management/rpm/repo-discussions/4158 at github.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rpm.org/pipermail/rpm-maint/attachments/20260318/de01ccda/attachment-0001.htm>
More information about the Rpm-maint
mailing list