File: //usr/share/ruby/vendor_ruby/puppet/pops/evaluator/epp_evaluator.rb
# Handler of Epp call/evaluation from the epp and inline_epp functions
#
class Puppet::Pops::Evaluator::EppEvaluator
def self.inline_epp(scope, epp_source, template_args = nil)
unless epp_source.is_a? String
raise ArgumentError, "inline_epp(): the first argument must be a String with the epp source text, got a #{epp_source.class}"
end
# Parse and validate the source
parser = Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new
begin
result = parser.parse_string(epp_source, 'inlined-epp-text')
rescue Puppet::ParseError => e
raise ArgumentError, "inline_epp(): Invalid EPP: #{e.message}"
end
# Evaluate (and check template_args)
evaluate(parser, 'inline_epp', scope, false, result, template_args)
end
def self.epp(scope, file, env_name, template_args = nil)
unless file.is_a? String
raise ArgumentError, "epp(): the first argument must be a String with the filename, got a #{file.class}"
end
file = file + ".epp" unless file =~ /\.epp$/
scope.debug "Retrieving epp template #{file}"
template_file = Puppet::Parser::Files.find_template(file, env_name)
unless template_file
raise Puppet::ParseError, "Could not find template '#{file}'"
end
# Parse and validate the source
parser = Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new
begin
result = parser.parse_file(template_file)
rescue Puppet::ParseError => e
raise ArgumentError, "epp(): Invalid EPP: #{e.message}"
end
# Evaluate (and check template_args)
evaluate(parser, 'epp', scope, true, result, template_args)
end
private
def self.evaluate(parser, func_name, scope, use_global_scope_only, parse_result, template_args)
template_args, template_args_set = handle_template_args(func_name, template_args)
body = parse_result.body
unless body.is_a?(Puppet::Pops::Model::LambdaExpression)
raise ArgumentError, "#{func_name}(): the parser did not produce a LambdaExpression, got '#{body.class}'"
end
unless body.body.is_a?(Puppet::Pops::Model::EppExpression)
raise ArgumentError, "#{func_name}(): the parser did not produce an EppExpression, got '#{body.body.class}'"
end
unless parse_result.definitions.empty?
raise ArgumentError, "#{func_name}(): The EPP template contains illegal expressions (definitions)"
end
see_scope = body.body.see_scope
if see_scope && !template_args_set
# no epp params and no arguments were given => inline_epp logic sees all local variables, epp all global
closure_scope = use_global_scope_only ? scope.find_global_scope : scope
spill_over = false
else
# no epp params or user provided arguments in a hash, epp logic only sees global + what was given
closure_scope = scope.find_global_scope
# given spill over if there are no params (e.g. replace closure scope by a new scope with the given args)
spill_over = see_scope
end
evaluated_result = parser.closure(body, closure_scope).call_by_name(scope, template_args, spill_over)
evaluated_result
end
def self.handle_template_args(func_name, template_args)
if template_args.nil?
[{}, false]
else
unless template_args.is_a?(Hash)
raise ArgumentError, "#{func_name}(): the template_args must be a Hash, got a #{template_args.class}"
end
[template_args, true]
end
end
end