提交 6774e12a 编写于 作者: J José Valim

Clean up the builder abstraction in AppGenerator.

This commit may be reverted once documentation and a proper way to handle actions are added.
上级 ae812e9f
......@@ -6,152 +6,12 @@
require 'uri'
module Rails
module ActionMethods
attr_reader :options
def initialize(generator)
@generator = generator
@options = generator.options
end
private
%w(template copy_file directory empty_directory inside
empty_directory_with_gitkeep create_file chmod shebang).each do |method|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method}(*args, &block)
@generator.send(:#{method}, *args, &block)
end
RUBY
end
# 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
class AppBuilder
def rakefile
template "Rakefile"
end
def readme
copy_file "README"
end
def gemfile
template "Gemfile"
end
def configru
template "config.ru"
end
def gitignore
copy_file "gitignore", ".gitignore"
end
def app
directory 'app'
end
def config
empty_directory "config"
inside "config" do
template "routes.rb"
template "application.rb"
template "environment.rb"
directory "environments"
directory "initializers"
directory "locales"
end
end
def database_yml
template "config/databases/#{@options[:database]}.yml", "config/database.yml"
end
def db
directory "db"
end
def doc
directory "doc"
end
def lib
empty_directory "lib"
empty_directory_with_gitkeep "lib/tasks"
end
def log
empty_directory "log"
inside "log" do
%w( server production development test ).each do |file|
create_file "#{file}.log"
chmod "#{file}.log", 0666, :verbose => false
end
end
end
def public_directory
directory "public", "public", :recursive => false
end
def images
directory "public/images"
end
def stylesheets
empty_directory_with_gitkeep "public/stylesheets"
end
def javascripts
unless options[:skip_prototype]
directory "public/javascripts"
else
empty_directory_with_gitkeep "public/javascripts"
create_file "public/javascripts/application.js"
end
end
def script
directory "script" do |content|
"#{shebang}\n" + content
end
chmod "script", 0755, :verbose => false
end
def test
directory "test"
end
def tmp
empty_directory "tmp"
inside "tmp" do
%w(sessions sockets cache pids).each do |dir|
empty_directory(dir)
end
end
end
def vendor_plugins
empty_directory_with_gitkeep "vendor/plugins"
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[application destroy benchmarker profiler
plugin runner test]
RESERVED_NAMES = %w(application destroy benchmarker profiler plugin runner test)
class AppGenerator < Base
DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
......@@ -164,9 +24,6 @@ class AppGenerator < Base
class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
:desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
class_option :builder, :type => :string, :aliases => "-b",
:desc => "Path to an application builder (can be a filesystem path or URL)"
class_option :template, :type => :string, :aliases => "-m",
:desc => "Path to an application template (can be a filesystem path or URL)"
......@@ -200,7 +57,6 @@ class AppGenerator < Base
def initialize(*args)
raise Error, "Options should be given after the application name. For details run: rails --help" if args[0].blank?
@original_wd = Dir.pwd
super
......@@ -220,19 +76,29 @@ def create_root
end
def create_root_files
build(:readme)
build(:rakefile)
build(:configru)
build(:gitignore) unless options[:skip_git]
build(:gemfile) unless options[:skip_gemfile]
copy_file "README"
template "Rakefile"
template "config.ru"
copy_file "gitignore", ".gitignore" unless options[:skip_git]
template "Gemfile" unless options[:skip_gemfile]
end
def create_app_files
build(:app)
directory 'app'
end
def create_config_files
build(:config)
empty_directory "config"
inside "config" do
template "routes.rb"
template "application.rb"
template "environment.rb"
directory "environments"
directory "initializers"
directory "locales"
end
end
def create_boot_file
......@@ -241,59 +107,77 @@ def create_boot_file
def create_active_record_files
return if options[:skip_active_record]
build(:database_yml)
template "config/databases/#{@options[:database]}.yml", "config/database.yml"
end
def create_db_files
build(:db)
directory "db"
end
def create_doc_files
build(:doc)
directory "doc"
end
def create_lib_files
build(:lib)
empty_directory "lib"
empty_directory_with_gitkeep "lib/tasks"
end
def create_log_files
build(:log)
empty_directory "log"
inside "log" do
%w( server production development test ).each do |file|
create_file "#{file}.log"
chmod "#{file}.log", 0666, :verbose => false
end
end
end
def create_public_files
build(:public_directory)
directory "public", "public", :recursive => false
end
def create_public_image_files
build(:images)
directory "public/images"
end
def create_public_stylesheets_files
build(:stylesheets)
empty_directory_with_gitkeep "public/stylesheets"
end
def create_prototype_files
build(:javascripts)
def create_public_javascripts_files
unless options[:skip_prototype]
directory "public/javascripts"
else
empty_directory_with_gitkeep "public/javascripts"
create_file "public/javascripts/application.js"
end
end
def create_script_files
build(:script)
directory "script" do |content|
"#{shebang}\n" + content
end
chmod "script", 0755, :verbose => false
end
def create_test_files
build(:test) unless options[:skip_test_unit]
directory "test" unless options[:skip_test_unit]
end
def create_tmp_files
build(:tmp)
end
empty_directory "tmp"
def create_vendor_files
build(:vendor_plugins)
inside "tmp" do
%w(sessions sockets cache pids).each do |dir|
empty_directory(dir)
end
end
end
def finish_template
build(:leftovers)
def create_vendor_files
empty_directory_with_gitkeep "vendor/plugins"
end
def apply_rails_template
......@@ -313,29 +197,6 @@ def self.banner
"rails new #{self.arguments.map(&:usage).join(' ')} [options]"
end
def builder
@builder ||= begin
if path = options[:builder]
if URI(path).is_a?(URI::HTTP)
contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
else
contents = open(File.expand_path(path, @original_wd)) {|io| io.read }
end
prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1)
instance_eval(&prok)
end
builder_class = defined?(::AppBuilder) ? ::AppBuilder : Rails::AppBuilder
builder_class.send(:include, ActionMethods)
builder_class.new(self)
end
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:\/\//
......
......@@ -261,70 +261,4 @@ def action(*args, &block)
silence(:stdout){ generator.send(*args, &block) }
end
end
class CustomAppGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
tests Rails::Generators::AppGenerator
arguments [destination_root]
def setup
Rails.application = TestApp::Application
super
Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
@bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
end
def teardown
super
Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
Object.class_eval { remove_const :AppBuilder if const_defined?(:AppBuilder) }
Rails.application = TestApp::Application.instance
end
def test_builder_option_with_empty_app_builder
FileUtils.cd(Rails.root)
run_generator([destination_root, "-b", "#{Rails.root}/lib/empty_builder.rb"])
DEFAULT_APP_FILES.each{ |path| assert_no_file path }
end
def test_builder_option_with_simple_app_builder
FileUtils.cd(Rails.root)
run_generator([destination_root, "-b", "#{Rails.root}/lib/simple_builder.rb"])
(DEFAULT_APP_FILES - ['config.ru']).each{ |path| assert_no_file path }
assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }]
end
def test_builder_option_with_relative_path
here = File.expand_path(File.dirname(__FILE__))
FileUtils.cd(here)
run_generator([destination_root, "-b", "../fixtures/lib/simple_builder.rb"])
(DEFAULT_APP_FILES - ['config.ru']).each{ |path| assert_no_file path }
assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }]
end
def test_builder_option_with_tweak_app_builder
FileUtils.cd(Rails.root)
run_generator([destination_root, "-b", "#{Rails.root}/lib/tweak_builder.rb"])
DEFAULT_APP_FILES.each{ |path| assert_file path }
assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }]
end
def test_builder_option_with_http
path = "http://gist.github.com/103208.txt"
template = "class AppBuilder; end"
template.instance_eval "def read; self; end" # Make the string respond to read
generator([destination_root], :builder => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
capture(:stdout) { generator.invoke_all }
DEFAULT_APP_FILES.each{ |path| assert_no_file path }
end
protected
def action(*args, &block)
silence(:stdout){ generator.send(*args, &block) }
end
end
end
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册