From cfbf41feeed5eee44f621928118dde9cdecfdbca Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 26 Jun 2026 08:15:52 +0300 Subject: [PATCH 01/15] Add reexports for gears deps generation to gears macro Signed-off-by: Mauro Lacy --- libs/toolkit-macros/src/lib.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/libs/toolkit-macros/src/lib.rs b/libs/toolkit-macros/src/lib.rs index 2171dc118..38f1512fa 100644 --- a/libs/toolkit-macros/src/lib.rs +++ b/libs/toolkit-macros/src/lib.rs @@ -768,6 +768,23 @@ pub fn gear(attr: TokenStream, item: TokenStream) -> TokenStream { } }; + // Generate re-exports for gear dependencies so their `inventory::submit!` + // registrations survive linking when this gear is pulled in transitively. + let dep_reexports: Vec<_> = deps_owned + .iter() + .map(|dep| { + let crate_ident = Ident::new(&dep.replace('-', "_"), Span::call_site()); + let alias_ident = Ident::new( + &format!("_gear_dep_{}", dep.replace('-', "_")), + Span::call_site(), + ); + quote! { + #[doc(hidden)] + pub use #crate_ident as #alias_ident; + } + }) + .collect(); + // Final expansion: let expanded = quote! { #input @@ -775,6 +792,9 @@ pub fn gear(attr: TokenStream, item: TokenStream) -> TokenStream { // Compile-time capability assertions (better errors if trait impls are missing) #(#cap_asserts)* + // Re-export gear dependencies to force-link their inventory registrations + #(#dep_reexports)* + // Registrator that targets the *builder*, not the final registry #[doc(hidden)] fn #registrator_name(b: &mut ::toolkit::registry::RegistryBuilder) { From bbb03d4a8f8abcc3c1dcc7c94527992ff604fc39 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 26 Jun 2026 08:17:06 +0300 Subject: [PATCH 02/15] Add system gears decls to Cargo.toml Signed-off-by: Mauro Lacy --- Cargo.toml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index d1295ad45..d2903ebb0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -279,6 +279,14 @@ cf-gears-system-sdk-directory = { version = "0.1.37", path = "libs/system-sdks/s # System gears types-registry = { package = "cf-gears-types-registry", version = "0.1.23", path = "gears/system/types-registry/types-registry" } +authn-resolver = { package = "cf-gears-authn-resolver", version = "0.2.17", path = "gears/system/authn-resolver/authn-resolver" } +authz-resolver = { package = "cf-gears-authz-resolver", version = "0.1.24", path = "gears/system/authz-resolver/authz-resolver" } +tenant-resolver = { package = "cf-gears-tenant-resolver", version = "0.1.22", path = "gears/system/tenant-resolver/tenant-resolver" } +resource-group = { package = "cf-gears-resource-group", version = "0.1.4", path = "gears/system/resource-group/resource-group" } +credstore = { package = "cf-gears-credstore", version = "0.1.23", path = "gears/credstore/credstore" } +oagw = { package = "cf-gears-oagw", version = "0.2.26", path = "gears/system/oagw/oagw" } +account-management = { package = "cf-gears-account-management", version = "0.1.3", path = "gears/system/account-management/account-management" } +usage-collector = { package = "cf-gears-usage-collector", version = "0.1.0", path = "gears/system/usage-collector/usage-collector" } cf-gears-cluster-sdk = { version = "0.1.0", path = "gears/system/cluster/cluster-sdk" } cf-gears-cluster-conformance = { version = "0.1.0", path = "gears/system/cluster/cluster-conformance" } From f86aae8fb7311d5ebb526e0eacb0b2aefcb905c8 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 26 Jun 2026 08:17:53 +0300 Subject: [PATCH 03/15] Add full crates for deps exporting Signed-off-by: Mauro Lacy --- .../calculator-gateway/calculator-gateway/Cargo.toml | 1 + examples/toolkit/users-info/users-info/Cargo.toml | 1 + gears/credstore/credstore/Cargo.toml | 1 + gears/credstore/plugins/static-credstore-plugin/Cargo.toml | 1 + gears/mini-chat/mini-chat/Cargo.toml | 4 ++++ gears/simple-user-settings/simple-user-settings/Cargo.toml | 1 + gears/system/account-management/account-management/Cargo.toml | 4 ++++ .../account-management/plugins/static-idp-plugin/Cargo.toml | 1 + gears/system/api-gateway/Cargo.toml | 2 ++ gears/system/authn-resolver/authn-resolver/Cargo.toml | 1 + .../authn-resolver/plugins/oidc-authn-plugin/Cargo.toml | 2 ++ .../authn-resolver/plugins/static-authn-plugin/Cargo.toml | 1 + gears/system/authz-resolver/authz-resolver/Cargo.toml | 1 + .../authz-resolver/plugins/static-authz-plugin/Cargo.toml | 1 + .../system/authz-resolver/plugins/tr-authz-plugin/Cargo.toml | 2 ++ gears/system/oagw/oagw/Cargo.toml | 4 ++++ gears/system/resource-group/resource-group/Cargo.toml | 2 ++ gears/system/tenant-resolver/plugins/rg-tr-plugin/Cargo.toml | 2 ++ .../plugins/single-tenant-tr-plugin/Cargo.toml | 1 + .../tenant-resolver/plugins/static-tr-plugin/Cargo.toml | 1 + gears/system/tenant-resolver/tenant-resolver/Cargo.toml | 1 + .../plugins/noop-usage-collector-plugin/Cargo.toml | 1 + gears/system/usage-collector/usage-collector/Cargo.toml | 2 ++ 23 files changed, 38 insertions(+) diff --git a/examples/oop-gears/calculator-gateway/calculator-gateway/Cargo.toml b/examples/oop-gears/calculator-gateway/calculator-gateway/Cargo.toml index 923d6ed9f..4491f44c8 100644 --- a/examples/oop-gears/calculator-gateway/calculator-gateway/Cargo.toml +++ b/examples/oop-gears/calculator-gateway/calculator-gateway/Cargo.toml @@ -10,6 +10,7 @@ description = "Calculator gateway module - example in-process REST service" [dependencies] # External SDKs (dependencies on other modules) calculator-sdk = { path = "../../calculator/calculator-sdk" } +calculator = { path = "../../calculator/calculator" } # ToolKit toolkit = { workspace = true } diff --git a/examples/toolkit/users-info/users-info/Cargo.toml b/examples/toolkit/users-info/users-info/Cargo.toml index 837c7e18f..30a05f4dd 100644 --- a/examples/toolkit/users-info/users-info/Cargo.toml +++ b/examples/toolkit/users-info/users-info/Cargo.toml @@ -20,6 +20,7 @@ users-info-sdk = { path = "../users-info-sdk", features = ["odata"] } # AuthZ resolver for authorization (PEP flow) authz-resolver-sdk = { package = "cf-gears-authz-resolver-sdk", path = "../../../../gears/system/authz-resolver/authz-resolver-sdk" } +authz-resolver = { workspace = true } # Core dependencies anyhow = { workspace = true } diff --git a/gears/credstore/credstore/Cargo.toml b/gears/credstore/credstore/Cargo.toml index daab6ea78..a804e2c04 100644 --- a/gears/credstore/credstore/Cargo.toml +++ b/gears/credstore/credstore/Cargo.toml @@ -23,6 +23,7 @@ workspace = true toolkit-canonical-errors = { workspace = true } credstore-sdk = { workspace = true } types-registry-sdk = { workspace = true } +types-registry = { workspace = true } anyhow = { workspace = true } async-trait = { workspace = true } diff --git a/gears/credstore/plugins/static-credstore-plugin/Cargo.toml b/gears/credstore/plugins/static-credstore-plugin/Cargo.toml index f2cbb4a6a..d5f4a7a23 100644 --- a/gears/credstore/plugins/static-credstore-plugin/Cargo.toml +++ b/gears/credstore/plugins/static-credstore-plugin/Cargo.toml @@ -19,6 +19,7 @@ workspace = true # Local dependencies credstore-sdk = { package = "cf-gears-credstore-sdk", version = "0.1.26", path = "../../credstore-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../../system/types-registry/types-registry-sdk" } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/mini-chat/mini-chat/Cargo.toml b/gears/mini-chat/mini-chat/Cargo.toml index 00a3cde64..3e3e18c4d 100644 --- a/gears/mini-chat/mini-chat/Cargo.toml +++ b/gears/mini-chat/mini-chat/Cargo.toml @@ -37,6 +37,10 @@ oagw-sdk = { workspace = true } # Types registry for plugin discovery types-registry-sdk = { workspace = true } +types-registry = { workspace = true } +authn-resolver = { workspace = true } +authz-resolver = { workspace = true } +oagw = { workspace = true } # Core dependencies anyhow = { workspace = true } diff --git a/gears/simple-user-settings/simple-user-settings/Cargo.toml b/gears/simple-user-settings/simple-user-settings/Cargo.toml index 47bf46f51..d884a206a 100644 --- a/gears/simple-user-settings/simple-user-settings/Cargo.toml +++ b/gears/simple-user-settings/simple-user-settings/Cargo.toml @@ -22,6 +22,7 @@ simple-user-settings-sdk = { package = "cf-gears-simple-user-settings-sdk", vers # AuthZ resolver for authorization (PEP flow) authz-resolver-sdk = { package = "cf-gears-authz-resolver-sdk", path = "../../../gears/system/authz-resolver/authz-resolver-sdk" } +authz-resolver = { workspace = true } anyhow = { workspace = true } async-trait = { workspace = true } diff --git a/gears/system/account-management/account-management/Cargo.toml b/gears/system/account-management/account-management/Cargo.toml index 67a6029cd..662496693 100644 --- a/gears/system/account-management/account-management/Cargo.toml +++ b/gears/system/account-management/account-management/Cargo.toml @@ -43,8 +43,11 @@ axum = { workspace = true, features = ["macros"] } http = { workspace = true } utoipa = { workspace = true, features = ["time"] } resource-group-sdk = { workspace = true } +resource-group = { workspace = true } tenant-resolver-sdk = { workspace = true } +tenant-resolver = { workspace = true } types-registry-sdk = { workspace = true } +types-registry = { workspace = true } gts = { workspace = true } uuid = { workspace = true, features = ["v4", "serde"] } @@ -76,6 +79,7 @@ tokio-util = { workspace = true } anyhow = { workspace = true } authz-resolver-sdk = { workspace = true } +authz-resolver = { workspace = true } [features] # Gates the Postgres-backed real-DB integration tests. Disabled by diff --git a/gears/system/account-management/plugins/static-idp-plugin/Cargo.toml b/gears/system/account-management/plugins/static-idp-plugin/Cargo.toml index b12b6af18..257ce731e 100644 --- a/gears/system/account-management/plugins/static-idp-plugin/Cargo.toml +++ b/gears/system/account-management/plugins/static-idp-plugin/Cargo.toml @@ -22,6 +22,7 @@ toolkit-canonical-errors = { workspace = true } # Local dependencies account-management-sdk = { package = "cf-gears-account-management-sdk", version = "0.2.0", path = "../../account-management-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/api-gateway/Cargo.toml b/gears/system/api-gateway/Cargo.toml index 31c761e34..a4d216c1e 100644 --- a/gears/system/api-gateway/Cargo.toml +++ b/gears/system/api-gateway/Cargo.toml @@ -25,6 +25,8 @@ toolkit-security = { workspace = true } toolkit-canonical-errors = { workspace = true, features = ["axum"] } authn-resolver-sdk = { package = "cf-gears-authn-resolver-sdk", version = "0.3.18", path = "../authn-resolver/authn-resolver-sdk" } toolkit-gts = { workspace = true } +grpc_hub = { workspace = true } +authn-resolver = { workspace = true } toolkit-macros = { workspace = true } inventory = { workspace = true } anyhow = { workspace = true } diff --git a/gears/system/authn-resolver/authn-resolver/Cargo.toml b/gears/system/authn-resolver/authn-resolver/Cargo.toml index 0f0e0d106..339625bf0 100644 --- a/gears/system/authn-resolver/authn-resolver/Cargo.toml +++ b/gears/system/authn-resolver/authn-resolver/Cargo.toml @@ -23,6 +23,7 @@ toolkit-canonical-errors = { workspace = true } # Local dependencies authn-resolver-sdk = { package = "cf-gears-authn-resolver-sdk", version = "0.3.18", path = "../authn-resolver-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/authn-resolver/plugins/oidc-authn-plugin/Cargo.toml b/gears/system/authn-resolver/plugins/oidc-authn-plugin/Cargo.toml index 1b6fb25a4..274cfcd1a 100644 --- a/gears/system/authn-resolver/plugins/oidc-authn-plugin/Cargo.toml +++ b/gears/system/authn-resolver/plugins/oidc-authn-plugin/Cargo.toml @@ -24,6 +24,8 @@ types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3", path = "../../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } +authn-resolver = { workspace = true } # ToolKit dependencies toolkit.workspace = true diff --git a/gears/system/authn-resolver/plugins/static-authn-plugin/Cargo.toml b/gears/system/authn-resolver/plugins/static-authn-plugin/Cargo.toml index 710e148db..0a83b6d34 100644 --- a/gears/system/authn-resolver/plugins/static-authn-plugin/Cargo.toml +++ b/gears/system/authn-resolver/plugins/static-authn-plugin/Cargo.toml @@ -21,6 +21,7 @@ workspace = true # Local dependencies authn-resolver-sdk = { package = "cf-gears-authn-resolver-sdk", version = "0.3.18", path = "../../authn-resolver-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/authz-resolver/authz-resolver/Cargo.toml b/gears/system/authz-resolver/authz-resolver/Cargo.toml index aa69d2173..ac9ab8cd3 100644 --- a/gears/system/authz-resolver/authz-resolver/Cargo.toml +++ b/gears/system/authz-resolver/authz-resolver/Cargo.toml @@ -23,6 +23,7 @@ toolkit-canonical-errors = { workspace = true } # Local dependencies authz-resolver-sdk = { package = "cf-gears-authz-resolver-sdk", version = "0.3.9", path = "../authz-resolver-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/authz-resolver/plugins/static-authz-plugin/Cargo.toml b/gears/system/authz-resolver/plugins/static-authz-plugin/Cargo.toml index d92a4d101..3b26b168c 100644 --- a/gears/system/authz-resolver/plugins/static-authz-plugin/Cargo.toml +++ b/gears/system/authz-resolver/plugins/static-authz-plugin/Cargo.toml @@ -21,6 +21,7 @@ workspace = true # Local dependencies authz-resolver-sdk = { package = "cf-gears-authz-resolver-sdk", version = "0.3.9", path = "../../authz-resolver-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/authz-resolver/plugins/tr-authz-plugin/Cargo.toml b/gears/system/authz-resolver/plugins/tr-authz-plugin/Cargo.toml index 384c1a251..734e55c15 100644 --- a/gears/system/authz-resolver/plugins/tr-authz-plugin/Cargo.toml +++ b/gears/system/authz-resolver/plugins/tr-authz-plugin/Cargo.toml @@ -22,6 +22,8 @@ workspace = true authz-resolver-sdk = { package = "cf-gears-authz-resolver-sdk", version = "0.3.9", path = "../../authz-resolver-sdk" } tenant-resolver-sdk = { package = "cf-gears-tenant-resolver-sdk", version = "0.3.9", path = "../../../tenant-resolver/tenant-resolver-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } +tenant-resolver = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/oagw/oagw/Cargo.toml b/gears/system/oagw/oagw/Cargo.toml index ea6e7ee76..541e925e0 100644 --- a/gears/system/oagw/oagw/Cargo.toml +++ b/gears/system/oagw/oagw/Cargo.toml @@ -56,9 +56,13 @@ url = { workspace = true } gts = { workspace = true } utoipa = { workspace = true } types-registry-sdk = { workspace = true } +types-registry = { workspace = true } authz-resolver-sdk = { workspace = true } +authz-resolver = { workspace = true } tenant-resolver-sdk = { workspace = true } +tenant-resolver = { workspace = true } credstore-sdk = { workspace = true } +credstore = { workspace = true } # Metrics / OpenTelemetry opentelemetry = { workspace = true } heck = { workspace = true } diff --git a/gears/system/resource-group/resource-group/Cargo.toml b/gears/system/resource-group/resource-group/Cargo.toml index cedf5212a..9fc4444d2 100644 --- a/gears/system/resource-group/resource-group/Cargo.toml +++ b/gears/system/resource-group/resource-group/Cargo.toml @@ -60,6 +60,8 @@ authz-resolver-sdk = { workspace = true } # GTS type system — types registry for schema resolution types-registry-sdk = { workspace = true } +authz-resolver = { workspace = true } +types-registry = { workspace = true } gts = { workspace = true } # Local dependencies diff --git a/gears/system/tenant-resolver/plugins/rg-tr-plugin/Cargo.toml b/gears/system/tenant-resolver/plugins/rg-tr-plugin/Cargo.toml index 7252c0dd1..3a68b26a9 100644 --- a/gears/system/tenant-resolver/plugins/rg-tr-plugin/Cargo.toml +++ b/gears/system/tenant-resolver/plugins/rg-tr-plugin/Cargo.toml @@ -22,6 +22,8 @@ workspace = true tenant-resolver-sdk = { package = "cf-gears-tenant-resolver-sdk", version = "0.3.9", path = "../../tenant-resolver-sdk" } resource-group-sdk = { package = "cf-gears-resource-group-sdk", version = "0.2.0", path = "../../../resource-group/resource-group-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } +resource-group = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/tenant-resolver/plugins/single-tenant-tr-plugin/Cargo.toml b/gears/system/tenant-resolver/plugins/single-tenant-tr-plugin/Cargo.toml index b7648c8b4..977436879 100644 --- a/gears/system/tenant-resolver/plugins/single-tenant-tr-plugin/Cargo.toml +++ b/gears/system/tenant-resolver/plugins/single-tenant-tr-plugin/Cargo.toml @@ -21,6 +21,7 @@ workspace = true # Local dependencies tenant-resolver-sdk = { package = "cf-gears-tenant-resolver-sdk", version = "0.3.9", path = "../../tenant-resolver-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/tenant-resolver/plugins/static-tr-plugin/Cargo.toml b/gears/system/tenant-resolver/plugins/static-tr-plugin/Cargo.toml index ed731c8c9..708bd986f 100644 --- a/gears/system/tenant-resolver/plugins/static-tr-plugin/Cargo.toml +++ b/gears/system/tenant-resolver/plugins/static-tr-plugin/Cargo.toml @@ -21,6 +21,7 @@ workspace = true # Local dependencies tenant-resolver-sdk = { package = "cf-gears-tenant-resolver-sdk", version = "0.3.9", path = "../../tenant-resolver-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/tenant-resolver/tenant-resolver/Cargo.toml b/gears/system/tenant-resolver/tenant-resolver/Cargo.toml index de581091b..e660d9278 100644 --- a/gears/system/tenant-resolver/tenant-resolver/Cargo.toml +++ b/gears/system/tenant-resolver/tenant-resolver/Cargo.toml @@ -23,6 +23,7 @@ toolkit-canonical-errors = { workspace = true } # Local dependencies tenant-resolver-sdk = { package = "cf-gears-tenant-resolver-sdk", version = "0.3.9", path = "../tenant-resolver-sdk" } types-registry-sdk = { package = "cf-gears-types-registry-sdk", version = "0.3.0", path = "../../types-registry/types-registry-sdk" } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/usage-collector/plugins/noop-usage-collector-plugin/Cargo.toml b/gears/system/usage-collector/plugins/noop-usage-collector-plugin/Cargo.toml index aed0aad51..7ae5e4f89 100644 --- a/gears/system/usage-collector/plugins/noop-usage-collector-plugin/Cargo.toml +++ b/gears/system/usage-collector/plugins/noop-usage-collector-plugin/Cargo.toml @@ -20,6 +20,7 @@ workspace = true # Local dependencies usage-collector-sdk = { workspace = true } types-registry-sdk = { workspace = true } +types-registry = { workspace = true } # ToolKit dependencies toolkit = { workspace = true } diff --git a/gears/system/usage-collector/usage-collector/Cargo.toml b/gears/system/usage-collector/usage-collector/Cargo.toml index 4dd860726..69388dc26 100644 --- a/gears/system/usage-collector/usage-collector/Cargo.toml +++ b/gears/system/usage-collector/usage-collector/Cargo.toml @@ -20,7 +20,9 @@ workspace = true [dependencies] usage-collector-sdk = { workspace = true } types-registry-sdk = { workspace = true } +types-registry = { workspace = true } authz-resolver-sdk = { workspace = true } +authz-resolver = { workspace = true } anyhow = { workspace = true } async-trait = { workspace = true } From 1b147f733dce77d3bbf1f128b5f810c3b1ab72f6 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 26 Jun 2026 08:18:21 +0300 Subject: [PATCH 04/15] Fix: Don't add reexports on tests Signed-off-by: Mauro Lacy --- libs/toolkit-macros/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/toolkit-macros/src/lib.rs b/libs/toolkit-macros/src/lib.rs index 38f1512fa..f31287aa0 100644 --- a/libs/toolkit-macros/src/lib.rs +++ b/libs/toolkit-macros/src/lib.rs @@ -779,6 +779,7 @@ pub fn gear(attr: TokenStream, item: TokenStream) -> TokenStream { Span::call_site(), ); quote! { + #[cfg(not(test))] #[doc(hidden)] pub use #crate_ident as #alias_ident; } From d60ea06aed567b47ed500468171c6af1354c9283 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Fri, 26 Jun 2026 10:20:41 +0300 Subject: [PATCH 05/15] Anchor re-export path with leading :: to avoid module-scope shadowing Signed-off-by: Mauro Lacy --- libs/toolkit-macros/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/toolkit-macros/src/lib.rs b/libs/toolkit-macros/src/lib.rs index f31287aa0..53e4e4571 100644 --- a/libs/toolkit-macros/src/lib.rs +++ b/libs/toolkit-macros/src/lib.rs @@ -781,7 +781,7 @@ pub fn gear(attr: TokenStream, item: TokenStream) -> TokenStream { quote! { #[cfg(not(test))] #[doc(hidden)] - pub use #crate_ident as #alias_ident; + pub use ::#crate_ident as #alias_ident; } }) .collect(); From 11f59033e2c472b2de7886d7622ad9e19f647da4 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 13 Jul 2026 09:59:39 +0200 Subject: [PATCH 06/15] Add full crates for deps exporting to new modules as well Signed-off-by: Mauro Lacy --- gears/bss/ledger/ledger/Cargo.toml | 3 +++ gears/file-storage/file-storage/Cargo.toml | 1 + 2 files changed, 4 insertions(+) diff --git a/gears/bss/ledger/ledger/Cargo.toml b/gears/bss/ledger/ledger/Cargo.toml index ca1c1bd18..ce0ee2af1 100644 --- a/gears/bss/ledger/ledger/Cargo.toml +++ b/gears/bss/ledger/ledger/Cargo.toml @@ -68,6 +68,7 @@ toolkit-odata = { workspace = true, features = ["with-utoipa"] } # schemas at `init()` (the crate RBAC uses for the same purpose). Depend on the # SDK contract crate — not the gear implementation — to preserve gear isolation. types-registry-sdk = { workspace = true } +types-registry = { workspace = true } # `tokio::time::interval` drives the `serve` tick-loop; `macros`/`rt` for the # loop's `tokio::select!` / `tokio::spawn`. tokio = { workspace = true, features = ["time", "macros", "rt"] } @@ -79,9 +80,11 @@ toolkit-macros = { workspace = true } toolkit-security = { workspace = true } # PEP (`PolicyEnforcer`, `ResourceType`, `AccessRequest`) for the authz gate. authz-resolver-sdk = { workspace = true } +authz-resolver = { workspace = true } # AM client (`get_tenant` -> tenant_type) for the provisioning seller-type guard # (only a tenant whose type owns a billing ledger may be provisioned, §4.12). account-management-sdk = { workspace = true } +account-management = { workspace = true } # `AuthzPermissionV1` + `gts_instance!` for the permission catalog. toolkit-gts = { workspace = true } # `gts_instance!`'s expansion references the `gts` crate directly (same as rbac). diff --git a/gears/file-storage/file-storage/Cargo.toml b/gears/file-storage/file-storage/Cargo.toml index b2b0ae6f9..3003a8f57 100644 --- a/gears/file-storage/file-storage/Cargo.toml +++ b/gears/file-storage/file-storage/Cargo.toml @@ -32,6 +32,7 @@ cf-gears-file-storage-sdk = { path = "../file-storage-sdk" } # Authorization Service (PEP) — per-type access decisions cf-gears-authz-resolver-sdk = { path = "../../system/authz-resolver/authz-resolver-sdk" } +authz-resolver = { workspace = true } # Core dependencies anyhow = { workspace = true } From d9427fe9f1b438068f7a21503c90dccbeb5d42fb Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 13 Jul 2026 10:00:54 +0200 Subject: [PATCH 07/15] Update exported versions Signed-off-by: Mauro Lacy --- Cargo.lock | 4 ++++ Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9774503ad..ce932f808 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1071,7 +1071,9 @@ dependencies = [ "axum", "bss-ledger", "bss-ledger-sdk", + "cf-gears-account-management", "cf-gears-account-management-sdk", + "cf-gears-authz-resolver", "cf-gears-authz-resolver-sdk", "cf-gears-toolkit", "cf-gears-toolkit-canonical-errors", @@ -1081,6 +1083,7 @@ dependencies = [ "cf-gears-toolkit-macros", "cf-gears-toolkit-odata", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "chrono", "coord", @@ -1796,6 +1799,7 @@ dependencies = [ "axum", "base64 0.22.1", "bytes", + "cf-gears-authz-resolver", "cf-gears-authz-resolver-sdk", "cf-gears-file-storage-sdk", "cf-gears-toolkit", diff --git a/Cargo.toml b/Cargo.toml index d2903ebb0..bc286cf23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -285,7 +285,7 @@ tenant-resolver = { package = "cf-gears-tenant-resolver", version = "0.1.22", pa resource-group = { package = "cf-gears-resource-group", version = "0.1.4", path = "gears/system/resource-group/resource-group" } credstore = { package = "cf-gears-credstore", version = "0.1.23", path = "gears/credstore/credstore" } oagw = { package = "cf-gears-oagw", version = "0.2.26", path = "gears/system/oagw/oagw" } -account-management = { package = "cf-gears-account-management", version = "0.1.3", path = "gears/system/account-management/account-management" } +account-management = { package = "cf-gears-account-management", version = "0.2.0", path = "gears/system/account-management/account-management" } usage-collector = { package = "cf-gears-usage-collector", version = "0.1.0", path = "gears/system/usage-collector/usage-collector" } cf-gears-cluster-sdk = { version = "0.1.0", path = "gears/system/cluster/cluster-sdk" } From 71456e8146f25c6b77c1669687fa5636595d0bba Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 14 Jul 2026 09:43:11 +0200 Subject: [PATCH 08/15] Add the new "unused" crates to shear ignored list Signed-off-by: Mauro Lacy --- Cargo.toml | 14 ++++++++++++++ .../calculator-gateway/Cargo.toml | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index bc286cf23..6fdb87d31 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -600,3 +600,17 @@ gts-macros = "0.11.0" [workspace.metadata.cargo-shear] ignored-paths = ["**/tests/ui/**"] +# Gear crate deps only consumed by macro-generated re-exports in #[toolkit::gear(deps = [...])]. +# cargo-shear cannot trace usage through proc-macro expansion, so these appear unused. +ignored = [ + "account-management", + "authn-resolver", + "authz-resolver", + "credstore", + "grpc_hub", + "oagw", + "resource-group", + "tenant-resolver", + "types-registry", + "usage-collector", +] diff --git a/examples/oop-gears/calculator-gateway/calculator-gateway/Cargo.toml b/examples/oop-gears/calculator-gateway/calculator-gateway/Cargo.toml index 4491f44c8..493b90577 100644 --- a/examples/oop-gears/calculator-gateway/calculator-gateway/Cargo.toml +++ b/examples/oop-gears/calculator-gateway/calculator-gateway/Cargo.toml @@ -36,3 +36,7 @@ thiserror = { workspace = true } anyhow = { workspace = true } tracing = { workspace = true } inventory = { workspace = true } + +[package.metadata.cargo-shear] +# Gear dep only consumed by macro-generated re-export in #[toolkit::gear(deps = [...])]. +ignored = ["calculator"] From b5fdbb60ca435382c824af9b183b2af35d519762 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Jul 2026 17:01:02 +0200 Subject: [PATCH 09/15] Update lock file Signed-off-by: Mauro Lacy --- Cargo.lock | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index ce932f808..69a947b80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1254,6 +1254,7 @@ dependencies = [ "anyhow", "async-trait", "axum", + "calculator", "calculator-sdk", "cf-gears-toolkit", "cf-gears-toolkit-macros", @@ -1447,8 +1448,11 @@ dependencies = [ "axum", "bigdecimal", "cf-gears-account-management-sdk", + "cf-gears-authz-resolver", "cf-gears-authz-resolver-sdk", + "cf-gears-resource-group", "cf-gears-resource-group-sdk", + "cf-gears-tenant-resolver", "cf-gears-tenant-resolver-sdk", "cf-gears-toolkit", "cf-gears-toolkit-canonical-errors", @@ -1460,6 +1464,7 @@ dependencies = [ "cf-gears-toolkit-odata-macros", "cf-gears-toolkit-security", "cf-gears-toolkit-utils", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "fnv", "futures", @@ -1520,7 +1525,9 @@ dependencies = [ "async-trait", "axum", "bytes", + "cf-gears-authn-resolver", "cf-gears-authn-resolver-sdk", + "cf-gears-grpc-hub", "cf-gears-toolkit", "cf-gears-toolkit-canonical-errors", "cf-gears-toolkit-gts", @@ -1564,6 +1571,7 @@ dependencies = [ "cf-gears-toolkit", "cf-gears-toolkit-canonical-errors", "cf-gears-toolkit-macros", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -1598,6 +1606,7 @@ dependencies = [ "cf-gears-toolkit", "cf-gears-toolkit-canonical-errors", "cf-gears-toolkit-macros", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -1690,6 +1699,7 @@ dependencies = [ "cf-gears-toolkit-gts", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -1917,9 +1927,12 @@ dependencies = [ "axum", "base64 0.22.1", "bytes", + "cf-gears-authn-resolver", "cf-gears-authn-resolver-sdk", + "cf-gears-authz-resolver", "cf-gears-authz-resolver-sdk", "cf-gears-mini-chat-sdk", + "cf-gears-oagw", "cf-gears-oagw-sdk", "cf-gears-toolkit", "cf-gears-toolkit-canonical-errors", @@ -1929,6 +1942,7 @@ dependencies = [ "cf-gears-toolkit-macros", "cf-gears-toolkit-odata", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "chrono", "futures", @@ -2037,6 +2051,7 @@ dependencies = [ "cf-gears-toolkit", "cf-gears-toolkit-macros", "cf-gears-toolkit-odata", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "cf-gears-usage-collector-sdk", "inventory", @@ -2059,10 +2074,13 @@ dependencies = [ "async-trait", "axum", "bytes", + "cf-gears-authz-resolver", "cf-gears-authz-resolver-sdk", + "cf-gears-credstore", "cf-gears-credstore-sdk", "cf-gears-oagw", "cf-gears-oagw-sdk", + "cf-gears-tenant-resolver", "cf-gears-tenant-resolver-sdk", "cf-gears-toolkit", "cf-gears-toolkit-auth", @@ -2071,6 +2089,7 @@ dependencies = [ "cf-gears-toolkit-http", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "dashmap", "form_urlencoded", @@ -2142,11 +2161,13 @@ dependencies = [ "anyhow", "async-trait", "base64 0.22.1", + "cf-gears-authn-resolver", "cf-gears-authn-resolver-sdk", "cf-gears-toolkit", "cf-gears-toolkit-gts", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "criterion", "dashmap", @@ -2180,6 +2201,7 @@ dependencies = [ "anyhow", "async-trait", "axum", + "cf-gears-authz-resolver", "cf-gears-authz-resolver-sdk", "cf-gears-resource-group-sdk", "cf-gears-toolkit", @@ -2190,6 +2212,7 @@ dependencies = [ "cf-gears-toolkit-macros", "cf-gears-toolkit-odata", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "gts", "http", @@ -2233,6 +2256,7 @@ version = "0.1.4" dependencies = [ "anyhow", "async-trait", + "cf-gears-resource-group", "cf-gears-resource-group-sdk", "cf-gears-tenant-resolver-sdk", "cf-gears-toolkit", @@ -2240,6 +2264,7 @@ dependencies = [ "cf-gears-toolkit-macros", "cf-gears-toolkit-odata", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -2287,6 +2312,7 @@ dependencies = [ "anyhow", "async-trait", "axum", + "cf-gears-authz-resolver", "cf-gears-authz-resolver-sdk", "cf-gears-simple-user-settings-sdk", "cf-gears-toolkit", @@ -2330,6 +2356,7 @@ dependencies = [ "cf-gears-toolkit", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -2361,6 +2388,7 @@ dependencies = [ "cf-gears-toolkit", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "secrecy", @@ -2381,6 +2409,7 @@ dependencies = [ "cf-gears-toolkit-gts", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -2400,6 +2429,7 @@ dependencies = [ "cf-gears-toolkit", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -2422,6 +2452,7 @@ dependencies = [ "cf-gears-toolkit-macros", "cf-gears-toolkit-odata", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "gts", "inventory", @@ -2443,6 +2474,7 @@ dependencies = [ "cf-gears-toolkit", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -2484,6 +2516,7 @@ dependencies = [ "cf-gears-toolkit-canonical-errors", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -2900,11 +2933,13 @@ dependencies = [ "anyhow", "async-trait", "cf-gears-authz-resolver-sdk", + "cf-gears-tenant-resolver", "cf-gears-tenant-resolver-sdk", "cf-gears-toolkit", "cf-gears-toolkit-gts", "cf-gears-toolkit-macros", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "inventory", "serde", @@ -2961,6 +2996,7 @@ dependencies = [ "async-trait", "axum", "bigdecimal", + "cf-gears-authz-resolver", "cf-gears-authz-resolver-sdk", "cf-gears-toolkit", "cf-gears-toolkit-canonical-errors", @@ -2968,6 +3004,7 @@ dependencies = [ "cf-gears-toolkit-macros", "cf-gears-toolkit-odata", "cf-gears-toolkit-security", + "cf-gears-types-registry", "cf-gears-types-registry-sdk", "cf-gears-usage-collector-sdk", "futures", @@ -10941,6 +10978,7 @@ dependencies = [ "anyhow", "async-trait", "axum", + "cf-gears-authz-resolver", "cf-gears-authz-resolver-sdk", "cf-gears-toolkit", "cf-gears-toolkit-canonical-errors", From eef3dc0259b2ddf0e20a022f81d733c935b83813 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Jul 2026 17:48:08 +0200 Subject: [PATCH 10/15] Change gears macro to use idents in deps Signed-off-by: Mauro Lacy --- libs/toolkit-macros/src/lib.rs | 39 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/libs/toolkit-macros/src/lib.rs b/libs/toolkit-macros/src/lib.rs index 53e4e4571..bc119e9b3 100644 --- a/libs/toolkit-macros/src/lib.rs +++ b/libs/toolkit-macros/src/lib.rs @@ -18,7 +18,7 @@ mod utils; /// Configuration parsed from #[gear(...)] attribute struct GearConfig { name: String, - deps: Vec, + deps: Vec, caps: Vec, ctor: Option, // arbitrary constructor expression client: Option, // trait path for client DX helpers @@ -197,9 +197,10 @@ impl Default for LcGearCfg { } impl Parse for GearConfig { + #[allow(clippy::too_many_lines)] fn parse(input: ParseStream) -> syn::Result { let mut name: Option = None; - let mut deps: Vec = Vec::new(); + let mut deps: Vec = Vec::new(); let mut caps: Vec = Vec::new(); let mut ctor: Option = None; let mut client: Option = None; @@ -304,15 +305,20 @@ impl Parse for GearConfig { Expr::Array(arr) => { for elem in arr.elems { match elem { - Expr::Lit(syn::ExprLit { - lit: Lit::Str(s), .. - }) => { - deps.push(s.value()); + Expr::Path(ref path) => { + if let Some(ident) = path.path.get_ident() { + deps.push(ident.clone()); + } else { + return Err(syn::Error::new_spanned( + path, + "deps must be crate identifiers, e.g. deps = [authn_resolver, types_registry]", + )); + } } other => { return Err(syn::Error::new_spanned( other, - "deps must be an array of string literals, e.g. deps = [\"db\", \"auth\"]", + "deps must be crate identifiers, e.g. deps = [authn_resolver, types_registry]", )); } } @@ -321,7 +327,7 @@ impl Parse for GearConfig { other => { return Err(syn::Error::new_spanned( other, - "deps must be an array, e.g. deps = [\"db\", \"auth\"]", + "deps must be an array, e.g. deps = [authn_resolver, types_registry]", )); } } @@ -488,7 +494,7 @@ pub fn gear(attr: TokenStream, item: TokenStream) -> TokenStream { let (impl_generics, ty_generics, where_clause) = generics_clone.split_for_impl(); let name_owned: String = config.name.clone(); - let deps_owned: Vec = config.deps.clone(); + let deps_idents: Vec = config.deps.clone(); let caps_for_asserts: Vec = config.caps.clone(); let caps_for_regs: Vec = config.caps.clone(); let ctor_expr_opt: Option = config.ctor.clone(); @@ -497,9 +503,10 @@ pub fn gear(attr: TokenStream, item: TokenStream) -> TokenStream { // Prepare string literals for name/deps let name_lit = LitStr::new(&name_owned, Span::call_site()); - let deps_lits: Vec = deps_owned + // Derive runtime dep names from crate identifiers: authn_resolver -> "authn-resolver" + let deps_lits: Vec = deps_idents .iter() - .map(|s| LitStr::new(s, Span::call_site())) + .map(|ident| LitStr::new(&ident.to_string().replace('_', "-"), Span::call_site())) .collect(); // Constructor expression (provided or Default::default()) @@ -770,14 +777,10 @@ pub fn gear(attr: TokenStream, item: TokenStream) -> TokenStream { // Generate re-exports for gear dependencies so their `inventory::submit!` // registrations survive linking when this gear is pulled in transitively. - let dep_reexports: Vec<_> = deps_owned + let dep_reexports: Vec<_> = deps_idents .iter() - .map(|dep| { - let crate_ident = Ident::new(&dep.replace('-', "_"), Span::call_site()); - let alias_ident = Ident::new( - &format!("_gear_dep_{}", dep.replace('-', "_")), - Span::call_site(), - ); + .map(|crate_ident| { + let alias_ident = format_ident!("_gear_dep_{}", crate_ident); quote! { #[cfg(not(test))] #[doc(hidden)] From 9b0501d4f75584660e7f41e38c79a7e2d40fe6cf Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Jul 2026 17:52:20 +0200 Subject: [PATCH 11/15] Adapt docs / examples / tests Signed-off-by: Mauro Lacy --- .../oop-gears/calculator-gateway/calculator-gateway/src/gear.rs | 2 +- examples/toolkit/users-info/users-info/src/gear.rs | 2 +- libs/toolkit/src/lib.rs | 2 +- libs/toolkit/tests/macro_tests.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/oop-gears/calculator-gateway/calculator-gateway/src/gear.rs b/examples/oop-gears/calculator-gateway/calculator-gateway/src/gear.rs index 69cf309bc..05e292911 100644 --- a/examples/oop-gears/calculator-gateway/calculator-gateway/src/gear.rs +++ b/examples/oop-gears/calculator-gateway/calculator-gateway/src/gear.rs @@ -23,7 +23,7 @@ use crate::domain::Service; #[toolkit::gear( name = "calculator-gateway", capabilities = [rest], - deps = ["calculator"] + deps = [calculator] )] pub struct CalculatorGateway; diff --git a/examples/toolkit/users-info/users-info/src/gear.rs b/examples/toolkit/users-info/users-info/src/gear.rs index 8d5a18aa6..e477ba91c 100644 --- a/examples/toolkit/users-info/users-info/src/gear.rs +++ b/examples/toolkit/users-info/users-info/src/gear.rs @@ -38,7 +38,7 @@ pub(crate) type ConcreteAppServices = /// Main gear struct with DDD-light layout and proper `ClientHub` integration #[toolkit::gear( name = "users-info", - deps = ["authz-resolver"], + deps = [authz_resolver], capabilities = [db, rest] )] pub struct UsersInfo { diff --git a/libs/toolkit/src/lib.rs b/libs/toolkit/src/lib.rs index f78d0770a..2f1d3a9f1 100644 --- a/libs/toolkit/src/lib.rs +++ b/libs/toolkit/src/lib.rs @@ -57,7 +57,7 @@ //! use toolkit::{gear, Gear, DbGear, RestfulGear, StatefulGear}; //! //! #[derive(Default)] -//! #[gear(name = "user", deps = ["database"], capabilities = [db, rest, stateful])] +//! #[gear(name = "user", deps = [database], capabilities = [db, rest, stateful])] //! pub struct UserGear; //! //! // Implement the declared capabilities... diff --git a/libs/toolkit/tests/macro_tests.rs b/libs/toolkit/tests/macro_tests.rs index 163a45d74..7291f1321 100644 --- a/libs/toolkit/tests/macro_tests.rs +++ b/libs/toolkit/tests/macro_tests.rs @@ -106,7 +106,7 @@ impl RunnableCapability for FullFeaturedGear { } #[derive(Default)] -#[gear(name = "dependent", deps = ["basic", "full-featured"])] +#[gear(name = "dependent", deps = [basic, full_featured])] struct DependentGear; #[async_trait] From cec1f7fd4de7d0f97176177d4bdfde89a6ef78f5 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Jul 2026 17:52:41 +0200 Subject: [PATCH 12/15] Adapt gears macro invocations to new format Signed-off-by: Mauro Lacy --- gears/bss/ledger/ledger/src/module.rs | 2 +- gears/credstore/credstore/src/gear.rs | 2 +- gears/credstore/plugins/static-credstore-plugin/src/gear.rs | 2 +- gears/file-storage/file-storage/src/gear.rs | 2 +- gears/mini-chat/mini-chat/src/gear.rs | 2 +- .../mini-chat/mini-chat/src/infra/plugins/static_audit/gear.rs | 2 +- .../mini-chat/src/infra/plugins/static_model_policy/gear.rs | 2 +- gears/simple-user-settings/simple-user-settings/src/gear.rs | 2 +- gears/system/account-management/account-management/src/gear.rs | 2 +- .../account-management/plugins/static-idp-plugin/src/gear.rs | 2 +- gears/system/api-gateway/src/gear.rs | 2 +- gears/system/authn-resolver/authn-resolver/src/gear.rs | 2 +- .../system/authn-resolver/plugins/oidc-authn-plugin/src/gear.rs | 2 +- .../authn-resolver/plugins/static-authn-plugin/src/gear.rs | 2 +- gears/system/authz-resolver/authz-resolver/src/gear.rs | 2 +- .../authz-resolver/plugins/static-authz-plugin/src/gear.rs | 2 +- gears/system/authz-resolver/plugins/tr-authz-plugin/src/gear.rs | 2 +- gears/system/oagw/oagw/src/gear.rs | 2 +- gears/system/resource-group/resource-group/src/gear.rs | 2 +- gears/system/tenant-resolver/plugins/rg-tr-plugin/src/gear.rs | 2 +- .../tenant-resolver/plugins/single-tenant-tr-plugin/src/gear.rs | 2 +- .../system/tenant-resolver/plugins/static-tr-plugin/src/gear.rs | 2 +- gears/system/tenant-resolver/tenant-resolver/src/gear.rs | 2 +- .../plugins/noop-usage-collector-plugin/src/module.rs | 2 +- gears/system/usage-collector/usage-collector/src/module.rs | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/gears/bss/ledger/ledger/src/module.rs b/gears/bss/ledger/ledger/src/module.rs index fcacbde81..9da7edc03 100644 --- a/gears/bss/ledger/ledger/src/module.rs +++ b/gears/bss/ledger/ledger/src/module.rs @@ -169,7 +169,7 @@ pub(crate) struct LedgerRuntime { // broker-free no-op/metrics-only publisher). Declaring it would make the gear // unschedulable (the orchestrator can't satisfy a dep no gear provides). Re-add // it here once the broker gear exists and `events_enabled` is wired to it. -#[toolkit::gear(name = "bss-ledger", capabilities = [db, rest, stateful], deps = ["types-registry", "authz-resolver", "account-management"], lifecycle(entry = "serve", stop_timeout = "30s"))] +#[toolkit::gear(name = "bss-ledger", capabilities = [db, rest, stateful], deps = [types_registry, authz_resolver, account_management], lifecycle(entry = "serve", stop_timeout = "30s"))] pub struct BssLedgerGear { /// Typed runtime built inside [`Gear::init`] and consumed by /// [`RestApiCapability::register_rest`] and [`BssLedgerGear::serve`]. diff --git a/gears/credstore/credstore/src/gear.rs b/gears/credstore/credstore/src/gear.rs index 7b0984415..4fe7ecf30 100644 --- a/gears/credstore/credstore/src/gear.rs +++ b/gears/credstore/credstore/src/gear.rs @@ -23,7 +23,7 @@ use crate::domain::{CredStoreLocalClient, Service}; /// registration is needed. #[toolkit::gear( name = "credstore", - deps = ["types-registry"], + deps = [types_registry], capabilities = [system] )] pub struct CredStoreGear { diff --git a/gears/credstore/plugins/static-credstore-plugin/src/gear.rs b/gears/credstore/plugins/static-credstore-plugin/src/gear.rs index 55f3b26d7..cbfd3d252 100644 --- a/gears/credstore/plugins/static-credstore-plugin/src/gear.rs +++ b/gears/credstore/plugins/static-credstore-plugin/src/gear.rs @@ -17,7 +17,7 @@ use crate::domain::Service; /// Serves pre-configured secrets from YAML configuration for development and testing. #[toolkit::gear( name = "static-credstore-plugin", - deps = ["types-registry"] + deps = [types_registry] )] pub struct StaticCredStorePlugin { service: OnceLock>, diff --git a/gears/file-storage/file-storage/src/gear.rs b/gears/file-storage/file-storage/src/gear.rs index 153a21494..2ee42e1a7 100644 --- a/gears/file-storage/file-storage/src/gear.rs +++ b/gears/file-storage/file-storage/src/gear.rs @@ -45,7 +45,7 @@ const MEMORY_ID: &str = "memory"; /// is used only for the cooperative background cleanup sweep. #[toolkit::gear( name = "file-storage", - deps = ["authz-resolver"], + deps = [authz_resolver], capabilities = [db, rest, stateful] )] pub struct FileStorageGear { diff --git a/gears/mini-chat/mini-chat/src/gear.rs b/gears/mini-chat/mini-chat/src/gear.rs index 1eb977e75..632e56f7d 100644 --- a/gears/mini-chat/mini-chat/src/gear.rs +++ b/gears/mini-chat/mini-chat/src/gear.rs @@ -53,7 +53,7 @@ pub const DEFAULT_URL_PREFIX: &str = "/mini-chat"; /// The mini-chat gear: multi-tenant AI chat with SSE streaming. #[toolkit::gear( name = "mini-chat", - deps = ["types-registry", "authn-resolver", "authz-resolver", "oagw"], + deps = [types_registry, authn_resolver, authz_resolver, oagw], capabilities = [db, rest, stateful], )] pub struct MiniChatGear { diff --git a/gears/mini-chat/mini-chat/src/infra/plugins/static_audit/gear.rs b/gears/mini-chat/mini-chat/src/infra/plugins/static_audit/gear.rs index 10b27535f..85e94b998 100644 --- a/gears/mini-chat/mini-chat/src/infra/plugins/static_audit/gear.rs +++ b/gears/mini-chat/mini-chat/src/infra/plugins/static_audit/gear.rs @@ -20,7 +20,7 @@ use super::service::Service; /// all emit methods return immediately without logging. #[toolkit::gear( name = "static-mini-chat-audit-plugin", - deps = ["types-registry"] + deps = [types_registry] )] pub struct StaticMiniChatAuditPlugin { service: OnceLock>, diff --git a/gears/mini-chat/mini-chat/src/infra/plugins/static_model_policy/gear.rs b/gears/mini-chat/mini-chat/src/infra/plugins/static_model_policy/gear.rs index 73aa02b1f..7ed8289ce 100644 --- a/gears/mini-chat/mini-chat/src/infra/plugins/static_model_policy/gear.rs +++ b/gears/mini-chat/mini-chat/src/infra/plugins/static_model_policy/gear.rs @@ -17,7 +17,7 @@ use super::service::Service; /// Provides a config-driven model catalog for development and testing. #[toolkit::gear( name = "static-mini-chat-model-policy-plugin", - deps = ["types-registry"] + deps = [types_registry] )] pub struct StaticMiniChatModelPolicyPlugin { service: OnceLock>, diff --git a/gears/simple-user-settings/simple-user-settings/src/gear.rs b/gears/simple-user-settings/simple-user-settings/src/gear.rs index a686c64f6..e5d6d1edf 100644 --- a/gears/simple-user-settings/simple-user-settings/src/gear.rs +++ b/gears/simple-user-settings/simple-user-settings/src/gear.rs @@ -23,7 +23,7 @@ type ConcreteService = Service; #[toolkit::gear( name = "simple-user-settings", - deps = ["authz-resolver"], + deps = [authz_resolver], capabilities = [rest, db] )] pub struct SettingsGear { diff --git a/gears/system/account-management/account-management/src/gear.rs b/gears/system/account-management/account-management/src/gear.rs index 68b798a0f..1b12d6b58 100644 --- a/gears/system/account-management/account-management/src/gear.rs +++ b/gears/system/account-management/account-management/src/gear.rs @@ -82,7 +82,7 @@ struct BootstrapParams { #[toolkit::gear( name = "account-management", - deps = ["authz-resolver", "types-registry", "resource-group", "tenant-resolver"], + deps = [authz_resolver, types_registry, resource_group, tenant_resolver], capabilities = [db, rest, stateful], lifecycle(entry = "serve", stop_timeout = "30s", await_ready) )] diff --git a/gears/system/account-management/plugins/static-idp-plugin/src/gear.rs b/gears/system/account-management/plugins/static-idp-plugin/src/gear.rs index 552f31e47..74449272b 100644 --- a/gears/system/account-management/plugins/static-idp-plugin/src/gear.rs +++ b/gears/system/account-management/plugins/static-idp-plugin/src/gear.rs @@ -34,7 +34,7 @@ use crate::domain::Service; /// on the chosen `gts_id`. #[toolkit::gear( name = "static-idp-plugin", - deps = ["types-registry"] + deps = [types_registry] )] pub struct StaticIdpPlugin { service: OnceLock>, diff --git a/gears/system/api-gateway/src/gear.rs b/gears/system/api-gateway/src/gear.rs index 402bbe34b..2a0aad1d7 100644 --- a/gears/system/api-gateway/src/gear.rs +++ b/gears/system/api-gateway/src/gear.rs @@ -63,7 +63,7 @@ use crate::web; #[toolkit::gear( name = "api-gateway", capabilities = [rest_host, rest, stateful], - deps = ["grpc-hub", "authn-resolver"], + deps = [grpc_hub, authn_resolver], lifecycle(entry = "serve", stop_timeout = "30s", await_ready) )] pub struct ApiGateway { diff --git a/gears/system/authn-resolver/authn-resolver/src/gear.rs b/gears/system/authn-resolver/authn-resolver/src/gear.rs index 4c74f6986..9a6801bfd 100644 --- a/gears/system/authn-resolver/authn-resolver/src/gear.rs +++ b/gears/system/authn-resolver/authn-resolver/src/gear.rs @@ -24,7 +24,7 @@ use crate::domain::{AuthNResolverLocalClient, Service}; /// call after types-registry is ready. #[toolkit::gear( name = "authn-resolver", - deps = ["types-registry"], + deps = [types_registry], capabilities = [system] )] pub(crate) struct AuthNResolver { diff --git a/gears/system/authn-resolver/plugins/oidc-authn-plugin/src/gear.rs b/gears/system/authn-resolver/plugins/oidc-authn-plugin/src/gear.rs index 1f7d39d57..11238e7b1 100644 --- a/gears/system/authn-resolver/plugins/oidc-authn-plugin/src/gear.rs +++ b/gears/system/authn-resolver/plugins/oidc-authn-plugin/src/gear.rs @@ -27,7 +27,7 @@ use crate::infra::runtime::build_oidc_authn_plugin; /// in types-registry before this gear registers plugin instance metadata. #[toolkit::gear( name = "oidc-authn-plugin", - deps = ["types-registry", "authn-resolver"] + deps = [types_registry, authn_resolver] )] #[derive(Default)] pub struct OidcAuthNPluginGear; diff --git a/gears/system/authn-resolver/plugins/static-authn-plugin/src/gear.rs b/gears/system/authn-resolver/plugins/static-authn-plugin/src/gear.rs index af454aff6..db1ab2035 100644 --- a/gears/system/authn-resolver/plugins/static-authn-plugin/src/gear.rs +++ b/gears/system/authn-resolver/plugins/static-authn-plugin/src/gear.rs @@ -24,7 +24,7 @@ use crate::domain::Service; /// - This plugin registers its scoped client (implementation in `ClientHub`) #[toolkit::gear( name = "static-authn-plugin", - deps = ["types-registry"] + deps = [types_registry] )] pub struct StaticAuthNPlugin { service: OnceLock>, diff --git a/gears/system/authz-resolver/authz-resolver/src/gear.rs b/gears/system/authz-resolver/authz-resolver/src/gear.rs index 936736a8f..bde465afe 100644 --- a/gears/system/authz-resolver/authz-resolver/src/gear.rs +++ b/gears/system/authz-resolver/authz-resolver/src/gear.rs @@ -24,7 +24,7 @@ use crate::domain::{AuthZResolverLocalClient, Service}; /// call after types-registry is ready. #[toolkit::gear( name = "authz-resolver", - deps = ["types-registry"], + deps = [types_registry], capabilities = [system] )] pub(crate) struct AuthZResolver { diff --git a/gears/system/authz-resolver/plugins/static-authz-plugin/src/gear.rs b/gears/system/authz-resolver/plugins/static-authz-plugin/src/gear.rs index f9a757044..8065f4da4 100644 --- a/gears/system/authz-resolver/plugins/static-authz-plugin/src/gear.rs +++ b/gears/system/authz-resolver/plugins/static-authz-plugin/src/gear.rs @@ -17,7 +17,7 @@ use crate::domain::Service; /// Static `AuthZ` resolver plugin gear. #[toolkit::gear( name = "static-authz-plugin", - deps = ["types-registry"] + deps = [types_registry] )] pub struct StaticAuthZPlugin { service: OnceLock>, diff --git a/gears/system/authz-resolver/plugins/tr-authz-plugin/src/gear.rs b/gears/system/authz-resolver/plugins/tr-authz-plugin/src/gear.rs index 1ec46d496..094ed9a38 100644 --- a/gears/system/authz-resolver/plugins/tr-authz-plugin/src/gear.rs +++ b/gears/system/authz-resolver/plugins/tr-authz-plugin/src/gear.rs @@ -21,7 +21,7 @@ use crate::domain::Service; /// accessing Resource Group directly. #[toolkit::gear( name = "tr-authz-plugin", - deps = ["types-registry", "tenant-resolver"] + deps = [types_registry, tenant_resolver] )] pub struct TrAuthZPlugin { service: OnceLock>, diff --git a/gears/system/oagw/oagw/src/gear.rs b/gears/system/oagw/oagw/src/gear.rs index 689edb48e..77d9fb425 100644 --- a/gears/system/oagw/oagw/src/gear.rs +++ b/gears/system/oagw/oagw/src/gear.rs @@ -40,7 +40,7 @@ pub struct AppState { /// Outbound API Gateway gear: wires repos, services, and routes. #[toolkit::gear( name = "oagw", - deps = ["types-registry", "authz-resolver", "credstore", "tenant-resolver"], + deps = [types_registry, authz_resolver, credstore, tenant_resolver], capabilities = [system, rest] )] pub struct OutboundApiGatewayGear { diff --git a/gears/system/resource-group/resource-group/src/gear.rs b/gears/system/resource-group/resource-group/src/gear.rs index a37c3623e..2089001b5 100644 --- a/gears/system/resource-group/resource-group/src/gear.rs +++ b/gears/system/resource-group/resource-group/src/gear.rs @@ -33,7 +33,7 @@ pub type ConcreteRgService = RgService>, diff --git a/gears/system/tenant-resolver/plugins/single-tenant-tr-plugin/src/gear.rs b/gears/system/tenant-resolver/plugins/single-tenant-tr-plugin/src/gear.rs index 9bb23ffaf..5c6e193e5 100644 --- a/gears/system/tenant-resolver/plugins/single-tenant-tr-plugin/src/gear.rs +++ b/gears/system/tenant-resolver/plugins/single-tenant-tr-plugin/src/gear.rs @@ -20,7 +20,7 @@ use crate::domain::Service; /// Returns the tenant from security context as the only accessible tenant. #[toolkit::gear( name = "single-tenant-tr-plugin", - deps = ["types-registry"] + deps = [types_registry] )] pub struct SingleTenantTrPlugin; diff --git a/gears/system/tenant-resolver/plugins/static-tr-plugin/src/gear.rs b/gears/system/tenant-resolver/plugins/static-tr-plugin/src/gear.rs index 17d713925..f786d2a12 100644 --- a/gears/system/tenant-resolver/plugins/static-tr-plugin/src/gear.rs +++ b/gears/system/tenant-resolver/plugins/static-tr-plugin/src/gear.rs @@ -24,7 +24,7 @@ use crate::domain::Service; /// - This plugin registers its scoped client (implementation in `ClientHub`) #[toolkit::gear( name = "static-tr-plugin", - deps = ["types-registry"] + deps = [types_registry] )] pub struct StaticTrPlugin { service: OnceLock>, diff --git a/gears/system/tenant-resolver/tenant-resolver/src/gear.rs b/gears/system/tenant-resolver/tenant-resolver/src/gear.rs index c60e0c05a..5d7520f98 100644 --- a/gears/system/tenant-resolver/tenant-resolver/src/gear.rs +++ b/gears/system/tenant-resolver/tenant-resolver/src/gear.rs @@ -24,7 +24,7 @@ use crate::domain::{Service, TenantResolverLocalClient}; /// call after types-registry is ready. #[toolkit::gear( name = "tenant-resolver", - deps = ["types-registry"], + deps = [types_registry], capabilities = [system] )] pub(crate) struct TenantResolver { diff --git a/gears/system/usage-collector/plugins/noop-usage-collector-plugin/src/module.rs b/gears/system/usage-collector/plugins/noop-usage-collector-plugin/src/module.rs index eda007525..7bac3da5e 100644 --- a/gears/system/usage-collector/plugins/noop-usage-collector-plugin/src/module.rs +++ b/gears/system/usage-collector/plugins/noop-usage-collector-plugin/src/module.rs @@ -19,7 +19,7 @@ use crate::plugin::NoopBackend; /// resolves end-to-end in development and testing without a real DB backend. #[toolkit::gear( name = "noop-usage-collector-plugin", - deps = ["types-registry"] + deps = [types_registry] )] #[derive(Default)] pub struct NoopUsageCollectorPlugin; diff --git a/gears/system/usage-collector/usage-collector/src/module.rs b/gears/system/usage-collector/usage-collector/src/module.rs index c25c51b46..04e79e86e 100644 --- a/gears/system/usage-collector/usage-collector/src/module.rs +++ b/gears/system/usage-collector/usage-collector/src/module.rs @@ -43,7 +43,7 @@ use crate::domain::{Service, UsageCollectorLocalClient}; /// registration is needed. #[toolkit::gear( name = "usage-collector", - deps = ["types-registry", "authz-resolver"], + deps = [types_registry, authz_resolver], capabilities = [rest, stateful], lifecycle(entry = "serve", stop_timeout = "30s") )] From 65ff21effa1996bc2e50c2bfcf245c21a5171a52 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Jul 2026 21:27:04 +0200 Subject: [PATCH 13/15] Fix: deps_not_array test Signed-off-by: Mauro Lacy --- libs/toolkit-macros-tests/tests/ui/fail/deps_not_array.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/toolkit-macros-tests/tests/ui/fail/deps_not_array.stderr b/libs/toolkit-macros-tests/tests/ui/fail/deps_not_array.stderr index 4c001980d..075e9ec59 100644 --- a/libs/toolkit-macros-tests/tests/ui/fail/deps_not_array.stderr +++ b/libs/toolkit-macros-tests/tests/ui/fail/deps_not_array.stderr @@ -1,4 +1,4 @@ -error: deps must be an array, e.g. deps = ["db", "auth"] +error: deps must be an array, e.g. deps = [authn_resolver, types_registry] --> tests/ui/fail/deps_not_array.rs:3:23 | 3 | #[gear(name="x", deps="db")] From 0cd439e3d9512ce1748fb56f932aa6b4d660b205 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Jul 2026 21:33:59 +0200 Subject: [PATCH 14/15] Free up some disk space before llvm-cov and shear CI jobs Signed-off-by: Mauro Lacy --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8ca78bab..794ac0dbc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -348,6 +348,16 @@ jobs: env: RUSTUP_TOOLCHAIN: nightly-2026-04-16 steps: + - name: Free disk space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + swap-storage: true + - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -437,6 +447,16 @@ jobs: env: RUSTUP_TOOLCHAIN: nightly-2026-04-16 steps: + - name: Free disk space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + swap-storage: true + - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: From ea5f5810ed782abdd9972c6e1c1659ba699fc621 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 16 Jul 2026 23:27:02 +0200 Subject: [PATCH 15/15] docs: document cargo-shear ignore list requirement for gear deps The #[gear(deps = [...])] macro generates hidden pub use re-exports that cargo-shear cannot trace. Document this in the macro's rustdoc and in CONTRIBUTING.md so new gear dependencies don't cause unexpected CI failures in the shear job. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Mauro Lacy --- CONTRIBUTING.md | 17 +++++++++++++++++ libs/toolkit-macros/src/lib.rs | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 23d51da29..009678b76 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,6 +89,23 @@ Follow the coding standards and guidelines: Gear directories under `gears/` must use kebab-case (validated by `tools/scripts/validate_gear_names.py` and enforced in CI). +#### Gear dependencies and `cargo-shear` + +When a gear declares dependencies via `#[gear(deps = [...])]`, the dep entries are +**crate identifiers** (snake_case). The runtime gear name is derived by replacing +underscores with hyphens (`authn_resolver` → `"authn-resolver"`), matching the +convention that `lib-name == gear-name` across the workspace. + +The macro generates hidden `pub use` re-exports that force the linker to keep each +dependency's `inventory::submit!` registration alive. Because these re-exports only +exist in macro-expanded code, `cargo-shear` cannot see them and will flag the +dependency crates as unused. + +**When adding a new gear dependency**, add the crate name to the +`[workspace.metadata.cargo-shear] ignored` list in the workspace `Cargo.toml`. +Forgetting this will cause the `shear` CI job to fail with an error unrelated to +your actual change. + Always include unit tests when introducing new code. ### 2.4. Run Code Quality Checks diff --git a/libs/toolkit-macros/src/lib.rs b/libs/toolkit-macros/src/lib.rs index bc119e9b3..a7fbaaea4 100644 --- a/libs/toolkit-macros/src/lib.rs +++ b/libs/toolkit-macros/src/lib.rs @@ -482,6 +482,22 @@ fn parse_lifecycle_list(list: &MetaList) -> syn::Result { /// /// `ctor` must be a Rust expression that evaluates to the gear instance, /// e.g. `ctor = MyGear::new()` or `ctor = Default::default()`. +/// +/// # Gear dependencies (`deps`) +/// +/// `deps` lists the **crate identifiers** (`snake_case`) of gears that this gear +/// depends on. The runtime gear name is derived by replacing underscores with +/// hyphens (`authn_resolver` → `"authn-resolver"`), which matches the universal +/// convention that `lib-name == gear-name` across the workspace. +/// +/// The macro generates hidden `pub use` re-exports so the linker keeps each +/// dependency's `inventory::submit!` registration alive. Because these +/// re-exports only exist in macro-expanded code, `cargo-shear` cannot see +/// them and will flag the dependency crates as unused. +/// +/// **When adding a new gear dependency** you must also add the crate name to +/// the `[workspace.metadata.cargo-shear] ignored` list in the workspace +/// `Cargo.toml`, otherwise the `shear` CI job will fail. #[proc_macro_attribute] #[allow(clippy::too_many_lines)] pub fn gear(attr: TokenStream, item: TokenStream) -> TokenStream {