• 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

52.94
/src/python/pants/engine/desktop.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
1✔
5
from collections.abc import Iterable
1✔
6
from dataclasses import dataclass
1✔
7
from pathlib import PurePath
1✔
8

9
from pants.core.environments.rules import ChosenLocalEnvironmentName, EnvironmentName
1✔
10
from pants.core.util_rules.system_binaries import BinaryPathRequest, find_binary
1✔
11
from pants.engine.internals.platform_rules import complete_environment_vars, current_platform
1✔
12
from pants.engine.process import InteractiveProcess
1✔
13
from pants.engine.rules import collect_rules, concurrently, implicitly, rule
1✔
14

15
logger = logging.getLogger(__name__)
1✔
16

17

18
@dataclass(frozen=True)
1✔
19
class OpenFilesRequest:
1✔
20
    files: tuple[PurePath, ...]
21
    error_if_open_not_found: bool
22

23
    def __init__(self, files: Iterable[PurePath], *, error_if_open_not_found: bool = True) -> None:
1✔
24
        object.__setattr__(self, "files", tuple(files))
×
25
        object.__setattr__(self, "error_if_open_not_found", error_if_open_not_found)
×
26

27

28
@dataclass(frozen=True)
1✔
29
class OpenFiles:
1✔
30
    processes: tuple[InteractiveProcess, ...]
31

32

33
@rule
1✔
34
async def find_open_program(
1✔
35
    request: OpenFilesRequest,
36
    local_environment_name: ChosenLocalEnvironmentName,
37
) -> OpenFiles:
38
    plat, complete_env = await concurrently(
×
39
        current_platform(**implicitly({local_environment_name.val: EnvironmentName})),
40
        complete_environment_vars(**implicitly(local_environment_name.val)),
41
    )
42
    open_program_name = "open" if plat.is_macos else "xdg-open"
×
43
    open_program_paths = await find_binary(
×
44
        **implicitly(
45
            {
46
                BinaryPathRequest(
47
                    binary_name=open_program_name, search_path=("/bin", "/usr/bin")
48
                ): BinaryPathRequest,
49
                local_environment_name.val: EnvironmentName,
50
            }
51
        )
52
    )
53
    if not open_program_paths.first_path:
×
54
        error = (
×
55
            f"Could not find the program '{open_program_name}' on `/bin` or `/usr/bin`, so cannot "
56
            f"open the files {sorted(request.files)}."
57
        )
58
        if request.error_if_open_not_found:
×
59
            raise OSError(error)
×
60
        logger.error(error)
×
61
        return OpenFiles(())
×
62

63
    if plat.is_macos:
×
64
        processes = [
×
65
            InteractiveProcess(
66
                argv=(open_program_paths.first_path.path, *(str(f) for f in request.files)),
67
                run_in_workspace=True,
68
                restartable=True,
69
            )
70
        ]
71
    else:
72
        processes = [
×
73
            InteractiveProcess(
74
                argv=(open_program_paths.first_path.path, str(f)),
75
                run_in_workspace=True,
76
                # The xdg-open binary needs many environment variables to work properly. In addition
77
                # to the various XDG_* environment variables, DISPLAY and other X11 variables are
78
                # required. Instead of attempting to track all of these we just export the full user
79
                # environment since this is not a cached process.
80
                env=complete_env,
81
                restartable=True,
82
            )
83
            for f in request.files
84
        ]
85

86
    return OpenFiles(tuple(processes))
×
87

88

89
def rules():
1✔
UNCOV
90
    return collect_rules()
×
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