• 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

92.0
/src/python/pants/engine/internals/platform_rules.py
1
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
2✔
5

6
import os
2✔
7

8
from pants.core.environments.subsystems import EnvironmentsSubsystem
2✔
9
from pants.core.environments.target_types import (
2✔
10
    DockerImageField,
11
    DockerPlatformField,
12
    EnvironmentTarget,
13
    RemotePlatformField,
14
)
15
from pants.core.util_rules.env_vars import environment_vars_subset
2✔
16
from pants.engine.env_vars import (
2✔
17
    CompleteEnvironmentVars,
18
    EnvironmentVarsRequest,
19
    PathEnvironmentVariable,
20
)
21
from pants.engine.internals.session import SessionValues
2✔
22
from pants.engine.platform import Platform
2✔
23
from pants.engine.process import Process, execute_process_or_raise
2✔
24
from pants.engine.rules import collect_rules, implicitly, rule
2✔
25
from pants.option.global_options import GlobalOptions
2✔
26
from pants.util.logging import LogLevel
2✔
27

28

29
@rule
2✔
30
async def current_platform(
2✔
31
    env_tgt: EnvironmentTarget,
32
    global_options: GlobalOptions,
33
    environments_subsystem: EnvironmentsSubsystem,
34
) -> Platform:
35
    if environments_subsystem.remote_execution_used_globally(global_options):
2✔
36
        return Platform.linux_x86_64
2✔
37

38
    if env_tgt.val:
2✔
39
        if env_tgt.val.has_field(DockerPlatformField):
2✔
40
            return Platform(env_tgt.val[DockerPlatformField].normalized_value)
2✔
41
        if env_tgt.val.has_field(RemotePlatformField):
2✔
42
            remote_platform = env_tgt.val[RemotePlatformField].value
2✔
43
            if remote_platform:
2✔
44
                return Platform(remote_platform)
2✔
45
    return Platform.create_for_localhost()
2✔
46

47

48
@rule
2✔
49
async def complete_environment_vars(
2✔
50
    session_values: SessionValues,
51
    env_tgt: EnvironmentTarget,
52
    global_options: GlobalOptions,
53
    environments_subsystem: EnvironmentsSubsystem,
54
) -> CompleteEnvironmentVars:
55
    # If a local environment is used, we simply use SessionValues. Otherwise, we need to run `env`
56
    # and parse the output.
57
    #
58
    # Note that running `env` works for both Docker and Remote Execution because we intentionally
59
    # do not strip the environment from either runtime. It is reasonable to not strip because
60
    # every user will have the same consistent Docker image or Remote Execution environment, unlike
61
    # local environments.
62
    if env_tgt.val:
2✔
63
        if env_tgt.val.has_field(DockerImageField):
2✔
64
            description_of_env_source = f"the Docker image {env_tgt.val[DockerImageField].value}"
2✔
65
        elif env_tgt.val.has_field(RemotePlatformField):
2✔
66
            description_of_env_source = "the remote execution environment"
2✔
67
        else:
68
            # Else, it's a local environment.
69
            return session_values[CompleteEnvironmentVars]
2✔
70
    else:
71
        if environments_subsystem.remote_execution_used_globally(global_options):
2✔
72
            description_of_env_source = "the remote execution environment"
2✔
73
        else:
74
            return session_values[CompleteEnvironmentVars]
2✔
75

76
    env_process_result = await execute_process_or_raise(
2✔
77
        **implicitly(
78
            Process(
79
                ["env", "-0"],
80
                description=f"Extract environment variables from {description_of_env_source}",
81
                level=LogLevel.DEBUG,
82
                cache_scope=env_tgt.executable_search_path_cache_scope(),
83
            )
84
        )
85
    )
86
    result = {}
2✔
87
    for line in env_process_result.stdout.decode("utf-8").rstrip().split("\0"):
2✔
88
        if not line:
2✔
89
            continue
×
90
        k, v = line.split("=", maxsplit=1)
2✔
91
        result[k] = v
2✔
92
    return CompleteEnvironmentVars(result)
2✔
93

94

95
@rule
2✔
96
async def environment_path_variable() -> PathEnvironmentVariable:
2✔
97
    env = await environment_vars_subset(EnvironmentVarsRequest(("PATH",)), **implicitly())
×
98
    path = env.get("PATH", None)
×
99
    return PathEnvironmentVariable(path.split(os.pathsep) if path else ())
×
100

101

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