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

pantsbuild / pants / 22893710013

10 Mar 2026 08:29AM UTC coverage: 91.148% (-1.8%) from 92.932%
22893710013

Pull #23032

github

web-flow
Merge c09ecdff4 into 2804a4673
Pull Request #23032: Bugfix: Add support for pull option in podman

87 of 93 new or added lines in 4 files covered. (93.55%)

1432 existing lines in 69 files now uncovered.

84014 of 92173 relevant lines covered (91.15%)

3.91 hits per line

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

52.27
/src/python/pants/backend/codegen/export_codegen_goal.py
1
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
import logging
6✔
5

6
from pants.core.util_rules.distdir import DistDir
6✔
7
from pants.engine.fs import MergeDigests, Workspace
6✔
8
from pants.engine.goal import Goal, GoalSubsystem
6✔
9
from pants.engine.internals.graph import hydrate_sources
6✔
10
from pants.engine.intrinsics import merge_digests
6✔
11
from pants.engine.rules import collect_rules, concurrently, goal_rule, implicitly
6✔
12
from pants.engine.target import (
6✔
13
    FilteredTargets,
14
    GenerateSourcesRequest,
15
    HydrateSourcesRequest,
16
    RegisteredTargetTypes,
17
    SourcesField,
18
)
19
from pants.engine.unions import UnionMembership
6✔
20
from pants.util.strutil import softwrap
6✔
21

22
logger = logging.getLogger(__name__)
6✔
23

24

25
class ExportCodegenSubsystem(GoalSubsystem):
6✔
26
    name = "export-codegen"
6✔
27
    help = "Write generated files to `dist/codegen` for use outside of Pants."
6✔
28

29
    @classmethod
6✔
30
    def activated(cls, union_membership: UnionMembership) -> bool:
6✔
31
        return GenerateSourcesRequest in union_membership
×
32

33

34
class ExportCodegen(Goal):
6✔
35
    subsystem_cls = ExportCodegenSubsystem
6✔
36
    environment_behavior = Goal.EnvironmentBehavior.LOCAL_ONLY  # TODO(#17129) — Migrate this.
6✔
37

38

39
@goal_rule
6✔
40
async def export_codegen(
6✔
41
    targets: FilteredTargets,
42
    union_membership: UnionMembership,
43
    workspace: Workspace,
44
    dist_dir: DistDir,
45
    registered_target_types: RegisteredTargetTypes,
46
) -> ExportCodegen:
47
    # We run all possible code generators. Running codegen requires specifying the expected
48
    # output_type, so we must inspect what is possible to generate.
UNCOV
49
    all_generate_request_types = union_membership.get(GenerateSourcesRequest)
×
UNCOV
50
    inputs_to_outputs = [
×
51
        (req.input, req.output) for req in all_generate_request_types if req.exportable
52
    ]
UNCOV
53
    codegen_sources_fields_with_output = []
×
UNCOV
54
    for tgt in targets:
×
UNCOV
55
        if not tgt.has_field(SourcesField):
×
56
            continue
×
UNCOV
57
        sources = tgt[SourcesField]
×
UNCOV
58
        for input_type, output_type in inputs_to_outputs:
×
UNCOV
59
            if isinstance(sources, input_type):
×
UNCOV
60
                codegen_sources_fields_with_output.append((sources, output_type))
×
61

UNCOV
62
    if not codegen_sources_fields_with_output:
×
UNCOV
63
        codegen_targets = sorted(
×
64
            {
65
                tgt_type.alias
66
                for tgt_type in registered_target_types.types
67
                for input_source in {input_source for input_source, _ in inputs_to_outputs}
68
                if tgt_type.class_has_field(input_source, union_membership=union_membership)
69
            }
70
        )
UNCOV
71
        logger.warning(
×
72
            softwrap(
73
                f"""
74
                No codegen files/targets matched. All codegen target types:
75
                {", ".join(codegen_targets)}
76
                """
77
            )
78
        )
UNCOV
79
        return ExportCodegen(exit_code=0)
×
80

UNCOV
81
    all_hydrated_sources = await concurrently(
×
82
        hydrate_sources(
83
            HydrateSourcesRequest(
84
                sources,
85
                for_sources_types=(output_type,),
86
                enable_codegen=True,
87
            ),
88
            **implicitly(),
89
        )
90
        for sources, output_type in codegen_sources_fields_with_output
91
    )
92

UNCOV
93
    merged_digest = await merge_digests(
×
94
        MergeDigests(hydrated_sources.snapshot.digest for hydrated_sources in all_hydrated_sources)
95
    )
96

UNCOV
97
    dest = str(dist_dir.relpath / "codegen")
×
UNCOV
98
    logger.info(f"Writing generated files to {dest}")
×
UNCOV
99
    workspace.write_digest(merged_digest, path_prefix=dest)
×
UNCOV
100
    return ExportCodegen(exit_code=0)
×
101

102

103
def rules():
6✔
104
    return collect_rules()
6✔
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