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

pantsbuild / pants / 21552830208

31 Jan 2026 11:40PM UTC coverage: 80.277% (-0.05%) from 80.324%
21552830208

Pull #23062

github

web-flow
Merge 808a9786c into 2c4dcf9cf
Pull Request #23062: Remove support for Get

18 of 25 new or added lines in 4 files covered. (72.0%)

17119 existing lines in 541 files now uncovered.

78278 of 97510 relevant lines covered (80.28%)

3.36 hits per line

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

53.33
/src/python/pants/backend/codegen/protobuf/jvm_symbol_mapper.py
1
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
UNCOV
3
from __future__ import annotations
3✔
4

UNCOV
5
import os
3✔
UNCOV
6
import re
3✔
UNCOV
7
from collections import defaultdict
3✔
UNCOV
8
from collections.abc import Mapping
3✔
UNCOV
9
from dataclasses import dataclass
3✔
UNCOV
10
from typing import DefaultDict
3✔
11

UNCOV
12
from pants.backend.codegen.protobuf.target_types import AllProtobufTargets, ProtobufSourceField
3✔
UNCOV
13
from pants.engine.addresses import Address
3✔
UNCOV
14
from pants.engine.fs import FileContent
3✔
UNCOV
15
from pants.engine.internals.graph import hydrate_sources
3✔
UNCOV
16
from pants.engine.intrinsics import get_digest_contents
3✔
UNCOV
17
from pants.engine.rules import collect_rules, concurrently, implicitly, rule
3✔
UNCOV
18
from pants.engine.target import HydrateSourcesRequest
3✔
UNCOV
19
from pants.jvm.dependency_inference.artifact_mapper import MutableTrieNode
3✔
UNCOV
20
from pants.jvm.dependency_inference.symbol_mapper import SymbolMap
3✔
UNCOV
21
from pants.jvm.subsystems import JvmSubsystem
3✔
UNCOV
22
from pants.jvm.target_types import JvmResolveField
3✔
UNCOV
23
from pants.util.ordered_set import OrderedSet
3✔
24

UNCOV
25
_ResolveName = str
3✔
26

27

UNCOV
28
@dataclass(frozen=True)
3✔
UNCOV
29
class FirstPartyProtobufJvmMappingRequest:
3✔
UNCOV
30
    capitalize_base_name: bool
3✔
31

32

UNCOV
33
@rule
3✔
UNCOV
34
async def map_first_party_protobuf_jvm_targets_to_symbols(
3✔
35
    request: FirstPartyProtobufJvmMappingRequest,
36
    all_protobuf_targets: AllProtobufTargets,
37
    jvm: JvmSubsystem,
38
) -> SymbolMap:
39
    sources = await concurrently(
×
40
        hydrate_sources(
41
            HydrateSourcesRequest(
42
                tgt[ProtobufSourceField],
43
                for_sources_types=(ProtobufSourceField,),
44
                enable_codegen=True,
45
            ),
46
            **implicitly(),
47
        )
48
        for tgt in all_protobuf_targets
49
    )
50

51
    all_contents = await concurrently(
×
52
        get_digest_contents(source.snapshot.digest) for source in sources
53
    )
54

55
    namespace_mapping: DefaultDict[tuple[_ResolveName, str], OrderedSet[Address]] = defaultdict(
×
56
        OrderedSet
57
    )
58
    for tgt, contents in zip(all_protobuf_targets, all_contents):
×
59
        if not contents:
×
60
            continue
×
61
        if len(contents) > 1:
×
62
            raise AssertionError(
×
63
                f"Protobuf target `{tgt.address}` mapped to more than one source file."
64
            )
65

66
        resolve = tgt[JvmResolveField].normalized_value(jvm)
×
67
        namespace = _determine_namespace(
×
68
            contents[0], capitalize_base_name=request.capitalize_base_name
69
        )
70
        namespace_mapping[(resolve, namespace)].add(tgt.address)
×
71

72
    mapping: Mapping[str, MutableTrieNode] = defaultdict(MutableTrieNode)
×
73
    for (resolve, namespace), addresses in namespace_mapping.items():
×
74
        mapping[resolve].insert(namespace, addresses, first_party=True, recursive=True)
×
75

76
    return SymbolMap((resolve, node.frozen()) for resolve, node in mapping.items())
×
77

78

79
# Determine generated Java/Scala package name
80
# * https://grpc.io/docs/languages/java/generated-code
81
# * https://scalapb.github.io/docs/generated-code
UNCOV
82
def _determine_namespace(file: FileContent, *, capitalize_base_name: bool) -> str:
3✔
83
    base_name, _, _ = os.path.basename(file.path).partition(".")
×
84
    base_name = base_name.capitalize() if capitalize_base_name else base_name
×
85
    package_definition = _parse_package_definition(file.content)
×
86
    return f"{package_definition}.{base_name}" if package_definition else base_name
×
87

88

UNCOV
89
_QUOTE_CHAR = r"(?:'|\")"
3✔
UNCOV
90
_JAVA_PACKAGE_OPTION_RE = re.compile(
3✔
91
    rf"^\s*option\s+java_package\s+=\s+{_QUOTE_CHAR}(.+){_QUOTE_CHAR};"
92
)
UNCOV
93
_PACKAGE_RE = re.compile(r"^\s*package\s+(.+);")
3✔
94

95

UNCOV
96
def _parse_package_definition(content_raw: bytes) -> str | None:
3✔
97
    content = content_raw.decode()
×
98
    for line in content.splitlines():
×
99
        m = _JAVA_PACKAGE_OPTION_RE.match(line)
×
100
        if m:
×
101
            return m.group(1)
×
102
        m = _PACKAGE_RE.match(line)
×
103
        if m:
×
104
            return m.group(1)
×
105
    return None
×
106

107

UNCOV
108
def rules():
3✔
UNCOV
109
    return collect_rules()
3✔
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