• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 20632486505

01 Jan 2026 04:21AM UTC coverage: 43.231% (-37.1%) from 80.281%
20632486505

Pull #22962

github

web-flow
Merge 08d5c63b0 into f52ab6675
Pull Request #22962: Bump the gha-deps group across 1 directory with 6 updates

26122 of 60424 relevant lines covered (43.23%)

0.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/python/pants/backend/nfpm/native_libs/rules.py
1
# Copyright 2025 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
×
5

6
from collections.abc import Iterable
×
7
from dataclasses import dataclass
×
8

9
from pants.backend.nfpm.field_sets import NfpmRpmPackageFieldSet
×
10
from pants.backend.nfpm.fields.rpm import NfpmRpmDependsField, NfpmRpmProvidesField
×
11
from pants.backend.nfpm.native_libs.elfdeps.rules import RequestPexELFInfo, elfdeps_analyze_pex
×
12
from pants.backend.nfpm.native_libs.elfdeps.rules import rules as elfdeps_rules
×
13
from pants.backend.nfpm.util_rules.contents import (
×
14
    GetPackageFieldSetsForNfpmContentFileDepsRequest,
15
    get_package_field_sets_for_nfpm_content_file_deps,
16
)
17
from pants.backend.nfpm.util_rules.inject_config import (
×
18
    InjectedNfpmPackageFields,
19
    InjectNfpmPackageFieldsRequest,
20
)
21
from pants.backend.python.goals.package_pex_binary import PexBinaryFieldSet, package_pex_binary
×
22
from pants.backend.python.util_rules.pex import Pex, create_pex
×
23
from pants.backend.python.util_rules.pex_from_targets import PexFromTargetsRequest
×
24
from pants.engine.addresses import Address
×
25
from pants.engine.internals.selectors import concurrently
×
26
from pants.engine.rules import Rule, collect_rules, implicitly, rule
×
27
from pants.engine.target import Field, Target
×
28
from pants.engine.unions import UnionMembership, UnionRule
×
29

30

31
@dataclass(frozen=True)
×
32
class RpmDependsFromPexRequest:
×
33
    target_pex: Pex
×
34

35

36
@dataclass(frozen=True)
×
37
class RpmDependsInfo:
×
38
    provides: tuple[str, ...]
×
39
    requires: tuple[str, ...]
×
40

41

42
@rule
×
43
async def rpm_depends_from_pex(request: RpmDependsFromPexRequest) -> RpmDependsInfo:
×
44
    # This rule provides a platform-agnostic replacement for `rpmdeps` in native rpm builds.
45
    pex_elf_info = await elfdeps_analyze_pex(RequestPexELFInfo(request.target_pex), **implicitly())
×
46
    return RpmDependsInfo(
×
47
        provides=tuple(provided.so_info for provided in pex_elf_info.provides),
48
        requires=tuple(required.so_info for required in pex_elf_info.requires),
49
    )
50

51

52
async def _get_pex_deps_of_content_file_targets(
×
53
    address: Address, union_membership: UnionMembership
54
) -> tuple[Pex, ...]:
55
    """Get all pex_binary targets that are (transitive) deps of nfpm_content_file targets."""
56
    package_field_sets_for_nfpm_content_files = (
×
57
        await get_package_field_sets_for_nfpm_content_file_deps(
58
            GetPackageFieldSetsForNfpmContentFileDepsRequest([address], [PexBinaryFieldSet]),
59
            **implicitly(),
60
        )
61
    )
62
    pex_binary_field_sets = package_field_sets_for_nfpm_content_files.package_field_sets
×
63
    build_pex_requests = await concurrently(
×
64
        package_pex_binary(field_set, **implicitly())
65
        for field_set in pex_binary_field_sets.field_sets
66
    )
67
    pex_binaries = await concurrently(
×
68
        create_pex(**implicitly({pex_request.request: PexFromTargetsRequest}))
69
        for pex_request in build_pex_requests
70
    )
71
    return pex_binaries
×
72

73

74
class NativeLibsNfpmPackageFieldsRequest(InjectNfpmPackageFieldsRequest):
×
75
    # low priority to allow in-repo plugins to override/correct injected dependencies.
76
    priority = 2
×
77

78
    @classmethod
×
79
    def is_applicable(cls, target: Target) -> bool:
×
80
        return NfpmRpmPackageFieldSet.is_applicable(target)
×
81

82

83
@rule
×
84
async def inject_native_libs_dependencies_in_package_fields(
×
85
    request: NativeLibsNfpmPackageFieldsRequest,
86
    union_membership: UnionMembership,
87
) -> InjectedNfpmPackageFields:
88
    address = request.target.address
×
89

90
    fields: list[Field] = list(request.injected_fields.values())
×
91

92
    # TODO: support scanning more packaged binaries than just pex_binaries.
93

94
    pex_binaries = await _get_pex_deps_of_content_file_targets(address, union_membership)
×
95
    if not pex_binaries:
×
96
        return InjectedNfpmPackageFields(fields, address=address)
×
97

98
    if NfpmRpmPackageFieldSet.is_applicable(request.target):
×
99
        # This is like running rpmdeps -> elfdeps.
100
        rpm_depends_infos = await concurrently(
×
101
            rpm_depends_from_pex(RpmDependsFromPexRequest(pex)) for pex in pex_binaries
102
        )
103
        provides = list(request.get_field(NfpmRpmProvidesField).value or ())
×
104
        depends = list(request.get_field(NfpmRpmDependsField).value or ())
×
105
        for rpm_depends_info in rpm_depends_infos:
×
106
            provides.extend(rpm_depends_info.provides)
×
107
            depends.extend(rpm_depends_info.requires)
×
108
        fields.extend(
×
109
            [
110
                NfpmRpmProvidesField(provides, address=address),
111
                NfpmRpmDependsField(depends, address=address),
112
            ]
113
        )
114

115
    return InjectedNfpmPackageFields(fields, address=address)
×
116

117

118
def rules() -> Iterable[Rule | UnionRule]:
×
119
    return (
×
120
        *elfdeps_rules(),
121
        *collect_rules(),
122
        UnionRule(InjectNfpmPackageFieldsRequest, NativeLibsNfpmPackageFieldsRequest),
123
    )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc