lib/mini_hiera.rb in mini_hiera-0.1.2 vs lib/mini_hiera.rb in mini_hiera-0.2.0.pre1
- old
+ new
@@ -10,25 +10,46 @@
class MiniHiera
CircularReferenceError = Class.new(RuntimeError)
KeyNotFoundError = Class.new(RuntimeError)
- attr_reader :config, :options
+ attr_reader :config, :options, :context_functions, :value_functions
def initialize(config, options={})
@config = config
@options = options
+ @context_functions = {}
+ @value_functions = {}
end
+ def context_function(name, &impl)
+ @context_functions[name] = impl
+ end
+ def value_function(name, &impl)
+ @value_functions[name] = impl
+ end
+
class Context
def initialize(hiera, data, options)
@hiera, @data, @options = hiera, data, options
end
def postprocess(value)
if value.is_a?(String)
value.gsub(/\%\{([^}]+)\}/) do |match|
- fetch($1)
+ replace = $1
+ _, block = @hiera.value_functions.find { |name, _| replace =~ /^#{name}\((.*)\)$/ }
+ if block
+ argument = $1
+ argument = if argument =~ /^["'](.*)['"]$/
+ $1
+ else
+ fetch(argument)
+ end
+ block.call(argument)
+ else
+ fetch(replace)
+ end
end
elsif value.is_a?(Hash)
Hash[value.map { |k,v| [k, postprocess(v)] }]
elsif value.is_a?(Array)
value.map { |v| postprocess(v) }
@@ -64,25 +85,41 @@
default_block ||= lambda { default == DefaultObject ? raise(KeyNotFoundError, [" ** Unknown key '#{key}'", error_message_suffix].join(" ")) : default }
default_block_wrapper = lambda { |*_| default_block.arity == 0 ? default_block.call : default_block.call(key) }
- data = hiera_data
+ # is the first key a function that yields a tree?
+ split_key = key.split(".")
+ _, block = @hiera.context_functions.find { |name, block| split_key.first =~ /^#{name}\(([^\)]*)\)$/ }
+ argument = $1
+
- key.split(".").each do |k|
- if data.is_a?(Array)
- raise TypeError, "no implicit conversion of String into Integer" unless k.to_i.to_s == k
- data = data[k.to_i]
- elsif data.is_a?(Hash)
- data = data.fetch(k, &default_block_wrapper)
+ if !!block
+ split_key.shift
+ argument = if argument =~ /^["'](.*)['"]$/
+ $1
else
- data = default_block_wrapper.call
- break
+ fetch(argument)
end
- end
- detect_circular_interpolation(key) do
- postprocess(data)
+ block.call(argument).fetch(split_key.join("."))
+ else
+ data = hiera_data
+ split_key.each do |k|
+ if data.is_a?(Array)
+ raise TypeError, "no implicit conversion of String into Integer" unless k.to_i.to_s == k
+ data = data[k.to_i]
+ elsif data.is_a?(Hash)
+ data = data.fetch(k, &default_block_wrapper)
+ else
+ data = default_block_wrapper.call
+ break
+ end
+ end
+
+ detect_circular_interpolation(key) do
+ postprocess(data)
+ end
end
end
def [](key)
fetch(key)