diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c15b701..3fe1f3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -260,6 +260,28 @@ jobs: - name: Check REUSE compliance run: reuse lint + machete: + name: Unused Dependencies + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Install cargo-machete + uses: taiki-e/install-action@41049aa56687c35e0afa74eed4f09cec4f9afabf # v2.85.2 + with: + tool: cargo-machete + + # The examples are the reference dependency set for a consumer, so + # a leftover there teaches the wrong thing — and would hide the + # facade regressing back to naming runtime crates in expansions. + # Dependencies reached only through emitted derives are declared + # in each manifest's cargo-machete metadata. + - name: Check for unused dependencies + run: cargo machete + workflows: name: Workflow Audit runs-on: ubuntu-latest @@ -511,6 +533,7 @@ jobs: - semver - reuse - workflows + - machete - test - examples - postgres diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9e527b0..096e78f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,6 +86,7 @@ run drops it once it is half an hour old. | Examples | `cargo check --manifest-path examples//Cargo.toml --all-targets` | | Feature combinations | `cargo hack check --workspace --feature-powerset --depth 2 --no-dev-deps` | | Dependency policy | `cargo deny check` | +| Unused dependencies | `cargo machete` | | Workflow audit | `zizmor --offline .github/workflows/` — actions must be pinned to a commit SHA | `CI Success` is the terminal job: it reports every other job's outcome as diff --git a/examples/basic/Cargo.toml b/examples/basic/Cargo.toml index ef73d4c..3b68ce9 100644 --- a/examples/basic/Cargo.toml +++ b/examples/basic/Cargo.toml @@ -8,6 +8,12 @@ edition = "2024" publish = false description = "Basic CRUD example with entity-derive and Axum" +# Reached only through derives the macro emits — `serde::Serialize` +# on the DTOs, `utoipa::ToSchema` on the OpenAPI ones — which the +# unused-dependency heuristic cannot see. +[package.metadata.cargo-machete] +ignored = ["serde"] + [features] default = ["postgres", "api"] postgres = [] @@ -20,7 +26,6 @@ entity-derive = { path = "../../crates/entity-derive", features = [ "postgres", "api", ] } -masterror = { version = "0.27", features = ["axum", "openapi"] } axum = "0.8" tokio = { version = "1", features = ["full"] } sqlx = { version = "0.9", features = [ @@ -32,9 +37,6 @@ sqlx = { version = "0.9", features = [ uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } -serde_json = "1" -async-trait = "0.1" -tower-http = { version = "0.7", features = ["trace"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } utoipa = { version = "5", features = ["axum_extras", "chrono", "uuid"] } diff --git a/examples/commands/Cargo.toml b/examples/commands/Cargo.toml index 862839d..816f0c5 100644 --- a/examples/commands/Cargo.toml +++ b/examples/commands/Cargo.toml @@ -8,6 +8,12 @@ edition = "2024" publish = false description = "CQRS commands example with entity-derive" +# Reached only through derives the macro emits — `serde::Serialize` +# on the DTOs, `utoipa::ToSchema` on the OpenAPI ones — which the +# unused-dependency heuristic cannot see. +[package.metadata.cargo-machete] +ignored = ["utoipa"] + [features] default = ["postgres", "api"] postgres = [] @@ -20,7 +26,6 @@ entity-derive = { path = "../../crates/entity-derive", features = [ "postgres", "api", ] } -entity-core = { path = "../../crates/entity-core", features = ["postgres"] } axum = "0.8" tokio = { version = "1", features = ["full"] } sqlx = { version = "0.9", features = [ @@ -32,8 +37,6 @@ sqlx = { version = "0.9", features = [ uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } -serde_json = "1" -async-trait = "0.1" utoipa = { version = "5", features = ["chrono", "uuid"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/examples/events/Cargo.toml b/examples/events/Cargo.toml index f9ba7ac..4ea97bf 100644 --- a/examples/events/Cargo.toml +++ b/examples/events/Cargo.toml @@ -8,6 +8,12 @@ edition = "2024" publish = false description = "Lifecycle events example with entity-derive" +# Reached only through derives the macro emits — `serde::Serialize` +# on the DTOs, `utoipa::ToSchema` on the OpenAPI ones — which the +# unused-dependency heuristic cannot see. +[package.metadata.cargo-machete] +ignored = ["utoipa"] + [features] default = ["postgres", "api"] postgres = [] @@ -20,7 +26,6 @@ entity-derive = { path = "../../crates/entity-derive", features = [ "postgres", "api", ] } -entity-core = { path = "../../crates/entity-core", features = ["postgres"] } axum = "0.8" tokio = { version = "1", features = ["full", "sync"] } sqlx = { version = "0.9", features = [ @@ -32,8 +37,6 @@ sqlx = { version = "0.9", features = [ uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } -serde_json = "1" -async-trait = "0.1" utoipa = { version = "5", features = ["chrono", "uuid"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/examples/filtering/Cargo.toml b/examples/filtering/Cargo.toml index 6d2aea4..cfb5e9d 100644 --- a/examples/filtering/Cargo.toml +++ b/examples/filtering/Cargo.toml @@ -8,6 +8,12 @@ edition = "2024" publish = false description = "Type-safe filtering example with entity-derive" +# Reached only through derives the macro emits — `serde::Serialize` +# on the DTOs, `utoipa::ToSchema` on the OpenAPI ones — which the +# unused-dependency heuristic cannot see. +[package.metadata.cargo-machete] +ignored = ["utoipa"] + [features] default = ["postgres", "api"] postgres = [] @@ -23,8 +29,6 @@ sqlx = { version = "0.9", features = ["runtime-tokio", "postgres", "uuid", "chro uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } -serde_json = "1" -async-trait = "0.1" utoipa = { version = "5", features = ["chrono", "uuid"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/examples/full-app/Cargo.toml b/examples/full-app/Cargo.toml index 07c942f..b2f9e2e 100644 --- a/examples/full-app/Cargo.toml +++ b/examples/full-app/Cargo.toml @@ -27,10 +27,8 @@ entity-core = { path = "../../crates/entity-core", features = [ "postgres", "streams", ] } -masterror = { version = "0.27", features = ["axum", "openapi"] } axum = "0.8" tokio = { version = "1", features = ["full", "sync"] } -tokio-stream = "0.1" sqlx = { version = "0.9", features = [ "runtime-tokio", "postgres", @@ -41,9 +39,7 @@ uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -async-trait = "0.1" futures = "0.3" -tower-http = { version = "0.7", features = ["trace", "cors"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } utoipa = { version = "5", features = ["axum_extras", "chrono", "uuid"] } diff --git a/examples/hooks/Cargo.toml b/examples/hooks/Cargo.toml index d8fac95..2b8b618 100644 --- a/examples/hooks/Cargo.toml +++ b/examples/hooks/Cargo.toml @@ -8,6 +8,12 @@ edition = "2024" publish = false description = "Lifecycle hooks example with entity-derive" +# Reached only through derives the macro emits — `serde::Serialize` +# on the DTOs, `utoipa::ToSchema` on the OpenAPI ones — which the +# unused-dependency heuristic cannot see. +[package.metadata.cargo-machete] +ignored = ["serde", "utoipa"] + [features] default = ["postgres", "api"] postgres = [] @@ -31,7 +37,6 @@ sqlx = { version = "0.9", features = [ uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } -serde_json = "1" async-trait = "0.1" utoipa = { version = "5", features = ["chrono", "uuid"] } tracing = "0.1" diff --git a/examples/relations/Cargo.toml b/examples/relations/Cargo.toml index 645033f..68c0503 100644 --- a/examples/relations/Cargo.toml +++ b/examples/relations/Cargo.toml @@ -8,6 +8,12 @@ edition = "2024" publish = false description = "Entity relations example with belongs_to and has_many" +# Reached only through derives the macro emits — `serde::Serialize` +# on the DTOs, `utoipa::ToSchema` on the OpenAPI ones — which the +# unused-dependency heuristic cannot see. +[package.metadata.cargo-machete] +ignored = ["serde", "utoipa"] + [features] default = ["postgres", "api"] postgres = [] @@ -24,7 +30,6 @@ uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -async-trait = "0.1" utoipa = { version = "5", features = ["chrono", "uuid"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/examples/soft-delete/Cargo.toml b/examples/soft-delete/Cargo.toml index c70e679..4470704 100644 --- a/examples/soft-delete/Cargo.toml +++ b/examples/soft-delete/Cargo.toml @@ -8,6 +8,12 @@ edition = "2024" publish = false description = "Soft delete example with entity-derive" +# Reached only through derives the macro emits — `serde::Serialize` +# on the DTOs, `utoipa::ToSchema` on the OpenAPI ones — which the +# unused-dependency heuristic cannot see. +[package.metadata.cargo-machete] +ignored = ["serde", "utoipa"] + [features] default = ["postgres", "api"] postgres = [] @@ -23,8 +29,6 @@ sqlx = { version = "0.9", features = ["runtime-tokio", "postgres", "uuid", "chro uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } -serde_json = "1" -async-trait = "0.1" utoipa = { version = "5", features = ["chrono", "uuid"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/examples/streams/Cargo.toml b/examples/streams/Cargo.toml index 1b59203..aa25759 100644 --- a/examples/streams/Cargo.toml +++ b/examples/streams/Cargo.toml @@ -8,6 +8,12 @@ edition = "2024" publish = false description = "Real-time streams example with entity-derive" +# Reached only through derives the macro emits — `serde::Serialize` +# on the DTOs, `utoipa::ToSchema` on the OpenAPI ones — which the +# unused-dependency heuristic cannot see. +[package.metadata.cargo-machete] +ignored = ["utoipa"] + [features] default = ["postgres", "api"] postgres = [] @@ -21,13 +27,8 @@ entity-derive = { path = "../../crates/entity-derive", features = [ "api", "streams", ] } -entity-core = { path = "../../crates/entity-core", features = [ - "postgres", - "streams", -] } axum = "0.8" tokio = { version = "1", features = ["full", "sync"] } -tokio-stream = "0.1" sqlx = { version = "0.9", features = [ "runtime-tokio", "postgres", @@ -38,7 +39,6 @@ uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -async-trait = "0.1" utoipa = { version = "5", features = ["chrono", "uuid"] } futures = "0.3" tracing = "0.1" diff --git a/examples/transactions/Cargo.toml b/examples/transactions/Cargo.toml index 3d0e5e7..f3b3138 100644 --- a/examples/transactions/Cargo.toml +++ b/examples/transactions/Cargo.toml @@ -8,6 +8,12 @@ edition = "2024" publish = false description = "Multi-entity transactions example with entity-derive" +# Reached only through derives the macro emits — `serde::Serialize` +# on the DTOs, `utoipa::ToSchema` on the OpenAPI ones — which the +# unused-dependency heuristic cannot see. +[package.metadata.cargo-machete] +ignored = ["utoipa"] + [features] default = ["postgres", "api"] postgres = [] @@ -28,8 +34,6 @@ sqlx = { version = "0.9", features = ["runtime-tokio", "postgres", "uuid", "chro uuid = { version = "1", features = ["v4", "v7", "serde"] } chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } -serde_json = "1" -async-trait = "0.1" utoipa = { version = "5", features = ["chrono", "uuid"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] }