Ruby config management with a strong, checked schema and mapping from environment
by Dan Brown [email protected]
Environmentor is a gem to help you provide the correct configuration for your Ruby application from the environment, and/or a configuration store. You define the configuration values you require, with certain types, and Environmentor will abort with a helpful error message if anything required is missing. The current alternatives are less declarative (so more room for error) or leave the discovery of missing configuration until runtime – often too late. Errors are collected and all are shown at once, making it easy to fix all missing or incorrect configuration in one go.
I’ve designed it for flexibility and transparency. The DSL, such as it is, is only a thin layer around an ordinary Ruby object graph, that is easy to construct yourself if you wish, and therefore also easy to understand and extend. Mappers take values from a given configuration defined by attributes in a schema. They can then map these values onto any ordinary Ruby module.
Add this line to your application’s Gemfile:
gem 'environmentor'
And then execute:
$ bundle
Or install it yourself as:
$ gem install environmentor
Here’s a quick example:
module AppConfig
extend Environmentor::Configurable
environmentor.with_mapper :env do
attr_config :welcome_message
end
end
Environmentor::Configurable
provides the method environmentor
, which is the DSL’s entry point to the API. This is so that the namespace of your module is as unpolluted as possible. with_mapper
creates a new schema, using mappers that you give. You can pass mappers as their actual Environmentor::Mapper
instance or by their symbol name. This will create a new mapper with default options.
The schema defines one attribute. The :env
mapper, using as it does environment variables, will guess that it’s looking for a variable called WELCOME_MESSAGE
. If it’s blank, there will be an error.
module AppConfig
extend Environmentor::Configurable
environmentor.with_mapper :env, prefix: 'MYAPP_' do
attr_config :welcome_message
attr_config :aws_access_id, mappers: {env: {full_name: 'AWS_ACCESS_ID'}}
end
end
Here’s a slightly more involved example. Here, Environmentor will look for MYAPP_WELCOME_MESSAGE
, but AWS_ACCESS_ID
. The prefix is applied by default, but the :env
mapper’s variable name guessing can be overridden. Supplying name:
instead of full_name:
would use the prefix.
module AppConfig
extend Environmentor::Configurable
environmentor.with_mapper :env, prefix: 'MYAPP_' do
attr_config :num_wibbles, type: :int
attr_config :ice_cream_flavour, required: false
attr_config :input_manager, required: false, default: 'auto'
end
end
You can coerce values coming in from the mapper’s source. Here, a value will be converted to an integer using #to_i
. There’s also a config attribute ice_cream_flavour
that isn’t required. Environmentor won’t raise an error if this isn’t present, and the attribute will return nil
. input_manager
is also not required, but has a default specified.
module AppConfig
extend Environmentor::Configurable
environmentor.with_mapper :env, prefix: 'MYAPP_' do
attr_config :reliable, type: :bool
namespace :stripe do
attr_config :api_key
end
end
end
Last one for now. Here we have reliable
, which to remind you here will take a value from the environment variable MYAPP_RELIABLE
, is set as a :bool
. This will take a boolean-looking value (including understanding t
, f
, yes
, no
, etc). Also we have a namespace. This is just a nested schema that knows about its parent. So the api_key
here will be taken from a variable called MYAPP_STRIPE_API_KEY
.
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)Please follow style and conventions already in the codebase. Particularly: 80 columns, de-indended protected
/private
, whitespace around block brackets, that sort of thing. Thanks!