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

pantsbuild / pants / 19381742489

15 Nov 2025 12:52AM UTC coverage: 49.706% (-30.6%) from 80.29%
19381742489

Pull #22890

github

web-flow
Merge d961abf79 into 42e1ebd41
Pull Request #22890: Updated all python subsystem constraints to 3.14

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

14659 existing lines in 485 files now uncovered.

31583 of 63540 relevant lines covered (49.71%)

0.79 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
            runnable_address_field_alias=AdhocToolRunnableField.alias,
84
            named_caches=FrozenDict(target.get(AdhocToolNamedCachesField).value or {}),
85
        )
86
    )
87

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

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

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

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

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

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

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

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

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

157

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