class Config::Sources::EnvSource

Allows settings to be loaded from a “flat” hash with string keys, like ENV.

Attributes

converter[R]
parse_arrays[R]
parse_values[R]
prefix[R]
separator[R]

Public Class Methods

new(env, prefix: Config.env_prefix || Config.const_name, separator: Config.env_separator, converter: Config.env_converter, parse_values: Config.env_parse_values, parse_arrays: Config.env_parse_arrays) click to toggle source
# File lib/config/sources/env_source.rb, line 11
def initialize(env,
               prefix: Config.env_prefix || Config.const_name,
               separator: Config.env_separator,
               converter: Config.env_converter,
               parse_values: Config.env_parse_values,
               parse_arrays: Config.env_parse_arrays)
  @env = env
  @prefix = prefix.to_s.split(separator)
  @separator = separator
  @converter = converter
  @parse_values = parse_values
  @parse_arrays = parse_arrays
end

Public Instance Methods

load() click to toggle source
# File lib/config/sources/env_source.rb, line 25
def load
  return {} if @env.nil? || @env.empty?

  hash = Hash.new

  @env.each do |variable, value|
    keys = variable.to_s.split(separator)

    next if keys.shift(prefix.size) != prefix

    keys.map! { |key|
      case converter
        when :downcase then
          key.downcase
        when nil then
          key
        else
          raise "Invalid ENV variables name converter: #{converter}"
      end
    }

    leaf = keys[0...-1].inject(hash) { |h, key|
      h[key] ||= {}
    }

    unless leaf.is_a?(Hash)
      conflicting_key = (prefix + keys[0...-1]).join(separator)
      raise "Environment variable #{variable} conflicts with variable #{conflicting_key}"
    end

    leaf[keys.last] = parse_values ? __value(value) : value
  end

  parse_arrays ? convert_hashes_to_arrays(hash) : hash
end

Private Instance Methods

__value(v) click to toggle source

Try to convert string to a correct type

# File lib/config/sources/env_source.rb, line 82
def __value(v)
  case v
  when 'false'
    false
  when 'true'
    true
  else
    Integer(v) rescue Float(v) rescue v
  end
end
consecutive_numeric_keys?(keys) click to toggle source
# File lib/config/sources/env_source.rb, line 77
def consecutive_numeric_keys?(keys)
  keys.map(&:to_i).sort == (0...keys.size).to_a && keys.all? { |k| k == k.to_i.to_s }
end
convert_hashes_to_arrays(hash) click to toggle source
# File lib/config/sources/env_source.rb, line 62
def convert_hashes_to_arrays(hash)
  hash.each_with_object({}) do |(key, value), new_hash|
    if value.is_a?(Hash)
      value = convert_hashes_to_arrays(value)
      if consecutive_numeric_keys?(value.keys)
        new_hash[key] = value.keys.sort_by(&:to_i).map { |k| value[k] }
      else
        new_hash[key] = value
      end
    else
      new_hash[key] = value
    end
  end
end