Class: Appydays::Configurable::Installer

Inherits:
Object
  • Object
show all
Defined in:
lib/appydays/configurable.rb

Instance Method Summary collapse

Constructor Details

#initialize(target, group_key) ⇒ Installer

Returns a new instance of Installer.



73
74
75
76
77
78
# File 'lib/appydays/configurable.rb', line 73

def initialize(target, group_key)
  @target = target
  @group_key = group_key
  @settings = {}
  @after_config_hooks = []
end

Instance Method Details

#_converter(default, converter) ⇒ Object

Raises:

  • (TypeError)


136
137
138
139
140
141
142
143
144
145
# File 'lib/appydays/configurable.rb', line 136

def _converter(default, converter)
  return converter if converter

  return ->(v) { v.to_s } if default.nil? || default.is_a?(String)
  return ->(v) { v.to_i } if default.is_a?(Integer)
  return ->(v) { v.to_f } if default.is_a?(Float)
  return ->(v) { v.to_sym } if default.is_a?(Symbol)
  return ->(v) { v.casecmp("true").zero? } if [TrueClass, FalseClass].include?(default.class)
  raise TypeError, "Uncoercable type %p" % [default.class]
end

#_group_keyObject



151
152
153
# File 'lib/appydays/configurable.rb', line 151

def _group_key
  return @group_key
end

#_reset(overrides) ⇒ Object



161
162
163
164
165
166
167
# File 'lib/appydays/configurable.rb', line 161

def _reset(overrides)
  @settings.each do |k, v|
    real_v = overrides.fetch(k, v)
    @target.send("#{k}=".to_sym, real_v)
  end
  self._run_after_configured
end

#_run_after_configuredObject



155
156
157
158
159
# File 'lib/appydays/configurable.rb', line 155

def _run_after_configured
  @after_config_hooks.each do |h|
    @target.instance_eval(&h)
  end
end

#_set_value(name, value, side_effect) ⇒ Object



123
124
125
126
127
128
129
130
# File 'lib/appydays/configurable.rb', line 123

def _set_value(name, value, side_effect)
  value = nil if value == ""
  # rubocop:disable Style/ClassVars
  self._target.class_variable_set("@@#{name}", value)
  # rubocop:enable Style/ClassVars
  self._target.instance_exec(value, &side_effect) if side_effect
  return value
end

#_targetObject



147
148
149
# File 'lib/appydays/configurable.rb', line 147

def _target
  return @target
end

#after_configured(&block) ⇒ Object



132
133
134
# File 'lib/appydays/configurable.rb', line 132

def after_configured(&block)
  @after_config_hooks << block
end

#setting(name, default, key: nil, convert: nil, side_effect: nil) ⇒ Object

Define a setting for the receiver, which acts as an attribute accessor.

Params:

name: The name of the accessor/setting. default: The default value.

If `convert` is not supplied, this must be nil, or a string, int, float, or boolean,
so the parsed environment value can be converted/coerced into the same type as 'default'.
If convert is passed, that is used as the converter so the default value can be any type.

key: The key to lookup the config value from the environment.

If nil, use an auto-generated combo of the configuration key and method name.
If key is an array, look up each (string) value as a key.
The first non-nil (ie, `ENV.fetch(x, nil)`) value will be used.

convert: If provided, call it with the string value so it can be parsed.

For example, you can parse a string JSON value here.
Convert will not be called with the default value.

side_effect: If this setting should have a side effect,

like configuring an external system, it should happen in this proc/lambda.
It is called with the parsed/processed config value.

Note that only ONE conversion will happen, and

  • If converter is provided, it will be used with the environment value.



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/appydays/configurable.rb', line 104

def setting(name, default, key: nil, convert: nil, side_effect: nil)
  installer = self

  @target.define_singleton_method(name) do
    self.class_variable_get("@@#{name}")
  end
  @target.define_singleton_method("#{name}=".to_sym) do |v|
    installer._set_value(name, v, side_effect)
  end

  key ||= "#{@group_key}_#{name}".upcase
  keys = Array(key)
  env_value = keys.filter_map { |k| ENV.fetch(k, nil) }.first
  converter = self._converter(default, convert)
  value = env_value.nil? ? default : converter[env_value]
  value = installer._set_value(name, value, side_effect)
  @settings[name] = value
end