import pyproject-rpm-macros-1.6.2-1.el9

This commit is contained in:
CentOS Sources 2023-05-09 05:33:09 +00:00 committed by Stepan Oksanichenko
parent ea2a246e51
commit 2ded090d3d
10 changed files with 443 additions and 110 deletions

View File

@ -140,7 +140,7 @@ such plugins will be BuildRequired as well.
Not all plugins are guaranteed to play well with [tox-current-env], Not all plugins are guaranteed to play well with [tox-current-env],
in worst case, patch/sed the requirement out from the tox configuration. in worst case, patch/sed the requirement out from the tox configuration.
Note that both `-x` and `-t` imply `-r`, Note that neither `-x` or `-t` can be used with `-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], You can only use those options if the build backend supports the [prepare-metadata-for-build-wheel hook],
or together with `-w`. or together with `-w`.
@ -152,12 +152,16 @@ or together with `-w`.
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:
%pyproject_buildrequires -r requirements/tests.in requirements/docs.in requirements/dev.in %pyproject_buildrequires requirements/tests.in requirements/docs.in requirements/dev.in
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 implies `-R` and cannot be used in combination with other options mentioned above
(`-r`, `-w`, `-e`, `-t`, `-x`). (`-w`, `-e`, `-t`, `-x`).
The `%pyproject_buildrequires` macro also accepts the `-r` flag for backward compatibility;
it means "include runtime dependencies" which has been the default since version 0-53.
Running tox based tests Running tox based tests
----------------------- -----------------------
@ -171,8 +175,9 @@ Then, use the `%tox` macro in `%check`:
The macro: The macro:
- Always prepends `$PATH` with `%{buildroot}%{_bindir}` - Sets environment variables via `%{py3_test_envvars}`, namely:
- If not defined, sets `$PYTHONPATH` to `%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}` - Always prepends `$PATH` with `%{buildroot}%{_bindir}`
- If not defined, sets `$PYTHONPATH` to `%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}`
- If not defined, sets `$TOX_TESTENV_PASSENV` to `*` - If not defined, sets `$TOX_TESTENV_PASSENV` to `*`
- Runs `tox` with `-q` (quiet), `--recreate` and `--current-env` (from [tox-current-env]) flags - Runs `tox` with `-q` (quiet), `--recreate` and `--current-env` (from [tox-current-env]) flags
- Implicitly uses the tox environment name stored in `%{toxenv}` - as overridden by `%pyproject_buildrequires -e` - Implicitly uses the tox environment name stored in `%{toxenv}` - as overridden by `%pyproject_buildrequires -e`
@ -265,6 +270,7 @@ If `%pyproject_save_files` is not used, calling `%pyproject_check_import` will f
When `%pyproject_save_files` is invoked, When `%pyproject_save_files` is invoked,
it creates a list of all valid and public (i.e. not starting with `_`) it creates a list of all valid and public (i.e. not starting with `_`)
importable module names found in the package. importable module names found in the package.
Each top-level module name matches at least one of the globs provided as an argument to `%pyproject_save_files`.
This list is then usable by `%pyproject_check_import` which performs an import check for each listed module. This list is then usable by `%pyproject_check_import` which performs an import check for each listed module.
When a module fails to import, the build fails. When a module fails to import, the build fails.

View File

@ -0,0 +1,7 @@
# This file is called macros.aaa-pyproject-srpm
# to sort alphabetically before macros.pyproject.
# When this file is installed but macros.pyproject is not
# this macro will cause the package with the real macro to be installed.
# When macros.pyproject is installed, it overrides this macro.
# Note: This needs to maintain the same set of options as the real macro.
%pyproject_buildrequires(rRxtNwe:) echo 'pyproject-rpm-macros' && exit 0

View File

@ -124,6 +124,7 @@ fi
%toxenv %{default_toxenv} %toxenv %{default_toxenv}
# Note: Keep the options in sync with this macro from macros.aaa-pyproject-srpm
%pyproject_buildrequires(rRxtNwe:) %{expand:\\\ %pyproject_buildrequires(rRxtNwe:) %{expand:\\\
%_set_pytest_addopts %_set_pytest_addopts
# The _auto_set_build_flags feature does not do this in %%generate_buildrequires section, # The _auto_set_build_flags feature does not do this in %%generate_buildrequires section,
@ -144,7 +145,7 @@ fi
%{-w:%{error:The -N and -w 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' # first stdout line matches the implementation in macros.aaa-pyproject-srpm
echo 'python%{python3_pkgversion}-devel' 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)'
@ -176,10 +177,10 @@ fi
%tox(e:) %{expand:\\\ %tox(e:) %{expand:\\\
TOX_TESTENV_PASSENV="${TOX_TESTENV_PASSENV:-*}" \\ TOX_TESTENV_PASSENV="${TOX_TESTENV_PASSENV:-*}" \\
PYTHONDONTWRITEBYTECODE=1 \\ %{?py3_test_envvars}%{?!py3_test_envvars:PYTHONDONTWRITEBYTECODE=1 \\
PATH="%{buildroot}%{_bindir}:$PATH" \\ PATH="%{buildroot}%{_bindir}:$PATH" \\
PYTHONPATH="${PYTHONPATH:-%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}}" \\ PYTHONPATH="${PYTHONPATH:-%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}}" \\
%{?__pytest_addopts:PYTEST_ADDOPTS="${PYTEST_ADDOPTS:-} %{__pytest_addopts}"} \\ %{?__pytest_addopts:PYTEST_ADDOPTS="${PYTEST_ADDOPTS:-} %{__pytest_addopts}"}} \\
HOSTNAME="rpmbuild" \\ HOSTNAME="rpmbuild" \\
%{__python3} -m tox --current-env -q --recreate -e "%{-e:%{-e*}}%{!-e:%{toxenv}}" %{?*} %{__python3} -m tox --current-env -q --recreate -e "%{-e:%{-e*}}%{!-e:%{toxenv}}" %{?*}
} }

View File

@ -4,9 +4,9 @@ import os
import sys import sys
import importlib.metadata import importlib.metadata
import argparse import argparse
import tempfile
import traceback import traceback
import contextlib import contextlib
from io import StringIO
import json import json
import subprocess import subprocess
import re import re
@ -48,11 +48,35 @@ from pyproject_convert import convert
@contextlib.contextmanager @contextlib.contextmanager
def hook_call(): def hook_call():
captured_out = StringIO() """Context manager that records all stdout content (on FD level)
with contextlib.redirect_stdout(captured_out): and prints it to stderr at the end, with a 'HOOK STDOUT: ' prefix."""
tmpfile = io.TextIOWrapper(
tempfile.TemporaryFile(buffering=0),
encoding='utf-8',
errors='replace',
write_through=True,
)
stdout_fd = 1
stdout_fd_dup = os.dup(stdout_fd)
stdout_orig = sys.stdout
# begin capture
sys.stdout = tmpfile
os.dup2(tmpfile.fileno(), stdout_fd)
try:
yield yield
for line in captured_out.getvalue().splitlines(): finally:
print_err('HOOK STDOUT:', line) # end capture
sys.stdout = stdout_orig
os.dup2(stdout_fd_dup, stdout_fd)
tmpfile.seek(0) # rewind
for line in tmpfile:
print_err('HOOK STDOUT:', line, end='')
tmpfile.close()
def guess_reason_for_invalid_requirement(requirement_str): def guess_reason_for_invalid_requirement(requirement_str):
@ -100,7 +124,7 @@ class Requirements:
return [{'extra': e} for e in sorted(self.extras)] return [{'extra': e} for e in sorted(self.extras)]
return [{'extra': ''}] return [{'extra': ''}]
def evaluate_all_environamnets(self, requirement): def evaluate_all_environments(self, requirement):
for marker_env in self.marker_envs: for marker_env in self.marker_envs:
if requirement.marker.evaluate(environment=marker_env): if requirement.marker.evaluate(environment=marker_env):
return True return True
@ -126,7 +150,7 @@ class Requirements:
name = canonicalize_name(requirement.name) name = canonicalize_name(requirement.name)
if (requirement.marker is not None and if (requirement.marker is not None and
not self.evaluate_all_environamnets(requirement)): not self.evaluate_all_environments(requirement)):
print_err(f'Ignoring alien requirement:', requirement_str) print_err(f'Ignoring alien requirement:', requirement_str)
return return
@ -424,34 +448,30 @@ def generate_requires(
def main(argv): def main(argv):
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='Generate BuildRequires for a Python project.' description='Generate BuildRequires for a Python project.',
prog='%pyproject_buildrequires',
add_help=False,
)
parser.add_argument(
'--help', action='help',
default=argparse.SUPPRESS,
help=argparse.SUPPRESS,
) )
parser.add_argument( parser.add_argument(
'-r', '--runtime', action='store_true', default=True, '-r', '--runtime', action='store_true', default=True,
help='Generate run-time requirements (default, disable with -R)', help=argparse.SUPPRESS, # Generate run-time requirements (backwards-compatibility only)
) )
parser.add_argument( parser.add_argument(
'-w', '--wheel', action='store_true', default=False, '--generate-extras', action='store_true',
help=('Generate run-time requirements by building the wheel ' help=argparse.SUPPRESS,
'(useful for build backends without the prepare_metadata_for_build_wheel hook)'), )
parser.add_argument(
'-p', '--python3_pkgversion', metavar='PYTHON3_PKGVERSION',
default="3", help=argparse.SUPPRESS,
) )
parser.add_argument( parser.add_argument(
'--wheeldir', metavar='PATH', default=None, '--wheeldir', metavar='PATH', default=None,
help='The directory with wheel, used when -w.', help=argparse.SUPPRESS,
)
parser.add_argument(
'-R', '--no-runtime', action='store_false', dest='runtime',
help="Don't generate run-time requirements (implied by -N)",
)
parser.add_argument(
'-e', '--toxenv', metavar='TOXENVS', action='append',
help=('specify tox environments (comma separated and/or repeated)'
'(implies --tox)'),
)
parser.add_argument(
'-t', '--tox', action='store_true',
help=('generate test tequirements from tox environment '
'(implies --runtime)'),
) )
parser.add_argument( parser.add_argument(
'-x', '--extras', metavar='EXTRAS', action='append', '-x', '--extras', metavar='EXTRAS', action='append',
@ -459,20 +479,31 @@ def main(argv):
'(e.g. -x testing,feature-x) (implies --runtime, can be repeated)', '(e.g. -x testing,feature-x) (implies --runtime, can be repeated)',
) )
parser.add_argument( parser.add_argument(
'--generate-extras', action='store_true', '-t', '--tox', action='store_true',
help='Generate build requirements on Python Extras', help=('generate test tequirements from tox environment '
'(implies --runtime)'),
) )
parser.add_argument( parser.add_argument(
'-p', '--python3_pkgversion', metavar='PYTHON3_PKGVERSION', '-e', '--toxenv', metavar='TOXENVS', action='append',
default="3", help=('Python version for pythonXdist()' help=('specify tox environments (comma separated and/or repeated)'
'or pythonX.Ydist() requirements'), '(implies --tox)'),
)
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(
'-R', '--no-runtime', action='store_false', dest='runtime',
help="Don't generate run-time requirements (implied by -N)",
) )
parser.add_argument( parser.add_argument(
'-N', '--no-use-build-system', dest='use_build_system', '-N', '--no-use-build-system', dest='use_build_system',
action='store_false', help='Use -N to indicate that project does not use any build system', action='store_false', help='Use -N to indicate that project does not use any build system',
) )
parser.add_argument( parser.add_argument(
'requirement_files', nargs='*', type=argparse.FileType('r'), 'requirement_files', nargs='*', type=argparse.FileType('r'),
metavar='REQUIREMENTS.TXT',
help=('Add buildrequires from file'), help=('Add buildrequires from file'),
) )

View File

@ -413,14 +413,24 @@ Tox dependencies:
toxdep2 toxdep2
commands = commands =
true true
expected: | expected:
python3dist(setuptools) >= 40.8 - | # tox 3
python3dist(wheel) python3dist(setuptools) >= 40.8
python3dist(wheel) python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6 python3dist(wheel)
python3dist(toxdep1) python3dist(tox-current-env) >= 0.0.6
python3dist(toxdep2) python3dist(toxdep1)
python3dist(inst) python3dist(toxdep2)
python3dist(inst)
- | # tox 4
python3dist(setuptools) >= 40.8
python3dist(wheel)
python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6
python3dist(tox)
python3dist(toxdep1)
python3dist(toxdep2)
python3dist(inst)
result: 0 result: 0
Tox extras: Tox extras:
@ -455,20 +465,36 @@ Tox extras:
extra1 extra1
commands = commands =
true true
expected: | expected:
python3dist(setuptools) >= 40.8 - | # tox 3
python3dist(wheel) python3dist(setuptools) >= 40.8
python3dist(wheel) python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6 python3dist(wheel)
python3dist(toxdep) python3dist(tox-current-env) >= 0.0.6
python3dist(inst) python3dist(toxdep)
python3dist(dep11) > 11.0 python3dist(inst)
python3dist(dep12) python3dist(dep11) > 11.0
python3dist(dep21) python3dist(dep12)
python3dist(dep22) python3dist(dep21)
python3dist(dep23) python3dist(dep22)
python3dist(extra-dep) python3dist(dep23)
python3dist(extra-dep[extra_dep]) python3dist(extra-dep)
python3dist(extra-dep[extra_dep])
- | # tox 4
python3dist(setuptools) >= 40.8
python3dist(wheel)
python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6
python3dist(tox)
python3dist(toxdep)
python3dist(inst)
python3dist(dep11) > 11.0
python3dist(dep12)
python3dist(dep21)
python3dist(dep22)
python3dist(dep23)
python3dist(extra-dep)
python3dist(extra-dep[extra_dep])
result: 0 result: 0
Tox provision unsatisfied: Tox provision unsatisfied:
@ -496,14 +522,24 @@ Tox provision unsatisfied:
deps = deps =
toxdep1 toxdep1
toxdep2 toxdep2
expected: | expected:
python3dist(setuptools) >= 40.8 - | # tox 3
python3dist(wheel) python3dist(setuptools) >= 40.8
python3dist(wheel) python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6 python3dist(wheel)
python3dist(tox) >= 3.999 python3dist(tox-current-env) >= 0.0.6
python3dist(setuptools) > 40.0 python3dist(tox) >= 3.999
python3dist(wheel) > 2.0 python3dist(setuptools) > 40.0
python3dist(wheel) > 2.0
- | # tox 4
python3dist(setuptools) >= 40.8
python3dist(wheel)
python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6
python3dist(tox) >= 3.999
python3dist(setuptools) > 40.0
python3dist(wheel) > 2.0
python3dist(tox) >= 3.999
result: 0 result: 0
Tox provision satisfied: Tox provision satisfied:
@ -530,16 +566,27 @@ Tox provision satisfied:
deps = deps =
toxdep1 toxdep1
toxdep2 toxdep2
expected: | expected:
python3dist(setuptools) >= 40.8 - | # tox 3
python3dist(wheel) python3dist(setuptools) >= 40.8
python3dist(wheel) python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6 python3dist(wheel)
python3dist(tox) >= 3.5 python3dist(tox-current-env) >= 0.0.6
python3dist(setuptools) > 40.0 python3dist(tox) >= 3.5
python3dist(toxdep1) python3dist(setuptools) > 40.0
python3dist(toxdep2) python3dist(toxdep1)
python3dist(inst) python3dist(toxdep2)
python3dist(inst)
- | # tox 4
python3dist(setuptools) >= 40.8
python3dist(wheel)
python3dist(wheel)
python3dist(tox-current-env) >= 0.0.6
python3dist(setuptools) > 40.0
python3dist(tox) >= 3.5
python3dist(toxdep1)
python3dist(toxdep2)
python3dist(inst)
result: 0 result: 0
Default build system, unmet deps in requirements file: Default build system, unmet deps in requirements file:
@ -771,3 +818,21 @@ Pre-releases are accepted:
python3dist(wheel) python3dist(wheel)
stderr_contains: "Requirement satisfied: cffi" stderr_contains: "Requirement satisfied: cffi"
result: 0 result: 0
Wrapped subprocess prints to stdout from setup.py:
installed:
setuptools: 50
wheel: 1
include_runtime: false
setup.py: |
import os
os.system('echo LEAK?')
from setuptools import setup
setup(name='test', version='0.1')
expected: |
python3dist(setuptools) >= 40.8
python3dist(wheel)
python3dist(wheel)
stderr_contains: "HOOK STDOUT: LEAK?"
result: 0

View File

@ -98,6 +98,4 @@ def expand_env_vars(lines):
return match['var'] return match['var']
return value return value
for line in lines: for line in lines:
if match := ENV_VAR_RE.search(line):
var = match['var']
yield ENV_VAR_RE.sub(repl, line) yield ENV_VAR_RE.sub(repl, line)

View File

@ -154,8 +154,8 @@ def add_lang_to_module(paths, module_name, path):
Returns True if the language code detection was successful Returns True if the language code detection was successful
""" """
for i, parent in enumerate(path.parents): for i, parent in enumerate(path.parents):
if i > 0 and parent.name == 'locale': if parent.name == 'LC_MESSAGES':
lang_country_code = path.parents[i-1].name lang_country_code = path.parents[i+1].name
break break
else: else:
return False return False
@ -286,6 +286,36 @@ def module_names_from_path(path):
return {'.'.join(parts[:x+1]) for x in range(len(parts))} return {'.'.join(parts[:x+1]) for x in range(len(parts))}
def is_license_file(path, license_files, license_directories):
"""
Check if the given BuildrootPath path matches any of the "License-File" entries.
The path is considered matched when resolved from any of the license_directories
matches string-wise what is stored in any "License-File" entry (license_files).
Examples:
>>> site_packages = BuildrootPath('/usr/lib/python3.12/site-packages')
>>> distinfo = site_packages / 'foo-1.0.dist-info'
>>> license_directories = [distinfo / 'licenses', distinfo]
>>> license_files = ['LICENSE.txt', 'AUTHORS.md']
>>> is_license_file(distinfo / 'AUTHORS.md', license_files, license_directories)
True
>>> is_license_file(distinfo / 'licenses/LICENSE.txt', license_files, license_directories)
True
>>> # we don't match based on directory only
>>> is_license_file(distinfo / 'licenses/COPYING', license_files, license_directories)
False
>>> is_license_file(site_packages / 'foo/LICENSE.txt', license_files, license_directories)
False
"""
if not license_files or not license_directories:
return False
for license_dir in license_directories:
if (path.is_relative_to(license_dir) and
str(path.relative_to(license_dir)) in license_files):
return True
return False
def classify_paths( def classify_paths(
record_path, parsed_record_content, metadata, sitedirs, python_version, prefix record_path, parsed_record_content, metadata, sitedirs, python_version, prefix
): ):
@ -311,10 +341,17 @@ def classify_paths(
"other": {"files": []}, # regular %file entries we could not parse :( "other": {"files": []}, # regular %file entries we could not parse :(
} }
license_files = metadata.get_all('License-File')
license_directory = distinfo / 'licenses' # See PEP 369 "Root License Directory"
# setuptools was the first known build backend to implement License-File.
# Unfortunately they don't put licenses to the license directory (yet):
# https://github.com/pypa/setuptools/issues/3596
# Hence, we check licenses in both licenses and dist-info
license_directories = (license_directory, distinfo)
# In RECORDs generated by pip, there are no directories, only files. # In RECORDs generated by pip, there are no directories, only files.
# The example RECORD from PEP 376 does not contain directories either. # The example RECORD from PEP 376 does not contain directories either.
# Hence, we'll only assume files, but TODO get it officially documented. # Hence, we'll only assume files, but TODO get it officially documented.
license_files = metadata.get_all('License-File')
for path in parsed_record_content: for path in parsed_record_content:
if path.suffix == ".pyc": if path.suffix == ".pyc":
# we handle bytecode separately # we handle bytecode separately
@ -325,7 +362,7 @@ def classify_paths(
# 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 str(path.relative_to(distinfo)) in license_files: if is_license_file(path, license_files, license_directories):
paths["metadata"]["licenses"].append(path) paths["metadata"]["licenses"].append(path)
else: else:
paths["metadata"]["files"].append(path) paths["metadata"]["files"].append(path)
@ -499,6 +536,50 @@ def generate_file_list(paths_dict, module_globs, include_others=False):
return sorted(files) return sorted(files)
def generate_module_list(paths_dict, module_globs):
"""
This function takes the paths_dict created by the classify_paths() function and
reads the modules names from it.
It filters those whose top-level module names match any of the provided module_globs.
Returns list with matching qualified module names.
Examples:
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'foo'})
['foo', 'foo.bar']
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'*foo'})
['foo', 'foo.bar']
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'foo', 'baz'})
['baz', 'foo', 'foo.bar']
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'*'})
['baz', 'foo', 'foo.bar']
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'bar'})
[]
Submodules aren't discovered:
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'*bar'})
[]
"""
module_names = paths_dict['module_names']
filtered_module_names = set()
for glob in module_globs:
for name in module_names:
# Match the top-level part of the qualified name, eg. 'foo.bar.baz' -> 'foo'
top_level_name = name.split('.')[0]
if fnmatch.fnmatchcase(top_level_name, glob):
filtered_module_names.add(name)
return sorted(filtered_module_names)
def parse_varargs(varargs): def parse_varargs(varargs):
""" """
Parse varargs from the %pyproject_save_files macro Parse varargs from the %pyproject_save_files macro
@ -627,7 +708,7 @@ def pyproject_save_files_and_modules(buildroot, sitelib, sitearch, python_versio
parsed_records = load_parsed_record(pyproject_record) parsed_records = load_parsed_record(pyproject_record)
final_file_list = [] final_file_list = []
all_module_names = set() final_module_list = []
for record_path, files in parsed_records.items(): for record_path, files in parsed_records.items():
metadata = dist_metadata(buildroot, record_path) metadata = dist_metadata(buildroot, record_path)
@ -638,12 +719,11 @@ def pyproject_save_files_and_modules(buildroot, sitelib, sitearch, python_versio
final_file_list.extend( final_file_list.extend(
generate_file_list(paths_dict, globs, include_auto) generate_file_list(paths_dict, globs, include_auto)
) )
all_module_names.update(paths_dict["module_names"]) final_module_list.extend(
generate_module_list(paths_dict, globs)
)
# Sort values, so they are always checked in the same order return final_file_list, final_module_list
all_module_names = sorted(all_module_names)
return final_file_list, all_module_names
def main(cli_args): def main(cli_args):
@ -662,17 +742,31 @@ def main(cli_args):
def argparser(): def argparser():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser(
description="Create %{pyproject_files} for a Python project.",
prog="%pyproject_save_files",
add_help=False,
# custom usage to add +auto
usage="%(prog)s MODULE_GLOB [MODULE_GLOB ...] [+auto]",
)
parser.add_argument(
'--help', action='help',
default=argparse.SUPPRESS,
help=argparse.SUPPRESS,
)
r = parser.add_argument_group("required arguments") r = parser.add_argument_group("required arguments")
r.add_argument("--output-files", type=PosixPath, required=True) r.add_argument("--output-files", type=PosixPath, required=True, help=argparse.SUPPRESS)
r.add_argument("--output-modules", type=PosixPath, required=True) r.add_argument("--output-modules", type=PosixPath, required=True, help=argparse.SUPPRESS)
r.add_argument("--buildroot", type=PosixPath, required=True) r.add_argument("--buildroot", type=PosixPath, required=True, help=argparse.SUPPRESS)
r.add_argument("--sitelib", type=BuildrootPath, required=True) r.add_argument("--sitelib", type=BuildrootPath, required=True, help=argparse.SUPPRESS)
r.add_argument("--sitearch", type=BuildrootPath, required=True) r.add_argument("--sitearch", type=BuildrootPath, required=True, help=argparse.SUPPRESS)
r.add_argument("--python-version", type=str, required=True) r.add_argument("--python-version", type=str, required=True, help=argparse.SUPPRESS)
r.add_argument("--pyproject-record", type=PosixPath, required=True) r.add_argument("--pyproject-record", type=PosixPath, required=True, help=argparse.SUPPRESS)
r.add_argument("--prefix", type=PosixPath, required=True) r.add_argument("--prefix", type=PosixPath, required=True, help=argparse.SUPPRESS)
parser.add_argument("varargs", nargs="+") parser.add_argument(
"varargs", nargs="+", metavar="MODULE_GLOB",
help="Shell-like glob matching top-level module names to save into %%{pyproject_files}",
)
return parser return parser

View File

@ -230,6 +230,28 @@ classified:
- /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/COPYING.md - /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/COPYING.md
- /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/INSTALLER - /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/INSTALLER
licenses: [] licenses: []
lang:
ipykernel:
fr:
- /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR/LC_MESSAGES/nbjs.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR/LC_MESSAGES/nbui.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR/LC_MESSAGES/notebook.mo
ja:
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP/LC_MESSAGES/nbjs.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP/LC_MESSAGES/nbui.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP/LC_MESSAGES/notebook.mo
nl:
- /usr/lib/python3.7/site-packages/ipykernel/i18n/nl/LC_MESSAGES/nbjs.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/nl/LC_MESSAGES/nbui.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/nl/LC_MESSAGES/notebook.mo
ru:
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU/LC_MESSAGES/nbjs.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU/LC_MESSAGES/nbui.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU/LC_MESSAGES/notebook.mo
zh:
- /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN/LC_MESSAGES/nbjs.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN/LC_MESSAGES/nbui.mo
- /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN/LC_MESSAGES/notebook.mo
modules: modules:
ipykernel: ipykernel:
- files: - files:
@ -279,6 +301,8 @@ classified:
- /usr/lib/python3.7/site-packages/ipykernel/gui/gtk3embed.py - /usr/lib/python3.7/site-packages/ipykernel/gui/gtk3embed.py
- /usr/lib/python3.7/site-packages/ipykernel/gui/gtkembed.py - /usr/lib/python3.7/site-packages/ipykernel/gui/gtkembed.py
- /usr/lib/python3.7/site-packages/ipykernel/heartbeat.py - /usr/lib/python3.7/site-packages/ipykernel/heartbeat.py
- /usr/lib/python3.7/site-packages/ipykernel/i18n/__init__.py
- /usr/lib/python3.7/site-packages/ipykernel/i18n/__pycache__/__init__.cpython-37{,.opt-?}.pyc
- /usr/lib/python3.7/site-packages/ipykernel/inprocess/__init__.py - /usr/lib/python3.7/site-packages/ipykernel/inprocess/__init__.py
- /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__/__init__.cpython-37{,.opt-?}.pyc - /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__/__init__.cpython-37{,.opt-?}.pyc
- /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__/blocking.cpython-37{,.opt-?}.pyc - /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__/blocking.cpython-37{,.opt-?}.pyc
@ -362,6 +386,18 @@ classified:
- /usr/lib/python3.7/site-packages/ipykernel/comm/__pycache__ - /usr/lib/python3.7/site-packages/ipykernel/comm/__pycache__
- /usr/lib/python3.7/site-packages/ipykernel/gui - /usr/lib/python3.7/site-packages/ipykernel/gui
- /usr/lib/python3.7/site-packages/ipykernel/gui/__pycache__ - /usr/lib/python3.7/site-packages/ipykernel/gui/__pycache__
- /usr/lib/python3.7/site-packages/ipykernel/i18n
- /usr/lib/python3.7/site-packages/ipykernel/i18n/__pycache__
- /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR
- /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR/LC_MESSAGES
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP/LC_MESSAGES
- /usr/lib/python3.7/site-packages/ipykernel/i18n/nl
- /usr/lib/python3.7/site-packages/ipykernel/i18n/nl/LC_MESSAGES
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU
- /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU/LC_MESSAGES
- /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN
- /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN/LC_MESSAGES
- /usr/lib/python3.7/site-packages/ipykernel/inprocess - /usr/lib/python3.7/site-packages/ipykernel/inprocess
- /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__ - /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__
- /usr/lib/python3.7/site-packages/ipykernel/inprocess/tests - /usr/lib/python3.7/site-packages/ipykernel/inprocess/tests
@ -7559,6 +7595,18 @@ dumped:
- '%dir /usr/lib/python3.7/site-packages/ipykernel/comm/__pycache__' - '%dir /usr/lib/python3.7/site-packages/ipykernel/comm/__pycache__'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/gui' - '%dir /usr/lib/python3.7/site-packages/ipykernel/gui'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/gui/__pycache__' - '%dir /usr/lib/python3.7/site-packages/ipykernel/gui/__pycache__'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/__pycache__'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR/LC_MESSAGES'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP/LC_MESSAGES'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/nl'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/nl/LC_MESSAGES'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU/LC_MESSAGES'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN/LC_MESSAGES'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/inprocess' - '%dir /usr/lib/python3.7/site-packages/ipykernel/inprocess'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__' - '%dir /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/inprocess/tests' - '%dir /usr/lib/python3.7/site-packages/ipykernel/inprocess/tests'
@ -7568,6 +7616,21 @@ dumped:
- '%dir /usr/lib/python3.7/site-packages/ipykernel/resources' - '%dir /usr/lib/python3.7/site-packages/ipykernel/resources'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/tests' - '%dir /usr/lib/python3.7/site-packages/ipykernel/tests'
- '%dir /usr/lib/python3.7/site-packages/ipykernel/tests/__pycache__' - '%dir /usr/lib/python3.7/site-packages/ipykernel/tests/__pycache__'
- '%lang(fr) /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR/LC_MESSAGES/nbjs.mo'
- '%lang(fr) /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR/LC_MESSAGES/nbui.mo'
- '%lang(fr) /usr/lib/python3.7/site-packages/ipykernel/i18n/fr_FR/LC_MESSAGES/notebook.mo'
- '%lang(ja) /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP/LC_MESSAGES/nbjs.mo'
- '%lang(ja) /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP/LC_MESSAGES/nbui.mo'
- '%lang(ja) /usr/lib/python3.7/site-packages/ipykernel/i18n/ja_JP/LC_MESSAGES/notebook.mo'
- '%lang(nl) /usr/lib/python3.7/site-packages/ipykernel/i18n/nl/LC_MESSAGES/nbjs.mo'
- '%lang(nl) /usr/lib/python3.7/site-packages/ipykernel/i18n/nl/LC_MESSAGES/nbui.mo'
- '%lang(nl) /usr/lib/python3.7/site-packages/ipykernel/i18n/nl/LC_MESSAGES/notebook.mo'
- '%lang(ru) /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU/LC_MESSAGES/nbjs.mo'
- '%lang(ru) /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU/LC_MESSAGES/nbui.mo'
- '%lang(ru) /usr/lib/python3.7/site-packages/ipykernel/i18n/ru_RU/LC_MESSAGES/notebook.mo'
- '%lang(zh) /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN/LC_MESSAGES/nbjs.mo'
- '%lang(zh) /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN/LC_MESSAGES/nbui.mo'
- '%lang(zh) /usr/lib/python3.7/site-packages/ipykernel/i18n/zh_CN/LC_MESSAGES/notebook.mo'
- /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/COPYING.md - /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/COPYING.md
- /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/INSTALLER - /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/INSTALLER
- /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/METADATA - /usr/lib/python3.7/site-packages/ipykernel-5.2.1.dist-info/METADATA
@ -7619,6 +7682,8 @@ dumped:
- /usr/lib/python3.7/site-packages/ipykernel/gui/gtk3embed.py - /usr/lib/python3.7/site-packages/ipykernel/gui/gtk3embed.py
- /usr/lib/python3.7/site-packages/ipykernel/gui/gtkembed.py - /usr/lib/python3.7/site-packages/ipykernel/gui/gtkembed.py
- /usr/lib/python3.7/site-packages/ipykernel/heartbeat.py - /usr/lib/python3.7/site-packages/ipykernel/heartbeat.py
- /usr/lib/python3.7/site-packages/ipykernel/i18n/__init__.py
- /usr/lib/python3.7/site-packages/ipykernel/i18n/__pycache__/__init__.cpython-37{,.opt-?}.pyc
- /usr/lib/python3.7/site-packages/ipykernel/inprocess/__init__.py - /usr/lib/python3.7/site-packages/ipykernel/inprocess/__init__.py
- /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__/__init__.cpython-37{,.opt-?}.pyc - /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__/__init__.cpython-37{,.opt-?}.pyc
- /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__/blocking.cpython-37{,.opt-?}.pyc - /usr/lib/python3.7/site-packages/ipykernel/inprocess/__pycache__/blocking.cpython-37{,.opt-?}.pyc
@ -7713,6 +7778,7 @@ dumped:
- ipykernel.gui.gtk3embed - ipykernel.gui.gtk3embed
- ipykernel.gui.gtkembed - ipykernel.gui.gtkembed
- ipykernel.heartbeat - ipykernel.heartbeat
- ipykernel.i18n
- ipykernel.inprocess - ipykernel.inprocess
- ipykernel.inprocess.blocking - ipykernel.inprocess.blocking
- ipykernel.inprocess.channels - ipykernel.inprocess.channels
@ -7755,7 +7821,6 @@ dumped:
- ipykernel.tests.utils - ipykernel.tests.utils
- ipykernel.trio_runner - ipykernel.trio_runner
- ipykernel.zmqshell - ipykernel.zmqshell
- ipykernel_launcher
- - zope - - zope
- zope - zope
- - '%dir /usr/lib/python3.7/site-packages/zope' - - '%dir /usr/lib/python3.7/site-packages/zope'
@ -15484,8 +15549,8 @@ metadata:
content: | content: |
Name: Django Name: Django
Version: 3.0.7 Version: 3.0.7
License-File: licenses/LICENSE License-File: LICENSE
License-File: licenses/LICENSE.python License-File: LICENSE.python
Whatever: False data Whatever: False data
records: records:
@ -15674,6 +15739,24 @@ records:
ipykernel/gui/gtk3embed.py,sha256=mjUXqAzPxF956OcmWdWzvU2VLJoZ4ZyXrqCImJcn_Ug,3222 ipykernel/gui/gtk3embed.py,sha256=mjUXqAzPxF956OcmWdWzvU2VLJoZ4ZyXrqCImJcn_Ug,3222
ipykernel/gui/gtkembed.py,sha256=yYp-Npg8jPrfXiN6mrzFy8L6JS7JeBOHz5WxTxSdvMA,3131 ipykernel/gui/gtkembed.py,sha256=yYp-Npg8jPrfXiN6mrzFy8L6JS7JeBOHz5WxTxSdvMA,3131
ipykernel/heartbeat.py,sha256=ZwIsWYgvjZQgFLjw6PrD9GJnN9XO1CzafUc89DEiPaA,4194 ipykernel/heartbeat.py,sha256=ZwIsWYgvjZQgFLjw6PrD9GJnN9XO1CzafUc89DEiPaA,4194
ipykernel/i18n/__init__.py,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/__pycache__/__init__.cpython-37.opt-1.pyc,,
ipykernel/i18n/__pycache__/__init__.cpython-37.pyc,,
ipykernel/i18n/fr_FR/LC_MESSAGES/nbjs.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/fr_FR/LC_MESSAGES/nbui.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/fr_FR/LC_MESSAGES/notebook.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/ja_JP/LC_MESSAGES/nbjs.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/ja_JP/LC_MESSAGES/nbui.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/ja_JP/LC_MESSAGES/notebook.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/nl/LC_MESSAGES/nbjs.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/nl/LC_MESSAGES/nbui.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/nl/LC_MESSAGES/notebook.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/ru_RU/LC_MESSAGES/nbjs.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/ru_RU/LC_MESSAGES/nbui.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/ru_RU/LC_MESSAGES/notebook.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/zh_CN/LC_MESSAGES/nbjs.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/zh_CN/LC_MESSAGES/nbui.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/i18n/zh_CN/LC_MESSAGES/notebook.mo,sha256=0000000000000000000000000000000000000000000,10
ipykernel/inprocess/__init__.py,sha256=UrsfQEevAq5OZ3au4Fn9bu_7c6b_QqroRIE7vE4PB_o,211 ipykernel/inprocess/__init__.py,sha256=UrsfQEevAq5OZ3au4Fn9bu_7c6b_QqroRIE7vE4PB_o,211
ipykernel/inprocess/__pycache__/__init__.cpython-37.pyc,, ipykernel/inprocess/__pycache__/__init__.cpython-37.pyc,,
ipykernel/inprocess/__pycache__/blocking.cpython-37.pyc,, ipykernel/inprocess/__pycache__/blocking.cpython-37.pyc,,

View File

@ -71,7 +71,12 @@ def test_data(case_name, capfd, tmp_path, monkeypatch):
out, err = capfd.readouterr() out, err = capfd.readouterr()
if 'expected' in case: if 'expected' in case:
assert out == case['expected'] expected = case['expected']
if isinstance(expected, list):
# at least one of them needs to match
assert any(out == e for e in expected)
else:
assert out == expected
# stderr_contains may be a string or list of strings # stderr_contains may be a string or list of strings
stderr_contains = case.get('stderr_contains') stderr_contains = case.get('stderr_contains')

View File

@ -12,11 +12,12 @@ 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.3.3 Version: 1.6.2
Release: 1%{?dist} Release: 1%{?dist}
# Macro files # Macro files
Source001: macros.pyproject Source001: macros.pyproject
Source002: macros.aaa-pyproject-srpm
# Implementation files # Implementation files
Source101: pyproject_buildrequires.py Source101: pyproject_buildrequires.py
@ -48,6 +49,7 @@ BuildArch: noarch
%if %{with tests} %if %{with tests}
BuildRequires: python3dist(pytest) BuildRequires: python3dist(pytest)
BuildRequires: python3dist(pytest-xdist)
BuildRequires: python3dist(pyyaml) BuildRequires: python3dist(pyyaml)
BuildRequires: python3dist(packaging) BuildRequires: python3dist(packaging)
BuildRequires: python3dist(pip) BuildRequires: python3dist(pip)
@ -64,6 +66,7 @@ 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
Requires: (pyproject-srpm-macros = %{?epoch:%{epoch}:}%{version}-%{release} if pyproject-srpm-macros)
# We use the following tools outside of coreutils # We use the following tools outside of coreutils
Requires: /usr/bin/find Requires: /usr/bin/find
@ -84,6 +87,17 @@ These macros replace %%py3_build and %%py3_install,
which only work with setup.py. which only work with setup.py.
%package -n pyproject-srpm-macros
Summary: Minimal implementation of %%pyproject_buildrequires
Requires: (pyproject-rpm-macros = %{?epoch:%{epoch}:}%{version}-%{release} if pyproject-rpm-macros)
%description -n pyproject-srpm-macros
This package contains a minimal implementation of %%pyproject_buildrequires.
When used in %%generate_buildrequires, it will generate BuildRequires
for pyproject-rpm-macros. When both packages are installed, the full version
takes precedence.
%prep %prep
# Not strictly necessary but allows working on file names instead # Not strictly necessary but allows working on file names instead
# of source numbers in install section # of source numbers in install section
@ -97,6 +111,7 @@ cp -p %{sources} .
mkdir -p %{buildroot}%{_rpmmacrodir} mkdir -p %{buildroot}%{_rpmmacrodir}
mkdir -p %{buildroot}%{_rpmconfigdir}/redhat mkdir -p %{buildroot}%{_rpmconfigdir}/redhat
install -pm 644 macros.pyproject %{buildroot}%{_rpmmacrodir}/ install -pm 644 macros.pyproject %{buildroot}%{_rpmmacrodir}/
install -pm 644 macros.aaa-pyproject-srpm %{buildroot}%{_rpmmacrodir}/
install -pm 644 pyproject_buildrequires.py %{buildroot}%{_rpmconfigdir}/redhat/ install -pm 644 pyproject_buildrequires.py %{buildroot}%{_rpmconfigdir}/redhat/
install -pm 644 pyproject_convert.py %{buildroot}%{_rpmconfigdir}/redhat/ install -pm 644 pyproject_convert.py %{buildroot}%{_rpmconfigdir}/redhat/
install -pm 644 pyproject_save_files.py %{buildroot}%{_rpmconfigdir}/redhat/ install -pm 644 pyproject_save_files.py %{buildroot}%{_rpmconfigdir}/redhat/
@ -108,7 +123,7 @@ 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
%pytest -vv --doctest-modules %pytest -vv --doctest-modules -n auto
# 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
@ -128,7 +143,35 @@ export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856
%doc README.md %doc README.md
%license LICENSE %license LICENSE
%files -n pyproject-srpm-macros
%{_rpmmacrodir}/macros.aaa-pyproject-srpm
%license LICENSE
%changelog %changelog
* Wed Feb 08 2023 Lumír Balhar <lbalhar@redhat.com> - 1.6.2-1
- Improve detection of lang files
* Fri Feb 03 2023 Miro Hrončok <mhroncok@redhat.com> - 1.6.1-1
- %%pyproject_buildrequires: Avoid leaking stdout from subprocesses
* Fri Jan 20 2023 Miro Hrončok <miro@hroncok.cz> - 1.6.0-1
- Add pyproject-srpm-macros with a minimal %%pyproject_buildrequires macro
* Fri Jan 13 2023 Miro Hrončok <mhroncok@redhat.com> - 1.5.1-1
- Adjusts %%pyproject_buildrequires tests for tox 4
* Mon Nov 28 2022 Miro Hrončok <mhroncok@redhat.com> - 1.5.0-1
- Use %%py3_test_envvars in %%tox when available
* Mon Sep 19 2022 Python Maint <python-maint@redhat.com> - 1.4.0-1
- %%pyproject_save_files: Support License-Files installed into the *Root License Directory* from PEP 369
- %%pyproject_check_import: Import only the modules whose top-level names
match any of the globs provided to %%pyproject_save_files
* Tue Aug 30 2022 Otto Liljalaakso <otto.liljalaakso@iki.fi> - 1.3.4-1
- Fix typo in internal function name
* Tue Aug 09 2022 Karolina Surma <ksurma@redhat.com> - 1.3.3-1 * Tue Aug 09 2022 Karolina Surma <ksurma@redhat.com> - 1.3.3-1
- Don't fail %%pyproject_save_files '*' if no modules are detected - Don't fail %%pyproject_save_files '*' if no modules are detected