diff --git a/macros.aaa-pyproject-srpm b/macros.aaa-pyproject-srpm index ee98cf3..5795c7b 100644 --- a/macros.aaa-pyproject-srpm +++ b/macros.aaa-pyproject-srpm @@ -20,6 +20,9 @@ %pyproject_patch_dependency() %{expand:\\\ %{!?1:%{error:%%pyproject_patch_dependency requires an argument}}\\\ %{?2:%{error:%%pyproject_patch_dependency accepts exactly one argument per call}}\\\ +if [ -f %{__python3} ] && [ -f %{_rpmconfigdir}/redhat/pyproject_dependency_overrides.py ]; then + %{__python3} -Bs %{_rpmconfigdir}/redhat/pyproject_dependency_overrides.py '%1' +fi echo '%1' >> %{_pyproject_dep_overrides} } diff --git a/pyproject-rpm-macros.spec b/pyproject-rpm-macros.spec index 8ef8905..3d1f51e 100644 --- a/pyproject-rpm-macros.spec +++ b/pyproject-rpm-macros.spec @@ -183,6 +183,7 @@ export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856 - Add long option support for all public parametric macros - E.g. %%pyproject_buildrequires --no-runtime is equivalent to %%pyproject_buildrequires -R - %%pyproject_save_files: Allow to use --auto instead of +auto +- %%pyproject_patch_dependency: Validate arguments early, in %%prep * Wed Apr 29 2026 Tomáš Hrnčiar - 1.21.0-1 - Implement extras validation diff --git a/pyproject_dependency_overrides.py b/pyproject_dependency_overrides.py index dbe3f03..33e0afc 100644 --- a/pyproject_dependency_overrides.py +++ b/pyproject_dependency_overrides.py @@ -135,3 +135,13 @@ def apply_overrides_to_specifiers(specifiers, overrides, package_name=None, new_specifiers.append(Specifier(f'>={value}')) return new_specifiers + + +if __name__ == '__main__': + import sys + override_str = sys.argv[1].removesuffix(':br_only') + try: + parse_override_string(override_str) + except ValueError as e: + print(e, file=sys.stderr) + sys.exit(1) diff --git a/test_dependency_overrides.py b/test_dependency_overrides.py index 93b65d9..be041cf 100644 --- a/test_dependency_overrides.py +++ b/test_dependency_overrides.py @@ -1,5 +1,8 @@ """Unit tests for dependency override functionality.""" +import subprocess +import sys + import pytest from packaging.requirements import Requirement @@ -47,6 +50,56 @@ class TestParseOverrideString: parse_override_string('pkg:set_upper:not_a_version!!!') +# ---- CLI validation (pyproject_dependency_overrides.py __main__) ---- + +SCRIPT = 'pyproject_dependency_overrides.py' + + +class TestCLIValidation: + def _run(self, arg): + return subprocess.run( + [sys.executable, '-Bs', SCRIPT, arg], + capture_output=True, text=True, + ) + + def test_valid_drop_upper(self): + assert self._run('numpy:drop_upper').returncode == 0 + + def test_valid_set_upper(self): + assert self._run('numpy:set_upper:2.0').returncode == 0 + + def test_valid_ignore_br_only(self): + assert self._run('pkg:ignore:br_only').returncode == 0 + + def test_valid_set_lower_br_only(self): + assert self._run('pkg:set_lower:1.0:br_only').returncode == 0 + + def test_invalid_no_colon(self): + r = self._run('justpackage') + assert r.returncode == 1 + assert 'Invalid dependency override format' in r.stderr + + def test_invalid_action(self): + r = self._run('pkg:bogus') + assert r.returncode == 1 + assert 'Invalid dependency override action' in r.stderr + + def test_set_upper_missing_value(self): + r = self._run('pkg:set_upper') + assert r.returncode == 1 + assert 'requires a value' in r.stderr + + def test_drop_upper_rejects_value(self): + r = self._run('pkg:drop_upper:2.0') + assert r.returncode == 1 + assert 'does not accept a value' in r.stderr + + def test_invalid_version(self): + r = self._run('pkg:set_upper:not_a_version!!!') + assert r.returncode == 1 + assert 'Invalid version' in r.stderr + + # ---- apply_overrides_to_specifiers (shared module) ---- class TestApplyOverridesToSpecifiers: