mirror of
https://github.com/element-hq/synapse.git
synced 2024-11-24 02:25:45 +03:00
Fix check for outdated Rust library (#17861)
This failed when install with poetry, so let's properly try and detect what's going on.
This commit is contained in:
parent
e9f9625d6b
commit
d427403c67
2 changed files with 66 additions and 22 deletions
1
changelog.d/17861.bugfix
Normal file
1
changelog.d/17861.bugfix
Normal file
|
@ -0,0 +1 @@
|
|||
Fix detection when the built Rust library was outdated when using source installations.
|
|
@ -19,9 +19,12 @@
|
|||
#
|
||||
#
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.parse
|
||||
from hashlib import blake2b
|
||||
from importlib.metadata import Distribution, PackageNotFoundError
|
||||
from typing import Optional
|
||||
|
||||
import synapse
|
||||
from synapse.synapse_rust import get_rust_file_digest
|
||||
|
@ -32,22 +35,17 @@ def check_rust_lib_up_to_date() -> None:
|
|||
be rebuilt.
|
||||
"""
|
||||
|
||||
if not _dist_is_editable():
|
||||
return
|
||||
|
||||
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
|
||||
|
||||
# ... and it looks like the root of a python project.
|
||||
if not os.path.exists("pyproject.toml"):
|
||||
return
|
||||
# Get the location of the editable install.
|
||||
synapse_root = get_synapse_source_directory()
|
||||
if synapse_root is None:
|
||||
return None
|
||||
|
||||
# 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():
|
||||
raise Exception("Rust module outdated. Please rebuild using `poetry install`")
|
||||
|
@ -82,10 +80,55 @@ def _hash_rust_files_in_directory(directory: str) -> str:
|
|||
return hasher.hexdigest()
|
||||
|
||||
|
||||
def _dist_is_editable() -> bool:
|
||||
"""Is distribution an editable install?"""
|
||||
for path_item in sys.path:
|
||||
egg_link = os.path.join(path_item, "matrix-synapse.egg-link")
|
||||
if os.path.isfile(egg_link):
|
||||
return True
|
||||
return False
|
||||
def get_synapse_source_directory() -> Optional[str]:
|
||||
"""Try and find the source directory of synapse for editable installs (like
|
||||
those used in development).
|
||||
|
||||
Returns None if not an editable install (or otherwise can't find the source
|
||||
directory).
|
||||
"""
|
||||
|
||||
# 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
|
||||
|
|
Loading…
Reference in a new issue