Skip to content
Snippets Groups Projects
Unverified Commit d427403c authored by Erik Johnston's avatar Erik Johnston Committed by GitHub
Browse files

Fix check for outdated Rust library (#17861)

This failed when install with poetry, so let's properly try and detect
what's going on.
parent e9f9625d
No related branches found
No related tags found
No related merge requests found
Fix detection when the built Rust library was outdated when using source installations.
...@@ -19,9 +19,12 @@ ...@@ -19,9 +19,12 @@
# #
# #
import json
import os import os
import sys import urllib.parse
from hashlib import blake2b from hashlib import blake2b
from importlib.metadata import Distribution, PackageNotFoundError
from typing import Optional
import synapse import synapse
from synapse.synapse_rust import get_rust_file_digest from synapse.synapse_rust import get_rust_file_digest
...@@ -32,22 +35,17 @@ def check_rust_lib_up_to_date() -> None: ...@@ -32,22 +35,17 @@ def check_rust_lib_up_to_date() -> None:
be rebuilt. be rebuilt.
""" """
if not _dist_is_editable(): # Get the location of the editable install.
return synapse_root = get_synapse_source_directory()
if synapse_root is None:
synapse_dir = os.path.dirname(synapse.__file__) return None
synapse_root = os.path.abspath(os.path.join(synapse_dir, ".."))
# Double check we've not gone into site-packages...
if os.path.basename(synapse_root) == "site-packages":
return
# ... and it looks like the root of a python project.
if not os.path.exists("pyproject.toml"):
return
# Get the hash of all Rust source files # Get the hash of all Rust source files
hash = _hash_rust_files_in_directory(os.path.join(synapse_root, "rust", "src")) rust_path = os.path.join(synapse_root, "rust", "src")
if not os.path.exists(rust_path):
return None
hash = _hash_rust_files_in_directory(rust_path)
if hash != get_rust_file_digest(): if hash != get_rust_file_digest():
raise Exception("Rust module outdated. Please rebuild using `poetry install`") raise Exception("Rust module outdated. Please rebuild using `poetry install`")
...@@ -82,10 +80,55 @@ def _hash_rust_files_in_directory(directory: str) -> str: ...@@ -82,10 +80,55 @@ def _hash_rust_files_in_directory(directory: str) -> str:
return hasher.hexdigest() return hasher.hexdigest()
def _dist_is_editable() -> bool: def get_synapse_source_directory() -> Optional[str]:
"""Is distribution an editable install?""" """Try and find the source directory of synapse for editable installs (like
for path_item in sys.path: those used in development).
egg_link = os.path.join(path_item, "matrix-synapse.egg-link")
if os.path.isfile(egg_link): Returns None if not an editable install (or otherwise can't find the source
return True directory).
return False """
# Try and find the installed matrix-synapse package.
try:
package = Distribution.from_name("matrix-synapse")
except PackageNotFoundError:
# The package is not found, so it's not installed and so must be being
# pulled out from a local directory (usually the current one).
synapse_dir = os.path.dirname(synapse.__file__)
synapse_root = os.path.abspath(os.path.join(synapse_dir, ".."))
# Double check we've not gone into site-packages...
if os.path.basename(synapse_root) == "site-packages":
return None
# ... and it looks like the root of a python project.
if not os.path.exists("pyproject.toml"):
return None
return synapse_root
# Read the `direct_url.json` metadata for the package. This won't exist for
# packages installed via a repository/etc.
# c.f. https://packaging.python.org/en/latest/specifications/direct-url/
direct_url_json = package.read_text("direct_url.json")
if direct_url_json is None:
return None
# c.f. https://packaging.python.org/en/latest/specifications/direct-url/ for
# the format
direct_url_dict: dict = json.loads(direct_url_json)
# `url` must exist as a key, and point to where we fetched the repo from.
project_url = urllib.parse.urlparse(direct_url_dict["url"])
# If its not a local file then we must have built the rust libs either a)
# after we downloaded the package, or b) we built the download wheel.
if project_url.scheme != "file":
return None
# And finally if its not an editable install then the files can't have
# changed since we installed the package.
if not direct_url_dict.get("dir_info", {}).get("editable", False):
return None
return project_url.path
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment