diff --git a/functions/deferrable_epp.pp b/functions/deferrable_epp.pp new file mode 100644 index 000000000..c1daa9b36 --- /dev/null +++ b/functions/deferrable_epp.pp @@ -0,0 +1,18 @@ +# This function returns either a rendered template or a deferred function to render at runtime. +# If any of the values in the variables hash are deferred, then the template will be deferred. +# +# Note: this function requires all parameters to be explicitly passed in. It cannot expect to +# use facts, class variables, and other variables in scope. This is because when deferred, we +# have to explicitly pass the entire scope to the client. +# +function stdlib::deferrable_epp(String $template, Hash $variables) >> Variant[String, Deferred] { + if $variables.any |$key, $value| { $value.is_a(Deferred) } { + Deferred( + 'inline_epp', + [find_template($template).file, $variables], + ) + } + else { + epp($template, $variables) + } +} diff --git a/spec/functions/stdlib_deferrable_epp_spec.rb b/spec/functions/stdlib_deferrable_epp_spec.rb new file mode 100644 index 000000000..71e959925 --- /dev/null +++ b/spec/functions/stdlib_deferrable_epp_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe 'stdlib::deferrable_epp' do + context 'call epp on non-deferred input' do + let(:pre_condition) do + 'function epp($str, $data) { return "rendered"}' + end + + it { + is_expected.to run.with_params('mymod/template.epp', { 'foo' => 'bar' }).and_return('rendered') + } + end + + context 'defers rendering with deferred input' do + let(:pre_condition) do + <<~END + function epp($str, $data) { fail("should not have invoked epp()") } + function find_template($str) { return "path" } + function file($path) { return "foo: <%= foo %>" } + END + end + + it { + foo = Puppet::Pops::Types::TypeFactory.deferred.create('join', [1, 2, 3]) + # This kind_of matcher requires https://github.com/puppetlabs/rspec-puppet/pull/24 + is_expected.to run.with_params('mymod/template.epp', { 'foo' => foo }) # .and_return(kind_of Puppet::Pops::Types::PuppetObject) + } + end +end