mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1759084: Print reason for site being out-of-date r=ahal
There are cases in CI where sites are being considered out-of-date, despite the situation being unexpected - for example, the "site out-of-date even though already activated" issue described in this patch's associated bug. Return a `reason` string from `_is_venv_up_to_date()`, and print it in cases where a virtualenv being out-of-date is erroneous. Differential Revision: https://phabricator.services.mozilla.com/D140855
This commit is contained in:
parent
338a1fa71c
commit
0a5464aef2
@ -49,6 +49,12 @@ class InstallPipRequirementsException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class SiteUpToDateResult:
|
||||
def __init__(self, is_up_to_date, reason=None):
|
||||
self.is_up_to_date = is_up_to_date
|
||||
self.reason = reason
|
||||
|
||||
|
||||
class SitePackagesSource(enum.Enum):
|
||||
NONE = "none"
|
||||
SYSTEM = "system"
|
||||
@ -338,7 +344,7 @@ class MachSiteManager:
|
||||
|
||||
def _up_to_date(self):
|
||||
if self._site_packages_source == SitePackagesSource.NONE:
|
||||
return True
|
||||
return SiteUpToDateResult(True)
|
||||
elif self._site_packages_source == SitePackagesSource.SYSTEM:
|
||||
pthfile_lines = [
|
||||
*self._requirements.pths_as_absolute(self._topsrcdir),
|
||||
@ -347,7 +353,7 @@ class MachSiteManager:
|
||||
_assert_pip_check(
|
||||
self._topsrcdir, pthfile_lines, "mach", self._requirements
|
||||
)
|
||||
return True
|
||||
return SiteUpToDateResult(True)
|
||||
elif self._site_packages_source == SitePackagesSource.VENV:
|
||||
environment = self._virtualenv()
|
||||
return _is_venv_up_to_date(
|
||||
@ -359,15 +365,15 @@ class MachSiteManager:
|
||||
)
|
||||
|
||||
def ensure(self, *, force=False):
|
||||
up_to_date = self._up_to_date()
|
||||
if force or not up_to_date:
|
||||
result = self._up_to_date()
|
||||
if force or not result.is_up_to_date:
|
||||
if Path(sys.prefix) == Path(self._metadata.prefix):
|
||||
# If the Mach virtualenv is already activated, then the changes caused
|
||||
# by rebuilding the virtualenv won't take effect until the next time
|
||||
# Mach is used, which can lead to confusing one-off errors.
|
||||
# Instead, request that the user resolve the out-of-date situation,
|
||||
# *then* come back and run the intended command.
|
||||
raise VirtualenvOutOfDateException()
|
||||
raise VirtualenvOutOfDateException(result.reason)
|
||||
self._build()
|
||||
|
||||
def attempt_populate_optional_packages(self):
|
||||
@ -560,9 +566,11 @@ class CommandSiteManager:
|
||||
If using a virtualenv Python binary directly, it's useful to call this function
|
||||
first to ensure that the virtualenv doesn't have obsolete references or packages.
|
||||
"""
|
||||
if not self._up_to_date():
|
||||
result = self._up_to_date()
|
||||
if not result.is_up_to_date:
|
||||
active_site = MozSiteMetadata.from_runtime()
|
||||
if active_site.site_name == self._site_name:
|
||||
print(result.reason, file=sys.stderr)
|
||||
raise Exception(
|
||||
f'The "{self._site_name}" site is out-of-date, even though it has '
|
||||
f"already been activated. Was it modified while this Mach process "
|
||||
@ -1201,8 +1209,12 @@ def _is_venv_up_to_date(
|
||||
expected_metadata,
|
||||
):
|
||||
if not os.path.exists(target_venv.prefix):
|
||||
return False
|
||||
return SiteUpToDateResult(False, f'"{target_venv.prefix}" does not exist')
|
||||
|
||||
# Modifications to any of the following files mean the virtualenv should be
|
||||
# rebuilt:
|
||||
# * The `virtualenv` package
|
||||
# * Any of our requirements manifest files
|
||||
virtualenv_package = os.path.join(
|
||||
topsrcdir,
|
||||
"third_party",
|
||||
@ -1212,41 +1224,50 @@ def _is_venv_up_to_date(
|
||||
"version.py",
|
||||
)
|
||||
deps = [virtualenv_package] + requirements.requirements_paths
|
||||
|
||||
# Modifications to any of the following files mean the virtualenv should be
|
||||
# rebuilt:
|
||||
# * This file
|
||||
# * The `virtualenv` package
|
||||
# * Any of our requirements manifest files
|
||||
metadata_mtime = os.path.getmtime(
|
||||
os.path.join(target_venv.prefix, METADATA_FILENAME)
|
||||
)
|
||||
dep_mtime = max(os.path.getmtime(p) for p in deps)
|
||||
if dep_mtime > metadata_mtime:
|
||||
return False
|
||||
for dep_file in deps:
|
||||
if os.path.getmtime(dep_file) > metadata_mtime:
|
||||
return SiteUpToDateResult(
|
||||
False, f'"{dep_file}" has changed since the virtualenv was created'
|
||||
)
|
||||
|
||||
try:
|
||||
existing_metadata = MozSiteMetadata.from_path(target_venv.prefix)
|
||||
except MozSiteMetadataOutOfDateError:
|
||||
except MozSiteMetadataOutOfDateError as e:
|
||||
# The metadata is missing required fields, so must be out-of-date.
|
||||
return False
|
||||
return SiteUpToDateResult(False, str(e))
|
||||
|
||||
if existing_metadata != expected_metadata:
|
||||
# The metadata doesn't exist or some fields have different values.
|
||||
return False
|
||||
return SiteUpToDateResult(
|
||||
False,
|
||||
f"The existing metadata on-disk ({vars(existing_metadata)}) does not match "
|
||||
f"the expected metadata ({vars(expected_metadata)}",
|
||||
)
|
||||
|
||||
platlib_site_packages_dir = target_venv.resolve_sysconfig_packages_path("platlib")
|
||||
pthfile_path = os.path.join(platlib_site_packages_dir, PTH_FILENAME)
|
||||
try:
|
||||
with open(os.path.join(platlib_site_packages_dir, PTH_FILENAME)) as file:
|
||||
with open(pthfile_path) as file:
|
||||
current_pthfile_contents = file.read().strip()
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
return SiteUpToDateResult(False, f'No pthfile found at "{pthfile_path}"')
|
||||
|
||||
expected_pthfile_contents = "\n".join(expected_pthfile_lines)
|
||||
if current_pthfile_contents != expected_pthfile_contents:
|
||||
return False
|
||||
return SiteUpToDateResult(
|
||||
False,
|
||||
f'The pthfile at "{pthfile_path}" does not match the expected value.\n'
|
||||
f"# --- on-disk pthfile: ---\n"
|
||||
f"{current_pthfile_contents}\n"
|
||||
f"# --- expected pthfile contents ---\n"
|
||||
f"{expected_pthfile_contents}\n"
|
||||
f"# ---",
|
||||
)
|
||||
|
||||
return True
|
||||
return SiteUpToDateResult(True)
|
||||
|
||||
|
||||
def activate_virtualenv(virtualenv: PythonVirtualenv):
|
||||
|
Loading…
Reference in New Issue
Block a user