Class AutomateIt::TemplateManager::BaseDriver
In: lib/automateit/template_manager/base.rb
Parent: AutomateIt::Plugin::Driver

TemplateManager::BaseDriver

Base class for all TemplateManager drivers.

Methods

_backup   _exists?   _mtime   _newer   _read   _render_helper   _write   setup  

Attributes

default_check  [RW]  Name of default algorithm for performing checks, e.g., :compare

Public Instance methods

Options:

  • :default_check - Set the default_check, e.g., :compare

[Source]

# File lib/automateit/template_manager/base.rb, line 10
  def setup(opts={})
    super(opts)
    if opts[:default_check]
      @default_check = opts[:default_check]
    else
      @default_check ||= :compare
    end
  end

Protected Instance methods

Backup filename.

[Source]

# File lib/automateit/template_manager/base.rb, line 60
  def _backup(filename)
    interpreter.backup(filename)
  end

Does filename exist?

[Source]

# File lib/automateit/template_manager/base.rb, line 35
  def _exists?(filename)
    return File.exists?(filename)
  end

Return the modification date for filename.

[Source]

# File lib/automateit/template_manager/base.rb, line 65
  def _mtime(filename)
    return _exists? ? File.mtime(filename) : nil
  end

Return Array of dependencies newer than filename. Will be empty if filename is newer than all of the dependencies.

[Source]

# File lib/automateit/template_manager/base.rb, line 25
  def _newer(filename, *dependencies)
    updated = []
    timestamp = _mtime(filename)
    for dependency in dependencies
      updated << dependency if _mtime(dependency) > timestamp
    end
    return updated
  end

Return the contents of filename.

[Source]

# File lib/automateit/template_manager/base.rb, line 40
  def _read(filename)
    begin
      result = File.read(filename)
      return result
    rescue Errno::ENOENT => e
      if writing?
        raise e
      else
        return ""
      end
    end
  end

Render a template specified in the block. It takes the same arguments and returns the same results as the render call.

This method is used by the render methods for different template drivers and provides all the logic for parsing arguments, figuring out if a template should be rendered, what to do with the rendering, etc.

This method calls the supplied block with a hash containing:

  • :text — Template‘s text.
  • :filename — Template‘s filename, or nil if none. The template
  • :binder — Binding containing the locals as variables.
  • :locals — Hash of locals.
  • :opts — Hash of options passed to the _render_helper.

The supplied block must return the text of the rendered template.

See the TemplateManager::ERB#render method for a usage example.

[Source]

# File lib/automateit/template_manager/base.rb, line 86
  def _render_helper(*options, &block) # :yields: block_opts
    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
      # source_filename, target_filename, opts={}
      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]
        # Create a binding that the template can get variables from without
        # polluting the Driver's namespace.
        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

Write contents to filename.

[Source]

# File lib/automateit/template_manager/base.rb, line 54
  def _write(filename, contents)
    File.open(filename, "w+"){|writer| writer.write(contents)} if writing?
    return true
  end

[Validate]