aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlhuda <carlhuda@engineyard.com>2010-04-29 18:30:19 -0700
committerCarlhuda <carlhuda@engineyard.com>2010-04-30 13:48:06 -0700
commit0761d1b0f7e89d49fe8cd6ab7eed3f084bd56fbd (patch)
tree925ab2801363defdb2bec6c153a7f49a8128a5d6
parent1d2257deebb97e5a27ef86acd29ecc6c4f5efa37 (diff)
downloadrails-0761d1b0f7e89d49fe8cd6ab7eed3f084bd56fbd.tar.gz
rails-0761d1b0f7e89d49fe8cd6ab7eed3f084bd56fbd.tar.bz2
rails-0761d1b0f7e89d49fe8cd6ab7eed3f084bd56fbd.zip
Set up app generator class to make it easier to for alt-stacks to override targeted areas
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb321
-rw-r--r--railties/test/generators/app_generator_test.rb4
2 files changed, 221 insertions, 104 deletions
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 667a123025..29e78a898c 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -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"
- end
-
- def create_activerecord_files
- return if options[:skip_activerecord]
- template "config/databases/#{options[:database]}.yml", "config/database.yml"
+ def database_yml
+ 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
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 2e402c4f3a..1e5aa156ce 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -21,6 +21,10 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator
%w(
+ .gitignore
+ Gemfile
+ Rakefile
+ config.ru
app/controllers
app/helpers
app/models