module Cog::Generator

This module defines an interface which can be used by generator objects. Specifically, it makes it easy to find ERB templates and render them into generated source code files, using the {#stamp} method.

@see github.com/ktonon/cog#generators Introduction to Generators

Public Instance Methods

embed(hook, &block) click to toggle source

Provide a value for embeds with the given hook @param hook [String] hook name used in the embed statements @yieldparam context [EmbedContext] provides information about the environment in which the embed statement was found @yieldreturn The value which will be used to expand the embed (or replace the embedded content) @return [nil]

# File lib/cog/generator.rb, line 67
def embed(hook, &block)
  eaten = 0 # keep track of eaten statements so that the index can be adjusted
  Embeds.find(hook) do |c|
    c.eaten = eaten
    if Embeds.update c, &block
      eaten += 1 if c.once?
      STDOUT.write "Updated #{c.path.relative_to_project_root} - #{(c.index + 1).ordinalize} occurrence of embed '#{c.hook}'\n".color :white
    end
  end
end
gcontext() click to toggle source

@api developer @return [Hash] Generator context. Generator methods should place context into here instead of instance variables to avoid polluting the instance variable name space

# File lib/cog/generator.rb, line 20
def gcontext
  if @generator_context.nil?
    @generator_context = {
      :scopes => []
    }
  end
  @generator_context
end
stamp(template_path, destination=nil, opt={}) click to toggle source

Stamp a template into a file or return it as a string @param template_path [String] path to template file relative to {Config#template_path} @param destination [String] path to which the generated file should be written, relative to the {Config::ProjectConfig#project_path} @option opt [Boolean] :absolute_template_path (false) is the template_path absolute? @option opt [Boolean] :absolute_destination (false) is the destination absolute? @option opt [Boolean] :once (false) if true, the file will not be updated if it already exists @option opt [Binding] :binding (nil) an optional binding to use while evaluating the template @option opt [String, Array<String>] :filter (nil) name(s) of {Filters} @option opt [Boolean] :quiet (false) suppress writing to STDOUT? @return [nil or String] if destination is not provided, the stamped template is returned as a string

# File lib/cog/generator.rb, line 39
def stamp(template_path, destination=nil, opt={})
  # Ignore destination if its a hash, its meant to be opt
  opt, destination = destination, nil if destination.is_a? Hash
  
  # Render and filter
  r = find_and_render template_path, opt
  r = filter_through r, opt[:filter]
  return r if destination.nil?

  # Place it in a file
  write_scratch_file(destination, r, opt[:absolute_destination]) do |path, scratch|
    updated = File.exists? path
    Embeds.copy_keeps(path, scratch)
    if files_are_same?(path, scratch) || (opt[:once] && updated)
      FileUtils.rm scratch
    else
      FileUtils.mv scratch, path
      STDOUT.write "#{updated ? :Updated : :Created} #{path.relative_to_project_root}\n".color(updated ? :white : :green) unless opt[:quiet]
    end
  end
  nil
end

Private Instance Methods

filter_through(text, f) click to toggle source

@param text [String] text to run through filters @param f [String, Array<String>] name(s) of {Filters}

# File lib/cog/generator.rb, line 94
def filter_through(text, f)
  f = [f].compact unless f.is_a?(Array)
  f.each {|name| text = call_filter name, text }
  text
end
find_and_render(template_path, opt={}) click to toggle source

@param template_path [String] path to template file relative one of the {Config#template_paths} @option opt [Boolean] :absolute_template_path (false) is the template_path absolute? @option opt [Binding] :binding (nil) an optional binding to use while evaluating the template @return [String] result of rendering the template

# File lib/cog/generator.rb, line 84
def find_and_render(template_path, opt={})
  t = get_template template_path, :absolute => opt[:absolute_template_path]
  b = opt[:binding] || binding
  Cog.activate_language :ext => File.extname(template_path.to_s) do
    t.result(b)
  end
end
write_scratch_file(original, text, absolute=false, &block) click to toggle source

@param original [String] path to the original file @param text [String] text to write into the scratch file @param absolute [Boolean] is the path absolute or relative to the project root? @yieldparam original [String] absolute path to original file @yieldparam scratch [String] path to the scratch file @return [nil]

# File lib/cog/generator.rb, line 106
def write_scratch_file(original, text, absolute=false, &block)
  path = absolute ? original : File.join(Cog.project_path, original)
  FileUtils.mkpath File.dirname(path) unless File.exists? path
  scratch = "#{path}.scratch"
  File.open(scratch, 'w') {|file| file.write text}
  block.call path, scratch
end