• 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

61.7
/src/python/pants/base/build_root.py
1
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
import os
1✔
5
from collections.abc import Iterator
1✔
6
from contextlib import contextmanager
1✔
7
from pathlib import Path
1✔
8

9
from pants.util.meta import SingletonMetaclass
1✔
10

11

12
class BuildRoot(metaclass=SingletonMetaclass):
1✔
13
    """Represents the global workspace build root.
14

15
    By default, a Pants workspace is defined by a root directory where one of multiple sentinel
16
    files resides, such as `pants.toml` or `BUILD_ROOT`. This path can also be manipulated through
17
    this interface for re-location of the build root in tests.
18
    """
19

20
    sentinel_files = ["pants.toml", "pants", "BUILDROOT", "BUILD_ROOT"]
1✔
21

22
    class NotFoundError(Exception):
1✔
23
        """Raised when unable to find the current workspace build root."""
24

25
    def find_buildroot(self) -> str:
1✔
26
        buildroot = Path.cwd().resolve()
1✔
27
        while not any((buildroot / sentinel).is_file() for sentinel in self.sentinel_files):
1✔
UNCOV
28
            if buildroot != buildroot.parent:
×
UNCOV
29
                buildroot = buildroot.parent
×
30
            else:
UNCOV
31
                raise self.NotFoundError(
×
32
                    "No build root detected. Pants detects the build root by looking for at least one file "
33
                    f"from {self.sentinel_files} in the cwd and its ancestors. If you have none of these "
34
                    f"files, you can create an empty file in your build root."
35
                )
36
        return str(buildroot)
1✔
37

38
    def __init__(self) -> None:
1✔
39
        self._root_dir: str | None = None
1✔
40

41
    @property
1✔
42
    def pathlib_path(self) -> Path:
1✔
43
        return Path(self.path)
×
44

45
    @property
1✔
46
    def path(self) -> str:
1✔
47
        """Returns the build root for the current workspace."""
48
        if self._root_dir is None:
1✔
49
            # Do not remove/change this env var without coordinating with `pantsbuild/scie-pants` as
50
            # it is being used when bootstrapping Pants.
51
            override_buildroot = os.environ.get("PANTS_BUILDROOT_OVERRIDE", None)
1✔
52
            if override_buildroot:
1✔
UNCOV
53
                self._root_dir = override_buildroot
×
54
            else:
55
                self._root_dir = os.path.realpath(self.find_buildroot())
1✔
56
        return self._root_dir
1✔
57

58
    @path.setter
1✔
59
    def path(self, root_dir: str) -> None:
1✔
60
        """Manually establishes the build root for the current workspace."""
UNCOV
61
        path = os.path.realpath(root_dir)
×
UNCOV
62
        if not os.path.exists(path):
×
63
            raise ValueError(f"Build root does not exist: {root_dir}")
×
UNCOV
64
        self._root_dir = path
×
65

66
    def reset(self) -> None:
1✔
67
        """Clears the last calculated build root for the current workspace."""
UNCOV
68
        self._root_dir = None
×
69

70
    def __str__(self) -> str:
1✔
71
        return f"BuildRoot({self._root_dir})"
×
72

73
    @contextmanager
1✔
74
    def temporary(self, path: str) -> Iterator[None]:
1✔
75
        """Establishes a temporary build root, restoring the prior build root on exit."""
UNCOV
76
        if path is None:
×
77
            raise ValueError("Can only temporarily establish a build root given a path.")
×
UNCOV
78
        prior = self._root_dir
×
UNCOV
79
        self._root_dir = path
×
UNCOV
80
        try:
×
UNCOV
81
            yield
×
82
        finally:
UNCOV
83
            self._root_dir = prior
×
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