diff --git a/misc/python/materialize/cli/lint-cargo.py b/misc/python/materialize/cli/lint-cargo.py index c4e2c8e55d0ea..aeab7cb96e632 100644 --- a/misc/python/materialize/cli/lint-cargo.py +++ b/misc/python/materialize/cli/lint-cargo.py @@ -146,6 +146,59 @@ def version_req(spec: object) -> str | None: return success +def check_fuzz_patches_mirror_root(workspace: Workspace) -> bool: + """Checks that the cargo-fuzz workspace (test/cargo-fuzz) carries the root + workspace's `[patch.crates-io]` entries verbatim. + + Cargo never fails over a patch mismatch. An entry that does not apply lands + in `[[patch.unused]]` with only a warning, and a missing entry passes with no + warning at all. Either way the fuzz targets silently build against the + crates.io release instead of the fork production uses, and the build breaks + whenever the fork carries API the published crate lacks.""" + + # Root patches for crates outside the fuzz crates' dependency graph. Cargo + # would warn that they are unused, so the fuzz workspace leaves them out. + OMITTED = {"duckdb", "postgres_array"} + + with open(MZ_ROOT / "Cargo.toml") as f: + root_patches = toml.load(f).get("patch", {}).get("crates-io", {}) + with open(MZ_ROOT / "test" / "cargo-fuzz" / "Cargo.toml") as f: + fuzz_patches = toml.load(f).get("patch", {}).get("crates-io", {}) + + success = True + for name, spec in sorted(fuzz_patches.items()): + if name not in root_patches: + print( + f"test/cargo-fuzz/Cargo.toml: {name} is patched here but not in " + f"the root Cargo.toml", + file=sys.stderr, + ) + success = False + elif spec != root_patches[name]: + print( + f"test/cargo-fuzz/Cargo.toml: {name} = {spec} must match the " + f"root Cargo.toml's {name} = {root_patches[name]}", + file=sys.stderr, + ) + success = False + for name in sorted(root_patches.keys() - fuzz_patches.keys() - OMITTED): + print( + f"test/cargo-fuzz/Cargo.toml: {name} is patched in the root " + f"Cargo.toml but not here", + file=sys.stderr, + ) + success = False + if not success: + print( + "\nhint: copy the entry from the root `[patch.crates-io]` verbatim, " + "or drop it here if the root no longer patches that crate. A root " + "entry that no fuzz crate depends on goes into `OMITTED` in " + "check_fuzz_patches_mirror_root instead.", + file=sys.stderr, + ) + return success + + def main() -> None: workspace = Workspace(MZ_ROOT) lints = [ @@ -153,6 +206,7 @@ def main() -> None: check_default_members, check_workspace_dependencies, check_fuzz_versions_mirror_root, + check_fuzz_patches_mirror_root, ] # Run every lint, then combine. `success and lint(...)` would short-circuit # and skip the remaining lints after the first failure, under-reporting. diff --git a/test/cargo-fuzz/Cargo.toml b/test/cargo-fuzz/Cargo.toml index d0f62d2ebded9..b4e5f7d560af1 100644 --- a/test/cargo-fuzz/Cargo.toml +++ b/test/cargo-fuzz/Cargo.toml @@ -10,12 +10,12 @@ # per-crate duplication. Each fuzz crate points here via # `package.workspace = "../../../test/cargo-fuzz"`. # -# `[patch.crates-io]` below is the SUBSET of the root `Cargo.toml`'s patches that -# the fuzz crates' dependency graph actually uses (root entries with no consumer -# here, currently `duckdb` and `postgres_array`, are omitted to avoid cargo's -# "patch was not used in the crate graph" warnings). Every entry that IS present -# must match the root's rev/version verbatim. If a fuzz crate gains a dependency -# that needs another patched crate, copy that entry from the root. +# `[patch.crates-io]` below mirrors the root `Cargo.toml`'s, minus the root +# entries that no fuzz crate depends on (they would only trigger cargo's "patch +# was not used in the crate graph" warning). `bin/lint-cargo` lists those +# omissions and enforces that every other root entry is present here verbatim. +# If a fuzz crate gains a dependency on an omitted crate, copy its entry from the +# root and remove it from that list. [workspace] resolver = "2" @@ -48,12 +48,13 @@ postgres-replication = { git = "https://github.com/MaterializeInc/rust-postgres" postgres-types = { git = "https://github.com/MaterializeInc/rust-postgres" } postgres-openssl = { git = "https://github.com/MaterializeInc/rust-postgres" } +# Upstream chrono-tz is unmaintained and stops at tzdata 2025b. The fork's +# `mz_changes` branch carries current IANA data only, no code changes. +chrono-tz = { git = "https://github.com/MaterializeInc/chrono-tz.git", rev = "5999cdd1b971694f834ec3467d11ef9147fc297c" } + # Waiting on https://github.com/MaterializeInc/serde-value/pull/35. serde-value = { git = "https://github.com/MaterializeInc/serde-value.git" } -# Waiting for resolution of https://github.com/launchdarkly/rust-server-sdk/issues/116 -launchdarkly-server-sdk = { git = "https://github.com/MaterializeInc/rust-server-sdk", rev = "3e0a0b98b09a2970f292577a07e1c9382b65b5da" } - # Waiting on https://github.com/edenhill/librdkafka/pull/4051. rdkafka = { git = "https://github.com/MaterializeInc/rust-rdkafka.git" } rdkafka-sys = { git = "https://github.com/MaterializeInc/rust-rdkafka.git" } @@ -69,7 +70,7 @@ tiberius = { git = "https://github.com/MaterializeInc/tiberius", rev="64ca594cc2 async-compression = { git = "https://github.com/MaterializeInc/async-compression.git", rev = "fe7411eb6104a02a89e2c3a76ab326dd6594214d" } # Custom iceberg features for mz -# All changes should go to the `mz_v0.9.0` branch. -iceberg = { git = "https://github.com/MaterializeInc/iceberg-rust.git", rev = "dedd9231ee88ee979b648e14792878b40e74c20a" } -iceberg-catalog-rest = { git = "https://github.com/MaterializeInc/iceberg-rust.git", rev = "dedd9231ee88ee979b648e14792878b40e74c20a" } -iceberg-storage-opendal = { git = "https://github.com/MaterializeInc/iceberg-rust.git", rev = "dedd9231ee88ee979b648e14792878b40e74c20a" } +# All changes should go to the `mz_v0.10.x` branch. +iceberg = { git = "https://github.com/MaterializeInc/iceberg-rust.git", rev = "9e252ad09e27950d2f3cbc7e2da0d1f5255731a0" } +iceberg-catalog-rest = { git = "https://github.com/MaterializeInc/iceberg-rust.git", rev = "9e252ad09e27950d2f3cbc7e2da0d1f5255731a0" } +iceberg-storage-opendal = { git = "https://github.com/MaterializeInc/iceberg-rust.git", rev = "9e252ad09e27950d2f3cbc7e2da0d1f5255731a0" }