Packages

Weave allows you to configure your application just-in-time (JIT), embracing the 12-Factor manifesto. Weave supports loading configuration from environment variables and files, with prefix and filename filtering. Works great with Kubernetes and Docker Swarm.

Current section

Files

Jump to
weave lib loader file.ex
Raw

lib/loader/file.ex

defmodule Weave.Loader.File do
require Logger
def load_configuration() do
with file_directory <- Application.get_env(:weave, :file_directory, :weave_no_directory),
handler <- Application.get_env(:weave, :handler, :weave_no_handler),
file_directory <- String.trim_trailing(file_directory, "/"),
true <- File.exists?(file_directory),
{:ok, files} <- File.ls(file_directory)
do
Logger.debug("Found configuration parameters: #{inspect files}")
Enum.each(files, fn (file_name) ->
load_configuration(file_directory, file_name, handler)
end)
else
:weave_no_directory -> Logger.warn("Tried to load configuration, but {:weave, :file_directory} hasn't been configured")
:weave_no_handler -> Logger.warn("Tried to load configuration, but {:weave, :handler} hasn't been configured")
false -> Logger.warn("Tried to load configuration from '#{Application.get_env(:weave, :file_directory)}', but directory doesn't exist.")
end
end
defp load_configuration(file_directory, file_name, handler) do
configuration = "#{file_directory}/#{file_name}"
|> File.read!()
|> String.trim()
try do
{app, key, value} = handler.handle_configuration(file_name, configuration)
Application.put_env(app, key, merge(Application.get_env(app, key), value))
Logger.debug("Configuration for #{app}:#{key} loaded: #{inspect Application.get_env(app, key)}")
rescue
error in UndefinedFunctionError ->
Logger.info("#{inspect error}")
handle_configuration(file_name, configuration)
end
end
defp merge(nil, new) when is_list(new) do
merge([], new)
end
defp merge(old, new) when is_list(new) do
if Keyword.keyword?(new) do
Logger.debug("Merging keywords: #{inspect old} and #{inspect new}")
Keyword.merge(old, new)
else
Logger.debug("Merging lists #{inspect old} and #{inspect new}")
old ++ new
end
end
defp merge(nil, new) when is_map(new) do
merge(%{}, new)
end
defp merge(old, new) when is_map(new) do
Map.merge(old, new)
end
defp merge(old, new) when is_binary(new) do
new
end
defp handle_configuration(file_name, configuration) do
Logger.warn("External configuration (#{file_name}) provided, but not loaded")
Logger.debug("configuration value for ignored '#{file_name}' is '#{configuration}'")
end
end