import pyproject-rpm-macros-1.3.3-1.el9
This commit is contained in:
parent
665439642a
commit
086dd79c67
@ -69,8 +69,7 @@ the package's runtime dependencies need to also be included as build requirement
|
|||||||
|
|
||||||
Hence, `%pyproject_buildrequires` also generates runtime dependencies by default.
|
Hence, `%pyproject_buildrequires` also generates runtime dependencies by default.
|
||||||
|
|
||||||
For this to work, the project's build system must support the
|
For this to work, the project's build system must support the [prepare-metadata-for-build-wheel hook].
|
||||||
[`prepare-metadata-for-build-wheel` hook](https://www.python.org/dev/peps/pep-0517/#prepare-metadata-for-build-wheel).
|
|
||||||
The popular buildsystems (setuptools, flit, poetry) do support it.
|
The popular buildsystems (setuptools, flit, poetry) do support it.
|
||||||
|
|
||||||
This behavior can be disabled
|
This behavior can be disabled
|
||||||
@ -80,6 +79,28 @@ using the `-R` flag:
|
|||||||
%generate_buildrequires
|
%generate_buildrequires
|
||||||
%pyproject_buildrequires -R
|
%pyproject_buildrequires -R
|
||||||
|
|
||||||
|
Alternatively, the runtime dependencies can be obtained by building the wheel and reading the metadata from the built wheel.
|
||||||
|
This can be enabled by using the `-w` flag.
|
||||||
|
Support for building wheels with `%pyproject_buildrequires -w` is **provisional** and the behavior might change.
|
||||||
|
Please subscribe to Fedora's [python-devel list] if you use the option.
|
||||||
|
|
||||||
|
%generate_buildrequires
|
||||||
|
%pyproject_buildrequires -w
|
||||||
|
|
||||||
|
When this is used, the wheel is going to be built at least twice,
|
||||||
|
becasue the `%generate_buildrequires` section runs repeatedly.
|
||||||
|
To avoid accidentally reusing a wheel leaking from a previous (different) build,
|
||||||
|
it cannot be reused between `%generate_buildrequires` rounds.
|
||||||
|
Contrarily to that, rebuilding the wheel again in the `%build` section is redundant
|
||||||
|
and the packager can omit the `%build` section entirely
|
||||||
|
to reuse the wheel built from the last round of `%generate_buildrequires`.
|
||||||
|
Be extra careful when attempting to modify the sources after `%pyproject_buildrequires`,
|
||||||
|
e.g. when running extra commands in the `%build` section:
|
||||||
|
|
||||||
|
%build
|
||||||
|
cython src/wrong.pyx # this is too late with %%pyproject_buildrequires -w
|
||||||
|
%pyproject_wheel
|
||||||
|
|
||||||
For projects that specify test requirements using an [`extra`
|
For projects that specify test requirements using an [`extra`
|
||||||
provide](https://packaging.python.org/specifications/core-metadata/#provides-extra-multiple-use),
|
provide](https://packaging.python.org/specifications/core-metadata/#provides-extra-multiple-use),
|
||||||
these can be added using the `-x` flag.
|
these can be added using the `-x` flag.
|
||||||
@ -121,9 +142,12 @@ in worst case, patch/sed the requirement out from the tox configuration.
|
|||||||
|
|
||||||
Note that both `-x` and `-t` imply `-r`,
|
Note that both `-x` and `-t` imply `-r`,
|
||||||
because runtime dependencies are always required for testing.
|
because runtime dependencies are always required for testing.
|
||||||
|
You can only use those options if the build backend supports the [prepare-metadata-for-build-wheel hook],
|
||||||
|
or together with `-w`.
|
||||||
|
|
||||||
[tox]: https://tox.readthedocs.io/
|
[tox]: https://tox.readthedocs.io/
|
||||||
[tox-current-env]: https://github.com/fedora-python/tox-current-env/
|
[tox-current-env]: https://github.com/fedora-python/tox-current-env/
|
||||||
|
[prepare-metadata-for-build-wheel hook]: https://www.python.org/dev/peps/pep-0517/#prepare-metadata-for-build-wheel
|
||||||
|
|
||||||
Additionally to generated requirements you can supply multiple file names to `%pyproject_buildrequires` macro.
|
Additionally to generated requirements you can supply multiple file names to `%pyproject_buildrequires` macro.
|
||||||
Dependencies will be loaded from them:
|
Dependencies will be loaded from them:
|
||||||
@ -133,7 +157,7 @@ Dependencies will be loaded from them:
|
|||||||
For packages not using build system you can use `-N` to entirely skip automatical
|
For packages not using build system you can use `-N` to entirely skip automatical
|
||||||
generation of requirements and install requirements only from manually specified files.
|
generation of requirements and install requirements only from manually specified files.
|
||||||
`-N` option cannot be used in combination with other options mentioned above
|
`-N` option cannot be used in combination with other options mentioned above
|
||||||
(`-r`, `-e`, `-t`, `-x`).
|
(`-r`, `-w`, `-e`, `-t`, `-x`).
|
||||||
|
|
||||||
Running tox based tests
|
Running tox based tests
|
||||||
-----------------------
|
-----------------------
|
||||||
@ -220,7 +244,7 @@ However, in Fedora packages, always list executables explicitly to avoid uninten
|
|||||||
|
|
||||||
`%pyproject_save_files` can automatically mark license files with `%license` macro
|
`%pyproject_save_files` can automatically mark license files with `%license` macro
|
||||||
and language (`*.mo`) files with `%lang` macro and appropriate language code.
|
and language (`*.mo`) files with `%lang` macro and appropriate language code.
|
||||||
Only license files declared via [PEP 639] `License-Field` field are detected.
|
Only license files declared via [PEP 639] `License-File` field are detected.
|
||||||
[PEP 639] is still a draft and can be changed in the future.
|
[PEP 639] is still a draft and can be changed in the future.
|
||||||
|
|
||||||
Note that `%pyproject_save_files` uses data from the [RECORD file](https://www.python.org/dev/peps/pep-0627/).
|
Note that `%pyproject_save_files` uses data from the [RECORD file](https://www.python.org/dev/peps/pep-0627/).
|
||||||
@ -319,7 +343,7 @@ in the `%build` section, e.g. to build the documentation with Sphinx.
|
|||||||
With pure Python packages, it might be possible to set `PYTHONPATH=${PWD}` or `PYTHONPATH=${PWD}/src`.
|
With pure Python packages, it might be possible to set `PYTHONPATH=${PWD}` or `PYTHONPATH=${PWD}/src`.
|
||||||
However, it is a bit more complicated with extension modules.
|
However, it is a bit more complicated with extension modules.
|
||||||
|
|
||||||
The location of just-built modules might differ depending on Python version, architecture, pip version.
|
The location of just-built modules might differ depending on Python version, architecture, pip version, etc.
|
||||||
Hence, the macro `%{pyproject_build_lib}` exists to be used like this:
|
Hence, the macro `%{pyproject_build_lib}` exists to be used like this:
|
||||||
|
|
||||||
%build
|
%build
|
||||||
@ -335,7 +359,25 @@ Depending on the pip version, the expanded value will differ:
|
|||||||
|
|
||||||
[python-devel list]: https://lists.fedoraproject.org/archives/list/python-devel@lists.fedoraproject.org/
|
[python-devel list]: https://lists.fedoraproject.org/archives/list/python-devel@lists.fedoraproject.org/
|
||||||
|
|
||||||
### New pip 21.3+ with in-tree-build (Fedora 36+)
|
### New pip 21.3+ with in-tree-build and setuptools 62.1+ (Fedora 37+)
|
||||||
|
|
||||||
|
Always use the macro from the same directory where you called `%pyproject_wheel` from.
|
||||||
|
The value will expand to something like:
|
||||||
|
|
||||||
|
* `/builddir/build/BUILD/%{name}-%{version}/build/lib.linux-x86_64-cpython-311` for wheels with extension modules
|
||||||
|
* `/builddir/build/BUILD/%{name}-%{version}/build/lib` for pure Python wheels
|
||||||
|
|
||||||
|
If multiple wheels were built from the same directory,
|
||||||
|
some pure Python and some with extension modules,
|
||||||
|
the expanded value will be combined with `:`:
|
||||||
|
|
||||||
|
* `/builddir/build/BUILD/%{name}-%{version}/build/lib.linux-x86_64-cypthon-311:/builddir/build/BUILD/%{name}-%{version}/build/lib`
|
||||||
|
|
||||||
|
If multiple wheels were built from different directories,
|
||||||
|
the value will differ depending on the current directory.
|
||||||
|
|
||||||
|
|
||||||
|
### New pip 21.3+ with in-tree-build and older setuptools (Fedora 36)
|
||||||
|
|
||||||
Always use the macro from the same directory where you called `%pyproject_wheel` from.
|
Always use the macro from the same directory where you called `%pyproject_wheel` from.
|
||||||
The value will expand to something like:
|
The value will expand to something like:
|
||||||
@ -353,7 +395,7 @@ If multiple wheels were built from different directories,
|
|||||||
the value will differ depending on the current directory.
|
the value will differ depending on the current directory.
|
||||||
|
|
||||||
|
|
||||||
### Older pip with out-of-tree-build (Fedora 34, 35, and EL 9)
|
### Older pip with out-of-tree-build (Fedora 35 and EL 9)
|
||||||
|
|
||||||
The value will expand to something like:
|
The value will expand to something like:
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# This is a directory where wheels are stored and installed from, relative to PWD
|
# This is a directory where wheels are stored and installed from, absolute
|
||||||
%_pyproject_wheeldir %{_builddir}%{?buildsubdir:/%{buildsubdir}}/pyproject-wheeldir
|
%_pyproject_wheeldir %{_builddir}%{?buildsubdir:/%{buildsubdir}}/pyproject-wheeldir
|
||||||
|
|
||||||
# This is a directory used as TMPDIR, where pip copies sources to and builds from, relative to PWD
|
# This is a directory used as TMPDIR, where pip copies sources to and builds from, relative to PWD
|
||||||
@ -10,10 +10,15 @@
|
|||||||
# https://docs.pytest.org/en/latest/reference.html#confval-norecursedirs
|
# https://docs.pytest.org/en/latest/reference.html#confval-norecursedirs
|
||||||
%_pyproject_builddir %{_builddir}%{?buildsubdir:/%{buildsubdir}}/.pyproject-builddir
|
%_pyproject_builddir %{_builddir}%{?buildsubdir:/%{buildsubdir}}/.pyproject-builddir
|
||||||
|
|
||||||
%pyproject_files %{_builddir}/pyproject-files
|
# We prefix all created files with this value to make them unique
|
||||||
%_pyproject_modules %{_builddir}/pyproject-modules
|
# Ideally, we would put them into %%{buildsubdir}, but that value changes during the spec
|
||||||
%_pyproject_ghost_distinfo %{_builddir}/pyproject-ghost-distinfo
|
# The used value is similar to the one used to define the default %%buildroot
|
||||||
%_pyproject_record %{_builddir}/pyproject-record
|
%_pyproject_files_prefix %{name}-%{version}-%{release}.%{_arch}
|
||||||
|
|
||||||
|
%pyproject_files %{_builddir}/%{_pyproject_files_prefix}-pyproject-files
|
||||||
|
%_pyproject_modules %{_builddir}/%{_pyproject_files_prefix}-pyproject-modules
|
||||||
|
%_pyproject_ghost_distinfo %{_builddir}/%{_pyproject_files_prefix}-pyproject-ghost-distinfo
|
||||||
|
%_pyproject_record %{_builddir}/%{_pyproject_files_prefix}-pyproject-record
|
||||||
|
|
||||||
# Avoid leaking %%{_pyproject_builddir} to pytest collection
|
# Avoid leaking %%{_pyproject_builddir} to pytest collection
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1935212
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1935212
|
||||||
@ -24,13 +29,16 @@
|
|||||||
%_set_pytest_addopts
|
%_set_pytest_addopts
|
||||||
mkdir -p "%{_pyproject_builddir}"
|
mkdir -p "%{_pyproject_builddir}"
|
||||||
CFLAGS="${CFLAGS:-${RPM_OPT_FLAGS}}" LDFLAGS="${LDFLAGS:-${RPM_LD_FLAGS}}" TMPDIR="%{_pyproject_builddir}" \\\
|
CFLAGS="${CFLAGS:-${RPM_OPT_FLAGS}}" LDFLAGS="${LDFLAGS:-${RPM_LD_FLAGS}}" TMPDIR="%{_pyproject_builddir}" \\\
|
||||||
%{__python3} -m pip wheel --wheel-dir %{_pyproject_wheeldir} --no-deps --use-pep517 --no-build-isolation --disable-pip-version-check --no-clean --progress-bar off --verbose .
|
%{__python3} -Bs %{_rpmconfigdir}/redhat/pyproject_wheel.py %{_pyproject_wheeldir}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
%pyproject_build_lib %{expand:\\\
|
%pyproject_build_lib %{expand:\\\
|
||||||
$(
|
$(
|
||||||
pyproject_build_lib=()
|
pyproject_build_lib=()
|
||||||
|
if [ -d build/lib.%{python3_platform}-cpython-%{python3_version_nodots} ]; then
|
||||||
|
pyproject_build_lib+=( "${PWD}/build/lib.%{python3_platform}-cpython-%{python3_version_nodots}" )
|
||||||
|
fi
|
||||||
if [ -d build/lib.%{python3_platform}-%{python3_version} ]; then
|
if [ -d build/lib.%{python3_platform}-%{python3_version} ]; then
|
||||||
pyproject_build_lib+=( "${PWD}/build/lib.%{python3_platform}-%{python3_version}" )
|
pyproject_build_lib+=( "${PWD}/build/lib.%{python3_platform}-%{python3_version}" )
|
||||||
fi
|
fi
|
||||||
@ -49,7 +57,7 @@ echo $(IFS=:; echo "${pyproject_build_lib[*]}")
|
|||||||
|
|
||||||
%pyproject_install() %{expand:\\\
|
%pyproject_install() %{expand:\\\
|
||||||
specifier=$(ls %{_pyproject_wheeldir}/*.whl | xargs basename --multiple | sed -E 's/([^-]+)-([^-]+)-.+\\\.whl/\\\1==\\\2/')
|
specifier=$(ls %{_pyproject_wheeldir}/*.whl | xargs basename --multiple | sed -E 's/([^-]+)-([^-]+)-.+\\\.whl/\\\1==\\\2/')
|
||||||
TMPDIR="%{_pyproject_builddir}" %{__python3} -m pip install --root %{buildroot} --no-deps --disable-pip-version-check --progress-bar off --verbose --ignore-installed --no-warn-script-location --no-index --no-cache-dir --find-links %{_pyproject_wheeldir} $specifier
|
TMPDIR="%{_pyproject_builddir}" %{__python3} -m pip install --root %{buildroot} --prefix %{_prefix} --no-deps --disable-pip-version-check --progress-bar off --verbose --ignore-installed --no-warn-script-location --no-index --no-cache-dir --find-links %{_pyproject_wheeldir} $specifier
|
||||||
if [ -d %{buildroot}%{_bindir} ]; then
|
if [ -d %{buildroot}%{_bindir} ]; then
|
||||||
%py3_shebang_fix %{buildroot}%{_bindir}/*
|
%py3_shebang_fix %{buildroot}%{_bindir}/*
|
||||||
rm -rfv %{buildroot}%{_bindir}/__pycache__
|
rm -rfv %{buildroot}%{_bindir}/__pycache__
|
||||||
@ -116,13 +124,24 @@ fi
|
|||||||
%toxenv %{default_toxenv}
|
%toxenv %{default_toxenv}
|
||||||
|
|
||||||
|
|
||||||
%pyproject_buildrequires(rRxtNe:) %{expand:\\\
|
%pyproject_buildrequires(rRxtNwe:) %{expand:\\\
|
||||||
%{-R:%{-r:%{error:The -R and -r options are mutually exclusive}}}
|
%_set_pytest_addopts
|
||||||
|
# The _auto_set_build_flags feature does not do this in %%generate_buildrequires section,
|
||||||
|
# but we want to get an environment consistent with %%build:
|
||||||
|
%{?_auto_set_build_flags:%set_build_flags}
|
||||||
|
# The default flags expect the package note file to exist
|
||||||
|
# see https://bugzilla.redhat.com/show_bug.cgi?id=2097535
|
||||||
|
%{?_package_note_flags:%_generate_package_note_file}
|
||||||
|
%{-R:
|
||||||
|
%{-r:%{error:The -R and -r options are mutually exclusive}}
|
||||||
|
%{-w:%{error:The -R and -w options are mutually exclusive}}
|
||||||
|
}
|
||||||
%{-N:
|
%{-N:
|
||||||
%{-r:%{error:The -N and -r options are mutually exclusive}}
|
%{-r:%{error:The -N and -r options are mutually exclusive}}
|
||||||
%{-x:%{error:The -N and -x options are mutually exclusive}}
|
%{-x:%{error:The -N and -x options are mutually exclusive}}
|
||||||
%{-e:%{error:The -N and -e options are mutually exclusive}}
|
%{-e:%{error:The -N and -e options are mutually exclusive}}
|
||||||
%{-t:%{error:The -N and -t options are mutually exclusive}}
|
%{-t:%{error:The -N and -t options are mutually exclusive}}
|
||||||
|
%{-w:%{error:The -N and -w options are mutually exclusive}}
|
||||||
}
|
}
|
||||||
%{-e:%{expand:%global toxenv %(%{__python3} -s %{_rpmconfigdir}/redhat/pyproject_construct_toxenv.py %{?**})}}
|
%{-e:%{expand:%global toxenv %(%{__python3} -s %{_rpmconfigdir}/redhat/pyproject_construct_toxenv.py %{?**})}}
|
||||||
echo 'pyproject-rpm-macros' # we already have this installed, but this way, it's repoqueryable
|
echo 'pyproject-rpm-macros' # we already have this installed, but this way, it's repoqueryable
|
||||||
@ -130,7 +149,13 @@ echo 'python%{python3_pkgversion}-devel'
|
|||||||
echo 'python%{python3_pkgversion}dist(pip) >= 19'
|
echo 'python%{python3_pkgversion}dist(pip) >= 19'
|
||||||
echo 'python%{python3_pkgversion}dist(packaging)'
|
echo 'python%{python3_pkgversion}dist(packaging)'
|
||||||
%{!-N:if [ -f pyproject.toml ]; then
|
%{!-N:if [ -f pyproject.toml ]; then
|
||||||
echo 'python%{python3_pkgversion}dist(toml)'
|
%["%{python3_pkgversion}" == "3"
|
||||||
|
? "echo '(python%{python3_pkgversion}dist(toml) if python%{python3_pkgversion}-devel < 3.11)'"
|
||||||
|
: "%[v"%{python3_pkgversion}" < v"3.11"
|
||||||
|
? "echo 'python%{python3_pkgversion}dist(toml)'"
|
||||||
|
: "true # will use tomllib, echo nothing"
|
||||||
|
]"
|
||||||
|
]
|
||||||
elif [ -f setup.py ]; then
|
elif [ -f setup.py ]; then
|
||||||
# Note: If the default requirements change, also change them in the script!
|
# Note: If the default requirements change, also change them in the script!
|
||||||
echo 'python%{python3_pkgversion}dist(setuptools) >= 40.8'
|
echo 'python%{python3_pkgversion}dist(setuptools) >= 40.8'
|
||||||
@ -142,7 +167,9 @@ fi}
|
|||||||
# setuptools assumes no pre-existing dist-info
|
# setuptools assumes no pre-existing dist-info
|
||||||
rm -rfv *.dist-info/ >&2
|
rm -rfv *.dist-info/ >&2
|
||||||
if [ -f %{__python3} ]; then
|
if [ -f %{__python3} ]; then
|
||||||
RPM_TOXENV="%{toxenv}" HOSTNAME="rpmbuild" %{__python3} -s %{_rpmconfigdir}/redhat/pyproject_buildrequires.py %{?!_python_no_extras_requires:--generate-extras} --python3_pkgversion %{python3_pkgversion} %{?**}
|
mkdir -p "%{_pyproject_builddir}"
|
||||||
|
CFLAGS="${CFLAGS:-${RPM_OPT_FLAGS}}" LDFLAGS="${LDFLAGS:-${RPM_LD_FLAGS}}" TMPDIR="%{_pyproject_builddir}" \\\
|
||||||
|
RPM_TOXENV="%{toxenv}" HOSTNAME="rpmbuild" %{__python3} -Bs %{_rpmconfigdir}/redhat/pyproject_buildrequires.py %{?!_python_no_extras_requires:--generate-extras} --python3_pkgversion %{python3_pkgversion} --wheeldir %{_pyproject_wheeldir} %{?**}
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import glob
|
||||||
|
import io
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import importlib.metadata
|
import importlib.metadata
|
||||||
@ -11,6 +13,7 @@ import re
|
|||||||
import tempfile
|
import tempfile
|
||||||
import email.parser
|
import email.parser
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import zipfile
|
||||||
|
|
||||||
from pyproject_requirements_txt import convert_requirements_txt
|
from pyproject_requirements_txt import convert_requirements_txt
|
||||||
|
|
||||||
@ -184,21 +187,32 @@ class Requirements:
|
|||||||
self.add(req_str, **kwargs)
|
self.add(req_str, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def get_backend(requirements):
|
def toml_load(opened_binary_file):
|
||||||
try:
|
try:
|
||||||
f = open('pyproject.toml')
|
# tomllib is in the standard library since 3.11.0b1
|
||||||
except FileNotFoundError:
|
import tomllib as toml_module
|
||||||
pyproject_data = {}
|
load_from = opened_binary_file
|
||||||
else:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
# lazy import toml here, not needed without pyproject.toml
|
# note: we could use tomli here,
|
||||||
import toml
|
# but for backwards compatibility with RHEL 9, we use toml instead
|
||||||
|
import toml as toml_module
|
||||||
|
load_from = io.TextIOWrapper(opened_binary_file, encoding='utf-8')
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
print_err('Import error:', e)
|
print_err('Import error:', e)
|
||||||
# already echoed by the %pyproject_buildrequires macro
|
# already echoed by the %pyproject_buildrequires macro
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
return toml_module.load(load_from)
|
||||||
|
|
||||||
|
|
||||||
|
def get_backend(requirements):
|
||||||
|
try:
|
||||||
|
f = open('pyproject.toml', 'rb')
|
||||||
|
except FileNotFoundError:
|
||||||
|
pyproject_data = {}
|
||||||
|
else:
|
||||||
with f:
|
with f:
|
||||||
pyproject_data = toml.load(f)
|
pyproject_data = toml_load(f)
|
||||||
|
|
||||||
buildsystem_data = pyproject_data.get('build-system', {})
|
buildsystem_data = pyproject_data.get('build-system', {})
|
||||||
requirements.extend(
|
requirements.extend(
|
||||||
@ -253,21 +267,67 @@ def generate_build_requirements(backend, requirements):
|
|||||||
requirements.check(source='get_requires_for_build_wheel')
|
requirements.check(source='get_requires_for_build_wheel')
|
||||||
|
|
||||||
|
|
||||||
def generate_run_requirements(backend, requirements):
|
def requires_from_metadata_file(metadata_file):
|
||||||
|
message = email.parser.Parser().parse(metadata_file, headersonly=True)
|
||||||
|
return {k: message.get_all(k, ()) for k in ('Requires', 'Requires-Dist')}
|
||||||
|
|
||||||
|
|
||||||
|
def generate_run_requirements_hook(backend, requirements):
|
||||||
hook_name = 'prepare_metadata_for_build_wheel'
|
hook_name = 'prepare_metadata_for_build_wheel'
|
||||||
prepare_metadata = getattr(backend, hook_name, None)
|
prepare_metadata = getattr(backend, hook_name, None)
|
||||||
if not prepare_metadata:
|
if not prepare_metadata:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'build backend cannot provide build metadata '
|
'The build backend cannot provide build metadata '
|
||||||
+ '(incl. runtime requirements) before build'
|
'(incl. runtime requirements) before build. '
|
||||||
|
'Use the provisional -w flag to build the wheel and parse the metadata from it, '
|
||||||
|
'or use the -R flag not to generate runtime dependencies.'
|
||||||
)
|
)
|
||||||
with hook_call():
|
with hook_call():
|
||||||
dir_basename = prepare_metadata('.')
|
dir_basename = prepare_metadata('.')
|
||||||
with open(dir_basename + '/METADATA') as f:
|
with open(dir_basename + '/METADATA') as metadata_file:
|
||||||
message = email.parser.Parser().parse(f, headersonly=True)
|
for key, requires in requires_from_metadata_file(metadata_file).items():
|
||||||
for key in 'Requires', 'Requires-Dist':
|
requirements.extend(requires, source=f'hook generated metadata: {key}')
|
||||||
requires = message.get_all(key, ())
|
|
||||||
requirements.extend(requires, source=f'wheel metadata: {key}')
|
|
||||||
|
def find_built_wheel(wheeldir):
|
||||||
|
wheels = glob.glob(os.path.join(wheeldir, '*.whl'))
|
||||||
|
if not wheels:
|
||||||
|
return None
|
||||||
|
if len(wheels) > 1:
|
||||||
|
raise RuntimeError('Found multiple wheels in %{_pyproject_wheeldir}, '
|
||||||
|
'this is not supported with %pyproject_buildrequires -w.')
|
||||||
|
return wheels[0]
|
||||||
|
|
||||||
|
|
||||||
|
def generate_run_requirements_wheel(backend, requirements, wheeldir):
|
||||||
|
# Reuse the wheel from the previous round of %pyproject_buildrequires (if it exists)
|
||||||
|
wheel = find_built_wheel(wheeldir)
|
||||||
|
if not wheel:
|
||||||
|
import pyproject_wheel
|
||||||
|
returncode = pyproject_wheel.build_wheel(wheeldir=wheeldir, stdout=sys.stderr)
|
||||||
|
if returncode != 0:
|
||||||
|
raise RuntimeError('Failed to build the wheel for %pyproject_buildrequires -w.')
|
||||||
|
wheel = find_built_wheel(wheeldir)
|
||||||
|
if not wheel:
|
||||||
|
raise RuntimeError('Cannot locate the built wheel for %pyproject_buildrequires -w.')
|
||||||
|
|
||||||
|
print_err(f'Reading metadata from {wheel}')
|
||||||
|
with zipfile.ZipFile(wheel) as wheelfile:
|
||||||
|
for name in wheelfile.namelist():
|
||||||
|
if name.count('/') == 1 and name.endswith('.dist-info/METADATA'):
|
||||||
|
with io.TextIOWrapper(wheelfile.open(name), encoding='utf-8') as metadata_file:
|
||||||
|
for key, requires in requires_from_metadata_file(metadata_file).items():
|
||||||
|
requirements.extend(requires, source=f'built wheel metadata: {key}')
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise RuntimeError('Could not find *.dist-info/METADATA in built wheel.')
|
||||||
|
|
||||||
|
|
||||||
|
def generate_run_requirements(backend, requirements, *, build_wheel, wheeldir):
|
||||||
|
if build_wheel:
|
||||||
|
generate_run_requirements_wheel(backend, requirements, wheeldir)
|
||||||
|
else:
|
||||||
|
generate_run_requirements_hook(backend, requirements)
|
||||||
|
|
||||||
|
|
||||||
def generate_tox_requirements(toxenv, requirements):
|
def generate_tox_requirements(toxenv, requirements):
|
||||||
@ -282,7 +342,7 @@ def generate_tox_requirements(toxenv, requirements):
|
|||||||
'--print-deps-to', deps.name,
|
'--print-deps-to', deps.name,
|
||||||
'--print-extras-to', extras.name,
|
'--print-extras-to', extras.name,
|
||||||
'--no-provision', provision.name,
|
'--no-provision', provision.name,
|
||||||
'-qre', toxenv],
|
'-q', '-r', '-e', toxenv],
|
||||||
check=False,
|
check=False,
|
||||||
encoding='utf-8',
|
encoding='utf-8',
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
@ -326,7 +386,7 @@ def python3dist(name, op=None, version=None, python3_pkgversion="3"):
|
|||||||
|
|
||||||
|
|
||||||
def generate_requires(
|
def generate_requires(
|
||||||
*, include_runtime=False, toxenv=None, extras=None,
|
*, include_runtime=False, build_wheel=False, wheeldir=None, toxenv=None, extras=None,
|
||||||
get_installed_version=importlib.metadata.version, # for dep injection
|
get_installed_version=importlib.metadata.version, # for dep injection
|
||||||
generate_extras=False, python3_pkgversion="3", requirement_files=None, use_build_system=True
|
generate_extras=False, python3_pkgversion="3", requirement_files=None, use_build_system=True
|
||||||
):
|
):
|
||||||
@ -357,7 +417,7 @@ def generate_requires(
|
|||||||
include_runtime = True
|
include_runtime = True
|
||||||
generate_tox_requirements(toxenv, requirements)
|
generate_tox_requirements(toxenv, requirements)
|
||||||
if include_runtime:
|
if include_runtime:
|
||||||
generate_run_requirements(backend, requirements)
|
generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir)
|
||||||
except EndPass:
|
except EndPass:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -370,6 +430,15 @@ def main(argv):
|
|||||||
'-r', '--runtime', action='store_true', default=True,
|
'-r', '--runtime', action='store_true', default=True,
|
||||||
help='Generate run-time requirements (default, disable with -R)',
|
help='Generate run-time requirements (default, disable with -R)',
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-w', '--wheel', action='store_true', default=False,
|
||||||
|
help=('Generate run-time requirements by building the wheel '
|
||||||
|
'(useful for build backends without the prepare_metadata_for_build_wheel hook)'),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--wheeldir', metavar='PATH', default=None,
|
||||||
|
help='The directory with wheel, used when -w.',
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-R', '--no-runtime', action='store_false', dest='runtime',
|
'-R', '--no-runtime', action='store_false', dest='runtime',
|
||||||
help="Don't generate run-time requirements (implied by -N)",
|
help="Don't generate run-time requirements (implied by -N)",
|
||||||
@ -412,6 +481,10 @@ def main(argv):
|
|||||||
if not args.use_build_system:
|
if not args.use_build_system:
|
||||||
args.runtime = False
|
args.runtime = False
|
||||||
|
|
||||||
|
if args.wheel:
|
||||||
|
if not args.wheeldir:
|
||||||
|
raise ValueError('--wheeldir must be set when -w.')
|
||||||
|
|
||||||
if args.toxenv:
|
if args.toxenv:
|
||||||
args.tox = True
|
args.tox = True
|
||||||
|
|
||||||
@ -427,6 +500,8 @@ def main(argv):
|
|||||||
try:
|
try:
|
||||||
generate_requires(
|
generate_requires(
|
||||||
include_runtime=args.runtime,
|
include_runtime=args.runtime,
|
||||||
|
build_wheel=args.wheel,
|
||||||
|
wheeldir=args.wheeldir,
|
||||||
toxenv=args.toxenv,
|
toxenv=args.toxenv,
|
||||||
extras=args.extras,
|
extras=args.extras,
|
||||||
generate_extras=args.generate_extras,
|
generate_extras=args.generate_extras,
|
||||||
|
@ -268,6 +268,8 @@ Run dependencies with extras (not selected):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
setup(
|
setup(
|
||||||
|
name = "pytest",
|
||||||
|
version = "6.6.6",
|
||||||
setup_requires=["setuptools>=40.0"],
|
setup_requires=["setuptools>=40.0"],
|
||||||
# fmt: off
|
# fmt: off
|
||||||
extras_require={
|
extras_require={
|
||||||
@ -358,6 +360,35 @@ Run dependencies with multiple extras:
|
|||||||
python3dist(dep1)
|
python3dist(dep1)
|
||||||
result: 0
|
result: 0
|
||||||
|
|
||||||
|
Run dependencies with extras and build wheel option:
|
||||||
|
installed:
|
||||||
|
setuptools: 50
|
||||||
|
wheel: 1
|
||||||
|
pyyaml: 1
|
||||||
|
include_runtime: true
|
||||||
|
build_wheel: true
|
||||||
|
extras:
|
||||||
|
- testing
|
||||||
|
setup.py: *pytest_setup_py
|
||||||
|
expected: |
|
||||||
|
python3dist(setuptools) >= 40.8
|
||||||
|
python3dist(wheel)
|
||||||
|
python3dist(wheel)
|
||||||
|
python3dist(setuptools) >= 40
|
||||||
|
python3dist(py) >= 1.5
|
||||||
|
python3dist(six) >= 1.10
|
||||||
|
python3dist(setuptools)
|
||||||
|
python3dist(attrs) >= 17.4
|
||||||
|
python3dist(atomicwrites) >= 1
|
||||||
|
python3dist(pluggy) >= 0.11
|
||||||
|
python3dist(more-itertools) >= 4
|
||||||
|
python3dist(argcomplete)
|
||||||
|
python3dist(hypothesis) >= 3.56
|
||||||
|
python3dist(nose)
|
||||||
|
python3dist(requests)
|
||||||
|
result: 0
|
||||||
|
stderr_contains: "Reading metadata from {wheeldir}/pytest-6.6.6-py3-none-any.whl"
|
||||||
|
|
||||||
Tox dependencies:
|
Tox dependencies:
|
||||||
installed:
|
installed:
|
||||||
setuptools: 50
|
setuptools: 50
|
||||||
|
@ -320,15 +320,20 @@ def classify_paths(
|
|||||||
# we handle bytecode separately
|
# we handle bytecode separately
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if path.parent == distinfo:
|
if distinfo in path.parents:
|
||||||
if path.name in ("RECORD", "REQUESTED"):
|
if path.parent == distinfo and path.name in ("RECORD", "REQUESTED"):
|
||||||
# RECORD and REQUESTED files are removed in %pyproject_install
|
# RECORD and REQUESTED files are removed in %pyproject_install
|
||||||
# See PEP 627
|
# See PEP 627
|
||||||
continue
|
continue
|
||||||
if license_files and path.name in license_files:
|
if license_files and str(path.relative_to(distinfo)) in license_files:
|
||||||
paths["metadata"]["licenses"].append(path)
|
paths["metadata"]["licenses"].append(path)
|
||||||
else:
|
else:
|
||||||
paths["metadata"]["files"].append(path)
|
paths["metadata"]["files"].append(path)
|
||||||
|
# nested directories within distinfo
|
||||||
|
index = path.parents.index(distinfo)
|
||||||
|
for parent in list(path.parents)[:index]: # no direct slice until Python 3.10
|
||||||
|
if parent not in paths["metadata"]["dirs"]:
|
||||||
|
paths["metadata"]["dirs"].append(parent)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for sitedir in sitedirs:
|
for sitedir in sitedirs:
|
||||||
@ -480,6 +485,12 @@ def generate_file_list(paths_dict, module_globs, include_others=False):
|
|||||||
done_modules.add(name)
|
done_modules.add(name)
|
||||||
done_globs.add(glob)
|
done_globs.add(glob)
|
||||||
|
|
||||||
|
# Users using '*' don't care about the files in the package, so it's ok
|
||||||
|
# not to fail the build when no modules are detected
|
||||||
|
# There can be legitimate reasons to create a package without Python modules
|
||||||
|
if not modules and fnmatch.fnmatchcase("", glob):
|
||||||
|
done_globs.add(glob)
|
||||||
|
|
||||||
missed = module_globs - done_globs
|
missed = module_globs - done_globs
|
||||||
if missed:
|
if missed:
|
||||||
missed_text = ", ".join(sorted(missed))
|
missed_text = ", ".join(sorted(missed))
|
||||||
|
@ -409,10 +409,27 @@ classified:
|
|||||||
other:
|
other:
|
||||||
files:
|
files:
|
||||||
- /usr/lib/python3.7/site-packages/zope.event-4.4-py3.7-nspkg.pth
|
- /usr/lib/python3.7/site-packages/zope.event-4.4-py3.7-nspkg.pth
|
||||||
|
comic2pdf:
|
||||||
|
metadata:
|
||||||
|
dirs:
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info
|
||||||
|
docs: []
|
||||||
|
files:
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/METADATA
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/WHEEL
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/entry_points.txt
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/top_level.txt
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/zip-safe
|
||||||
|
licenses: []
|
||||||
|
modules: []
|
||||||
|
other:
|
||||||
|
files:
|
||||||
|
- /usr/bin/comic2pdf.py
|
||||||
django:
|
django:
|
||||||
metadata:
|
metadata:
|
||||||
dirs:
|
dirs:
|
||||||
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info
|
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info
|
||||||
|
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/licenses
|
||||||
docs: []
|
docs: []
|
||||||
files:
|
files:
|
||||||
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/AUTHORS
|
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/AUTHORS
|
||||||
@ -422,8 +439,8 @@ classified:
|
|||||||
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/entry_points.txt
|
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/entry_points.txt
|
||||||
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/top_level.txt
|
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/top_level.txt
|
||||||
licenses:
|
licenses:
|
||||||
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/LICENSE
|
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/licenses/LICENSE
|
||||||
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/LICENSE.python
|
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/licenses/LICENSE.python
|
||||||
lang:
|
lang:
|
||||||
django:
|
django:
|
||||||
af:
|
af:
|
||||||
@ -7763,9 +7780,20 @@ dumped:
|
|||||||
- zope.event
|
- zope.event
|
||||||
- zope.event.classhandler
|
- zope.event.classhandler
|
||||||
- zope.event.tests
|
- zope.event.tests
|
||||||
|
- - comic2pdf
|
||||||
|
- '*'
|
||||||
|
- - '%dir /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info'
|
||||||
|
- /usr/bin/comic2pdf.py
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/METADATA
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/WHEEL
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/entry_points.txt
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/top_level.txt
|
||||||
|
- /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/zip-safe
|
||||||
|
- []
|
||||||
- - django
|
- - django
|
||||||
- django
|
- django
|
||||||
- - '%dir /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info'
|
- - '%dir /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info'
|
||||||
|
- '%dir /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/licenses'
|
||||||
- '%dir /usr/lib/python3.7/site-packages/django'
|
- '%dir /usr/lib/python3.7/site-packages/django'
|
||||||
- '%dir /usr/lib/python3.7/site-packages/django/__pycache__'
|
- '%dir /usr/lib/python3.7/site-packages/django/__pycache__'
|
||||||
- '%dir /usr/lib/python3.7/site-packages/django/apps'
|
- '%dir /usr/lib/python3.7/site-packages/django/apps'
|
||||||
@ -11349,8 +11377,8 @@ dumped:
|
|||||||
- '%lang(zh) /usr/lib/python3.7/site-packages/django/contrib/sessions/locale/zh_Hant/LC_MESSAGES/django.mo'
|
- '%lang(zh) /usr/lib/python3.7/site-packages/django/contrib/sessions/locale/zh_Hant/LC_MESSAGES/django.mo'
|
||||||
- '%lang(zh) /usr/lib/python3.7/site-packages/django/contrib/sites/locale/zh_Hans/LC_MESSAGES/django.mo'
|
- '%lang(zh) /usr/lib/python3.7/site-packages/django/contrib/sites/locale/zh_Hans/LC_MESSAGES/django.mo'
|
||||||
- '%lang(zh) /usr/lib/python3.7/site-packages/django/contrib/sites/locale/zh_Hant/LC_MESSAGES/django.mo'
|
- '%lang(zh) /usr/lib/python3.7/site-packages/django/contrib/sites/locale/zh_Hant/LC_MESSAGES/django.mo'
|
||||||
- '%license /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/LICENSE'
|
- '%license /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/licenses/LICENSE'
|
||||||
- '%license /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/LICENSE.python'
|
- '%license /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/licenses/LICENSE.python'
|
||||||
- /usr/bin/django-admin
|
- /usr/bin/django-admin
|
||||||
- /usr/bin/django-admin.py
|
- /usr/bin/django-admin.py
|
||||||
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/AUTHORS
|
- /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/AUTHORS
|
||||||
@ -15456,8 +15484,8 @@ metadata:
|
|||||||
content: |
|
content: |
|
||||||
Name: Django
|
Name: Django
|
||||||
Version: 3.0.7
|
Version: 3.0.7
|
||||||
License-File: LICENSE
|
License-File: licenses/LICENSE
|
||||||
License-File: LICENSE.python
|
License-File: licenses/LICENSE.python
|
||||||
Whatever: False data
|
Whatever: False data
|
||||||
|
|
||||||
records:
|
records:
|
||||||
@ -15743,6 +15771,17 @@ records:
|
|||||||
zope/event/classhandler.py,sha256=CEx6issKWSia0Wruob_jIQI2EfYX45krokoTHyVsJFQ,1816
|
zope/event/classhandler.py,sha256=CEx6issKWSia0Wruob_jIQI2EfYX45krokoTHyVsJFQ,1816
|
||||||
zope/event/tests.py,sha256=bvEzvOmPoQETMqYiqsR9EeVsC8Dzy-HOclfpQFVjDhE,1871
|
zope/event/tests.py,sha256=bvEzvOmPoQETMqYiqsR9EeVsC8Dzy-HOclfpQFVjDhE,1871
|
||||||
|
|
||||||
|
comic2pdf:
|
||||||
|
path: /usr/lib/python3.7/site-packages/comic2pdf-3.1.0.dist-info/RECORD
|
||||||
|
content: |
|
||||||
|
../../../bin/comic2pdf.py,sha256=ad0XbWxj2fzn_oYi1h-usY8jsxAvfpYA1aaify1Ym88,3266
|
||||||
|
comic2pdf-3.1.0.dist-info/METADATA,sha256=qMVNbSPY02NdWfGex5yWNxoK1d96ereES-XoKxshVEA,3195
|
||||||
|
comic2pdf-3.1.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
||||||
|
comic2pdf-3.1.0.dist-info/entry_points.txt,sha256=uORK0FJD-i46W74x2mNHfloSPS4QElN3-Y0vKQZ7svw,46
|
||||||
|
comic2pdf-3.1.0.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
||||||
|
comic2pdf-3.1.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
||||||
|
comic2pdf-3.1.0.dist-info/RECORD,,
|
||||||
|
|
||||||
django:
|
django:
|
||||||
path: /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/RECORD
|
path: /usr/lib/python3.7/site-packages/Django-3.0.7.dist-info/RECORD
|
||||||
content: |
|
content: |
|
||||||
@ -15751,8 +15790,8 @@ records:
|
|||||||
../../../bin/django-admin.py,sha256=OOv0QKYqhDD2O4X3HQx3gFFQ-CC7hSLnWuzZnQXeiiA,115
|
../../../bin/django-admin.py,sha256=OOv0QKYqhDD2O4X3HQx3gFFQ-CC7hSLnWuzZnQXeiiA,115
|
||||||
Django-3.0.7.dist-info/AUTHORS,sha256=cV29hNQ1SpKhTmZuPff3LWHyQ7mHNBWP7_0JufEUHbs,36806
|
Django-3.0.7.dist-info/AUTHORS,sha256=cV29hNQ1SpKhTmZuPff3LWHyQ7mHNBWP7_0JufEUHbs,36806
|
||||||
Django-3.0.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
Django-3.0.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||||
Django-3.0.7.dist-info/LICENSE,sha256=uEZBXRtRTpwd_xSiLeuQbXlLxUbKYSn5UKGM0JHipmk,1552
|
Django-3.0.7.dist-info/licenses/LICENSE,sha256=uEZBXRtRTpwd_xSiLeuQbXlLxUbKYSn5UKGM0JHipmk,1552
|
||||||
Django-3.0.7.dist-info/LICENSE.python,sha256=Z-Pr3SuMPxOcaosqZSgr_NAjh2cFRcFyPZjP7nMeQrQ,13231
|
Django-3.0.7.dist-info/licenses/LICENSE.python,sha256=Z-Pr3SuMPxOcaosqZSgr_NAjh2cFRcFyPZjP7nMeQrQ,13231
|
||||||
Django-3.0.7.dist-info/METADATA,sha256=0ZU0N0E-CHKarXMLp4oOYf7EMUHR8eJ79f2yqw2NwoM,3574
|
Django-3.0.7.dist-info/METADATA,sha256=0ZU0N0E-CHKarXMLp4oOYf7EMUHR8eJ79f2yqw2NwoM,3574
|
||||||
Django-3.0.7.dist-info/RECORD,,
|
Django-3.0.7.dist-info/RECORD,,
|
||||||
Django-3.0.7.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
|
Django-3.0.7.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
|
||||||
|
25
SOURCES/pyproject_wheel.py
Normal file
25
SOURCES/pyproject_wheel.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def build_wheel(*, wheeldir, stdout=None):
|
||||||
|
command = (
|
||||||
|
sys.executable,
|
||||||
|
'-m', 'pip',
|
||||||
|
'wheel',
|
||||||
|
'--wheel-dir', wheeldir,
|
||||||
|
'--no-deps',
|
||||||
|
'--use-pep517',
|
||||||
|
'--no-build-isolation',
|
||||||
|
'--disable-pip-version-check',
|
||||||
|
'--no-clean',
|
||||||
|
'--progress-bar', 'off',
|
||||||
|
'--verbose',
|
||||||
|
'.',
|
||||||
|
)
|
||||||
|
cp = subprocess.run(command, stdout=stdout)
|
||||||
|
return cp.returncode
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(build_wheel(wheeldir=sys.argv[1]))
|
@ -13,12 +13,14 @@ with Path(__file__).parent.joinpath('pyproject_buildrequires_testcases.yaml').op
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('case_name', testcases)
|
@pytest.mark.parametrize('case_name', testcases)
|
||||||
def test_data(case_name, capsys, tmp_path, monkeypatch):
|
def test_data(case_name, capfd, tmp_path, monkeypatch):
|
||||||
case = testcases[case_name]
|
case = testcases[case_name]
|
||||||
|
|
||||||
cwd = tmp_path.joinpath('cwd')
|
cwd = tmp_path.joinpath('cwd')
|
||||||
cwd.mkdir()
|
cwd.mkdir()
|
||||||
monkeypatch.chdir(cwd)
|
monkeypatch.chdir(cwd)
|
||||||
|
wheeldir = cwd.joinpath('wheeldir')
|
||||||
|
wheeldir.mkdir()
|
||||||
|
|
||||||
if case.get('xfail'):
|
if case.get('xfail'):
|
||||||
pytest.xfail(case.get('xfail'))
|
pytest.xfail(case.get('xfail'))
|
||||||
@ -45,6 +47,8 @@ def test_data(case_name, capsys, tmp_path, monkeypatch):
|
|||||||
generate_requires(
|
generate_requires(
|
||||||
get_installed_version=get_installed_version,
|
get_installed_version=get_installed_version,
|
||||||
include_runtime=case.get('include_runtime', use_build_system),
|
include_runtime=case.get('include_runtime', use_build_system),
|
||||||
|
build_wheel=case.get('build_wheel', False),
|
||||||
|
wheeldir=str(wheeldir),
|
||||||
extras=case.get('extras', []),
|
extras=case.get('extras', []),
|
||||||
toxenv=case.get('toxenv', None),
|
toxenv=case.get('toxenv', None),
|
||||||
generate_extras=case.get('generate_extras', False),
|
generate_extras=case.get('generate_extras', False),
|
||||||
@ -64,7 +68,7 @@ def test_data(case_name, capsys, tmp_path, monkeypatch):
|
|||||||
# if we ever need to do that, we can remove the check or change it:
|
# if we ever need to do that, we can remove the check or change it:
|
||||||
assert 'expected' in case or 'stderr_contains' in case
|
assert 'expected' in case or 'stderr_contains' in case
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capfd.readouterr()
|
||||||
|
|
||||||
if 'expected' in case:
|
if 'expected' in case:
|
||||||
assert out == case['expected']
|
assert out == case['expected']
|
||||||
@ -75,7 +79,7 @@ def test_data(case_name, capsys, tmp_path, monkeypatch):
|
|||||||
if isinstance(stderr_contains, str):
|
if isinstance(stderr_contains, str):
|
||||||
stderr_contains = [stderr_contains]
|
stderr_contains = [stderr_contains]
|
||||||
for expected_substring in stderr_contains:
|
for expected_substring in stderr_contains:
|
||||||
assert expected_substring in err
|
assert expected_substring.format(**locals()) in err
|
||||||
finally:
|
finally:
|
||||||
for req in requirement_files:
|
for req in requirement_files:
|
||||||
req.close()
|
req.close()
|
||||||
|
@ -12,7 +12,7 @@ License: MIT
|
|||||||
# Increment Y and reset Z when new macros or features are added
|
# Increment Y and reset Z when new macros or features are added
|
||||||
# Increment Z when this is a bugfix or a cosmetic change
|
# Increment Z when this is a bugfix or a cosmetic change
|
||||||
# Dropping support for EOL Fedoras is *not* considered a breaking change
|
# Dropping support for EOL Fedoras is *not* considered a breaking change
|
||||||
Version: 1.0.0~rc1
|
Version: 1.3.3
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
|
|
||||||
# Macro files
|
# Macro files
|
||||||
@ -25,6 +25,7 @@ Source103: pyproject_convert.py
|
|||||||
Source104: pyproject_preprocess_record.py
|
Source104: pyproject_preprocess_record.py
|
||||||
Source105: pyproject_construct_toxenv.py
|
Source105: pyproject_construct_toxenv.py
|
||||||
Source106: pyproject_requirements_txt.py
|
Source106: pyproject_requirements_txt.py
|
||||||
|
Source107: pyproject_wheel.py
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
Source201: test_pyproject_buildrequires.py
|
Source201: test_pyproject_buildrequires.py
|
||||||
@ -51,12 +52,15 @@ BuildRequires: python3dist(pyyaml)
|
|||||||
BuildRequires: python3dist(packaging)
|
BuildRequires: python3dist(packaging)
|
||||||
BuildRequires: python3dist(pip)
|
BuildRequires: python3dist(pip)
|
||||||
BuildRequires: python3dist(setuptools)
|
BuildRequires: python3dist(setuptools)
|
||||||
BuildRequires: python3dist(toml)
|
|
||||||
BuildRequires: python3dist(tox-current-env) >= 0.0.6
|
BuildRequires: python3dist(tox-current-env) >= 0.0.6
|
||||||
BuildRequires: python3dist(wheel)
|
BuildRequires: python3dist(wheel)
|
||||||
|
BuildRequires: (python3dist(toml) if python3-devel < 3.11)
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
# We build on top of those:
|
# We build on top of those:
|
||||||
|
BuildRequires: python-rpm-macros
|
||||||
|
BuildRequires: python-srpm-macros
|
||||||
|
BuildRequires: python3-rpm-macros
|
||||||
Requires: python-rpm-macros
|
Requires: python-rpm-macros
|
||||||
Requires: python-srpm-macros
|
Requires: python-srpm-macros
|
||||||
Requires: python3-rpm-macros
|
Requires: python3-rpm-macros
|
||||||
@ -92,18 +96,19 @@ cp -p %{sources} .
|
|||||||
%install
|
%install
|
||||||
mkdir -p %{buildroot}%{_rpmmacrodir}
|
mkdir -p %{buildroot}%{_rpmmacrodir}
|
||||||
mkdir -p %{buildroot}%{_rpmconfigdir}/redhat
|
mkdir -p %{buildroot}%{_rpmconfigdir}/redhat
|
||||||
install -m 644 macros.pyproject %{buildroot}%{_rpmmacrodir}/
|
install -pm 644 macros.pyproject %{buildroot}%{_rpmmacrodir}/
|
||||||
install -m 644 pyproject_buildrequires.py %{buildroot}%{_rpmconfigdir}/redhat/
|
install -pm 644 pyproject_buildrequires.py %{buildroot}%{_rpmconfigdir}/redhat/
|
||||||
install -m 644 pyproject_convert.py %{buildroot}%{_rpmconfigdir}/redhat/
|
install -pm 644 pyproject_convert.py %{buildroot}%{_rpmconfigdir}/redhat/
|
||||||
install -m 644 pyproject_save_files.py %{buildroot}%{_rpmconfigdir}/redhat/
|
install -pm 644 pyproject_save_files.py %{buildroot}%{_rpmconfigdir}/redhat/
|
||||||
install -m 644 pyproject_preprocess_record.py %{buildroot}%{_rpmconfigdir}/redhat/
|
install -pm 644 pyproject_preprocess_record.py %{buildroot}%{_rpmconfigdir}/redhat/
|
||||||
install -m 644 pyproject_construct_toxenv.py %{buildroot}%{_rpmconfigdir}/redhat/
|
install -pm 644 pyproject_construct_toxenv.py %{buildroot}%{_rpmconfigdir}/redhat/
|
||||||
install -m 644 pyproject_requirements_txt.py %{buildroot}%{_rpmconfigdir}/redhat/
|
install -pm 644 pyproject_requirements_txt.py %{buildroot}%{_rpmconfigdir}/redhat/
|
||||||
|
install -pm 644 pyproject_wheel.py %{buildroot}%{_rpmconfigdir}/redhat/
|
||||||
|
|
||||||
%if %{with tests}
|
%if %{with tests}
|
||||||
%check
|
%check
|
||||||
export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856356
|
export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856356
|
||||||
%{python3} -m pytest -vv --doctest-modules
|
%pytest -vv --doctest-modules
|
||||||
|
|
||||||
# brp-compress is provided as an argument to get the right directory macro expansion
|
# brp-compress is provided as an argument to get the right directory macro expansion
|
||||||
%{python3} compare_mandata.py -f %{_rpmconfigdir}/brp-compress
|
%{python3} compare_mandata.py -f %{_rpmconfigdir}/brp-compress
|
||||||
@ -118,11 +123,44 @@ export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856
|
|||||||
%{_rpmconfigdir}/redhat/pyproject_preprocess_record.py
|
%{_rpmconfigdir}/redhat/pyproject_preprocess_record.py
|
||||||
%{_rpmconfigdir}/redhat/pyproject_construct_toxenv.py
|
%{_rpmconfigdir}/redhat/pyproject_construct_toxenv.py
|
||||||
%{_rpmconfigdir}/redhat/pyproject_requirements_txt.py
|
%{_rpmconfigdir}/redhat/pyproject_requirements_txt.py
|
||||||
|
%{_rpmconfigdir}/redhat/pyproject_wheel.py
|
||||||
|
|
||||||
%doc README.md
|
%doc README.md
|
||||||
%license LICENSE
|
%license LICENSE
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Aug 09 2022 Karolina Surma <ksurma@redhat.com> - 1.3.3-1
|
||||||
|
- Don't fail %%pyproject_save_files '*' if no modules are detected
|
||||||
|
|
||||||
|
* Wed Jun 15 2022 Benjamin A. Beasley <code@musicinmybrain.net> - 1.3.2-1
|
||||||
|
- Update %%pyproject_build_lib to support setuptools 62.1.0 and later
|
||||||
|
- %%pyproject_buildrequires: When extension modules are built,
|
||||||
|
support https://fedoraproject.org/wiki/Changes/Package_information_on_ELF_objects
|
||||||
|
|
||||||
|
* Fri May 27 2022 Owen Taylor <otaylor@redhat.com> - 1.3.1-1
|
||||||
|
- %%pyproject_install: pass %%{_prefix} explicitly to pip install
|
||||||
|
|
||||||
|
* Thu May 12 2022 Miro Hrončok <mhroncok@redhat.com> - 1.3.0-1
|
||||||
|
- Use tomllib from the standard library on Python 3.11+
|
||||||
|
|
||||||
|
* Wed Apr 27 2022 Miro Hrončok <mhroncok@redhat.com> - 1.2.0-1
|
||||||
|
- %%pyproject_buildrequires: Add provisional -w flag for build backends without
|
||||||
|
prepare_metadata_for_build_wheel hook
|
||||||
|
When used, the wheel is built in %%pyproject_buildrequires
|
||||||
|
and information about runtime requires and extras is read from that wheel.
|
||||||
|
|
||||||
|
* Tue Apr 12 2022 Miro Hrončok <mhroncok@redhat.com> - 1.1.0-1
|
||||||
|
- %%pyproject_save_files: Support nested directories in dist-info
|
||||||
|
|
||||||
|
* Tue Mar 22 2022 Miro Hrončok <mhroncok@redhat.com> - 1.0.1-1
|
||||||
|
- Prefix paths of intermediate files (such as %%{pyproject_files}) with NVRA
|
||||||
|
|
||||||
|
* Tue Mar 01 2022 Miro Hrončok <mhroncok@redhat.com> - 1.0.0-1
|
||||||
|
- Release final version 1.0.0
|
||||||
|
|
||||||
|
* Mon Feb 07 2022 Lumír Balhar <lbalhar@redhat.com> - 1.0.0~rc2-1
|
||||||
|
- Updated compatibility with tox4
|
||||||
|
|
||||||
* Tue Jan 25 2022 Miro Hrončok <mhroncok@redhat.com> - 1.0.0~rc1-1
|
* Tue Jan 25 2022 Miro Hrončok <mhroncok@redhat.com> - 1.0.0~rc1-1
|
||||||
- Release version 1.0.0, first release candidate
|
- Release version 1.0.0, first release candidate
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user