From 9780cdf2206968ca7fb394edd2fd5d22c6a45f07 Mon Sep 17 00:00:00 2001 From: Thibault Jouan Date: Fri, 10 Oct 2014 18:56:26 +0000 Subject: [PATCH] Support YAML templates --- features/task_template.feature | 12 ++++++++++ lib/producer/core.rb | 1 + lib/producer/core/template.rb | 29 ++++++++++++++++++++----- spec/fixtures/templates/basic_yaml.yaml | 1 + spec/producer/core/template_spec.rb | 8 +++++++ 5 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 spec/fixtures/templates/basic_yaml.yaml diff --git a/features/task_template.feature b/features/task_template.feature index cad3619..a037410 100644 --- a/features/task_template.feature +++ b/features/task_template.feature @@ -35,3 +35,15 @@ Feature: `template' task keyword """ When I execute the recipe Then the output must contain "basic template" + + Scenario: parses a yaml file + Given a file named "templates/basic.yaml" with: + """ + foo: bar + """ + And a recipe with: + """ + task(:echo_template) { echo template('basic')['foo'] } + """ + When I execute the recipe + Then the output must match /^bar$/ diff --git a/lib/producer/core.rb b/lib/producer/core.rb index 6f061dc..99d1530 100644 --- a/lib/producer/core.rb +++ b/lib/producer/core.rb @@ -3,6 +3,7 @@ require 'etc' require 'forwardable' require 'optparse' require 'pathname' +require 'yaml' require 'net/ssh' require 'net/sftp' diff --git a/lib/producer/core/template.rb b/lib/producer/core/template.rb index f6f2941..3d45fee 100644 --- a/lib/producer/core/template.rb +++ b/lib/producer/core/template.rb @@ -4,21 +4,40 @@ module Producer SEARCH_PATH = 'templates'.freeze def initialize(path, search_path: SEARCH_PATH) - @path = Pathname.new("#{path}.erb") + @path = Pathname.new(path) @search_path = Pathname.new(search_path) end def render(variables = {}) - tpl = ERB.new(File.read(resolve_path), nil, '-') - tpl.filename = resolve_path.to_s - tpl.result build_erb_binding variables + case (file_path = resolve_path).extname + when '.yaml' then render_yaml file_path + when '.erb' then render_erb file_path, variables + end end private + def render_erb(file_path, variables = {}) + tpl = ERB.new(File.read(file_path), nil, '-') + tpl.filename = file_path.to_s + tpl.result build_erb_binding variables + end + + def render_yaml(file_path) + YAML.load(File.read(file_path)) + end + def resolve_path - if @path.to_s =~ /\A\.\// then @path else @search_path + @path end + if @path.to_s =~ /\A\.\// + resolve_suffix @path + else + resolve_suffix @search_path + @path + end + end + + def resolve_suffix(path) + Pathname.glob("#{path}.{erb,yaml}").first end def build_erb_binding(variables) diff --git a/spec/fixtures/templates/basic_yaml.yaml b/spec/fixtures/templates/basic_yaml.yaml new file mode 100644 index 0000000..20e9ff3 --- /dev/null +++ b/spec/fixtures/templates/basic_yaml.yaml @@ -0,0 +1 @@ +foo: bar diff --git a/spec/producer/core/template_spec.rb b/spec/producer/core/template_spec.rb index 59348d3..a5e5175 100644 --- a/spec/producer/core/template_spec.rb +++ b/spec/producer/core/template_spec.rb @@ -13,6 +13,14 @@ module Producer::Core expect(template.render).to eq "basic template\n" end + context 'yaml templates' do + let(:path) { 'basic_yaml' } + + it 'renders yaml templates' do + expect(template.render).to eq({ 'foo' => 'bar' }) + end + end + context 'when variables are given' do let(:path) { 'variables' }