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

pantsbuild / pants / 18791134616

24 Oct 2025 08:18PM UTC coverage: 75.519% (-4.8%) from 80.282%
18791134616

Pull #22794

github

web-flow
Merge 098c595a0 into 7971a20bf
Pull Request #22794: Use self-hosted MacOS Intel runner

65803 of 87134 relevant lines covered (75.52%)

3.07 hits per line

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

70.21
/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
10✔
5
from collections.abc import Iterator
10✔
6
from contextlib import contextmanager
10✔
7
from pathlib import Path
10✔
8

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

11

12
class BuildRoot(metaclass=SingletonMetaclass):
10✔
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"]
10✔
21

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

25
    def find_buildroot(self) -> str:
10✔
26
        buildroot = Path.cwd().resolve()
10✔
27
        while not any((buildroot / sentinel).is_file() for sentinel in self.sentinel_files):
10✔
28
            if buildroot != buildroot.parent:
×
29
                buildroot = buildroot.parent
×
30
            else:
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)
10✔
37

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

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

45
    @property
10✔
46
    def path(self) -> str:
10✔
47
        """Returns the build root for the current workspace."""
48
        if self._root_dir is None:
10✔
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)
10✔
52
            if override_buildroot:
10✔
53
                self._root_dir = override_buildroot
1✔
54
            else:
55
                self._root_dir = os.path.realpath(self.find_buildroot())
10✔
56
        return self._root_dir
10✔
57

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

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

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

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