From e627b08786cb24c966e8f4f4da92b34035dde9fe Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 17 Feb 2026 14:48:59 +0100 Subject: [PATCH] Add cargo.lock to Rust build hash (#19470) This is so that when we update dependencies etc we correctly ensure that the Rust library has been rebuilt. --- changelog.d/19470.misc | 1 + rust/build.rs | 14 ++++++++++++++ synapse/util/rust.py | 19 +++++++++++++------ 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 changelog.d/19470.misc diff --git a/changelog.d/19470.misc b/changelog.d/19470.misc new file mode 100644 index 0000000000..e253d89b17 --- /dev/null +++ b/changelog.d/19470.misc @@ -0,0 +1 @@ +Correctly refuse to start if the Rust workspace config has changed and the Rust library has not been rebuilt. diff --git a/rust/build.rs b/rust/build.rs index ef370e6b41..8755f3bfa3 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -29,6 +29,13 @@ fn main() -> Result<(), std::io::Error> { } } + // Manually add Cargo.toml's, Cargo.lock and build.rs to the hash, since changes to + // these files should also invalidate the built module. + paths.push("Cargo.toml".to_string()); + paths.push("../Cargo.lock".to_string()); + paths.push("../Cargo.toml".to_string()); + paths.push("build.rs".to_string()); + paths.sort(); let mut hasher = Blake2b512::new(); @@ -41,5 +48,12 @@ fn main() -> Result<(), std::io::Error> { let hex_digest = hex::encode(hasher.finalize()); println!("cargo:rustc-env=SYNAPSE_RUST_DIGEST={hex_digest}"); + // The default rules don't pick up trivial changes to the workspace config + // files, but we need to rebuild if those change to pick up the changed + // hashes. + println!("cargo::rerun-if-changed=."); + println!("cargo::rerun-if-changed=../Cargo.lock"); + println!("cargo::rerun-if-changed=../Cargo.toml"); + Ok(()) } diff --git a/synapse/util/rust.py b/synapse/util/rust.py index d1e1a259e4..a7c9e976ea 100644 --- a/synapse/util/rust.py +++ b/synapse/util/rust.py @@ -40,24 +40,24 @@ def check_rust_lib_up_to_date() -> None: return None # Get the hash of all Rust source files - rust_path = os.path.join(synapse_root, "rust", "src") + rust_path = os.path.join(synapse_root, "rust") if not os.path.exists(rust_path): return None - hash = _hash_rust_files_in_directory(rust_path) + hash = _hash_rust_files_in_directory(synapse_root) if hash != get_rust_file_digest(): raise Exception("Rust module outdated. Please rebuild using `poetry install`") -def _hash_rust_files_in_directory(directory: str) -> str: +def _hash_rust_files_in_directory(synapse_root: str) -> str: """Get the hash of all files in a directory (recursively)""" - directory = os.path.abspath(directory) + src_directory = os.path.abspath(os.path.join(synapse_root, "rust", "src")) paths = [] - dirs = [directory] + dirs = [src_directory] while dirs: dir = dirs.pop() with os.scandir(dir) as d: @@ -67,13 +67,20 @@ def _hash_rust_files_in_directory(directory: str) -> str: else: paths.append(entry.path) + # Manually add Cargo.toml's, Cargo.lock and build.rs to the hash, since + # changes to these files should also invalidate the built module. + paths.append(os.path.join(synapse_root, "rust", "Cargo.toml")) + paths.append(os.path.join(synapse_root, "rust", "build.rs")) + paths.append(os.path.join(synapse_root, "Cargo.lock")) + paths.append(os.path.join(synapse_root, "Cargo.toml")) + # We sort to make sure that we get a consistent and well-defined ordering. paths.sort() hasher = blake2b() for path in paths: - with open(os.path.join(directory, path), "rb") as f: + with open(path, "rb") as f: hasher.update(f.read()) return hasher.hexdigest()