CouncilEx.AutoCouncil.Providers (CouncilEx v0.1.0)

Copy Markdown View Source

Helpers for discovering which providers a council references.

Used by CouncilEx.AutoCouncil provider_check: true to filter out catalog entries whose councils need providers that aren't configured.

Council form coverage

  • Static (use CouncilEx) — every static council compiles a __providers__/0 function via the CouncilEx.__before_compile__/1 hook. That function calls back into from_spec/1 with the council's compiled %Spec{}. Cheap, no provider config required.

  • Dynamic (%DynamicCouncil{})used/1 calls DynamicCouncil.to_spec/1 and walks the resulting %Spec{}. No I/O, just keyword merges + a profile lookup per member.

Sub-councils

A council member may itself be a sub-council shim (CouncilEx.Members.SubCouncilAdapter). Those shims expose __sub_council__/0 returning the target. from_spec/1 detects shims and recurses into the target so the parent's provider set covers all inner providers transitively.

Sentinels (:__sub_council__) and nil are filtered out.

Failure mode

used/1 returns {:error, term()} if introspection fails (e.g. a profile module isn't loaded). The caller should treat {:error, _} as "skip the eligibility check" rather than dropping the entry — load order races shouldn't starve the router.

Summary

Functions

Return the MapSet of provider keys the app currently has configured under :council_ex, :providers.

Returns true if every provider used by council is configured.

Walk a %Spec{} and collect referenced providers.

Return the set of providers a council references.

Functions

configured()

@spec configured() :: MapSet.t(atom())

Return the MapSet of provider keys the app currently has configured under :council_ex, :providers.

eligible?(council, configured \\ nil)

@spec eligible?(module() | CouncilEx.DynamicCouncil.t(), MapSet.t() | nil) ::
  boolean()

Returns true if every provider used by council is configured.

Treats introspection failures ({:error, _} from used/1) as "eligible" — better to attempt the run and surface a clear error than to silently drop a council due to a load-order race.

from_spec(spec)

@spec from_spec(CouncilEx.Spec.t()) :: MapSet.t(atom())

Walk a %Spec{} and collect referenced providers.

Public so the __providers__/0 hoisted into static councils can call into it without going through the polymorphic used/1 path.

used(dc)

@spec used(module() | CouncilEx.DynamicCouncil.t()) ::
  {:ok, MapSet.t()} | {:error, term()}

Return the set of providers a council references.

Polymorphic on council form. Returns {:ok, MapSet.t(atom())} or {:error, term()}.