From c14fe37c34be643b283293f4b72f3c4b4259af3e Mon Sep 17 00:00:00 2001 From: Luke Valenta Date: Mon, 13 Jul 2026 15:43:16 -0400 Subject: [PATCH] Switch unused-dependency check from cargo-machete to cargo-shear cargo-machete only inspects each crate's own dependency tables, so it misses unused entries in the workspace root and has substring-based false negatives. cargo-shear works from the resolved dependency graph and catches both, including unused `[workspace.dependencies]`. Swap the tool in CI, AGENTS.md, and the ct_worker README, then clean up the dead deps shear surfaced. Also fixes a latent TOML bug where integration_tests' homepage, repository, and description keys sat inside the cargo-machete metadata table instead of [package]. --- .github/workflows/rust.yml | 2 +- AGENTS.md | 4 ++-- Cargo.lock | 16 ---------------- Cargo.toml | 8 ++++++++ crates/bootstrap_mtc_worker/Cargo.toml | 10 ---------- crates/ct_worker/Cargo.toml | 10 ---------- crates/ct_worker/README.md | 2 +- crates/integration_tests/Cargo.toml | 21 ++++++++------------- crates/sct_validator/Cargo.toml | 1 - crates/tlog_tiles_wasm/Cargo.toml | 5 ----- crates/witness_worker/Cargo.toml | 3 --- 11 files changed, 20 insertions(+), 62 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5fbe872c..9e632116 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -22,7 +22,7 @@ jobs: run: cargo clippy --workspace --all-targets -- -Dwarnings -Dclippy::pedantic continue-on-error: true - name: Unused dependencies (advisory) - run: cargo install cargo-machete --quiet && cargo machete + run: cargo install cargo-shear --quiet && cargo shear continue-on-error: true - name: Formatting (advisory) run: cargo fmt --all --check diff --git a/AGENTS.md b/AGENTS.md index 1532fda2..61ba480d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -86,7 +86,7 @@ npx wrangler -e=${ENV} tail cargo clippy --workspace --all-targets -- -Dwarnings -Dclippy::pedantic # lint everything (including fuzz) cargo test # unit tests; uses default-members, so integration_tests and fuzz are skipped cargo fmt --all --check # advisory in CI, easy to fix -cargo machete # unused-dependency check; advisory in CI, easy to fix +cargo shear # unused-dependency check (incl. workspace deps); advisory in CI, easy to fix ``` `integration_tests` is excluded from the default test run because it requires a live `wrangler dev` instance (invoke it explicitly once wrangler is running; see the integration test workflow below). `fuzz` is excluded because it is the cargo-fuzz harness crate, run via `cargo fuzz run ` on a nightly toolchain. Both are still linted. @@ -97,7 +97,7 @@ If any step fails, fix the issue in the commit it belongs to (use `git commit -- ✅ **Always:** Before pushing, re-read the commit message and verify it reflects the current state of the code — counts, type names, and described behaviors can drift as code evolves. -✅ **Always:** Add new shared dependencies to `[workspace.dependencies]` in root `Cargo.toml`. Do not add a dependency to a crate's `Cargo.toml` before you actually use it — `cargo machete` will flag speculative additions. +✅ **Always:** Add new shared dependencies to `[workspace.dependencies]` in root `Cargo.toml`. Do not add a dependency to a crate's `Cargo.toml` (or the root `[workspace.dependencies]` table) before you actually use it — `cargo shear` will flag speculative additions, including unused entries in `[workspace.dependencies]` that no member inherits. Suppress unavoidable false positives (e.g. `getrandom`, which is a feature-only edge) via `[workspace.metadata.cargo-shear] ignored = [...]`. ✅ **Always:** Keep Workers-specific concerns (Durable Object storage formats, KV dedup cache, Worker runtime dependencies) out of the specification-level crates (`tlog_tiles`, `static_ct_api`, `bootstrap_mtc_api`, `signed_note`). Those crates implement public specs and are published to crates.io; they should not gain types, traits, or dependencies whose only consumers are Cloudflare Workers. Wire-format types used only by the sequencer and frontend belong in `generic_log_worker` or the concrete worker crate. ⚠️ **Requires Approval:** Publishing crates to crates.io (`tlog_tiles`, `static_ct_api`, `signed_note`, `signed_note`) — worker crates have `publish = false` diff --git a/Cargo.lock b/Cargo.lock index 1eaace90..c18386a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,7 +237,6 @@ name = "bootstrap_mtc_worker" version = "0.2.0" dependencies = [ "axum", - "base64", "base64ct", "bootstrap_mtc_api", "bootstrap_mtc_worker_config", @@ -245,15 +244,11 @@ dependencies = [ "csv", "der", "ed25519-dalek", - "futures-executor", "generic_log_worker", "getrandom 0.4.2", - "itertools 0.14.0", "jsonschema", "log", "p256", - "parking_lot", - "rand", "sct_validator", "serde", "serde_json", @@ -608,21 +603,16 @@ name = "ct_worker" version = "0.2.0" dependencies = [ "axum", - "base64", "base64ct", "chrono", "csv", "ct_worker_config", "ed25519-dalek", - "futures-executor", "generic_log_worker", "getrandom 0.4.2", - "itertools 0.14.0", "jsonschema", "log", "p256", - "parking_lot", - "rand", "serde", "serde_json", "serde_with", @@ -1532,16 +1522,12 @@ version = "0.2.0" dependencies = [ "anyhow", "base64", - "bootstrap_mtc_api", - "byteorder", "chrono", "const-oid", "crypto-common", "der", "ed25519-dalek", "hex", - "length_prefixed", - "log", "ml-dsa", "p256", "pkcs8", @@ -1562,7 +1548,6 @@ dependencies = [ "tlog_witness", "tokio", "x509-cert", - "x509_util", ] [[package]] @@ -2572,7 +2557,6 @@ dependencies = [ "serde", "serde_json", "sha2", - "signature", "spki", "thiserror 2.0.17", "x509-cert", diff --git a/Cargo.toml b/Cargo.toml index 7a588837..0c70d363 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,6 +67,14 @@ homepage = "https://github.com/cloudflare/azul" repository = "https://github.com/cloudflare/azul" description = "An implementation of the Static Certificate Transparency API on Cloudflare Workers" +[workspace.metadata.cargo-shear] +# getrandom is never imported directly. It is declared by the wasm crates +# solely so its `wasm_js` feature activates the correct backend for all +# transitive dependents; cargo-shear can't see this feature-only edge. A +# workspace-level ignore covers every member plus the workspace dependency +# itself. +ignored = ["getrandom"] + [profile.release] opt-level = "s" # Recommendations from https://developers.cloudflare.com/workers/languages/rust/#binary-size-wasm-opt: diff --git a/crates/bootstrap_mtc_worker/Cargo.toml b/crates/bootstrap_mtc_worker/Cargo.toml index 1ed0c23b..9e0e2465 100644 --- a/crates/bootstrap_mtc_worker/Cargo.toml +++ b/crates/bootstrap_mtc_worker/Cargo.toml @@ -36,15 +36,8 @@ url.workspace = true x509-cert.workspace = true der.workspace = true -[dev-dependencies] -rand.workspace = true -itertools.workspace = true -parking_lot.workspace = true -futures-executor.workspace = true - [dependencies] axum.workspace = true -base64.workspace = true base64ct.workspace = true chrono.workspace = true config = { path = "./config", package = "bootstrap_mtc_worker_config" } @@ -73,6 +66,3 @@ sct_validator.workspace = true unexpected_cfgs = { level = "warn", check-cfg = [ 'cfg(wasm_bindgen_unstable_test_coverage)', ] } - -[package.metadata.cargo-machete] -ignored = ["getrandom"] diff --git a/crates/ct_worker/Cargo.toml b/crates/ct_worker/Cargo.toml index 0a387b29..7cc4f494 100644 --- a/crates/ct_worker/Cargo.toml +++ b/crates/ct_worker/Cargo.toml @@ -31,15 +31,8 @@ serde.workspace = true url.workspace = true x509-cert.workspace = true -[dev-dependencies] -rand.workspace = true -itertools.workspace = true -parking_lot.workspace = true -futures-executor.workspace = true - [dependencies] axum.workspace = true -base64.workspace = true config = { path = "./config", package = "ct_worker_config" } generic_log_worker.workspace = true ed25519-dalek.workspace = true @@ -66,6 +59,3 @@ csv.workspace = true unexpected_cfgs = { level = "warn", check-cfg = [ 'cfg(wasm_bindgen_unstable_test_coverage)', ] } - -[package.metadata.cargo-machete] -ignored = ["getrandom"] diff --git a/crates/ct_worker/README.md b/crates/ct_worker/README.md index 4254a07a..e9e6e45d 100644 --- a/crates/ct_worker/README.md +++ b/crates/ct_worker/README.md @@ -200,7 +200,7 @@ profiling and debugging. Use `worker-build --dev` as the build command in `wrang ## Check for unnecessary dependencies - cargo machete + cargo shear ## Acknowledgements diff --git a/crates/integration_tests/Cargo.toml b/crates/integration_tests/Cargo.toml index 4e7e1ddd..f9cdc78b 100644 --- a/crates/integration_tests/Cargo.toml +++ b/crates/integration_tests/Cargo.toml @@ -8,10 +8,6 @@ version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true - -[package.metadata.cargo-machete] -# These deps are used in tests/ (not src/), which cargo-machete doesn't scan. -ignored = ["bootstrap_mtc_api", "byteorder", "length_prefixed", "log", "tlog_witness", "x509_util"] homepage.workspace = true repository.workspace = true description = "Integration tests for ct_worker (static CT API) and bootstrap_mtc_worker (MTC API)" @@ -25,29 +21,21 @@ name = "integration_tests" base64.workspace = true p256.workspace = true ed25519-dalek.workspace = true -ml-dsa.workspace = true -pkcs8.workspace = true sha2.workspace = true signed_note.workspace = true static_ct_api.workspace = true -bootstrap_mtc_api.workspace = true tlog_checkpoint.workspace = true tlog_core.workspace = true -tlog_cosignature.workspace = true tlog_entry.workspace = true tlog_tiles.workspace = true -tlog_witness.workspace = true sct_validator.workspace = true serde.workspace = true serde_json.workspace = true serde_with = { workspace = true, features = ["base64"] } anyhow = { workspace = true } -length_prefixed.workspace = true -byteorder = { workspace = true } chrono.workspace = true crypto-common.workspace = true hex.workspace = true -log.workspace = true rand.workspace = true x509-cert = { workspace = true, features = ["builder"] } der.workspace = true @@ -56,4 +44,11 @@ const-oid.workspace = true # Async HTTP client (native, not wasm) reqwest = { workspace = true } tokio = { version = "1", features = ["full"] } -x509_util.workspace = true + +[dev-dependencies] +# Used only by the integration test binaries in tests/, not by the shared +# support library in src/. +ml-dsa.workspace = true +pkcs8.workspace = true +tlog_cosignature.workspace = true +tlog_witness.workspace = true diff --git a/crates/sct_validator/Cargo.toml b/crates/sct_validator/Cargo.toml index d3b794bb..2476f1e5 100644 --- a/crates/sct_validator/Cargo.toml +++ b/crates/sct_validator/Cargo.toml @@ -21,7 +21,6 @@ p256.workspace = true serde.workspace = true serde_json.workspace = true sha2.workspace = true -signature.workspace = true spki.workspace = true thiserror.workspace = true x509-cert = { workspace = true, features = ["sct"] } diff --git a/crates/tlog_tiles_wasm/Cargo.toml b/crates/tlog_tiles_wasm/Cargo.toml index 018227e6..f3eb632e 100644 --- a/crates/tlog_tiles_wasm/Cargo.toml +++ b/crates/tlog_tiles_wasm/Cargo.toml @@ -9,11 +9,6 @@ publish = false [package.metadata.wasm-pack.profile.release] wasm-opt = false -[package.metadata.cargo-machete] -# getrandom is not called directly but must be present so its wasm_js feature -# activates the correct WASM backend for all transitive dependents. -ignored = ["getrandom"] - [lib] crate-type = ["cdylib"] diff --git a/crates/witness_worker/Cargo.toml b/crates/witness_worker/Cargo.toml index a2a36f6d..aeaec65c 100644 --- a/crates/witness_worker/Cargo.toml +++ b/crates/witness_worker/Cargo.toml @@ -57,6 +57,3 @@ p256.workspace = true unexpected_cfgs = { level = "warn", check-cfg = [ 'cfg(wasm_bindgen_unstable_test_coverage)', ] } - -[package.metadata.cargo-machete] -ignored = ["getrandom"]