Module: Sprout::Generator

Includes:
RubyFeature
Defined in:
sprout/lib/sprout/generator.rb,
sprout/lib/sprout/generator/base.rb,
sprout/lib/sprout/generator/command.rb,
sprout/lib/sprout/generator/manifest.rb,
sprout/lib/sprout/generator/file_manifest.rb,
sprout/lib/sprout/generator/template_manifest.rb,
sprout/lib/sprout/generator/directory_manifest.rb

Overview

Introduction

Sprout Generators are command line applications that are installed by RubyGems and should universally provide the following features:

  • Terminal tab completion to discover generators

  • Call with no arguments to see help output

  • Call with an --input (or trailing) argument to create

  • Call with a collection of arguments given on a previous run plus --delete to undo a previous create

Usage

Discovery

Sprout generators should be installed by RubyGems as command line applications on your system. After installing the flashsdk gem, you should have access to a variety of generators. You can find out what generators are available by typing: sprout- followed by pressing the <TAB> key.

Your terminal should list out all available applications that match this name.

Some generators are expected to create new projects, others expect to run within existing projects. You should be able to infer the kind of generator you're looking at by the name, but if you can't just run the generator with no arguments to see it's usage guidelines.

Generators that expect to be run from within a project will usually expect a file named Gemfile to exist in the project root. If you're trying to run Sprout generators in a project that wasn't created using Sprouts, create this file and add the Rubygems that include the generators that you want to use.

Execution

Generators are created by human beings and sometimes they have different assumptions than you do. If you're running a generator within a project (especially for the first time - or since updating a gem), be sure to get your project checked into version control before running anything.

Non-application generators should always be executed at the project root (where you store your Rakefile, Gemfile or build.xml).

Deletion

Any generator that inherits from the provided Sprout::Generators::Base includes support for deletion. If you run a generator and realize that you don't want the files that it created, you can always run the same generator again with the same arguments, but add the --delete (or -d) argument.

Templates

Each time a generator is asked to locate a template, it begins a lookup process. This process is designed to make it easy for you to modify any template at the scope you desire.

The lookup process will end at the first location where the expected file is found.

The search will begin with the location specified by the -templates option (if provided) and will continue by adding '/templates' to the end of each location specified by the listing for Sprout::Generator#search_paths .

Creation

The core Sprout gem comes with a Sprout::GeneratorGenerator. This command line application is intended to be executed within a project and given the name of a generator that you'd like to create.

Try experimenting with this, and please suggest any improvements to the Google Group.


Back to Home: README.textile

Next Topic: Library


See Also:

Defined Under Namespace

Classes: Base, Command, DirectoryManifest, FileManifest, Manifest, TemplateManifest

Class Method Summary (collapse)

Methods included from Concern

#append_features, extended, #included

Class Method Details

+ (Object) create_instance(type, options = nil)

Create an instance of a concrete Generator using a type argument.

The idea is that libraries may register a generator class named,

+TestGenerator+, and other generators can instantiate it without
including it's Class by reference with:

Sprout::Generator.create_instance :test

Parameters:

  • (Symbol) type

    A snake-cased name of the class without the Generator suffix. for example, to instantiate a generator named, TestSuiteGenerator, this argument would be :test_suite

  • (Hash) options (defaults to: nil)

    deprecated - please remove this argument wherever it's found.



149
150
151
152
153
154
155
156
157
# File 'sprout/lib/sprout/generator.rb', line 149

def create_instance type, options=nil
  class_name = "#{type.to_s.camel_case}Generator"
  registered_entities.each do |entity|
    if(entity.to_s.match(/::#{class_name}$/) || entity.to_s.match(/^#{class_name}$/))
      return entity.new
    end
  end
  raise Sprout::Errors::MissingGeneratorError.new "Could not find any generator named: (#{class_name}). Perhaps you need to add a RubyGem to your Gemfile?"
end

+ (Object) create_search_paths



212
213
214
215
216
217
218
219
220
# File 'sprout/lib/sprout/generator.rb', line 212

def create_search_paths
  paths = [
            File.join('config', 'generators'),
            File.join('vendor', 'generators'),
            Sprout.generator_cache
          ]
  paths << ENV['SPROUT_GENERATORS'] unless ENV['SPROUT_GENERATORS'].nil?
  paths
end

+ (Hash) register(generator_class, templates_path = nil)

Register a generator class and template path for future use. Generator class names must end with "Generator", and everything to the left will be used for future lookups.

The following example will register a TestGenerator that can be retrieved as :test.

Sprout::Generator.register TestGenerator

Parameters:

  • (Class) generator_class

    A reference to the concrete Generator class. Usually these classes extend Sprout::Generator::Base.

  • (Directory) templates_path (defaults to: nil)

    The path to the default templates that should be used for this generator. By default, a folder named templates relative to the class definition will be used. Templates will also be searched for in a variety of locations depending on the user system. This path is simply the final searching point.

Returns:

  • (Hash)

    the entity that was stored to represent the provided Generator. The entity will generally have the keys, :class and :templates.



131
132
133
134
# File 'sprout/lib/sprout/generator.rb', line 131

def register generator_class, templates_path=nil
  generator_paths << { :class => generator_class, :templates => templates_path } unless templates_path.nil?
  super(generator_class)
end

+ (Array) search_paths

Returns a new collection of paths to search within for generator declarations and more importantly, folders named, 'templates'.

The collection of search_paths will be a subset of the following that will include only those directories that exist:

./config/generators
./vendor/generators
~/Library/Sprouts/1.0/generators                          # OS X only
~/.sprouts/1.0/generators                                 # Unix only
[USER_HOME]/Application Data/Sprouts/cache/1.0/generators # Windows only
ENV['SPROUT_GENERATORS']                                  # Only if defined
[Generator Declaration __FILE__]
[Generator SUPER-class declaration __FILE__]
[Repeat step above until there is no super-class]

When the generators attempt to resolve templates, each of the preceding folders will be scanned for a child directory named 'templates'. Within that directory, the requested template name will be scanned and the first found template file will be used. This process will be repeated for each template file that is requested.

The results of this search are not cached, so you can override a single template and leave the rest wherever the generator has defined them.

Returns:

  • (Array)

    of paths



206
207
208
209
210
# File 'sprout/lib/sprout/generator.rb', line 206

def search_paths
  # NOTE: Do not cache this list, specific generators
  # will modify it with their own lookups
  create_search_paths.select { |path| File.directory?(path) }
end

+ (Object) template_folder_for(clazz)

Retrieve the root template folder for the provided Class.

This method will look for a templates folder next to each superclass in the inheritance chain.



165
166
167
168
169
170
171
172
173
174
175
176
# File 'sprout/lib/sprout/generator.rb', line 165

def template_folder_for clazz
  # Search the potential matches in reverse order
  # because subclasses have registered AFTER their
  # superclasses and superclasses match the ===
  # check...
  generator_paths.reverse.each do |options|
    if options[:class] === clazz
      return options[:templates]
    end
  end
  nil
end