Set up app generator class to make it easier to for alt-stacks to override targeted areas

This commit is contained in:
Carlhuda
2010-04-29 18:30:19 -07:00
parent 1d2257deeb
commit 0761d1b0f7
2 changed files with 221 additions and 104 deletions

View File

@@ -3,87 +3,30 @@ require 'active_support/secure_random'
require 'rails/version' unless defined?(Rails::VERSION)
require 'rbconfig'
module Rails::Generators
# We need to store the RAILS_DEV_PATH in a constant, otherwise the path
# can change in Ruby 1.8.7 when we FileUtils.cd.
RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__))
RESERVED_NAMES = %w[generate console server dbconsole
application destroy benchmarker profiler
plugin runner test]
class AppGenerator < Base
DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
attr_accessor :rails_template
add_shebang_option!
argument :app_path, :type => :string
class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
:desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
class_option :template, :type => :string, :aliases => "-m",
:desc => "Path to an application template (can be a filesystem path or URL)."
class_option :dev, :type => :boolean, :default => false,
:desc => "Setup the application with Gemfile pointing to your Rails checkout"
class_option :edge, :type => :boolean, :default => false,
:desc => "Setup the application with Gemfile pointing to Rails repository"
class_option :skip_gemfile, :type => :boolean, :default => false,
:desc => "Don't create a Gemfile"
class_option :skip_activerecord, :type => :boolean, :aliases => "-O", :default => false,
:desc => "Skip ActiveRecord files"
class_option :skip_testunit, :type => :boolean, :aliases => "-T", :default => false,
:desc => "Skip TestUnit files"
class_option :skip_prototype, :type => :boolean, :aliases => "-J", :default => false,
:desc => "Skip Prototype files"
class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
:desc => "Skip Git ignores and keeps"
# Add bin/rails options
class_option :version, :type => :boolean, :aliases => "-v", :group => :rails,
:desc => "Show Rails version number and quit"
class_option :help, :type => :boolean, :aliases => "-h", :group => :rails,
:desc => "Show this help message and quit"
def initialize(*args)
raise Error, "Options should be given after the application name. For details run: rails --help" if args[0].blank?
super
if !options[:skip_activerecord] && !DATABASES.include?(options[:database])
raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
end
module Rails
class AppBuilder
def initialize(generator)
@generator = generator
@options = generator.options
end
def create_root
self.destination_root = File.expand_path(app_path, destination_root)
valid_app_const?
empty_directory '.'
set_default_accessors!
FileUtils.cd(destination_root)
def gemfile
template "Gemfile"
end
def create_root_files
copy_file "README"
copy_file "gitignore", ".gitignore" unless options[:skip_git]
template "Rakefile"
def configru
template "config.ru"
template "Gemfile" unless options[:skip_gemfile]
end
def create_app_files
def gitignore
copy_file "gitignore", ".gitignore"
end
def app
directory 'app'
end
def create_config_files
def config
empty_directory "config"
inside "config" do
@@ -97,29 +40,24 @@ module Rails::Generators
end
end
def create_boot_file
template "config/boot.rb"
def database_yml
template "config/databases/#{@options[:database]}.yml", "config/database.yml"
end
def create_activerecord_files
return if options[:skip_activerecord]
template "config/databases/#{options[:database]}.yml", "config/database.yml"
end
def create_db_files
def db
directory "db"
end
def create_doc_files
def doc
directory "doc"
end
def create_lib_files
def lib
empty_directory "lib"
empty_directory_with_gitkeep "lib/tasks"
end
def create_log_files
def log
empty_directory "log"
inside "log" do
@@ -130,39 +68,34 @@ module Rails::Generators
end
end
def create_public_files
directory "public", "public", :recursive => false # Do small steps, so anyone can overwrite it.
def public_directory
directory "public", "public", :recursive => false
end
def create_public_image_files
def images
directory "public/images"
end
def create_public_stylesheets_files
def stylesheets
empty_directory_with_gitkeep "public/stylesheets"
end
def create_prototype_files
unless options[:skip_prototype]
directory "public/javascripts"
else
empty_directory_with_gitkeep "public/javascripts"
end
def javascripts
directory "public/javascripts"
end
def create_script_files
def script
directory "script" do |content|
"#{shebang}\n" + content
end
chmod "script", 0755, :verbose => false
end
def create_test_files
return if options[:skip_testunit]
def test
directory "test"
end
def create_tmp_files
def tmp
empty_directory "tmp"
inside "tmp" do
@@ -172,20 +105,195 @@ module Rails::Generators
end
end
def create_vendor_files
def vendor_plugins
empty_directory_with_gitkeep "vendor/plugins"
end
def apply_rails_template
apply rails_template if rails_template
rescue Thor::Error, LoadError, Errno::ENOENT => e
raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
private
%w(template copy_file directory empty_directory inside
empty_directory_with_gitkeep create_file chmod shebang).each do |method|
class_eval <<-RUBY
def #{method}(*args, &block)
@generator.send(:#{method}, *args, &block)
end
RUBY
end
def bundle_if_dev_or_edge
bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
run "#{bundle_command} install" if dev_or_edge?
# TODO: Remove once this is fully in place
def method_missing(meth, *args, &block)
STDERR.puts "Calling #{meth} with #{args.inspect} with #{block}"
@generator.send(meth, *args, &block)
end
end
module Generators
# We need to store the RAILS_DEV_PATH in a constant, otherwise the path
# can change in Ruby 1.8.7 when we FileUtils.cd.
RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__))
RESERVED_NAMES = %w[generate console server dbconsole
application destroy benchmarker profiler
plugin runner test]
class AppGenerator < Base
DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
attr_accessor :rails_template
add_shebang_option!
argument :app_path, :type => :string
class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
:desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
class_option :template, :type => :string, :aliases => "-m",
:desc => "Path to an application template (can be a filesystem path or URL)."
class_option :dev, :type => :boolean, :default => false,
:desc => "Setup the application with Gemfile pointing to your Rails checkout"
class_option :edge, :type => :boolean, :default => false,
:desc => "Setup the application with Gemfile pointing to Rails repository"
class_option :skip_gemfile, :type => :boolean, :default => false,
:desc => "Don't create a Gemfile"
class_option :skip_activerecord, :type => :boolean, :aliases => "-O", :default => false,
:desc => "Skip ActiveRecord files"
class_option :skip_testunit, :type => :boolean, :aliases => "-T", :default => false,
:desc => "Skip TestUnit files"
class_option :skip_prototype, :type => :boolean, :aliases => "-J", :default => false,
:desc => "Skip Prototype files"
class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
:desc => "Skip Git ignores and keeps"
# Add bin/rails options
class_option :version, :type => :boolean, :aliases => "-v", :group => :rails,
:desc => "Show Rails version number and quit"
class_option :help, :type => :boolean, :aliases => "-h", :group => :rails,
:desc => "Show this help message and quit"
def initialize(*args)
raise Error, "Options should be given after the application name. For details run: rails --help" if args[0].blank?
super
if builder = options[:builder]
apply builder
end
@builder = AppBuilder.new(self)
if !options[:skip_activerecord] && !DATABASES.include?(options[:database])
raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
end
end
def create_root
self.destination_root = File.expand_path(app_path, destination_root)
valid_app_const?
empty_directory '.'
set_default_accessors!
FileUtils.cd(destination_root)
end
def create_root_files
copy_file "README"
template "Rakefile"
build(:configru)
build(:gitignore) unless options[:skip_git]
build(:gemfile) unless options[:skip_gemfile]
end
def create_app_files
build(:app)
end
def create_config_files
build(:config)
end
def create_boot_file
template "config/boot.rb"
end
def create_activerecord_files
return if options[:skip_activerecord]
build(:database_yml)
end
def create_db_files
build(:db)
end
def create_doc_files
build(:doc)
end
def create_lib_files
build(:lib)
end
def create_log_files
build(:log)
end
def create_public_files
build(:public)
end
def create_public_image_files
build(:images)
end
def create_public_stylesheets_files
build(:stylesheets)
empty_directory_with_gitkeep "public/stylesheets"
end
def create_prototype_files
unless options[:skip_prototype]
build(:javascripts)
else
empty_directory_with_gitkeep "public/javascripts"
end
end
def create_script_files
build(:script)
end
def create_test_files
build(:test) unless options[:skip_testunit]
end
def create_tmp_files
build(:tmp)
end
def create_vendor_files
build(:vendor_plugins)
end
def finish_template
build(:leftovers)
end
def apply_rails_template
apply rails_template if rails_template
rescue Thor::Error, LoadError, Errno::ENOENT => e
raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
end
def bundle_if_dev_or_edge
bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
run "#{bundle_command} install" if dev_or_edge?
end
protected
@@ -193,6 +301,10 @@ module Rails::Generators
"rails #{self.arguments.map(&:usage).join(' ')} [options]"
end
def build(meth, *args)
@builder.send(meth, *args) if @builder.respond_to?(meth)
end
def set_default_accessors!
self.rails_template = case options[:template]
when /^http:\/\//
@@ -274,5 +386,6 @@ module Rails::Generators
empty_directory(destination, config)
create_file("#{destination}/.gitkeep") unless options[:skip_git]
end
end
end
end

View File

@@ -21,6 +21,10 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator
%w(
.gitignore
Gemfile
Rakefile
config.ru
app/controllers
app/helpers
app/models