diff --git a/pyproject-rpm-macros.spec b/pyproject-rpm-macros.spec index 84163d2..f35e222 100644 --- a/pyproject-rpm-macros.spec +++ b/pyproject-rpm-macros.spec @@ -10,7 +10,7 @@ License: MIT # Increment Y and reset Z when new macros or features are added # Increment Z when this is a bugfix or a cosmetic change # Dropping support for EOL Fedoras is *not* considered a breaking change -Version: 1.3.4 +Version: 1.4.0 Release: 1%{?dist} # Macro files @@ -127,6 +127,10 @@ export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856 %license LICENSE %changelog +* Mon Sep 19 2022 Miro HronĨok - 1.4.0-1 +- %%pyproject_save_files: Support License-Files installed into the *Root License Directory* from PEP 369 +- Fixes: rhbz#2127946 + * Tue Aug 30 2022 Otto Liljalaakso - 1.3.4-1 - Fix typo in internal function name diff --git a/pyproject_save_files.py b/pyproject_save_files.py index 18925f1..880dd2b 100644 --- a/pyproject_save_files.py +++ b/pyproject_save_files.py @@ -286,6 +286,36 @@ def module_names_from_path(path): 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( 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 :( } + 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. # The example RECORD from PEP 376 does not contain directories either. # 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: if path.suffix == ".pyc": # we handle bytecode separately @@ -325,7 +362,7 @@ def classify_paths( # RECORD and REQUESTED files are removed in %pyproject_install # See PEP 627 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) else: paths["metadata"]["files"].append(path) diff --git a/pyproject_save_files_test_data.yaml b/pyproject_save_files_test_data.yaml index c6d2291..44f368b 100644 --- a/pyproject_save_files_test_data.yaml +++ b/pyproject_save_files_test_data.yaml @@ -15484,8 +15484,8 @@ metadata: content: | Name: Django Version: 3.0.7 - License-File: licenses/LICENSE - License-File: licenses/LICENSE.python + License-File: LICENSE + License-File: LICENSE.python Whatever: False data records: diff --git a/tests/python-userpath.spec b/tests/python-userpath.spec index 5f937fd..b26c8fd 100644 --- a/tests/python-userpath.spec +++ b/tests/python-userpath.spec @@ -49,6 +49,13 @@ sed -Ei '/^(coverage)$/d' requirements-dev.txt %check %pytest +%if 0%{?fedora} > 35 || 0%{?rhel} > 9 +# Internal check that license file was recognized correctly with hatchling 1.9.0+ +grep '^%%license' %{pyproject_files} > tested.license +echo '%%license %{python3_sitelib}/userpath-%{version}.dist-info/licenses/LICENSE.txt' > expected.license +diff tested.license expected.license +%endif + %files -n python3-userpath -f %{pyproject_files} %{_bindir}/userpath