Packages
persist_config
0.4.44
0.4.56
0.4.55
0.4.54
0.4.53
0.4.52
0.4.51
0.4.50
0.4.49
0.4.48
0.4.47
0.4.46
0.4.45
0.4.44
0.4.43
0.4.42
0.4.41
0.4.40
0.4.39
0.4.38
0.4.37
0.4.36
0.4.35
0.4.34
0.4.33
0.4.32
0.4.31
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Persists configurations from given files at compile time.
Current section
Files
Jump to
Current section
Files
lib/persist_config.ex
defmodule PersistConfig do
@moduledoc ~S"""
Persists the configurations from a list of files __during compilation__.
Also puts the current application name in a module attribute and provides
macros `get_env/2`, `get_app_env/3` and `get_all_env/1` for concise
configuration value retrieval.
## Installation
Add `persist_config` to your list of dependencies in `mix.exs`. Also include
the required configuration files in the `package` definition of `mix.exs`:
```elixir
def project do
[
app: :your_app,
...
deps: deps(),
package: package(),
...
]
end
...
def deps do
[
{:persist_config, "~> 0.4", runtime: false}
]
end
...
defp package do
[
# NOTE: Config files... ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
files: ["lib", "mix.exs", "README*", "config/persist*.exs"],
maintainers: [...],
licenses: [...],
links: %{...}
]
end
```
## Usage
`use PersistConfig` supports the following options:
- `:app` - module attribute to hold the current application name,
defaults to `:app`
- `:files` - wildcard paths, defaults to `["config/persist*.exs"]`
Option `:files` selects the files whose configurations will be persisted.
Each wildcard path is relative to the root. If no matching files are found,
no configurations will be persisted.
Though not required, you can still import the configurations from the above
matching files in `config/config.exs` or friends. For example:
```elixir
import Config
import_config "persist_this_config.exs"
```
Even when your project is used as a dependency, this package will load and
persist the configurations from the specified files __during compilation__.
For example, you may configure some path to read an external file and want
to still read that __very__ file when your app is a dependency (without and
despite any path configuration in the parent app). To achieve this, you may:
__1.__ Use a module attribute as a __constant__:
```elixir
use PersistConfig
...
@path get_env(:path)
...
contents = File.read!(@path)
```
__2.__ Create a configuration file named, say, `config/persist_path.exs`:
```elixir
import Config
config :words_cache, path: "#{File.cwd!()}/assets/words.txt"
```
__3.__ In `mix.exs`, specify a package definition like this:
```elixir
def project do
[
app: :words_cache,
...
deps: deps(),
package: package(),
...
]
end
...
def deps do
[
{:persist_config, "~> 0.4", runtime: false}
]
end
...
defp package do
[
# ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
files: [... "assets/words.txt", "config/persist*.exs"],
maintainers: [...],
licenses: [...],
links: %{...}
]
end
```
#### Example 1
The current application name is in `@app` by default:
```elixir
use PersistConfig, files: ["config/persist_path.exs"]
...
@all_env get_all_env(@app)
@path get_env(:path)
```
#### Example 2
The current application name is in `@my_app` as an option:
```elixir
use PersistConfig, app: :my_app
...
@my_attr get_app_env(@my_app, :my_attr)
```
#### Example 3
You can use macro `get_env/2` to retrieve configuration values at runtime
when configuration is done by `config/config.exs` and friends:
```elixir
use PersistConfig
...
defp level, do: get_env(:level, :all)
```
"""
@doc """
Persists the configurations from a list of files __during compilation__.
Also puts the current application name in a module attribute.
`use PersistConfig` supports the following options:
- `:app` - module attribute to hold the current application name,
defaults to `:app`
- `:files` - wildcard paths, defaults to `["config/persist*.exs"]`
Option `:files` selects the files whose configurations will be persisted.
Each wildcard path is relative to the root. If no matching files are found,
no configurations will be persisted.
"""
defmacro __using__(options \\ []) do
app = Keyword.get(options, :app, :app)
files = Keyword.get(options, :files, ["config/persist*.exs"])
files = Enum.map(files, &Path.wildcard/1) |> List.flatten()
quote bind_quoted: [app: app, files: files], unquote: true do
import unquote(__MODULE__)
Enum.each(files, fn file ->
Config.Reader.read!(file) |> Application.put_all_env(persistent: true)
@external_resource Path.expand(file)
end)
Module.put_attribute(__MODULE__, app, Mix.Project.config()[:app])
end
end
@doc """
Returns the value for `key` in the current application's environment.
If the configuration parameter does not exist, returns the `default` value.
"""
@doc since: "0.4.0"
defmacro get_env(key, default \\ nil) do
app = Mix.Project.config()[:app]
quote bind_quoted: [app: app, key: key, default: default] do
:application.get_env(app, key, default)
end
end
@doc """
Returns the value for `key` in the given `app`'s environment.
If the configuration parameter does not exist, returns the `default` value.
"""
@doc since: "0.4.24"
defmacro get_app_env(app, key, default \\ nil) do
quote bind_quoted: [app: app, key: key, default: default] do
:application.get_env(app, key, default)
end
end
@doc """
Returns all key-value pairs for `app`.
"""
@doc since: "0.4.27"
defmacro get_all_env(app) do
quote bind_quoted: [app: app] do
:application.get_all_env(app)
end
end
end