class Jac::Configuration::ConfigurationReader

Reads and evaluates configuration for given set of streams and profile

Attributes

merger[R]

Public Class Methods

new(streams) click to toggle source

Creates configuration reader @param [Array] streams of pairs containing YAML document and provided

name for this stream
# File lib/jac/configuration.rb, line 206
def initialize(streams)
  @streams = streams
  @merger = Merger.new
end

Public Instance Methods

read(*profile) click to toggle source

Parses all streams and resolves requested profile @param [Array] profile list of profile names to be merged @return [OpenStruct] instance which contains all resolved profile fields

# File lib/jac/configuration.rb, line 214
def read(*profile)
  result = @streams
           .flat_map { |stream, _name| read_stream(stream) }
           .inject(default_configuration) { |acc, elem| update(acc, elem) }
  # Keep original profile name
  original_profile = profile
  # Add implicit profiles
  profile =
    [Configuration::BASE_PROFILE_NAME, profile, Configuration::TOP_PROFILE_NAME].flatten
  OpenStruct.new(evaluate(resolve(profile, result).merge('profile' => original_profile)))
end

Private Instance Methods

default_configuration() click to toggle source

Creates empty configuration object.

# File lib/jac/configuration.rb, line 229
def default_configuration
  Configuration::BASIC_PROFILES.inject({}) { |acc, elem| acc.update(elem => {}) }
end
evaluate(resolved_profile) click to toggle source
# File lib/jac/configuration.rb, line 276
def evaluate(resolved_profile)
  ConfigurationEvaluator.evaluate(resolved_profile)
end
merge!(base, values) click to toggle source

Merges two hash structures using following rules @param [Hash] base value mappings @param [Hash] values ovverides. @return [Hash] merged profile

# File lib/jac/configuration.rb, line 268
def merge!(base, values)
  merger.merge!(base, values)
end
read_stream(stream) click to toggle source
# File lib/jac/configuration.rb, line 233
def read_stream(stream)
  # Each stream consists of one or more documents
  YAML.parse_stream(stream).children.flat_map do |document|
    # Will use separate visitor per YAML document.
    visitor = Jac::Parser::VisitorToRuby.create
    # Expecting document to be single mapping
    profile_mapping = document.children.first
    raise(ArgumentError, 'Mapping expected') unless profile_mapping.is_a? Psych::Nodes::Mapping
    # Then mapping should be expanded to (key, value) pairs. Because yaml overwrites
    # values for duplicated keys. This is not desired behaviour. We need to merge
    # such entries
    profile_mapping
      .children
      .each_slice(2)
      .map { |k, v| { visitor.accept(k) => visitor.accept(v) } }
  end
end
resolve(profile, config) click to toggle source
# File lib/jac/configuration.rb, line 272
def resolve(profile, config)
  ProfileResolver.new(config).resolve(profile)
end
update(config, config_part) click to toggle source
# File lib/jac/configuration.rb, line 251
def update(config, config_part)
  config_part.each do |profile, values|
    profile_values = config[profile]
    unless profile_values
      profile_values = {}
      config[profile] = profile_values
    end
    merge!(profile_values, values)
  end

  config
end