171 lines
No EOL
4.4 KiB
Ruby
171 lines
No EOL
4.4 KiB
Ruby
|
|
|
|
module Comfpile
|
|
class ContextTag
|
|
def initialize(tag)
|
|
@@known_tags ||= {}
|
|
|
|
case tag
|
|
when Symbol, String
|
|
precompiled = @@known_tags[tag.to_sym]
|
|
|
|
if not precompiled.nil?
|
|
@tag = precompiled[:tag]
|
|
@tag_array = precompiled[:array]
|
|
else
|
|
@tag_array = tag.to_s.split('_').uniq.sort
|
|
|
|
end
|
|
when Array
|
|
@tag_array = tag.map(&:to_s).uniq.sort
|
|
@tag = @tag_array
|
|
end
|
|
|
|
@tag ||= @tag_array.join('_').to_sym
|
|
|
|
tag_data = {
|
|
tag: @tag,
|
|
array: @ŧag_array
|
|
}
|
|
|
|
@@known_tags[@tag] ||= tag_data
|
|
@@known_tags[tag] ||= tag_data
|
|
end
|
|
|
|
|
|
def self.tagify(tag)
|
|
@known_tags ||= {}
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
#
|
|
# This class represents the configuration of a specific context.
|
|
# It has two main jobs:
|
|
# To provide functions to set up and merge configuration options
|
|
# from the various tags given to it, and
|
|
# to give reader options for the various config options.
|
|
#
|
|
# Most importantly, it contains mechanisms for safely setting up
|
|
# configurations and flagging issues.
|
|
#
|
|
class ContextConfig
|
|
attr_reader :context_tag
|
|
|
|
attr_reader :config_options
|
|
|
|
def initialize(context_tag, parent)
|
|
@context_tag = context_tag
|
|
|
|
@seeder_blocks = []
|
|
|
|
@config_options = nil
|
|
end
|
|
|
|
def add_seeder_block(priority, &block)
|
|
@seeder_blocks << {
|
|
priority: priority,
|
|
block: block
|
|
}
|
|
end
|
|
|
|
def resolve_key(key)
|
|
if key.is_a? Array
|
|
return key.map {|k| k.to_sym }
|
|
elsif key.is_a? String
|
|
return key.split('.').map {|k| k.to_sym }
|
|
elsif key.is_a? Symbol
|
|
return resolve_key(key.to_s)
|
|
end
|
|
end
|
|
|
|
def [](key)
|
|
@config_options&.dig(*resolve_key(key))
|
|
end
|
|
def []=(key, value)
|
|
key = resolve_key(key)
|
|
|
|
current_hash = (@config_options ||= {})
|
|
key[0..-2].each do |key|
|
|
current_hash = (current_hash[key] ||= {})
|
|
next if current_hash.is_a? Hash
|
|
raise ArgumentError, "Attempted to set child-parameter of another parameter!"
|
|
end
|
|
|
|
current_hash[key[-1]] = value
|
|
|
|
value
|
|
end
|
|
alias set []=
|
|
|
|
def set_flag(key, value)
|
|
set resolve_key(key).append(value), true
|
|
end
|
|
def get_flags(key)
|
|
(@config_options&.dig(*resolve_key(key)) || {}).keys
|
|
end
|
|
|
|
def dig(arg0, *args)
|
|
@config_options&.dig(arg0, *args)
|
|
end
|
|
|
|
def append(key, value)
|
|
key = resolve_key key
|
|
array = @config_options&.dig(*key)
|
|
|
|
if array.nil?
|
|
array = set key, []
|
|
end
|
|
|
|
raise ArgumentError, "Attempted to append to a non-list parameter!" unless array.is_a? Array
|
|
|
|
array << value
|
|
end
|
|
alias append_to append
|
|
|
|
def assert(orig_key, value)
|
|
key = resolve_key orig_key
|
|
current_value = @config_options&.dig(*key)
|
|
|
|
if current_value.nil?
|
|
set key, value
|
|
elsif current_value != value
|
|
raise ArgumentError, "Config key assertion failed! #{orig_key} should be #{value}, is #{current_value}!"
|
|
end
|
|
end
|
|
|
|
def build_config
|
|
@config_options = nil
|
|
|
|
@seeder_blocks.sort { |block| block[:priority] }.each do |block|
|
|
self.instance_exec(block, &block[:block])
|
|
end
|
|
|
|
self.freeze
|
|
end
|
|
end
|
|
|
|
class ContextConfigContainer
|
|
def initialize
|
|
@context_configs_seeds = []
|
|
end
|
|
|
|
def find_seeds_for(context_tag)
|
|
out = []
|
|
|
|
@context_configs_seeds.each do |seed|
|
|
seed_tags = seed[:context_tags]
|
|
|
|
seed_tags.each do |tag|
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
def add_to_config(context_config)
|
|
raise ArgumentError, "No context supplied!" unless context_config.is_a? ContextConfig
|
|
end
|
|
end
|
|
end |