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

pantsbuild / pants / 19015773527

02 Nov 2025 05:33PM UTC coverage: 17.872% (-62.4%) from 80.3%
19015773527

Pull #22816

github

web-flow
Merge a12d75757 into 6c024e162
Pull Request #22816: Update Pants internal Python to 3.14

4 of 5 new or added lines in 3 files covered. (80.0%)

28452 existing lines in 683 files now uncovered.

9831 of 55007 relevant lines covered (17.87%)

0.18 hits per line

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

0.0
/src/python/pants/backend/adhoc/adhoc_tool.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
×
4

UNCOV
5
import logging
×
UNCOV
6
import os
×
7

UNCOV
8
from pants.backend.adhoc.target_types import (
×
9
    AdhocToolArgumentsField,
10
    AdhocToolCacheScopeField,
11
    AdhocToolExecutionDependenciesField,
12
    AdhocToolExtraEnvVarsField,
13
    AdhocToolLogOutputField,
14
    AdhocToolNamedCachesField,
15
    AdhocToolOutputDirectoriesField,
16
    AdhocToolOutputFilesField,
17
    AdhocToolOutputRootDirField,
18
    AdhocToolOutputsMatchMode,
19
    AdhocToolPathEnvModifyModeField,
20
    AdhocToolRunnableDependenciesField,
21
    AdhocToolRunnableField,
22
    AdhocToolSourcesField,
23
    AdhocToolStderrFilenameField,
24
    AdhocToolStdoutFilenameField,
25
    AdhocToolWorkdirField,
26
    AdhocToolWorkspaceInvalidationSourcesField,
27
)
UNCOV
28
from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior
×
UNCOV
29
from pants.core.environments.rules import (
×
30
    EnvironmentNameRequest,
31
    get_target_for_environment_name,
32
    resolve_environment_name,
33
)
UNCOV
34
from pants.core.target_types import FileSourceField
×
UNCOV
35
from pants.core.util_rules.adhoc_process_support import (
×
36
    AdhocProcessRequest,
37
    ToolRunnerRequest,
38
    convert_fallible_adhoc_process_result,
39
    create_tool_runner,
40
    prepare_env_vars,
41
)
UNCOV
42
from pants.core.util_rules.adhoc_process_support import rules as adhoc_process_support_rules
×
UNCOV
43
from pants.engine.environment import EnvironmentName
×
UNCOV
44
from pants.engine.fs import PathGlobs
×
UNCOV
45
from pants.engine.intrinsics import digest_to_snapshot
×
UNCOV
46
from pants.engine.rules import collect_rules, implicitly, rule
×
UNCOV
47
from pants.engine.target import GeneratedSources, GenerateSourcesRequest
×
UNCOV
48
from pants.engine.unions import UnionRule
×
UNCOV
49
from pants.util.frozendict import FrozenDict
×
UNCOV
50
from pants.util.logging import LogLevel
×
51

UNCOV
52
logger = logging.getLogger(__name__)
×
53

54

UNCOV
55
class GenerateFilesFromAdhocToolRequest(GenerateSourcesRequest):
×
UNCOV
56
    input = AdhocToolSourcesField
×
UNCOV
57
    output = FileSourceField
×
58

59

UNCOV
60
@rule(desc="Running run_in_sandbox target", level=LogLevel.DEBUG)
×
UNCOV
61
async def run_in_sandbox_request(
×
62
    request: GenerateFilesFromAdhocToolRequest,
63
) -> GeneratedSources:
64
    target = request.protocol_target
×
65
    description = f"the `{target.alias}` at {target.address}"
×
66

67
    environment_name = await resolve_environment_name(
×
68
        EnvironmentNameRequest.from_target(target), **implicitly()
69
    )
70
    environment_target = await get_target_for_environment_name(environment_name, **implicitly())
×
71

72
    runnable_address_str = target[AdhocToolRunnableField].value
×
73
    if not runnable_address_str:
×
74
        raise Exception(f"Must supply a value for `runnable` for {description}.")
×
75

76
    tool_runner = await create_tool_runner(
×
77
        ToolRunnerRequest(
78
            runnable_address_str=runnable_address_str,
79
            args=target.get(AdhocToolArgumentsField).value or (),
80
            execution_dependencies=target.get(AdhocToolExecutionDependenciesField).value or (),
81
            runnable_dependencies=target.get(AdhocToolRunnableDependenciesField).value or (),
82
            target=request.protocol_target,
83
            named_caches=FrozenDict(target.get(AdhocToolNamedCachesField).value or {}),
84
        )
85
    )
86

87
    working_directory = target[AdhocToolWorkdirField].value or ""
×
88
    root_output_directory = target[AdhocToolOutputRootDirField].value or ""
×
89

90
    output_files = target.get(AdhocToolOutputFilesField).value or ()
×
91
    output_directories = target.get(AdhocToolOutputDirectoriesField).value or ()
×
92

93
    cache_scope = environment_target.default_cache_scope
×
94
    maybe_override_cache_scope = target.get(AdhocToolCacheScopeField).enum_value
×
95
    if maybe_override_cache_scope is not None:
×
96
        cache_scope = maybe_override_cache_scope
×
97

98
    workspace_invalidation_globs: PathGlobs | None = None
×
99
    workspace_invalidation_sources = (
×
100
        target.get(AdhocToolWorkspaceInvalidationSourcesField).value or ()
101
    )
102
    if workspace_invalidation_sources:
×
103
        spec_path = target.address.spec_path
×
104
        workspace_invalidation_globs = PathGlobs(
×
105
            globs=(os.path.join(spec_path, glob) for glob in workspace_invalidation_sources),
106
            glob_match_error_behavior=GlobMatchErrorBehavior.error,
107
            description_of_origin=f"`{AdhocToolWorkspaceInvalidationSourcesField.alias}` for `adhoc_tool` target at `{target.address}`",
108
        )
109

110
    env_vars = await prepare_env_vars(
×
111
        tool_runner.extra_env,
112
        target.get(AdhocToolExtraEnvVarsField).value or (),
113
        extra_paths=tool_runner.extra_paths,
114
        path_env_modify_mode=target.get(AdhocToolPathEnvModifyModeField).enum_value,
115
        description_of_origin=f"`{AdhocToolExtraEnvVarsField.alias}` for `adhoc_tool` target at `{target.address}`",
116
    )
117

118
    outputs_match_mode = target.get(AdhocToolOutputsMatchMode).enum_value
×
119

120
    process_request = AdhocProcessRequest(
×
121
        description=description,
122
        address=target.address,
123
        working_directory=working_directory,
124
        root_output_directory=root_output_directory,
125
        argv=tool_runner.args,
126
        timeout=None,
127
        input_digest=tool_runner.digest,
128
        immutable_input_digests=FrozenDict.frozen(tool_runner.immutable_input_digests),
129
        append_only_caches=FrozenDict(tool_runner.append_only_caches),
130
        output_files=output_files,
131
        output_directories=output_directories,
132
        env_vars=env_vars,
133
        log_on_process_errors=None,
134
        log_output=target[AdhocToolLogOutputField].value,
135
        capture_stderr_file=target[AdhocToolStderrFilenameField].value,
136
        capture_stdout_file=target[AdhocToolStdoutFilenameField].value,
137
        workspace_invalidation_globs=workspace_invalidation_globs,
138
        cache_scope=cache_scope,
139
        use_working_directory_as_base_for_output_captures=environment_target.use_working_directory_as_base_for_output_captures,
140
        outputs_match_error_behavior=outputs_match_mode.glob_match_error_behavior,
141
        outputs_match_conjunction=outputs_match_mode.glob_expansion_conjunction,
142
    )
143

144
    adhoc_result = await convert_fallible_adhoc_process_result(
×
145
        **implicitly(
146
            {
147
                environment_name: EnvironmentName,
148
                process_request: AdhocProcessRequest,
149
            }
150
        )
151
    )
152

153
    output = await digest_to_snapshot(adhoc_result.adjusted_digest)
×
154
    return GeneratedSources(output)
×
155

156

UNCOV
157
def rules():
×
UNCOV
158
    return [
×
159
        *collect_rules(),
160
        *adhoc_process_support_rules(),
161
        UnionRule(GenerateSourcesRequest, GenerateFilesFromAdhocToolRequest),
162
    ]
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

© 2025 Coveralls, Inc