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

pantsbuild / pants / 22740642519

05 Mar 2026 11:00PM UTC coverage: 52.677% (-40.3%) from 92.931%
22740642519

Pull #23157

github

web-flow
Merge 2aa18e6d4 into f0030f5e7
Pull Request #23157: [pants ng] Partition source files by config.

31678 of 60136 relevant lines covered (52.68%)

0.53 hits per line

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

98.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
1✔
5

6
import os
1✔
7

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

28

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

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

47

48
@rule
1✔
49
async def complete_environment_vars(
1✔
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:
1✔
63
        if env_tgt.val.has_field(DockerImageField):
1✔
64
            description_of_env_source = f"the Docker image {env_tgt.val[DockerImageField].value}"
1✔
65
        elif env_tgt.val.has_field(RemotePlatformField):
1✔
66
            description_of_env_source = "the remote execution environment"
1✔
67
        else:
68
            # Else, it's a local environment.
69
            return session_values[CompleteEnvironmentVars]
1✔
70
    else:
71
        if environments_subsystem.remote_execution_used_globally(global_options):
1✔
72
            description_of_env_source = "the remote execution environment"
1✔
73
        else:
74
            return session_values[CompleteEnvironmentVars]
1✔
75

76
    env_process_result = await execute_process_or_raise(
1✔
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 = {}
1✔
87
    for line in env_process_result.stdout.decode("utf-8").rstrip().split("\0"):
1✔
88
        if not line:
1✔
89
            continue
×
90
        k, v = line.split("=", maxsplit=1)
1✔
91
        result[k] = v
1✔
92
    return CompleteEnvironmentVars(result)
1✔
93

94

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

101

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