Created
April 28, 2009 07:09
-
-
Save jnicklas/103003 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A suggestion for an improved DSL for templater. The idea is to unify a lot of concepts and make | |
# them simpler. | |
# | |
# * Options and arguments are unified into 'argument', that can have an optional position | |
# * Templates, Files, EmptyDirectories, Directories and Invocations are unified into Recipes | |
# * A use_recipe function which can be used to pick and choose certain recipes | |
# * A simple block syntax for opening up generators and adding stuff to them | |
# | |
Rails.generator(:model) do | |
# We can provide modules with some helpful functionality for building common types of generators | |
# A very nice way of doing this, since it's flexible and doesn't depend on load order. | |
# The end user of the generator will never see this, as it happens inside the framework | |
include Rails::Generators::BaseGenerator | |
include Rails::Generators::NamedGenerator | |
## ARGUMENTS | |
# this argument is required and it can be given as a positional argument | |
# the generator could be invoked like this: | |
# script/generate model --name User | |
# script/generate model User | |
argument :name do |arg| | |
arg.position = 0 | |
arg.description = "Name of the generator" | |
arg.required = true | |
arg.validate do |name| | |
name !~ /\s/ | |
end | |
arg.filter do |name| | |
name.camel_case | |
end | |
end | |
# this argument is not required and it cannot be given as a positional argument | |
# script/generate model --name User --no-migration | |
argument :no_migration do |arg| | |
arg.boolean = true | |
end | |
## RECIPES | |
recipe :model do | |
template "app/models/%file_name%.rb" # will copy the template, interpolationg %file_name% into the destination | |
end | |
recipe :spec do | |
directory 'spec' # will add all files in the directory 'spec' as templates | |
end | |
use_recipe :spec, :if => { :test_framework => :rspec } | |
recipe :test_unit do | |
template "test/models/model_test.rb", "test/models/#{file_name}_test.rb" | |
end | |
use_recipe :test_unit, :if => { :test_framework => :test_unit } | |
recipe :monkey do | |
template "test/monkey.rb" | |
end | |
use_recipe :monkey, false # do not use the monkey recipe | |
use_recipe :monkey, true # no, we changed our minds, use it! | |
use_recipe :monkey, :unless => { :monkey => 'Peter' } # use monkey recipe unless #monkey returns 'Peter' | |
use_recipe :monkey, :unless => :peter? # use monkey recipe unless #peter? returns true | |
recipe :migration do | |
generate :migration, "add_#{file_name}", :table_name => file_name.pluralize | |
end | |
use_recipe :migration, :unless => :no_migration? | |
recipe :add_route, :revertable => false do | |
append_text "\n\n resources :#{name}\n", :after => "Merb::Router.prepare do", :to => 'config/routes.rb' | |
end | |
## METHODS | |
# this is just a class so we can happily add methods to it | |
def monkey | |
"Peter" | |
end | |
def peter? | |
monkey == "Peter" | |
end | |
def file_name | |
name.snake_case | |
end | |
def class_name | |
name.camel_case | |
end | |
end | |
# We can use it like this in our code. | |
Rais.generator(:model).generate!(:name => "User", :recipes => [:model, :spec]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment