LemonCore.Env.Registry behaviour (lemon_core v0.1.0)

View Source

Contract for a module that declares environment variables.

LemonCore.Env is the framework: typing, aliases, defaults, resolution and reporting. The declarations belong to whichever app reads the variable, so each app ships its own registry module and the runtime lists them:

config :lemon_core, :env_registries, [
  LemonCore.Env.Declarations,
  LemonGateway.Env,
  LemonSimUi.Env
]

LemonCore.Env.all_declared/0 aggregates the listed modules, skipping any that are not loaded — so a build containing only some of the umbrella's apps reports exactly the variables its code can actually read.

Implementing

The contract is structural: a registry is any module exporting declarations/0 that returns a list of LemonCore.Env.declaration/0 maps. Apps that depend on lemon_core get compile-time validation from the macro:

defmodule MyApp.Env do
  use LemonCore.Env.Registry

  @declarations [
    %{
      name: :my_app_timeout_ms,
      env_var: "MY_APP_TIMEOUT_MS",
      aliases: [],
      type: :integer,
      default: 5_000,
      doc: "How long MyApp waits before giving up.",
      secret?: false,
      required?: false,
      area: :my_app,
      apps: [:my_app]
    }
  ]
end

Apps that must not depend on lemon_coreai is the one in this umbrella — simply define declarations/0 by hand; the aggregate treats them the same.

Summary

Functions

Validate a declaration list, raising with the offending entry.

Types

declaration()

@type declaration() :: LemonCore.Env.declaration()

Callbacks

declarations()

@callback declarations() :: [declaration()]

Functions

validate!(declarations, module)

@spec validate!([declaration()], module()) :: :ok

Validate a declaration list, raising with the offending entry.

Runs at compile time for registries using the macro; exposed so tooling and tests can check hand-written registries too.