1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import functools
import os
from typing import Callable, Optional
from mach.requirements import MachEnvRequirements, UnexpectedFlexibleRequirementException
from mach.site import (
PIP_NETWORK_INSTALL_RESTRICTED_VIRTUALENVS,
CommandSiteManager,
MozSiteMetadata,
SitePackagesSource,
_mach_virtualenv_root,
)
class SiteNotFoundException(Exception):
def __init__(self, site_name, manifest_paths):
self.site_name = site_name
self.manifest_paths = manifest_paths
self.args = (site_name, manifest_paths)
@functools.lru_cache(maxsize=None)
def find_manifest(topsrcdir, site_name):
manifest_paths = (
os.path.join(topsrcdir, "comm", "python", "sites", f"{site_name}.txt"),
os.path.join(topsrcdir, "python", "sites", f"{site_name}.txt"),
)
for check_path in manifest_paths:
if os.path.exists(check_path):
return check_path
raise SiteNotFoundException(site_name, manifest_paths)
@functools.lru_cache(maxsize=None)
def resolve_requirements(topsrcdir, site_name):
try:
manifest_path = find_manifest(topsrcdir, site_name)
except SiteNotFoundException as e:
raise Exception(
f'The current command is using the "{e.site_name}" '
"site. However, that site is missing its associated "
f"requirements definition file in one of the supported "
f"paths: {e.manifest_paths}."
)
is_thunderbird = True
try:
return MachEnvRequirements.from_requirements_definition(
topsrcdir,
is_thunderbird,
site_name not in PIP_NETWORK_INSTALL_RESTRICTED_VIRTUALENVS,
manifest_path,
)
except UnexpectedFlexibleRequirementException as e:
raise Exception(
f'The "{site_name}" site does not have all pypi packages pinned '
f'in the format "package==version" (found "{e.raw_requirement}").\n'
f"Only the {PIP_NETWORK_INSTALL_RESTRICTED_VIRTUALENVS} sites are "
"allowed to have unpinned packages."
)
class MutlhCommandSiteManager(CommandSiteManager):
@classmethod
def from_environment(
cls,
topsrcdir: str,
get_state_dir: Callable[[], Optional[str]],
site_name: str,
command_virtualenvs_dir: str,
):
"""
Args:
topsrcdir: The path to the Firefox repo
get_state_dir: A function that resolves the path to the checkout-scoped
state_dir, generally ~/.mozbuild/srcdirs/<checkout-based-dir>/
site_name: The name of this site, such as "build"
command_virtualenvs_dir: The location under which this site's virtualenv
should be created
"""
active_metadata = MozSiteMetadata.from_runtime()
assert (
active_metadata
), "A Mach-managed site must be active before doing work with command sites"
mach_site_packages_source = active_metadata.mach_site_packages_source
pip_restricted_site = site_name in PIP_NETWORK_INSTALL_RESTRICTED_VIRTUALENVS
if not pip_restricted_site and mach_site_packages_source == SitePackagesSource.SYSTEM:
# Sites that aren't pip-network-install-restricted are likely going to be
# incompatible with the system. Besides, this use case shouldn't exist, since
# using the system packages is supposed to only be needed to lower risk of
# important processes like building Firefox.
raise Exception(
'Cannot use MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE="system" for any '
f"sites other than {PIP_NETWORK_INSTALL_RESTRICTED_VIRTUALENVS}. The "
f'current attempted site is "{site_name}".'
)
mach_virtualenv_root = (
_mach_virtualenv_root(get_state_dir())
if mach_site_packages_source == SitePackagesSource.VENV
else None
)
populate_virtualenv = (
mach_site_packages_source == SitePackagesSource.VENV or not pip_restricted_site
)
return cls(
topsrcdir,
mach_virtualenv_root,
os.path.join(command_virtualenvs_dir, site_name),
site_name,
active_metadata,
populate_virtualenv,
resolve_requirements(topsrcdir, site_name),
)
|