-
Notifications
You must be signed in to change notification settings - Fork 44
RPM Architecture Filtering #1109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RPM Architecture Filtering #1109
Conversation
📝 WalkthroughWalkthroughIntroduces RPM binary-architecture filtering via a new RPMArchitectureFilter and integrates it into the RPM resolve/download flow. Signatures are extended to accept an optional RpmBinaryFilters. The download step validates and filters lockfile architectures before processing. New unit and integration tests cover filtering behavior and the updated control flow. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User as Caller
participant RPM as RPM (main)
participant Resolve as _resolve_rpm_project
participant Download as _download
participant Filter as RPMArchitectureFilter
participant Repo as Repos
User->>RPM: fetch_rpm_source(pkg, binary_filter)
RPM->>Resolve: _resolve_rpm_project(..., binary_filter)
Resolve->>Download: _download(lockfile, output_dir, ..., binary_filter)
Download->>Filter: validate_and_filter(lockfile.arches)
alt Constraints satisfiable
Filter-->>Download: arches_to_process
loop per arch in arches_to_process
Download->>Repo: fetch RPM for arch
Repo-->>Download: RPM metadata/path
end
Download-->>Resolve: results
else Unsatisfiable
Filter-->>Download: raise UnsatisfiableArchitectureFilter
Download-->>Resolve: propagate error
end
Resolve-->>RPM: components / error
RPM-->>User: result / error
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (9)
tests/integration/test_rpm.py (1)
71-80: Add a negative-case integration for an unsatisfiable arch filterConsider a companion case with binary={"arch": "s390x"} (or any absent arch) expecting a non‑zero exit and a clear error message. This guards the user‑error path end‑to‑end.
tests/unit/package_managers/rpm/test_rpm.py (1)
596-618: Fix unused mock and strengthen the assertionUse the patched asyncio.run to avoid Ruff ARG001 and assert it’s called exactly once (only the filtered arch is processed).
Apply this diff:
@mock.patch("hermeto.core.package_managers.rpm.main.asyncio.run") def test_download_filters_architectures( - mock_asyncio: mock.Mock, rooted_tmp_path: RootedPath + mock_asyncio: mock.Mock, rooted_tmp_path: RootedPath ) -> None: @@ assert all("x86_64" in p for p in paths) assert not any("aarch64" in p for p in paths) + # Ensure exactly one download loop ran (only the filtered arch). + mock_asyncio.assert_called_once()hermeto/core/package_managers/rpm/main.py (1)
319-325: Document the new binary_filter parameter in _downloadAdd a brief note so future readers don’t have to trace call sites.
Apply this diff:
def _download( lockfile: RedhatRpmsLock, output_dir: Path, ssl_options: Optional[SSLOptions] = None, binary_filter: Optional[RpmBinaryFilters] = None, ) -> dict[Path, Any]: """ Download packages and module metadata mentioned in the lockfile. Go through the parsed lockfile structure and find all RPM, SRPM and module metadata files. Create a metadata structure indexed by destination path used for later verification (size, checksum) after download. Prepare a list of files to be downloaded, and then download files. + If binary_filter is provided, only architectures matching the filter are processed. """hermeto/core/package_managers/rpm/binary_filters.py (3)
50-53: Tidy exception construction and handle empty-available caseMove long f-strings to variables (appeases Ruff TRY003) and provide a clearer message when no arches are available.
Apply this diff:
- raise UnsatisfiableArchitectureFilter( - f"Specified RPM architecture(s) not found in lockfile: {', '.join(sorted(unsatisfiable))}", - solution=f"Use one of the available architectures: {', '.join(sorted(available))}", - ) + reason = "Specified RPM architecture(s) not found in lockfile: " + ", ".join(sorted(unsatisfiable)) + available_msg = ", ".join(sorted(available)) if available else "none available in lockfile" + solution = f"Use one of the available architectures: {available_msg}" + raise UnsatisfiableArchitectureFilter(reason, solution=solution)
3-3: Remove unused logger
loggingimport andlogare unused.Apply this diff:
-import logging @@ -log = logging.getLogger(__name__)Also applies to: 11-11
40-43: Signature polish: accept Sequence to be more generalIf you want to accept tuples/lists equally, consider
Sequence[LockfileArch]for the parameter type.Apply this diff:
-from typing import Any, Optional +from typing import Any, Optional, Sequence @@ - def filter(self, arches: list[LockfileArch]) -> list[LockfileArch]: + def filter(self, arches: Sequence[LockfileArch]) -> list[LockfileArch]: """Filter a list of architectures based on constraints.""" return [arch for arch in arches if arch in self]tests/unit/package_managers/rpm/test_binary_filters.py (3)
35-39: Prefer typing.cast over type: ignoreAvoid suppressing type checking; cast the mocked list to the expected type.
Apply this diff:
-from typing import Optional +from typing import Optional, cast @@ - all_arches = [mock.Mock(spec=LockfileArch, arch=arch) for arch in lockfile_arches] - - filtered = arch_filter.validate_and_filter(all_arches) # type: ignore[arg-type] + all_arches = [mock.Mock(spec=LockfileArch, arch=arch) for arch in lockfile_arches] + all_arches_typed = cast(list[LockfileArch], all_arches) + + filtered = arch_filter.validate_and_filter(all_arches_typed) filtered_arch_strings = [arch.arch for arch in filtered]
14-28: Add edge-case coverage: ':all:' combined and whitespace handlingStrengthen guarantees around parsing by covering mixed ':all:' specs and whitespace trimming.
Apply this diff (add two params):
pytest.param( RpmBinaryFilters(arch=":all:"), ["x86_64", "aarch64", "s390x", "ppc64le"], id="all_keyword", ), + pytest.param( + RpmBinaryFilters(arch="x86_64,:all:"), + ["x86_64", "aarch64", "s390x", "ppc64le"], + id="all_mixed_with_other", + ), + pytest.param( + RpmBinaryFilters(arch="x86_64, aarch64"), + ["x86_64", "aarch64"], + id="whitespace_trim", + ),
58-59: Assert error message content for better contract checkingLock in user‑facing text fragment to prevent regressions.
Apply this diff:
- with pytest.raises(UnsatisfiableArchitectureFilter): - _ = arch_filter.validate_and_filter(all_arches) # type: ignore[arg-type] + with pytest.raises(UnsatisfiableArchitectureFilter, match="not found in lockfile"): + arch_filter.validate_and_filter(all_arches) # type: ignore[arg-type]
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
hermeto/core/package_managers/rpm/binary_filters.py(1 hunks)hermeto/core/package_managers/rpm/main.py(6 hunks)tests/integration/test_data/rpm_multiple_archs_with_filtering/.build-config.yaml(1 hunks)tests/integration/test_data/rpm_multiple_archs_with_filtering/bom.json(1 hunks)tests/integration/test_rpm.py(1 hunks)tests/unit/package_managers/rpm/test_binary_filters.py(1 hunks)tests/unit/package_managers/rpm/test_rpm.py(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
tests/integration/test_rpm.py (1)
tests/integration/utils.py (1)
TestParameters(66-74)
tests/unit/package_managers/rpm/test_binary_filters.py (3)
hermeto/core/models/input.py (1)
RpmBinaryFilters(235-238)hermeto/core/package_managers/rpm/binary_filters.py (3)
RPMArchitectureFilter(18-60)UnsatisfiableArchitectureFilter(14-15)validate_and_filter(55-60)hermeto/core/package_managers/rpm/redhat.py (1)
LockfileArch(28-41)
tests/unit/package_managers/rpm/test_rpm.py (4)
hermeto/core/models/input.py (4)
ExtraOptions(310-359)RpmBinaryFilters(235-238)RpmPackageInput(362-368)SSLOptions(141-176)tests/unit/conftest.py (1)
rooted_tmp_path(59-61)hermeto/core/package_managers/rpm/redhat.py (1)
RedhatRpmsLock(44-83)hermeto/core/package_managers/rpm/main.py (1)
_download(319-370)
hermeto/core/package_managers/rpm/binary_filters.py (4)
hermeto/core/binary_filters.py (2)
BinaryPackageFilter(9-30)_parse_filter_spec(12-26)hermeto/core/errors.py (1)
PackageRejected(84-100)hermeto/core/models/input.py (1)
RpmBinaryFilters(235-238)hermeto/core/package_managers/rpm/redhat.py (1)
LockfileArch(28-41)
hermeto/core/package_managers/rpm/main.py (3)
hermeto/core/models/input.py (1)
RpmBinaryFilters(235-238)hermeto/core/package_managers/general.py (1)
async_download_files(102-148)hermeto/core/package_managers/rpm/binary_filters.py (2)
RPMArchitectureFilter(18-60)validate_and_filter(55-60)
🪛 Ruff (0.12.2)
tests/unit/package_managers/rpm/test_rpm.py
598-598: Unused function argument: mock_asyncio
(ARG001)
hermeto/core/package_managers/rpm/binary_filters.py
50-53: Avoid specifying long messages outside the exception class
(TRY003)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build container image and run integration tests on it
- GitHub Check: Konflux kflux-prd-rh03 / on-pull-request
🔇 Additional comments (11)
tests/integration/test_data/rpm_multiple_archs_with_filtering/.build-config.yaml (1)
1-2: LGTM: minimal test config is fineEmpty env and project files are appropriate for this scenario.
tests/integration/test_data/rpm_multiple_archs_with_filtering/bom.json (1)
1-27: LGTM: BOM fixture matches the filtering caseThe PURL includes arch=x86_64 and checksum, which is consistent with the test intent.
tests/unit/package_managers/rpm/test_rpm.py (2)
12-12: LGTM: imports updated for binary filtersRpmBinaryFilters is correctly imported for the new tests.
361-362: LGTM: _resolve_rpm_project threads binary_filter to _downloadAssertion reflects the new fourth argument (binary_filter) and preserves call order.
hermeto/core/package_managers/rpm/main.py (5)
20-25: LGTM: imports for RpmBinaryFilters and RPMArchitectureFilterDependency injection is clean and localized.
229-230: LGTM: binary filter is passed from package inputForwarding package.binary keeps input flow explicit.
262-269: LGTM: _resolve_rpm_project accepts binary_filterSignature change is clear and preserves default behavior when None.
311-313: LGTM: _resolve_rpm_project applies the filter in _downloadThe filter plumbs through without affecting SSL/options handling.
333-338: LGTM: validated arch filtering before downloadvalidate_and_filter avoids silent no‑ops and provides clear errors on unsatisfiable constraints.
hermeto/core/package_managers/rpm/binary_filters.py (1)
21-25: LGTM on core filter flowConstructor, satisfiability check, and filter pipeline read clean and match the intended semantics for ':all:' and exact arch matching.
Also applies to: 55-60
tests/unit/package_managers/rpm/test_binary_filters.py (1)
41-41: LGTM: order-preserving filter assertionAsserting exact order verifies stable iteration over lockfile arches.
| def __contains__(self, item: Any) -> bool: | ||
| """Return True if an architecture is allowed by the filter constraints.""" | ||
| if isinstance(item, str): | ||
| arch = item | ||
| elif isinstance(item, LockfileArch): | ||
| arch = item.arch | ||
| else: | ||
| return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix: contains is too strict, breaks tests with LockfileArch mocks
Duck‑type on "arch" instead of requiring isinstance(LockfileArch). Current code returns False for mocks with spec=LockfileArch, causing filtering to drop all arches in tests.
Apply this diff:
- def __contains__(self, item: Any) -> bool:
+ def __contains__(self, item: Any) -> bool:
"""Return True if an architecture is allowed by the filter constraints."""
- if isinstance(item, str):
- arch = item
- elif isinstance(item, LockfileArch):
- arch = item.arch
- else:
- return False
+ if isinstance(item, str):
+ arch = item
+ elif hasattr(item, "arch"):
+ # Accept LockfileArch instances and test doubles/mocks with an `arch` attribute
+ arch = getattr(item, "arch")
+ else:
+ return False📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def __contains__(self, item: Any) -> bool: | |
| """Return True if an architecture is allowed by the filter constraints.""" | |
| if isinstance(item, str): | |
| arch = item | |
| elif isinstance(item, LockfileArch): | |
| arch = item.arch | |
| else: | |
| return False | |
| def __contains__(self, item: Any) -> bool: | |
| """Return True if an architecture is allowed by the filter constraints.""" | |
| if isinstance(item, str): | |
| arch = item | |
| elif hasattr(item, "arch"): | |
| # Accept LockfileArch instances and test doubles/mocks with an `arch` attribute | |
| arch = getattr(item, "arch") | |
| else: | |
| return False |
🤖 Prompt for AI Agents
In hermeto/core/package_managers/rpm/binary_filters.py around lines 26 to 33,
__contains__ is too strict by requiring isinstance(item, LockfileArch) which
causes mocks with spec=LockfileArch to be treated as non-matching; change the
branch to duck-type: if item is a str use it directly, elif it has an "arch"
attribute (hasattr(item, "arch")) use item.arch, otherwise return False; ensure
no direct isinstance check against LockfileArch so mocks pass.
fddebb9 to
da0e1dd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
hermeto/core/package_managers/rpm/binary_filters.py (1)
26-39: contains is too strict; breaks duck-typed tests and mocksDon't require isinstance(LockfileArch); accept any object with an arch attribute.
Apply this diff:
-from hermeto.core.package_managers.rpm.redhat import LockfileArch @@ - if isinstance(item, str): - arch = item - elif isinstance(item, LockfileArch): - arch = item.arch - else: - return False + if isinstance(item, str): + arch = item + elif hasattr(item, "arch"): + # Accept LockfileArch instances and test doubles/mocks with an `arch` attribute + arch = getattr(item, "arch") + else: + return FalseAnd remove the now-unused import:
-from hermeto.core.package_managers.rpm.redhat import LockfileArch
🧹 Nitpick comments (4)
tests/integration/test_rpm.py (1)
71-80: New multi-arch filtering scenario looks goodCovers the positive path for specifying a binary arch filter in integration. No issues spotted.
Consider adding a negative case (e.g., arch not present) to assert an UnsatisfiableArchitectureFilter is surfaced end-to-end.
tests/unit/package_managers/rpm/test_rpm.py (1)
596-618: Fix unused mocked argument; assert asyncio.run was invokedRuff flags mock_asyncio as unused (ARG001). Use it to assert the download path was exercised.
Apply this diff:
@mock.patch("hermeto.core.package_managers.rpm.main.asyncio.run") def test_download_filters_architectures( - mock_asyncio: mock.Mock, rooted_tmp_path: RootedPath + mock_asyncio: mock.Mock, rooted_tmp_path: RootedPath ) -> None: @@ assert all("x86_64" in p for p in paths) assert not any("aarch64" in p for p in paths) + + # Ensure the async download path was triggered + mock_asyncio.assert_called_once()hermeto/core/package_managers/rpm/binary_filters.py (2)
40-43: Fast-path when no constraintsReturn arches unmodified when accepting all to avoid needless membership checks.
Apply this diff:
def filter(self, arches: list[LockfileArch]) -> list[LockfileArch]: """Filter a list of architectures based on constraints.""" - return [arch for arch in arches if arch in self] + if self.arch_constraints is None: + return arches + return [arch for arch in arches if arch in self]
14-16: Tidy raise site per TRY003: move message formatting into the exceptionEncapsulates long messages in the exception class; improves reuse and satisfies style checks.
Apply this diff:
class UnsatisfiableArchitectureFilter(PackageRejected): - """RPM architecture filter constraints cannot be satisfied by lockfile architectures.""" + """RPM architecture filter constraints cannot be satisfied by lockfile architectures.""" + + def __init__(self, unsatisfiable: set[str], available: set[str]) -> None: + reason = ( + "Specified RPM architecture(s) not found in lockfile: " + f"{', '.join(sorted(unsatisfiable))}" + ) + solution = f"Use one of the available architectures: {', '.join(sorted(available))}" + super().__init__(reason, solution=solution) @@ - if unsatisfiable: - raise UnsatisfiableArchitectureFilter( - f"Specified RPM architecture(s) not found in lockfile: {', '.join(sorted(unsatisfiable))}", - solution=f"Use one of the available architectures: {', '.join(sorted(available))}", - ) + if unsatisfiable: + raise UnsatisfiableArchitectureFilter(unsatisfiable, available)Also applies to: 50-53
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
hermeto/core/package_managers/rpm/binary_filters.py(1 hunks)hermeto/core/package_managers/rpm/main.py(6 hunks)tests/integration/test_data/rpm_multiple_archs_with_filtering/.build-config.yaml(1 hunks)tests/integration/test_data/rpm_multiple_archs_with_filtering/bom.json(1 hunks)tests/integration/test_rpm.py(1 hunks)tests/unit/package_managers/rpm/test_binary_filters.py(1 hunks)tests/unit/package_managers/rpm/test_rpm.py(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- tests/integration/test_data/rpm_multiple_archs_with_filtering/.build-config.yaml
- tests/integration/test_data/rpm_multiple_archs_with_filtering/bom.json
- hermeto/core/package_managers/rpm/main.py
- tests/unit/package_managers/rpm/test_binary_filters.py
🧰 Additional context used
🧬 Code graph analysis (3)
tests/integration/test_rpm.py (1)
tests/integration/utils.py (1)
TestParameters(66-74)
hermeto/core/package_managers/rpm/binary_filters.py (4)
hermeto/core/binary_filters.py (2)
BinaryPackageFilter(9-30)_parse_filter_spec(12-26)hermeto/core/errors.py (1)
PackageRejected(84-100)hermeto/core/models/input.py (1)
RpmBinaryFilters(235-238)hermeto/core/package_managers/rpm/redhat.py (1)
LockfileArch(28-41)
tests/unit/package_managers/rpm/test_rpm.py (5)
hermeto/core/models/input.py (4)
ExtraOptions(310-359)RpmBinaryFilters(235-238)RpmPackageInput(362-368)SSLOptions(141-176)tests/unit/conftest.py (1)
rooted_tmp_path(59-61)hermeto/core/rooted_path.py (1)
RootedPath(13-122)hermeto/core/package_managers/rpm/redhat.py (1)
RedhatRpmsLock(44-83)hermeto/core/package_managers/rpm/main.py (1)
_download(319-370)
🪛 Ruff (0.12.2)
hermeto/core/package_managers/rpm/binary_filters.py
50-53: Avoid specifying long messages outside the exception class
(TRY003)
tests/unit/package_managers/rpm/test_rpm.py
598-598: Unused function argument: mock_asyncio
(ARG001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build container image and run integration tests on it
- GitHub Check: Konflux kflux-prd-rh03 / on-pull-request
🔇 Additional comments (2)
tests/unit/package_managers/rpm/test_rpm.py (2)
12-12: Importing RpmBinaryFilters is correctMatches the new public API and keeps tests self-contained.
360-362: Updated _download call signature verifiedPassing ssl_options=None and binary_filter=None aligns with the new function signature.
Signed-off-by: Taylor Madore <tmadore@redhat.com>
Add RPMArchitectureFilter class to assist with filtering RPM requests based on user-specified architecture constraints. This builds on the binary filtering framework established in earlier commits. Signed-off-by: Taylor Madore <tmadore@redhat.com> Assisted-by: Claude Sonnet 4
da0e1dd to
94b818c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
hermeto/core/package_managers/rpm/binary_filters.py (1)
23-35: contains is too strict; duck‑type onarchto support mocks and test doubles.
Usingisinstance(item, LockfileArch)breaks tests that pass mocks with anarchattribute.Apply this diff:
- if isinstance(item, str): - arch = item - elif isinstance(item, LockfileArch): - arch = item.arch - else: - return False + if isinstance(item, str): + arch = item + elif hasattr(item, "arch"): + # Accept LockfileArch instances and test doubles/mocks with an `arch` attribute + arch = getattr(item, "arch") + else: + return False
🧹 Nitpick comments (3)
tests/unit/package_managers/rpm/test_main.py (1)
596-599: Silence unused patched argument to satisfy Ruff ARG001.
Rename the unusedmock_asyncioparameter to_mock_asyncio(or use it) to avoid ARG001.Apply this diff:
@mock.patch("hermeto.core.package_managers.rpm.main.asyncio.run") def test_download_filters_architectures( - mock_asyncio: mock.Mock, rooted_tmp_path: RootedPath + _mock_asyncio: mock.Mock, rooted_tmp_path: RootedPath ) -> None:hermeto/core/package_managers/rpm/main.py (1)
333-335: Architecture filtering applied before download.
Consider adding a debug log to trace which arches were selected.Apply this diff:
arch_filter = RPMArchitectureFilter(binary_filter) arches_to_process = arch_filter.validate_and_filter(lockfile.arches) +log.debug("Filtered architectures to process: %s", [a.arch for a in arches_to_process])hermeto/core/package_managers/rpm/binary_filters.py (1)
47-50: Minor: long error message assembly inside raise.
Style-only: consider moving formatting into the exception class or a helper to satisfy TRY003.Example:
-class UnsatisfiableArchitectureFilter(PackageRejected): - """RPM architecture filter constraints cannot be satisfied by lockfile architectures.""" +class UnsatisfiableArchitectureFilter(PackageRejected): + """RPM architecture filter constraints cannot be satisfied by lockfile architectures.""" + def __init__(self, missing: set[str], available: set[str]) -> None: + super().__init__( + f"Specified RPM architecture(s) not found in lockfile: {', '.join(sorted(missing))}", + solution=f"Use one of the available architectures: {', '.join(sorted(available))}", + )and then:
- raise UnsatisfiableArchitectureFilter( - f"Specified RPM architecture(s) not found in lockfile: {', '.join(sorted(unsatisfiable))}", - solution=f"Use one of the available architectures: {', '.join(sorted(available))}", - ) + raise UnsatisfiableArchitectureFilter(unsatisfiable, available)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
hermeto/core/package_managers/rpm/binary_filters.py(1 hunks)hermeto/core/package_managers/rpm/main.py(6 hunks)tests/integration/test_data/rpm_multiple_archs_with_filtering/.build-config.yaml(1 hunks)tests/integration/test_data/rpm_multiple_archs_with_filtering/bom.json(1 hunks)tests/integration/test_rpm.py(1 hunks)tests/unit/package_managers/rpm/test_binary_filters.py(1 hunks)tests/unit/package_managers/rpm/test_main.py(3 hunks)
✅ Files skipped from review due to trivial changes (1)
- tests/integration/test_data/rpm_multiple_archs_with_filtering/bom.json
🚧 Files skipped from review as they are similar to previous changes (3)
- tests/integration/test_data/rpm_multiple_archs_with_filtering/.build-config.yaml
- tests/integration/test_rpm.py
- tests/unit/package_managers/rpm/test_binary_filters.py
🧰 Additional context used
🧬 Code graph analysis (3)
tests/unit/package_managers/rpm/test_main.py (2)
hermeto/core/models/input.py (4)
ExtraOptions(310-359)RpmBinaryFilters(235-238)RpmPackageInput(362-368)SSLOptions(141-176)hermeto/core/package_managers/rpm/main.py (1)
_download(319-370)
hermeto/core/package_managers/rpm/main.py (3)
hermeto/core/models/input.py (2)
RpmBinaryFilters(235-238)SSLOptions(141-176)hermeto/core/package_managers/general.py (1)
async_download_files(102-148)hermeto/core/package_managers/rpm/binary_filters.py (2)
RPMArchitectureFilter(15-57)validate_and_filter(52-57)
hermeto/core/package_managers/rpm/binary_filters.py (4)
hermeto/core/binary_filters.py (2)
BinaryPackageFilter(9-30)_parse_filter_spec(12-26)hermeto/core/errors.py (1)
PackageRejected(84-100)hermeto/core/models/input.py (1)
RpmBinaryFilters(235-238)hermeto/core/package_managers/rpm/redhat.py (1)
LockfileArch(28-41)
🪛 Ruff (0.12.2)
tests/unit/package_managers/rpm/test_main.py
598-598: Unused function argument: mock_asyncio
(ARG001)
hermeto/core/package_managers/rpm/binary_filters.py
47-50: Avoid specifying long messages outside the exception class
(TRY003)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build container image and run integration tests on it
- GitHub Check: Konflux kflux-prd-rh03 / on-pull-request
🔇 Additional comments (8)
tests/unit/package_managers/rpm/test_main.py (3)
12-12: Import of RpmBinaryFilters is appropriate for new filtering tests.
Looks good.
359-362: Updated _download call signature assertion is correct.
The additional binary_filter argument is properly accounted for in the expectation.
612-617: Good validation of architecture filtering behavior.
The assertions tightly verify that only the selected arch makes it into metadata.hermeto/core/package_managers/rpm/main.py (5)
20-25: Plumbing: import additions align with new filtering flow.
No issues spotted.
229-230: Thread binary_filter through fetch path.
Forwardingpackage.binaryensures per‑package filters are honored.
312-313: Passing binary_filter to _download is correct.
Keeps filter semantics centralized in the download step.
337-338: Looping only over filtered arches is correct.
This confines downloads and repo creation to the intended set.
267-268: Signature extended with binary_filter — no call-site changes required. binary_filter is Optional with default None; grep shows remaining two-arg callers are tests (compatible) and callers that need the filter already pass it.
Implement RPM architecture filtering
Maintainers will complete the following section
Note: if the contribution is external (not from an organization member), the CI
pipeline will not run automatically. After verifying that the CI is safe to run:
/ok-to-test(as is the standard for Pipelines as Code)