# `BoxTurtle.Runtime.Config`
[🔗](https://github.com/twajjo/box_turtle/blob/v0.1.0/lib/runtime/config.ex#L1)

Loads a runtime configuration script (standard `import Config` syntax, read with `Config.Reader`) into the
application environment. Combine with `BoxTurtle.Runtime.Config.Helper` to get properly typed values from
environment variables.

After `load_runtime_config/1` runs, the script's settings are read with the usual `Application`
functions, just like compile-time config. Unlike Mix's own `config/runtime.exs`, the script can live
anywhere (for example `/etc/my_app/settings.exs` beside a release) and can be loaded again later.

## Usage

1. Write the settings script. Give it a name other than `config/runtime.exs`, which Mix and releases
   already load by themselves:

       # config/settings.exs
       import Config
       alias BoxTurtle.Runtime.Config.Helper

       config :my_app,
         pool_size: Helper.get_env("POOL_SIZE", type: :integer, default: 10),
         feature_flags: Helper.get_env("FEATURE_FLAGS", type: :list, subtype: :atom, default: [])

2. Point each build at its script. Relative paths are resolved from the current working directory:

       # config/dev.exs
       config :my_app, runtime_config_file: "config/settings.exs"

       # config/test.exs
       config :my_app, runtime_config_file: "test/support/settings.exs"

       # config/prod.exs
       config :my_app, runtime_config_file: "/etc/my_app/settings.exs"

3. Load it before starting anything that reads those settings:

       defmodule MyApp.Application do
         use Application

         @impl true
         def start(_type, _args) do
           :ok = BoxTurtle.Runtime.Config.load_runtime_config(:my_app)

           children = [{MyApp.Pool, size: Application.fetch_env!(:my_app, :pool_size)}]
           Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
         end
       end

Only non-nil values replace existing settings, so an unset environment variable without a
`:default` keeps the compile-time value.

To load a specific file instead, pass its path: `load_runtime_config("/etc/my_app/settings.exs")`.

# `debug`

```elixir
@spec debug(any(), String.t() | nil, keyword()) :: any()
```

Logs an inspection of the given value, optionally preceded by a message, and returns the value unchanged.
Used to place inspections in the midst of a chain of piped calls.

Nothing is logged unless this module is listed in the application's `:debug_enabled_modules` setting.

## Options

  * `:condition` - a function/1 receiving the value; the message is only logged when it returns true.
    Useful for throttling messages in highly repetitive code (log only a given id, a matching name, etc.).

## Examples

    # Inside a module that does `use BoxTurtle.Debug.PipeDebug` and is listed in
    # config :my_app, debug_enabled_modules: [...]
    %{jazz: "Art", messenger: "Blakey"}
    |> Map.values()
    |> debug("Jazz Message")          # logs: Jazz Message: ["Art", "Blakey"]
    |> Enum.reverse()                 # returns ["Blakey", "Art"]

# `load_runtime_config`

```elixir
@spec load_runtime_config(atom() | String.t()) :: :ok
```

Load runtime config from environment variables and express them as Application-accessible values.

Loading a runtime config will replace existing values set during compile time if given the same names.

## Parameters

  - application - the Application atom whose runtime configuration is to be set.
  OR
  - config_path - the path to a runtime script file to parse and load.

## Returns

  :ok

---

*Consult [api-reference.md](api-reference.md) for complete listing*
