module Collapsium::EnvironmentOverride

The EnvironmentOverride module wraps read access methods to return the contents of environment variables derived from the key instead of the value contained in the Hash.

The environment variable to use is derived from the key by replacing all consecutive occurrences of non-alphanumeric characters with an underscore (_), and converting the alphabetic characters to upper case. Leading and trailing underscores will be stripped.

For example, the key “some!@email.org” will become “SOME_EMAIL_ORG”.

If PathedAccess is also used, the :path_prefix of nested hashes will be consulted after converting it in the same manner. NOTE: include EnvironmentOverride after PathedAccess for both to work well together.

Constants

ENV_ACCESS_READER

Returns a proc read access.

Public Class Methods

enhance(base) click to toggle source
# File lib/collapsium/environment_override.rb, line 103
def enhance(base)
  # Make the capabilities of classes using EnvironmentOverride viral.
  base.extend(ViralCapabilities)

  # Wrap read accessor functions to deal with paths
  (INDEXED_READ_METHODS + KEYED_READ_METHODS).each do |method|
    wrap_method(base, method, raise_on_missing: false, &ENV_ACCESS_READER)
  end
end
environment_variables_for_key(receiver, key) click to toggle source
# File lib/collapsium/environment_override.rb, line 113
def environment_variables_for_key(receiver, key)
  env_keys = []
  if receiver.respond_to?(:path_prefix)

    # If we have a prefix, use it.
    components = []
    if not receiver.path_prefix.nil?
      components += receiver.path_components(receiver.path_prefix)
    end

    # The key has its own components. If the key components and prefix
    # components overlap (it happens), ignore the duplication.
    key_comps = receiver.path_components(key.to_s)
    if key_comps.first == components.last
      components.pop
    end
    components += key_comps

    # Start with most qualified, shifting off the first component
    # until we reach just the last component.
    loop do
      path = receiver.normalize_path(components)
      env_keys << path
      components.shift
      if components.empty?
        break
      end
    end
  else
    env_keys = [key.to_s]
  end
  env_keys.map! { |k| key_to_env(k) }
  env_keys.reject!(&:empty?)
  env_keys.uniq!

  return env_keys
end
extended(base) click to toggle source
# File lib/collapsium/environment_override.rb, line 95
def extended(base)
  enhance(base)
end
included(base) click to toggle source
# File lib/collapsium/environment_override.rb, line 91
def included(base)
  enhance(base)
end
key_to_env(key) click to toggle source
# File lib/collapsium/environment_override.rb, line 188
def key_to_env(key)
  # First, convert to upper case
  env_key = key.upcase

  # Next, replace non-alphanumeric characters to underscore. This also
  # collapses them into a single undescore.
  env_key.gsub!(/[^[:alnum:]]+/, '_')

  # Strip leading and trailing underscores.
  env_key.gsub!(/^_*(.*?)_*$/, '\1')

  return env_key
end
override_value(variables, receiver, key) click to toggle source
# File lib/collapsium/environment_override.rb, line 151
def override_value(variables, receiver, key)
  value = nil
  variables.each do |env_key|
    # Grab the environment value; skip if there's nothing there.
    env_value = ENV[env_key]
    if env_value.nil?
      next
    end

    # If the environment variable parses as JSON, that's great, we'll use
    # the parsed result. Otherwise use it as a string.
    require 'json'
    # rubocop:disable Lint/HandleExceptions
    parsed = env_value
    begin
      parsed = JSON.parse(env_value)
    rescue JSON::ParserError
      # Do nothing. We just use the env_value verbatim.
    end
    # rubocop:enable Lint/HandleExceptions

    # Excellent, we've got an environment variable. Only use it if it
    # changes something, though. We'll temporarily unset the environment
    # variable while fetching the old value.
    ENV.delete(env_key)
    old_value = receiver[key]
    ENV[env_key] = env_value # not the parsed value!

    if parsed != old_value
      value = parsed
    end
    break
  end

  return value
end
prepended(base) click to toggle source
# File lib/collapsium/environment_override.rb, line 99
def prepended(base)
  enhance(base)
end