Simple base class for DRY inheritable configurations that can be loaded from multiple overriding yml files.
Sample uses include environment based e.g. development, test, production
and multi-domain white label configurations.
A programmatic seed configuration may be specified, as well as the ability to load one to many overriding configuration files.
Results may be re-written to an output file, useful for compiling static files for other processes such as docker-compose.yml
.
The elastic-beanstalk gem is a real world example that utilized Dry::Config::Base
.
Add this line to your application's Gemfile:
gem 'dry-config'
And then execute:
$ bundle
Or install it yourself as:
$ gem install dry-config
The following example shows a single file where environments will override base level settings. dry-config
is useful for simple, to multi-file, multi-environmet settings.
Note this sample uses the Singleton
pattern, which is useful but not required.
require 'singleton'
require 'dry/config'
class AcmeConfig < Dry::Config::Base
# (optional) make this the only instance
include Singleton
def initialize(options = {})
options = {
# seed the sensible defaults here (overridable)
default_configuration: {
environment: nil,
strategy: :blue_green,
package: {
verbose: false
},
options: {}
}}.merge(options)
super(options)
end
end
# sample config demonstrating multi-environment override
---
app: acme
title: Acme Holdings, LLC
#---
options:
aws:elasticbeanstalk:application:environment:
RAILS_ENV: foobar
aws:autoscaling:launchconfiguration:
InstanceType: foo
#---
development:
strategy: inplace-update
package:
verbose: true
options:
aws:autoscaling:launchconfiguration:
InstanceType: t1.micro
aws:elasticbeanstalk:application:environment:
RAILS_ENV: development
#---
production:
options:
aws:autoscaling:launchconfiguration:
InstanceType: t1.large
aws:elasticbeanstalk:application:environment:
RAILS_ENV: production
Note that multiple files can be loaded and overriden. A nil environment is also possible.
AcmeConfig.instance.load!(:production, 'path_to/acme.yml')
Note that all keys are symbolized upon loading.
config = Acme.config.instance
config.load!(:production, 'path_to/acme.yml')
config.app # acme
config.title # Acme Holdings, LLC
config.strategy # :blue_green,
config.options[:'aws:autoscaling:launchconfiguration'][:InstanceType] # t1.large
class WhiteLabelConfig < Dry::Config::Base
end
config = WhiteLabelConfig.new
config.load!(nil, 'base.yml', 'acme.com.yml', 'scheduling.acme.com.yml')
ENV variable substitution is supported and enabled by default. It may be disabled by initializing with {interpolation: false}
.
The following formats are acceptable:
interpolations:
- ~/foo
- $HOME/foo
- ${HOME}/foo
- #{HOME}/foo
# mixed example
- ~/docker/mysql/${PROJECT_NAME}-${BUILD}:/var/lib/mysql:rw
The default configuration is provided below, override any of these values on construction:
{
env: ENV, # default to ENV for interpolation
interpolation: true, # interpolate contents on read with env (above defaults to the current process's ENV)
symbolize: true, # provide symbol based key access for everything i.e. access :development instead of 'development' as a rule
unsymbolize_to_yaml: true, # on to_yaml or write_yaml_file unsymbolize keys (several external tools do not do well with symbolized keys i.e. write `development:` instead of `:development:`
default_configuration: {}, # seed configuration (file contents overlay this)
prune:
[:development, :test, :staging, :production] # used for pruning final configuration (optional - nice to have cleanup)
}
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request