Generate run-time requirements for tests
This commit is contained in:
parent
204b801da2
commit
bc156c4460
@ -17,12 +17,14 @@ if [ -d %{buildroot}%{python3_sitearch} ]; then
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
%pyproject_buildrequires() %{expand:\\\
|
%pyproject_buildrequires(r) %{expand:\\\
|
||||||
echo 'python3-devel'
|
echo 'python3-devel'
|
||||||
echo 'python3dist(packaging)'
|
echo 'python3dist(packaging)'
|
||||||
echo 'python3dist(pip) >= 19'
|
echo 'python3dist(pip) >= 19'
|
||||||
echo 'python3dist(pytoml)'
|
echo 'python3dist(pytoml)'
|
||||||
|
# setuptools assumes no pre-existing dist-info
|
||||||
|
rm -rfv *.dist-info/
|
||||||
if [ -f %{__python3} ]; then
|
if [ -f %{__python3} ]; then
|
||||||
%{__python3} -I %{_rpmconfigdir}/redhat/pyproject_buildrequires.py %{?*}
|
%{__python3} -I %{_rpmconfigdir}/redhat/pyproject_buildrequires.py %{?**}
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ BuildRequires: python3dist(pyyaml)
|
|||||||
BuildRequires: python3dist(packaging)
|
BuildRequires: python3dist(packaging)
|
||||||
BuildRequires: python3dist(pytoml)
|
BuildRequires: python3dist(pytoml)
|
||||||
BuildRequires: python3dist(pip)
|
BuildRequires: python3dist(pip)
|
||||||
|
BuildRequires: python3dist(setuptools)
|
||||||
|
BuildRequires: python3dist(wheel)
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ from io import StringIO
|
|||||||
import subprocess
|
import subprocess
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
|
import email.parser
|
||||||
|
|
||||||
print_err = functools.partial(print, file=sys.stderr)
|
print_err = functools.partial(print, file=sys.stderr)
|
||||||
|
|
||||||
@ -83,7 +84,6 @@ class Requirements:
|
|||||||
key=lambda s: (s.operator, s.version),
|
key=lambda s: (s.operator, s.version),
|
||||||
):
|
):
|
||||||
version = canonicalize_version(specifier.version)
|
version = canonicalize_version(specifier.version)
|
||||||
print_err(version)
|
|
||||||
if not VERSION_RE.fullmatch(str(specifier.version)):
|
if not VERSION_RE.fullmatch(str(specifier.version)):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f'Unknown character in version: {specifier.version}. '
|
f'Unknown character in version: {specifier.version}. '
|
||||||
@ -154,6 +154,22 @@ def generate_build_requirements(backend, requirements):
|
|||||||
requirements.extend(new_reqs, source='get_requires_for_build_wheel')
|
requirements.extend(new_reqs, source='get_requires_for_build_wheel')
|
||||||
|
|
||||||
|
|
||||||
|
def generate_run_requirements(backend, requirements):
|
||||||
|
prepare_metadata = getattr(backend, "prepare_metadata_for_build_wheel", None)
|
||||||
|
if not prepare_metadata:
|
||||||
|
raise ValueError(
|
||||||
|
'build backend cannot provide build metadata '
|
||||||
|
+ '(incl. runtime requirements) before buld'
|
||||||
|
)
|
||||||
|
with hook_call():
|
||||||
|
dir_basename = prepare_metadata('.')
|
||||||
|
with open(dir_basename + '/METADATA') as f:
|
||||||
|
message = email.parser.Parser().parse(f, headersonly=True)
|
||||||
|
for key in 'Requires', 'Requires-Dist':
|
||||||
|
requires = message.get_all(key, ())
|
||||||
|
requirements.extend(requires, source=f'wheel metadata: {key}')
|
||||||
|
|
||||||
|
|
||||||
def python3dist(name, op=None, version=None):
|
def python3dist(name, op=None, version=None):
|
||||||
if op is None:
|
if op is None:
|
||||||
if version is not None:
|
if version is not None:
|
||||||
@ -163,12 +179,14 @@ def python3dist(name, op=None, version=None):
|
|||||||
return f'python3dist({name}) {op} {version}'
|
return f'python3dist({name}) {op} {version}'
|
||||||
|
|
||||||
|
|
||||||
def generate_requires(freeze_output):
|
def generate_requires(freeze_output, *, include_runtime=False, toxenv=None):
|
||||||
requirements = Requirements(freeze_output)
|
requirements = Requirements(freeze_output)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
backend = get_backend(requirements)
|
backend = get_backend(requirements)
|
||||||
generate_build_requirements(backend, requirements)
|
generate_build_requirements(backend, requirements)
|
||||||
|
if include_runtime:
|
||||||
|
generate_run_requirements(backend, requirements)
|
||||||
except EndPass:
|
except EndPass:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -178,11 +196,11 @@ def main(argv):
|
|||||||
description='Generate BuildRequires for a Python project.'
|
description='Generate BuildRequires for a Python project.'
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--runtime', action='store_true',
|
'-r', '--runtime', action='store_true',
|
||||||
help='Generate run-time requirements (not implemented)',
|
help='Generate run-time requirements (not implemented)',
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--toxenv', metavar='TOXENVS',
|
'-t', '--toxenv', metavar='TOXENVS',
|
||||||
help='generate test tequirements from tox environment '
|
help='generate test tequirements from tox environment '
|
||||||
+ '(not implemented; implies --runtime)',
|
+ '(not implemented; implies --runtime)',
|
||||||
)
|
)
|
||||||
@ -190,8 +208,7 @@ def main(argv):
|
|||||||
args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
if args.toxenv:
|
if args.toxenv:
|
||||||
args.runtime = True
|
args.runtime = True
|
||||||
if args.runtime:
|
print_err('--toxenv is not implemented')
|
||||||
print_err('--runtime is not implemented')
|
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
freeze_output = subprocess.run(
|
freeze_output = subprocess.run(
|
||||||
@ -202,7 +219,7 @@ def main(argv):
|
|||||||
).stdout
|
).stdout
|
||||||
|
|
||||||
try:
|
try:
|
||||||
generate_requires(freeze_output)
|
generate_requires(freeze_output, include_runtime=args.runtime)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Log the traceback explicitly (it's useful debug info)
|
# Log the traceback explicitly (it's useful debug info)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
@ -28,10 +28,13 @@ def test_data(case_name, capsys, tmp_path, monkeypatch):
|
|||||||
try:
|
try:
|
||||||
generate_requires(
|
generate_requires(
|
||||||
case['freeze_output'],
|
case['freeze_output'],
|
||||||
|
include_runtime=case.get('include_runtime', False),
|
||||||
)
|
)
|
||||||
except SystemExit as e:
|
except SystemExit as e:
|
||||||
assert e.code == case['result']
|
assert e.code == case['result']
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if 'except' not in case:
|
||||||
|
raise
|
||||||
assert type(e).__name__ == case['except']
|
assert type(e).__name__ == case['except']
|
||||||
else:
|
else:
|
||||||
assert 0 == case['result']
|
assert 0 == case['result']
|
||||||
|
@ -99,7 +99,7 @@ Build system dependencies in pyproject.toml:
|
|||||||
python3dist(wheel)
|
python3dist(wheel)
|
||||||
result: 0
|
result: 0
|
||||||
|
|
||||||
Default build system, dependencies in setup.py:
|
Default build system, build dependencies in setup.py:
|
||||||
freeze_output: |
|
freeze_output: |
|
||||||
setuptools==50
|
setuptools==50
|
||||||
wheel==1
|
wheel==1
|
||||||
@ -109,6 +109,7 @@ Default build system, dependencies in setup.py:
|
|||||||
name='test',
|
name='test',
|
||||||
version='0.1',
|
version='0.1',
|
||||||
setup_requires=['foo', 'bar!=2'],
|
setup_requires=['foo', 'bar!=2'],
|
||||||
|
install_requires=['inst'],
|
||||||
)
|
)
|
||||||
expected: |
|
expected: |
|
||||||
python3dist(setuptools) >= 40.8
|
python3dist(setuptools) >= 40.8
|
||||||
@ -117,3 +118,26 @@ Default build system, dependencies in setup.py:
|
|||||||
python3dist(foo)
|
python3dist(foo)
|
||||||
(python3dist(bar) < 2 or python3dist(bar) > 2.0)
|
(python3dist(bar) < 2 or python3dist(bar) > 2.0)
|
||||||
result: 0
|
result: 0
|
||||||
|
|
||||||
|
Default build system, run dependencies in setup.py:
|
||||||
|
freeze_output: |
|
||||||
|
setuptools==50
|
||||||
|
wheel==1
|
||||||
|
pyyaml==1
|
||||||
|
include_runtime: true
|
||||||
|
setup.py: |
|
||||||
|
from setuptools import setup
|
||||||
|
setup(
|
||||||
|
name='test',
|
||||||
|
version='0.1',
|
||||||
|
setup_requires=['pyyaml'], # nb. setuptools will try to install this
|
||||||
|
install_requires=['inst > 1', 'inst2 < 3'],
|
||||||
|
)
|
||||||
|
expected: |
|
||||||
|
python3dist(setuptools) >= 40.8
|
||||||
|
python3dist(wheel)
|
||||||
|
python3dist(wheel)
|
||||||
|
python3dist(pyyaml)
|
||||||
|
python3dist(inst) > 1
|
||||||
|
python3dist(inst2) < 3
|
||||||
|
result: 0
|
||||||
|
@ -27,7 +27,8 @@ Discover and load entry points from installed packages.
|
|||||||
|
|
||||||
|
|
||||||
%generate_buildrequires
|
%generate_buildrequires
|
||||||
%pyproject_buildrequires
|
rm -rfv *.dist-info/
|
||||||
|
%pyproject_buildrequires -r
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
@ -27,7 +27,7 @@ py.test provides simple, yet powerful testing for Python.
|
|||||||
|
|
||||||
|
|
||||||
%generate_buildrequires
|
%generate_buildrequires
|
||||||
%pyproject_buildrequires
|
%pyproject_buildrequires -r
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
Loading…
Reference in New Issue
Block a user