Getting started
The package can be installed by adding confispex
to your list of dependencies in mix.exs
:
def deps do
[
{:confispex, "~> 1.1"}
]
end
Let's define the first version of a variables schema and runtime config with confispex
:
defmodule MyApp.RuntimeConfigSchema do
import Confispex.Schema
@behaviour Confispex.Schema
alias Confispex.Type
defvariables(%{
"LOG_LEVEL" => %{
cast:
{Type.Enum,
values: [
"emergency",
"alert",
"critical",
"error",
"warning",
"notice",
"info",
"debug",
"none"
]},
groups: [:base]
},
"DATABASE_URL" => %{
aliases: ["DB_URL"],
doc: "Full DB URL",
cast: Type.URL,
context: [env: [:prod]],
groups: [:primary_db],
required: [:primary_db]
},
"DATABASE_POOL_SIZE" => %{
aliases: ["DB_POOL_SIZE", "POOL_SIZE"],
cast: {Type.Integer, scope: :positive},
default: "10",
context: [env: [:prod]],
groups: [:primary_db]
},
"CONTACT_US_EMAILS" => %{
cast: {Type.CSV, of: Type.Email},
default: "help@example.com,feedback@example.com",
groups: [:landing_page],
context: [env: [:dev, :prod]]
}
})
end
You can read about all possible options in doc about the type Confispex.Schema.variable_spec/0
.
Put the following content to config/runtime.exs
:
import Config
Confispex.init(%{
schema: MyApp.RuntimeConfigSchema,
context: %{env: config_env(), target: config_target()}
})
# application config
config :logger,
level: String.to_atom(Confispex.get("LOG_LEVEL"))
config :my_app,
contact_us_emails: Confispex.get("CONTACT_US_EMAILS"),
database_pool: Confispex.get("DATABASE_POOL_SIZE"),
database_ssl: !Confispex.get("DATABASE_NO_SSL")
Now, if you run
LOG_LEVEL=info CONTACT_US_EMAILS=myemail1@example.com,myemail2 MIX_ENV=prod mix confispex.report --mode=detailed
you'll see the following report
Group colors
- green - group has required variables and they are present and valid. Such color is not present on a screenshot above, we'll make green group later.
- red - group has requried variables, they aren't present or they are invalid.
- blue - group doesn't have required variables and always functional, because there is always a default value to which system can fall back.
There are 3 groups in our example :landing_page
, :base
and :primary_db
:
:primary_db
is not functional, because all required variables weren't provided.:base
is functional, everything is valid.:landing_page
is functional too, because even if system failed to cast some value, default value is present and it is used.
Symbols
*
variable is required in specified group.?
variable is defined in schema, but was not invoked inruntime.exs
. It is not an error, just a warning. It might be a desired behavour for your case to have such items, because they may be hidden by some conditions which depend on other variables.✓
variable was provided and it is valid according to schema.-
variable wasn't provided and default value is used.
There is a block MISSING SCHEMA DEFINITIONS
at the bottom.
It simply prints variable names which were invoked in runtime.exs
, but not present in the schema.
Let's make everything functional.
Add DATABASE_NO_SSL
to the schema:
"DATABASE_NO_SSL" => %{
aliases: ["DB_NO_SSL"],
cast: Type.Boolean,
default: "false",
context: [env: [:prod]],
groups: [:primary_db]
}
Set DATABASE_URL
in runtime.exs
:
config :my_app,
# ...
database_url: Confispex.get("DATABASE_URL"),
and run report with valid values:
LOG_LEVEL=info CONTACT_US_EMAILS=myemail1@example.com,myemail2@host DB_URL=postgres://user:pwd@localhost:5432/db_name MIX_ENV=prod mix confispex.report --mode=detailed