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)