<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>script/console</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,48 @@
+# Blatantly stole this from Chef
+class TemplateError &lt; RuntimeError
+  attr_reader :original_exception, :context
+  SOURCE_CONTEXT_WINDOW = 2 unless defined? SOURCE_CONTEXT_WINDOW
+  
+  def initialize(original_exception, template, context)
+    @original_exception, @template, @context = original_exception, template, context
+  end
+  
+  def message
+    @original_exception.message
+  end
+  
+  def line_number
+    @line_number ||= $1.to_i if original_exception.backtrace.find {|line| line =~ /\(erubis\):(\d+)/ }
+  end
+  
+  def source_location
+    &quot;on line ##{line_number}&quot;
+  end
+  
+  def source_listing
+		return nil if line_number.nil?
+		
+    @source_listing ||= begin
+      line_index = line_number - 1
+      beginning_line = line_index &lt;= SOURCE_CONTEXT_WINDOW ? 0 : line_index - SOURCE_CONTEXT_WINDOW
+      source_size = SOURCE_CONTEXT_WINDOW * 2 + 1
+      lines = @template.split(/\n/)
+      contextual_lines = lines[beginning_line, source_size]
+      output = []
+      contextual_lines.each_with_index do |line, index|
+        line_number = (index+beginning_line+1).to_s.rjust(3)
+        output &lt;&lt; &quot;#{line_number}: #{line}&quot;
+      end
+      output.join(&quot;\n&quot;)
+    end
+  end
+  
+  def to_s
+    &quot;\n\n#{self.class} (#{message}) #{source_location}:\n\n&quot; +
+      &quot;#{source_listing}\n\n  #{original_exception.backtrace.join(&quot;\n  &quot;)}\n\n&quot;
+  end
+end
+
 module Sprinkle
   module Installers
     # Beware, strange &quot;installer&quot; coming your way.
@@ -25,6 +70,10 @@ module Sprinkle
 		# via this method. If you wish to disable recursive transfers, you can pass
 		# recursive =&gt; false, although it will not be obeyed when using the Vlad actor.
     #
+		# If you pass the option :render =&gt; true, this tells transfer that the source file
+		# is an ERB template to be rendered locally before being transferred (you can declare
+		# variables in the package scope). When render is true, recursive is turned off.
+		#
 		# Finally, should you need to run commands before or after the file transfer (making
 		# directories or changing permissions), you can use the pre/post :install directives
 		# and they will be run.
@@ -41,6 +90,35 @@ module Sprinkle
 				nil
 			end
 			
+			def self.render_template(template, context, prefix)
+				require 'tempfile'
+				require 'erubis'
+				
+				puts &quot;Foo: #{eval('foo', context)}&quot;
+				
+				begin
+          eruby = Erubis::Eruby.new(template)
+          output = eruby.result(context)
+        rescue Object =&gt; e
+          raise TemplateError.new(e, template, context)
+        end
+
+        final_tempfile = Tempfile.new(prefix)
+        final_tempfile.print(output)
+        final_tempfile.close
+				final_tempfile
+			end
+			
+			def render_template(template, context, prefix)
+				self.class.render_template(template, context, prefix)
+			end
+			
+			def render_template_file(path, context, prefix)
+				template = File.read(path)
+				tempfile = render_template(template, binding(), @package.name)
+				tempfile
+			end
+			
       def process(roles) #:nodoc:
         assert_delivery
 
@@ -56,9 +134,20 @@ module Sprinkle
 						@delivery.process @package.name, sequence, roles
 					end
 					
-          logger.info &quot;--&gt; Transferring #{@source} to #{@destination} for roles: #{roles}&quot;
-          @delivery.transfer(@package.name, @source, @destination, roles)
-
+					recursive = @options[:recursive]
+					
+					if options[:render] 
+						tempfile = render_template_file(@source, binding(), @package.name)
+						sourcepath = tempfile.path
+						logger.info &quot;Rendering template #{@source} to temporary file #{sourcepath}&quot;
+						recursive = false
+					else
+						sourcepath = @source
+					end
+					
+					logger.info &quot;--&gt; Transferring #{sourcepath} to #{@destination} for roles: #{roles}&quot;
+          @delivery.transfer(@package.name, sourcepath, @destination, roles, recursive)
+					
 					post = post_commands(:install)
 					unless post.empty?
 						sequence = post; sequence = sequence.join('; ') if sequence.is_a? Array</diff>
      <filename>lib/sprinkle/installers/transfer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,5 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
+require 'tempfile'
 
 describe Sprinkle::Installers::Transfer do
   include Sprinkle::Deployment
@@ -24,7 +25,7 @@ describe Sprinkle::Installers::Transfer do
   end
   
   describe 'when created' do
-    it 'should accept a single package to install' do
+    it 'should accept a source and destination to install' do
       @installer.source.should == @source
       @installer.destination.should == @destination
     end
@@ -36,18 +37,62 @@ describe Sprinkle::Installers::Transfer do
         pre :install, 'op1'
         post :install, 'op2'
       end
+
+			@delivery = @installer.delivery
     end
 
 		it &quot;should call the pre and post install commands around the file transfer&quot; do
-			delivery = @installer.delivery
-			
-			delivery.should_receive(:process).with(@package.name, 'op1', @roles).once.ordered.and_return
-      delivery.should_receive(:transfer).with(@package.name, @source, @destination, @roles).ordered.and_return
-			delivery.should_receive(:process).with(@package.name, 'op2', @roles).once.ordered.and_return
-		end		
+			@delivery.should_receive(:process).with(@package.name, 'op1', @roles).once.ordered.and_return
+      @delivery.should_receive(:transfer).ordered.and_return
+			@delivery.should_receive(:process).with(@package.name, 'op2', @roles).once.ordered.and_return
+		end	
+		
+		it &quot;should call transfer with recursive defaulted to nil&quot; do
+			@delivery.should_receive(:process).and_return
+      @delivery.should_receive(:transfer).with(@package.name, @source, @destination, @roles, nil)		
+		end	
   
 		after do
       @installer.process @roles
     end
   end
+
+	describe &quot;if the :render flag is true&quot; do
+		before do
+      @installer = create_transfer @source, @destination, :render =&gt; true
+			@delivery = @installer.delivery
+			@delivery.stub!(:render_template_file)
+    end
+
+		it &quot;should render the source file as a template to a tempfile&quot; do
+			@tempfile = Tempfile.new(&quot;foo&quot;)			
+			@installer.should_receive(:render_template_file).with(@source, anything, @package.name).and_return(@tempfile)
+			@delivery.stub!(:transfer)
+		end
+		
+		it &quot;should call transfer with recursive set to false&quot; do
+			@tempfile = Tempfile.new(&quot;foo&quot;)			
+			@installer.should_receive(:render_template_file).with(@source, anything, @package.name).and_return(@tempfile)
+			@delivery.should_receive(:transfer).with(@package.name, @tempfile.path, @destination, @roles, false).ordered.and_return
+		end
+		
+		after do
+      @installer.process @roles
+    end
+	end
+	
+	describe &quot;if the :recursive flag is explicitly set to false&quot; do
+		before do
+      @installer = create_transfer @source, @destination, :recursive =&gt; false
+    end
+
+		it &quot;should call transfer with recursive set to false&quot; do
+			delivery = @installer.delivery
+			delivery.should_receive(:transfer).with(@package.name, @source, @destination, @roles, false).ordered.and_return
+		end
+		
+		after do
+      @installer.process @roles
+    end
+	end
 end</diff>
      <filename>spec/sprinkle/installers/transfer_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>5c646097125767571bbe4ec636d13217311b964b</id>
    </parent>
  </parents>
  <author>
    <name>Jacob Harris</name>
    <email>jharris@nytimes.com</email>
  </author>
  <url>http://github.com/harrisj/sprinkle/commit/cd6b392c0dc9b9a011b7cb58183f3a4b115359fd</url>
  <id>cd6b392c0dc9b9a011b7cb58183f3a4b115359fd</id>
  <committed-date>2009-06-19T10:28:07-07:00</committed-date>
  <authored-date>2009-06-19T10:28:07-07:00</authored-date>
  <message>Support for rendering files with ERB before transfer</message>
  <tree>93dbfa388310a53c160826eecc5539c46dfead4a</tree>
  <committer>
    <name>Jacob Harris</name>
    <email>jharris@nytimes.com</email>
  </committer>
</commit>
