Add %pyproject_buildrequires
This commit is contained in:
parent
d81f3dfe39
commit
fdf511644e
24
README.md
24
README.md
@ -5,8 +5,6 @@ This is a provisional implementation of pyproject RPM macros for Fedora 30+.
|
||||
|
||||
These macros are useful for packaging Python projects that use the [PEP 517] `pyproject.toml` file, which specifies the package's build dependencies (including the build system, such as setuptools, flit or poetry).
|
||||
|
||||
[PEP 517]: https://www.python.org/dev/peps/pep-0517/
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
@ -17,12 +15,20 @@ If your upstream sources include `pyproject.toml` and you want to use these macr
|
||||
|
||||
This will bring in python3-devel, so you don't need to require python3-devel explicitly.
|
||||
|
||||
Then, build a wheel in %build:
|
||||
In order to get automatic build dependencies on Fedora 31+, run `%pyproject_buildrequires` in the `%generate_buildrequires` section:
|
||||
|
||||
%generate_buildrequires
|
||||
%pyproject_buildrequires
|
||||
|
||||
Only build dependencies according to [PEP 517] and [PEP 518] will be added.
|
||||
All other build dependencies (such as non-Python libraries or test dependencies) still need to be specified manually.
|
||||
|
||||
Then, build a wheel in `%build` with `%pyproject_wheel`:
|
||||
|
||||
%build
|
||||
%pyproject_wheel
|
||||
|
||||
And install the wheel in %install:
|
||||
And install the wheel in `%install` with `%pyproject_install`:
|
||||
|
||||
%install
|
||||
%pyproject_install
|
||||
@ -33,8 +39,12 @@ Limitations
|
||||
|
||||
`%pyproject_install` currently installs all wheels in `$PWD`. We are working on a more explicit solution.
|
||||
|
||||
This macro changes shebang lines of every Python script in `%{buildroot}%{_bindir}` to `#! %{__python3} %{py3_shbang_opt}` (`#! /usr/bin/python -s`).
|
||||
We plan to preserve exisiting Python flags in shebangs, but the work is not yet finished.
|
||||
This macro changes shebang lines of every Python script in `%{buildroot}%{_bindir}` to `#! %{__python3} %{py3_shbang_opt}` (`#! /usr/bin/python3 -s`).
|
||||
We plan to preserve existing Python flags in shebangs, but the work is not yet finished.
|
||||
|
||||
Currently, the macros do not automatically generate BuildRequires. We are working on that as well.
|
||||
The PEPs don't (yet) define a way to specify test dependencies and test runners.
|
||||
That means you still need to handle test dependencies and `%check` on your own.
|
||||
|
||||
|
||||
[PEP 517]: https://www.python.org/dev/peps/pep-0517/
|
||||
[PEP 518]: https://www.python.org/dev/peps/pep-0518/
|
||||
|
@ -1,18 +1,28 @@
|
||||
%pyproject_wheel() %{expand:\\\
|
||||
CFLAGS="${CFLAGS:-${RPM_OPT_FLAGS}}" LDFLAGS="${LDFLAGS:-${RPM_LD_FLAGS}}" \\\
|
||||
%{__python3} -m pip wheel --no-deps --use-pep517 --no-build-isolation --disable-pip-version-check --progress-bar off --verbose .
|
||||
CFLAGS="${CFLAGS:-${RPM_OPT_FLAGS}}" LDFLAGS="${LDFLAGS:-${RPM_LD_FLAGS}}" \\\
|
||||
%{__python3} -m pip wheel --no-deps --use-pep517 --no-build-isolation --disable-pip-version-check --progress-bar off --verbose .
|
||||
}
|
||||
|
||||
|
||||
%pyproject_install() %{expand:\\\
|
||||
%{__python3} -m pip install --root %{buildroot} --strip-file-prefix %{buildroot} --no-deps --disable-pip-version-check --progress-bar off --verbose --ignore-installed --no-warn-script-location ./*.whl
|
||||
if [ -e %{buildroot}%{_bindir} ]; then
|
||||
if [ -d %{buildroot}%{_bindir} ]; then
|
||||
pathfix.py -pni "%{__python3} %{py3_shbang_opts}" %{buildroot}%{_bindir}/*
|
||||
fi
|
||||
if [ -e %{buildroot}%{python3_sitelib}]; then
|
||||
sed -i -e 's/pip/rpm/g' %{buildroot}%{python3_sitelib}/*.dist-info/INSTALLER
|
||||
if [ -d %{buildroot}%{python3_sitelib} ]; then
|
||||
sed -i 's/pip/rpm/' %{buildroot}%{python3_sitelib}/*.dist-info/INSTALLER
|
||||
fi
|
||||
if [ -e %{buildroot}{python3_sitearch}]; then
|
||||
sed -i -e 's/pip/rpm/g' %{buildroot}%{python3_sitearch}/*.dist-info/INSTALLER
|
||||
if [ -d %{buildroot}%{python3_sitearch} ]; then
|
||||
sed -i 's/pip/rpm/' %{buildroot}%{python3_sitearch}/*.dist-info/INSTALLER
|
||||
fi
|
||||
}
|
||||
|
||||
%pyproject_buildrequires() %{expand:\\\
|
||||
echo 'python3-devel'
|
||||
echo 'python3dist(packaging)'
|
||||
echo 'python3dist(pip) >= 19'
|
||||
echo 'python3dist(pytoml)'
|
||||
if [ -f %{__python3} ]; then
|
||||
%{__python3} -I %{_rpmconfigdir}/redhat/pyproject_buildrequires.py
|
||||
fi
|
||||
}
|
||||
|
@ -1,24 +1,35 @@
|
||||
Name: pyproject-rpm-macros
|
||||
Version: 0
|
||||
Release: 2%{?dist}
|
||||
License: MIT
|
||||
Source0: macros.pyproject
|
||||
Source1: README.md
|
||||
Source2: LICENSE
|
||||
URL: https://src.fedoraproject.org/rpms/pyproject-rpm-macros
|
||||
BuildArch: noarch
|
||||
Summary: RPM macros for PEP 517 Python packages
|
||||
License: MIT
|
||||
|
||||
# Keep the version at zero and increment only release
|
||||
Version: 0
|
||||
Release: 3%{?dist}
|
||||
|
||||
Source0: macros.pyproject
|
||||
Source1: pyproject_buildrequires.py
|
||||
|
||||
Source8: README.md
|
||||
Source9: LICENSE
|
||||
|
||||
URL: https://src.fedoraproject.org/rpms/pyproject-rpm-macros
|
||||
|
||||
BuildArch: noarch
|
||||
|
||||
# We keep them here for now to avoid one loop of %%generate_buildrequires
|
||||
# And to allow the other macros without %%pyproject_buildrequires (e.g. on Fedora 30)
|
||||
# But those are also always in the output of %%generate_buildrequires
|
||||
# in order to be removable in the future
|
||||
Requires: python3-pip >= 19
|
||||
Requires: python3-devel
|
||||
|
||||
|
||||
%description
|
||||
This is a provisional implementation of pyproject RPM macros for Fedora 30+.
|
||||
These macros are useful for packaging Python projects that use the PEP 517
|
||||
pyproject.toml file, which specifies the package's build dependencies
|
||||
(including the build system, such as setuptools, flit or poetry).
|
||||
|
||||
|
||||
%prep
|
||||
# Not strictly necessary but allows working on file names instead
|
||||
# of source numbers in install section
|
||||
@ -29,16 +40,22 @@ cp -p %{sources} .
|
||||
# nothing to do, sources are not buildable
|
||||
|
||||
%install
|
||||
mkdir -p %{buildroot}/%{_rpmmacrodir}
|
||||
install -m 644 macros.pyproject %{buildroot}/%{_rpmmacrodir}/
|
||||
mkdir -p %{buildroot}%{_rpmmacrodir}
|
||||
mkdir -p %{buildroot}%{_rpmconfigdir}/redhat
|
||||
install -m 644 macros.pyproject %{buildroot}%{_rpmmacrodir}/
|
||||
install -m 644 pyproject_buildrequires.py %{buildroot}%{_rpmconfigdir}/redhat/
|
||||
|
||||
%files
|
||||
%{_rpmmacrodir}/macros.pyproject
|
||||
%{_rpmconfigdir}/redhat/pyproject_buildrequires.py
|
||||
|
||||
%doc README.md
|
||||
%license LICENSE
|
||||
|
||||
%changelog
|
||||
* Tue Jul 02 2019 Miro Hrončok <mhroncok@redhat.com> - 0-3
|
||||
- Add %%pyproject_buildrequires
|
||||
|
||||
* Tue Jul 02 2019 Miro Hrončok <mhroncok@redhat.com> - 0-2
|
||||
- Fix shell syntax errors in %%pyproject_install
|
||||
- Drop PATH warning in %%pyproject_install
|
||||
|
89
pyproject_buildrequires.py
Normal file
89
pyproject_buildrequires.py
Normal file
@ -0,0 +1,89 @@
|
||||
import sys
|
||||
|
||||
try:
|
||||
import pytoml
|
||||
from packaging.requirements import Requirement, InvalidRequirement
|
||||
from packaging.utils import canonicalize_name, canonicalize_version
|
||||
except ImportError:
|
||||
# already echoed by the %pyproject_buildrequires macro
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
try:
|
||||
with open("pyproject.toml") as f:
|
||||
pyproject_data = pytoml.load(f)
|
||||
except FileNotFoundError:
|
||||
pyproject_data = {}
|
||||
except Exception as e:
|
||||
sys.exit(e)
|
||||
else:
|
||||
import importlib
|
||||
|
||||
try:
|
||||
backend = importlib.import_module(
|
||||
pyproject_data["build-system"]["build-backend"]
|
||||
)
|
||||
except KeyError:
|
||||
try:
|
||||
import setuptools.build_meta
|
||||
except ImportError:
|
||||
print("python3dist(setuptools) >= 40.8")
|
||||
print("python3dist(wheel)")
|
||||
sys.exit(0)
|
||||
|
||||
backend = setuptools.build_meta
|
||||
except ImportError:
|
||||
backend = None
|
||||
|
||||
|
||||
requirements = set()
|
||||
rpm_requirements = set()
|
||||
|
||||
|
||||
def add_requirement(requirement):
|
||||
try:
|
||||
requirements.add(Requirement(requirement))
|
||||
except InvalidRequirement as e:
|
||||
print(
|
||||
f"WARNING: Skipping invalid requirement: {requirement}\n {e}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
|
||||
if "requires" in pyproject_data.get("build-system", {}):
|
||||
try:
|
||||
for requirement in pyproject_data["build-system"]["requires"]:
|
||||
add_requirement(requirement)
|
||||
except Exception as e:
|
||||
sys.exit(e)
|
||||
|
||||
|
||||
if hasattr(backend, "get_requires_for_build_wheel"):
|
||||
try:
|
||||
for requirement in backend.get_requires_for_build_wheel():
|
||||
add_requirement(requirement)
|
||||
except Exception as e:
|
||||
sys.exit(e)
|
||||
|
||||
for requirement in requirements:
|
||||
name = canonicalize_name(requirement.name)
|
||||
if requirement.marker is not None and not requirement.marker.evaluate():
|
||||
continue
|
||||
together = []
|
||||
for specifier in requirement.specifier:
|
||||
version = canonicalize_version(specifier.version)
|
||||
if specifier.operator == "!=":
|
||||
together.append(
|
||||
f"(python3dist({name}) < {version} or python3dist({name}) >= {version}.0)"
|
||||
)
|
||||
else:
|
||||
together.append(f"python3dist({name}) {specifier.operator} {version}")
|
||||
if len(together) == 0:
|
||||
rpm_requirements.add(f"python3dist({name})")
|
||||
if len(together) == 1:
|
||||
rpm_requirements.add(together[0])
|
||||
elif len(together) > 1:
|
||||
rpm_requirements.add(f"({' and '.join(together)})")
|
||||
|
||||
|
||||
print(*sorted(rpm_requirements), sep="\n")
|
46
tests/python-entrypoints.spec
Normal file
46
tests/python-entrypoints.spec
Normal file
@ -0,0 +1,46 @@
|
||||
%global pypi_name entrypoints
|
||||
Name: python-%{pypi_name}
|
||||
Version: 0.3
|
||||
Release: 0%{?dist}
|
||||
Summary: Discover and load entry points from installed packages
|
||||
License: MIT
|
||||
URL: https://entrypoints.readthedocs.io/
|
||||
Source0: %{pypi_source}
|
||||
|
||||
BuildArch: noarch
|
||||
BuildRequires: pyproject-rpm-macros
|
||||
|
||||
%description
|
||||
Discover and load entry points from installed packages.
|
||||
|
||||
|
||||
%package -n python3-%{pypi_name}
|
||||
Summary: %{summary}
|
||||
%{?python_provide:%python_provide python3-%{pypi_name}}
|
||||
|
||||
%description -n python3-%{pypi_name}
|
||||
Discover and load entry points from installed packages.
|
||||
|
||||
|
||||
%prep
|
||||
%autosetup -p1 -n %{pypi_name}-%{version}
|
||||
|
||||
|
||||
%generate_buildrequires
|
||||
%pyproject_buildrequires
|
||||
|
||||
|
||||
%build
|
||||
%pyproject_wheel
|
||||
|
||||
|
||||
%install
|
||||
%pyproject_install
|
||||
|
||||
|
||||
%files -n python3-%{pypi_name}
|
||||
%doc README.rst
|
||||
%license LICENSE
|
||||
%{python3_sitelib}/entrypoints-*.dist-info/
|
||||
%{python3_sitelib}/entrypoints.py
|
||||
%{python3_sitelib}/__pycache__/entrypoints.*
|
@ -1,6 +1,6 @@
|
||||
%global pypi_name pytest
|
||||
Name: python-%{pypi_name}
|
||||
Version: 5.0.0
|
||||
Version: 4.4.2
|
||||
Release: 0%{?dist}
|
||||
Summary: Simple powerful testing with Python
|
||||
License: MIT
|
||||
|
Loading…
Reference in New Issue
Block a user