def _render_helper(*options, &block)
args, opts = args_and_opts(*options)
source_filename = args[0] || opts[:file]
target_filename = args[1] || opts[:to]
source_text = opts[:text]
opts[:backup] = true if opts[:backup].nil?
raise ArgumentError.new("No source specified with :file or :text") if not source_filename and not source_text
raise Errno::ENOENT.new(source_filename) if writing? and source_filename and not _exists?(source_filename)
begin
opts[:check] ||= @default_check
target_exists = target_filename && _exists?(target_filename)
updates = []
if target_filename
unless opts[:force]
case opts[:check]
when :exists
if target_exists
log.debug(PNOTE+"Rendering for '#{target_filename}' skipped because it already exists")
return false
else
log.info(PNOTE+"Rendering '#{target_filename}' because of it doesn't exist")
end
when :timestamp
if target_exists
updates = _newer(target_filename, \
*[source_filename, opts[:dependencies]].reject{|t| t.nil?}.flatten)
if updates.empty?
log.debug(PNOTE+"Rendering for '#{target_filename}' skipped because dependencies haven't been updated")
return false
end
end
end
end
end
target_contents = target_exists ? _read(target_filename) : ""
source_text ||= _read(source_filename)
if source_text.blank? and preview?
return true
end
binder = nil
if opts[:locals]
callback = lambda{
code = ""
for key in opts[:locals].keys
code << "#{key} = opts[:locals][:#{key}]\n"
end
eval code
binding
}
binder = callback.call
end
block_opts = {
:binder => binder,
:filename => source_filename,
:text => source_text,
:locals => opts[:locals],
:opts => opts,
}
output = block.call(block_opts)
if target_filename
case opts[:check]
when :compare
if not target_exists
log.info(PNOTE+"Rendering '#{target_filename}' because of it doesn't exist")
elsif output == target_contents
log.debug(PNOTE+"Rendering for '#{target_filename}' skipped because contents are the same")
return false
else
log.info(PNOTE+"Rendering '#{target_filename}' because its contents changed")
end
when :timestamp
log.info(PNOTE+"Rendering '#{target_filename}' because of updated: #{updates.join(' ')}")
end
end
_backup(target_filename) if target_exists and opts[:backup]
return(target_filename ? _write(target_filename, output) : output)
ensure
if opts[:mode] or opts[:user] or opts[:group]
interpreter.chperm(target_filename, :mode => opts[:mode], :user => opts[:user], :group => opts[:group])
end
end
end