diff options
-rw-r--r-- | lib/chef/mixin/template.rb | 16 | ||||
-rw-r--r-- | lib/chef/provider/template.rb | 4 | ||||
-rw-r--r-- | spec/unit/mixin/template_spec.rb | 41 |
3 files changed, 61 insertions, 0 deletions
diff --git a/lib/chef/mixin/template.rb b/lib/chef/mixin/template.rb index 78148d2577..c25f5f6e1f 100644 --- a/lib/chef/mixin/template.rb +++ b/lib/chef/mixin/template.rb @@ -29,6 +29,22 @@ class Chef raise "Could not find a value for node. If you are explicitly setting variables in a template, " + "include a node variable if you plan to use it." end + + def render(partial_name, variables = nil) + raise "You cannot render partials in this context" unless @partial_resolver + + if variables + context = {} + context.merge!(variables) + context[:node] = node + else + context = self.dup + end + + template_location = @partial_resolver.call(partial_name) + eruby = Erubis::Eruby.new(IO.read(template_location)) + output = eruby.evaluate(context) + end end ::Erubis::Context.send(:include, ChefContext) diff --git a/lib/chef/provider/template.rb b/lib/chef/provider/template.rb index c937b9d980..cce3418f91 100644 --- a/lib/chef/provider/template.rb +++ b/lib/chef/provider/template.rb @@ -109,6 +109,10 @@ class Chef context = {} context.merge!(@new_resource.variables) context[:node] = node + context[:partial_resolver] = lambda do + cookbook = _run_context.cookbook_collection[resource_cookbook] + partial_location = cookbook.preferred_filename_on_disk_location(node, :templates, partial_name) + end render_template(IO.read(template_location), context, &block) end diff --git a/spec/unit/mixin/template_spec.rb b/spec/unit/mixin/template_spec.rb index 3d8a723a75..ebe46cbca4 100644 --- a/spec/unit/mixin/template_spec.rb +++ b/spec/unit/mixin/template_spec.rb @@ -44,6 +44,47 @@ describe Chef::Mixin::Template, "render_template" do end end + describe "with a template resource" do + before :each do + @cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks")) + Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, @cookbook_repo) } + + @node = Chef::Node.new + cl = Chef::CookbookLoader.new(@cookbook_repo) + cl.load_cookbooks + @cookbook_collection = Chef::CookbookCollection.new(cl) + @events = Chef::EventDispatch::Dispatcher.new + @run_context = Chef::RunContext.new(@node, @cookbook_collection, @events) + + @rendered_file_location = Dir.tmpdir + '/openldap_stuff.conf' + + @resource = Chef::Resource::Template.new(@rendered_file_location) + @resource.cookbook_name = 'openldap' + + @provider = Chef::Provider::Template.new(@resource, @run_context) + @current_resource = @resource.dup + @provider.current_resource = @current_resource + @access_controls = mock("access controls") + @provider.stub!(:access_controls).and_return(@access_controls) + end + + it "should provide a render method" do + _run_context = @run_context + context = {} + context[:node] = @node + context[:partial_resolver] = lambda do |partial_name| + @provider.instance_eval do + cookbook = run_context.cookbook_collection[resource_cookbook] + partial_location = cookbook.preferred_filename_on_disk_location(node, :templates, partial_name) + end + end + + @provider.render_template("before {<%= render 'test.erb' %>} after", context) do |tmp| + tmp.open.read.should == "before {We could be diving for pearls!\n} after" + end + end + end + describe "when an exception is raised in the template" do def do_raise @context = {:chef => "cool"} |