Class: Envolve::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/envolve/config.rb

Overview

Public: A Configuration class to hold your application configuration

Feed it ENV or some other Hash-like object and it will allow you to access the elements in that hash via methods.

You can also tell it to only pull those items from the initial hash that have a particular prefix, and that prefix will be stripped off of the elements for access.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env: self.class.environment_source, prefix: self.class.prefix, key_separator: self.class.key_separator) ⇒ Config

Public: Create a new Config



92
93
94
95
96
97
98
# File 'lib/envolve/config.rb', line 92

def initialize( env: self.class.environment_source, prefix: self.class.prefix,
               key_separator: self.class.key_separator )
  @_key_separator = key_separator
  @_prefix        = prefix.nil? ? nil : prefix.to_s.downcase.strip
  @_env           = process_env( env )

end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object

Internal: This is how we convert method calls into key lookups in the internal hash.



197
198
199
200
201
202
203
204
# File 'lib/envolve/config.rb', line 197

def method_missing( method, *args, &block )
  s_method = method.to_s
  if _env.has_key?( s_method ) then
    _env[ s_method ]
  else
    super
  end
end

Instance Attribute Details

#_envObject (readonly)

Internal: The internal hash like item holding all the keys and values



83
84
85
# File 'lib/envolve/config.rb', line 83

def _env
  @_env
end

#_key_separatorObject (readonly)

Internal: The character to use as the key separator



89
90
91
# File 'lib/envolve/config.rb', line 89

def _key_separator
  @_key_separator
end

#_prefixObject (readonly)

Internal: The prefix to strip off all the keys



86
87
88
# File 'lib/envolve/config.rb', line 86

def _prefix
  @_prefix
end

Class Method Details

.environment_source(*args, &block) ⇒ Object

Public: Return the default environment.

Override this to return a different environment source



15
16
17
18
19
20
21
22
23
24
# File 'lib/envolve/config.rb', line 15

def self.environment_source( *args, &block )
  if args.size > 0 then
    @_default_env = args.first
  elsif block_given? then
    @_default_env = block.call
  else
    @_default_env = ENV unless defined?( @_default_env )
  end
  @_default_env.to_h
end

.key_separator(*args, &block) ⇒ Object

Public: Return the key_separator to be used by the class

Override this to return a different key_separator, or meta program it in an inherited class.



43
44
45
46
47
48
49
50
# File 'lib/envolve/config.rb', line 43

def self.key_separator( *args, &block )
  if args.size > 0 then
    @_key_separator = args.first
  else
    @_key_separator = '_'.freeze unless defined?( @_key_separator )
  end
  @_key_separator
end

.prefix(*args) ⇒ Object

Public: Return the prefix to be used by the class

Override this to return a different prefix, or meta program it in an inherited class.



30
31
32
33
34
35
36
37
# File 'lib/envolve/config.rb', line 30

def self.prefix( *args )
  if args.size > 0 then
    @_prefix = args.first
  else
    @_prefix = nil unless defined?( @_prefix )
  end
  @_prefix
end

.propertiesObject

Internal: Return the hash holding the properties

Returns Hash



78
79
80
# File 'lib/envolve/config.rb', line 78

def self.properties
  @_properties ||= Hash.new
end

.property(property, key: nil, value: nil, default: nil, required: false) ⇒ Object

Public: Set a property, with possible transformations

In the conversion of the environment to the configuration properties sometimes the keys and/or values need to be converted to a new name.

All property transformations take place AFTER the initial keys have been downcased and prefix stripped.

property - the name of the property we want to appear in the configuration key - the source key from the environment where this property comes from value - the new value for this property default - setting a default for this property should the environment not

provide a value

required - this property is required to be set via env. If it is not, an

execption is raised when the environment is parsed

value may also be a lambda, in which ase the lambda is given the original value and the return value from the labmda is used for the new value.



71
72
73
# File 'lib/envolve/config.rb', line 71

def self.property( property, key: nil, value: nil, default: nil, required: false )
  properties[property] = { :key => key, :value => value, :default => default, :required => required }
end

Instance Method Details

#[](key) ⇒ Object

Public: return the value for the give key

key - the String key to use for fetching

Returns value or nil if no value is found



162
163
164
# File 'lib/envolve/config.rb', line 162

def []( key )
  _env[key]
end

#apply_transformation(input, transformer) ⇒ Object

Internal: Apply the given transformation to the input.

Returns the result of the transformation



137
138
139
140
141
# File 'lib/envolve/config.rb', line 137

def apply_transformation( input, transformer )
  return input                     if transformer.nil?
  return transformer.call( input ) if transformer.respond_to?( :call )
  return transformer
end

#config_with_prefix(prefix) ⇒ Object

Public: Return a subset of the config with just those items that have a prefix on them

The resulting Config only has those keys, and all with the prefixes stripped



171
172
173
# File 'lib/envolve/config.rb', line 171

def config_with_prefix( prefix )
  self.class.new( env: _env, prefix: prefix )
end

#keysObject

Public: Just the keys, only the keys, as Strings

Returns an Array of the keys as Strings



153
154
155
# File 'lib/envolve/config.rb', line 153

def keys
  _env.keys
end

#prefix_regex(prefix, key_separator) ⇒ Object

Internal: The prefix regular expression used for stripping leading prefix

This matches Beginning of String followed by the prefix followed by 0 or more key_separator characters.

This will use named captures. The prefix will be under key ‘prefix’ and the following will be under ‘rest’

Returns the regex



221
222
223
# File 'lib/envolve/config.rb', line 221

def prefix_regex( prefix, key_separator  )
  /\A(?<prefix>#{prefix}[#{key_separator}]*)(?<rest>.*)\Z/i
end

#process_env(env) ⇒ Object

Internal: Process and Transform the keys and values from the environment into the final hash



104
105
106
107
108
109
110
# File 'lib/envolve/config.rb', line 104

def process_env( env )
  env = downcase_keys( env )
  if _prefix then
    env = filter_by_prefix( env, _prefix )
  end
  env = transform_properties( env, self.class.properties )
end

#respond_to_missing?(symbol, include_all = false) ⇒ Boolean

Internal: Respond to missing should always be implemented if you implement method_missing

Returns:

  • (Boolean)


208
209
210
# File 'lib/envolve/config.rb', line 208

def respond_to_missing?( symbol, include_all = false )
  _env.has_key?( symbol.to_s ) || super
end

#sizeObject

Public: The number of elements in the config

Returns the number of elements



146
147
148
# File 'lib/envolve/config.rb', line 146

def size
  _env.size
end

#to_hObject Also known as: to_hash

Public: Return as hash of the keys and values

Returns a Hash



178
179
180
# File 'lib/envolve/config.rb', line 178

def to_h
  _env.to_h.dup
end

#to_symbolized_hObject Also known as: to_symbolized_hash

Public: Return a hash of the keys and values with the keys as symbols.

Returns a Hash



186
187
188
189
190
191
192
# File 'lib/envolve/config.rb', line 186

def to_symbolized_h
  h = {}
  _env.each do |key, value|
    h[key.to_sym] = value
  end
  return h
end

#transform_properties(env, properties) ⇒ Object

Internal: Transform the environment variables to propreties

Raises MissingPropertyError if the property is required Returns the transformed hash



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/envolve/config.rb', line 116

def transform_properties( env, properties )
  transformed = env.to_h.dup

  properties.each do |dest_key, trans|
    src_key = trans[:key]
    src_key ||= dest_key
    if value = transformed.delete(src_key) then
      value = apply_transformation(value, trans[:value]) if trans[:value]
    elsif value.nil? then
      ::Envolve::MissingPropertyError.raise(_prefix, src_key) if trans[:required]
      value = trans[:default] if trans[:default]
    end
    transformed[dest_key] = value
  end

  return transformed
end