class Figgy::Finder

Public Class Methods

new(config) click to toggle source
# File lib/figgy/finder.rb, line 3
def initialize(config)
  @config = config
end

Public Instance Methods

all_key_names() click to toggle source

@return [Array<String>] the names of all unique configuration keys

# File lib/figgy/finder.rb, line 44
def all_key_names
  Dir[*file_globs].map { |file| File.basename(file).sub(/\..+$/, '') }.uniq
end
files_for(name) click to toggle source

@param [String] name the configuration key to search for @return [Array<String>] the paths to all files to load for configuration key name

# File lib/figgy/finder.rb, line 39
def files_for(name)
  Dir[*file_globs(name)]
end
load(name) click to toggle source

Searches for files defining the configuration key name, merging each instance found with the previous. In this way, the overlay configuration at production/foo.yml can override values in foo.yml.

If the contents of the file were a Hash, Figgy will translate it into a {Figgy::Hash Figgy::Hash} and perform deep-merging for all overlays. This allows you to override only a single key deep within the configuration, and to access it using dot-notation, symbol keys or string keys.

@param [String] name the configuration file to load @return Whatever was in the config file loaded @raise [Figgy::FileNotFound] if no config file could be found for name

# File lib/figgy/finder.rb, line 19
def load(name)
  files = files_for(name)
  if files.empty?
    raise(Figgy::FileNotFound, "Can't find config files for key: #{name.inspect}")
  end

  final_result = files.reduce(nil) do |result, file|
    object = @config.handler_for(file).call(File.read(file))
    if result && result.respond_to?(:merge)
      deep_merge(result, object)
    else
      object
    end
  end

  deep_freeze(to_figgy_hash(final_result))
end

Private Instance Methods

deep_freeze(obj) click to toggle source
# File lib/figgy/finder.rb, line 73
def deep_freeze(obj)
  return obj unless @config.freeze?
  case obj
  when ::Hash
    obj.each_pair { |k, v| obj[deep_freeze(k)] = deep_freeze(v) }
  when Array
    obj.map! { |v| deep_freeze(v) }
  end
  obj.freeze
end
deep_merge(a, b) click to toggle source
# File lib/figgy/finder.rb, line 84
def deep_merge(a, b)
  a.merge(b) do |key, oldval, newval|
    oldval.respond_to?(:merge) && newval.respond_to?(:merge) ? deep_merge(oldval, newval) : newval
  end
end
extension_globs(name = '*') click to toggle source
# File lib/figgy/finder.rb, line 57
def extension_globs(name = '*')
  @config.extensions.map { |ext| "#{name}.#{ext}" }
end
file_globs(name = '*') click to toggle source
# File lib/figgy/finder.rb, line 50
def file_globs(name = '*')
  globs = extension_globs(name)
  @config.overlay_dirs.map { |dir|
    globs.map { |glob| File.join(dir, glob) }
  }.flatten
end
to_figgy_hash(obj) click to toggle source
# File lib/figgy/finder.rb, line 61
def to_figgy_hash(obj)
  case obj
  when ::Hash
    obj.each_pair { |k, v| obj[k] = to_figgy_hash(v) }
    Figgy::Hash.new(obj)
  when Array
    obj.map { |v| to_figgy_hash(v) }
  else
    obj
  end
end