class Dry::Config::Base

Dry::Config::Base allows for default settings and mounting a specific environment with overriding hash values and merging of array values.

NOTE: Anything can be overridden and merged into top-level settings (hashes) including
anything that is an array value.  Array values are merged *not* replaced.  If you think
something is screwy, see the defaults in the #initialize as those add some default array values.
If this behavior of merging arrays or the defaults are somehow un-sensible, file an issue and we'll revisit it.

Attributes

configuration[R]
environment[R]
filenames[R]

Public Class Methods

new(options = {}) click to toggle source
# File lib/dry/config/base.rb, line 24
def initialize(options = {})
  @options = {
      env: ENV,                  # default to ENV for interpolation
      interpolation: true,       # interpolate string contents on read with given ENV
      symbolize: true,           # provide symbol based key access for everything
      unsymbolize_to_yaml: true, # on to_yaml or write_yaml_file unsymbolize keys
      default_configuration: {}, # seed configuration
      prune: [:development, :test, :staging, :production] # used for pruning (optional)
  }.merge options

  @default_configuration = @options[:default_configuration]

  # (optional) used for pruning initial base set.  See #resolve_config
  @prune = @options[:prune]

  # setup a default configuration
  clear
end

Public Instance Methods

[](key) click to toggle source

configuration hash delegation with option based symbolization

# File lib/dry/config/base.rb, line 167
def [] key
  key = key.to_sym if symbolize?
  @configuration[key]
end
[]=(key, value) click to toggle source

configuration hash delegation with option based symbolization

# File lib/dry/config/base.rb, line 173
def []=(key, value)
  key = key.to_sym if symbolize?
  @configuration[key] = value
end
clear() click to toggle source
# File lib/dry/config/base.rb, line 154
def clear
  # clone a copy of the default
  @configuration = {}.merge @default_configuration
  @configuration.deep_symbolize if symbolize?
end
include?(key) click to toggle source

configuration hash delegation with option based symbolization

# File lib/dry/config/base.rb, line 179
def include?(key)
  key = key.to_sym if symbolize?
  @configuration.include? key
end
interpolate?() click to toggle source
# File lib/dry/config/base.rb, line 192
def interpolate?
  @options[:interpolation]
end
load!(environment, *filenames) click to toggle source

Load the configuration and save state.

We call load! and provide a name of the file to read as it’s argument. We can also pass in some options, but at the moment it’s being used to allow per-environment overrides in Rails

# File lib/dry/config/base.rb, line 48
def load!(environment, *filenames)

  # save these in case we #reload
  @environment = environment
  @filenames = filenames

  # load the configuration
  @configuration = load_unpruned(environment, *filenames)

  # Prune all known environments so that we end up with the top-level configuration.
  @prune.each do |env|
    @configuration.delete(env)
  end
end
load_unpruned(environment, *filenames) click to toggle source

Load the configuration without saving state. Useful for validation of complex configuration resolution without

altering the existing state.
# File lib/dry/config/base.rb, line 65
def load_unpruned(environment, *filenames)

  # raise 'Unspecified environment' if environment.nil?
  raise 'Unspecified filename' if filenames.nil?

  # ensure symbol if symbolize?
  environment = environment.to_sym if symbolize? && !environment.nil?

  # get a clone of the current configuration
  config = {}.merge @configuration

  filenames.each do |filename|
    # merge all top level settings with the defaults set in the #init
    config.deeper_merge! resolve_config(environment, filename)
  end

  config
end
load_yaml_file(filename) click to toggle source
# File lib/dry/config/base.rb, line 104
def load_yaml_file(filename)

  # without interpolation
  # config = Psych.load_file(filename)

  # get file contents as string
  file = File.open(filename, 'r:bom|utf-8')
  contents = file.read

  env = @options[:env]
  if interpolate?
    # interpolate/substitute/expand ENV variables with the string contents before parsing
    # bash - $VAR
    contents = contents.gsub(/\$(\w+)/) { env[$1] }
    # bash - ${VAR}
    contents = contents.gsub(/\${(\w+)}/) { env[$1] }
    # bash - ~ is env['HOME']
    contents = contents.gsub(/(~)/) { env['HOME'] }
    # ruby - #{VAR}
    contents = contents.gsub(/\#{(\w+)}/) { env[$1] }
  end
  # now parse
  config = Psych.load(contents, filename)

  raise "Failed to load #{filename}" if config.nil?
  config = config.deep_symbolize if symbolize?
  config
end
method_missing(name, *args, &block) click to toggle source
# File lib/dry/config/base.rb, line 160
def method_missing(name, *args, &block)
  @configuration[name.to_sym] ||
      #fail(NoMethodError, "Unknown settings root \'#{name}\'", caller)
      nil
end
reload!() click to toggle source
# File lib/dry/config/base.rb, line 149
def reload!
  clear
  load! @environment, @filenames
end
resolve_config(environment, filename) click to toggle source
# File lib/dry/config/base.rb, line 84
def resolve_config(environment, filename)
  config = load_yaml_file(filename)

  should_overlay_environment = environment && config[environment]

  # overlay the specific environment if provided
  if should_overlay_environment
    # re-read the file
    environment_settings = load_yaml_file(filename)

    # snag the requested environment
    environment_settings = environment_settings[environment.to_sym]

    # finally overlay what was provided the settings from the specific environment
    config.deeper_merge! environment_settings
  end

  config
end
symbolize?() click to toggle source
# File lib/dry/config/base.rb, line 184
def symbolize?
  @options[:symbolize]
end
to_yaml(config = @configuration) click to toggle source
# File lib/dry/config/base.rb, line 133
def to_yaml(config = @configuration)
  if unsymbolize_to_yaml?
    config = config.dup.deep_symbolize(true)
  else
    config = @configuration
  end

  Psych.dump(config)
end
unsymbolize_to_yaml?() click to toggle source
# File lib/dry/config/base.rb, line 188
def unsymbolize_to_yaml?
  @options[:unsymbolize_to_yaml]
end
write_yaml_file(filename, config = @configuration) click to toggle source
# File lib/dry/config/base.rb, line 143
def write_yaml_file(filename, config = @configuration)
  File.open(filename, 'w') do |file|
    file.write(to_yaml(config))
  end
end