diff --git a/railties/lib/generators.rb b/railties/lib/generators.rb index dd61a686c2186bdec46ccc844477415addc4a763..a4ce92e04b7d082e784fb4e97b71cf9cb2a16b91 100644 --- a/railties/lib/generators.rb +++ b/railties/lib/generators.rb @@ -10,7 +10,6 @@ end $:.unshift(File.dirname(__FILE__)) -require 'rails/version' unless defined?(Rails::VERSION) # TODO Use vendored Thor require 'rubygems' @@ -22,6 +21,46 @@ module Rails module Generators + DEFAULT_ALIASES = { + :actions => '-a', + :fixture_replacement => '-r', + :orm => '-o', + :resource_controller => '-c', + :scaffold_controller => '-c', + :stylesheets => '-y', + :test_framework => '-t', + :template_engine => '-e' + } + + DEFAULT_OPTIONS = { + :fixture => true, + :force_plural => false, + :helper => true, + :layout => true, + :migration => true, + :orm => 'active_record', + :resource_controller => 'controller', + :scaffold_controller => 'scaffold_controller', + :singleton => false, + :stylesheets => true, + :test_framework => 'test_unit', + :template_engine => 'erb', + :timestamps => true + } + + def self.aliases + @@aliases ||= DEFAULT_ALIASES.dup + end + + def self.options + @@options ||= DEFAULT_OPTIONS.dup + end + + # Remove the color from output. + # + def self.no_color! + Thor::Base.shell = Thor::Shell::Basic + end # Generators load paths used on lookup. The lookup happens as: # @@ -48,21 +87,7 @@ def self.load_path paths end end - load_path # Cache load paths - - # Keep builtin generators in an Array[Array[group, name]]. - # - def self.builtin - Dir[File.dirname(__FILE__) + '/generators/*/*'].collect do |file| - file.split('/')[-2, 2] - end - end - - # Remove the color from output. - # - def self.no_color! - Thor::Base.shell = Thor::Shell::Basic - end + load_path # Cache load paths. Needed to avoid __FILE__ pointing to wrong paths. # Receives a namespace and tries different combinations to find a generator. # @@ -106,6 +131,19 @@ def self.find_by_namespace(name, base=nil, context=nil) nil end + # Receives a namespace, arguments and the behavior to invoke the generator. + # It's used as the default entry point for generate, destroy and update + # commands. + # + def self.invoke(namespace, args=ARGV, config={}) + if klass = find_by_namespace(namespace, "rails") + args << "--help" if klass.arguments.any? { |a| a.required? } && args.empty? + klass.start args, config + else + puts "Could not find generator #{namespace}." + end + end + # Show help message with available generators. # def self.help @@ -137,19 +175,6 @@ def self.help puts "Others: #{others.join(', ')}." unless others.empty? end - # Receives a namespace, arguments and the behavior to invoke the generator. - # It's used as the default entry point for generate, destroy and update - # commands. - # - def self.invoke(namespace, args=ARGV, config={}) - if klass = find_by_namespace(namespace, "rails") - args << "--help" if klass.arguments.any? { |a| a.required? } && args.empty? - klass.start args, config - else - puts "Could not find generator #{namespace}." - end - end - protected # Return all defined namespaces. @@ -158,6 +183,14 @@ def self.namespaces Thor::Base.subclasses.map(&:namespace) end + # Keep builtin generators in an Array[Array[group, name]]. + # + def self.builtin + Dir[File.dirname(__FILE__) + '/generators/*/*'].collect do |file| + file.split('/')[-2, 2] + end + end + # Receives namespaces in an array and tries to find matching generators # in the load path. Each path is traversed into directory lookups. For # example: diff --git a/railties/lib/generators/base.rb b/railties/lib/generators/base.rb index 0d2d1657410c372249d5c378e44d01f851b33f3c..dcc210240e6b57f89bb19ba1e3b742a28e448532 100644 --- a/railties/lib/generators/base.rb +++ b/railties/lib/generators/base.rb @@ -2,33 +2,6 @@ module Rails module Generators - DEFAULTS = { - :fixture => true, - :force_plural => false, - :helper => true, - :layout => true, - :migration => true, - :orm => 'active_record', - :resource_controller => 'controller', - :scaffold_controller => 'scaffold_controller', - :singleton => false, - :stylesheets => true, - :test_framework => 'test_unit', - :template_engine => 'erb', - :timestamps => true - } - - ALIASES = { - :actions => '-a', - :fixture_replacement => '-r', - :orm => '-o', - :resource_controller => '-c', - :scaffold_controller => '-c', - :stylesheets => '-y', - :test_framework => '-t', - :template_engine => '-e' - } - class Error < Thor::Error end @@ -137,7 +110,7 @@ def self.hook_for(*names, &block) names.each do |name| defaults = if options[:type] == :boolean { } - elsif [true, false].include?(options.fetch(:default, DEFAULTS[name])) + elsif [true, false].include?(options.fetch(:default, Rails::Generators.options[name])) { :banner => "" } else { :desc => "#{name.to_s.humanize} to be invoked", :banner => "NAME" } @@ -212,12 +185,12 @@ def self.remove_hook_for(*names) end end - # Make class option aware of DEFAULTS and ALIASES. + # Make class option aware of Rails::Generators.options and Rails::Generators.aliases. # def self.class_option(name, options) #:nodoc: options[:desc] = "Indicates when to generate #{name.to_s.humanize.downcase}" unless options.key?(:desc) - options[:aliases] = ALIASES[name] unless options.key?(:aliases) - options[:default] = DEFAULTS[name] unless options.key?(:default) + options[:aliases] = Rails::Generators.aliases[name] unless options.key?(:aliases) + options[:default] = Rails::Generators.options[name] unless options.key?(:default) super(name, options) end diff --git a/railties/lib/generators/rails/app/app_generator.rb b/railties/lib/generators/rails/app/app_generator.rb index 1971d150c86eb4c42de13da70c1707c90d7fab25..dc1d360e3fc341aed85cd9043eab4ff7896594a8 100644 --- a/railties/lib/generators/rails/app/app_generator.rb +++ b/railties/lib/generators/rails/app/app_generator.rb @@ -1,5 +1,6 @@ require 'digest/md5' require 'active_support/secure_random' +require 'rails/version' unless defined?(RAILS::VERSION) module Rails::Generators class AppGenerator < Base diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb index f0fb78c8f4fb715159fadac52e8e5484eb78ac61..fa7d2d524975c6a3e58de01033e87ea54cb6ff1d 100644 --- a/railties/lib/initializer.rb +++ b/railties/lib/initializer.rb @@ -568,4 +568,14 @@ def self.run(initializer = nil, config = nil) ActiveSupport::Dependencies.unhook! end end + + # Load generators if RAILS_ENV == "generators" + Initializer.default.add :initialize_generators do + if RAILS_ENV == "generators" + require 'generators' + Rails::Generators.no_color! unless config.generators.colorize_logging + Rails::Generators.aliases.merge! config.generators.aliases + Rails::Generators.options.merge! config.generators.options + end + end end diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb index 4a5fe4da7d858209ad94cad4784f66f0293c5efd..1a8f261e6f4a417f59d8f32cd5291799be042ddb 100644 --- a/railties/lib/rails/configuration.rb +++ b/railties/lib/rails/configuration.rb @@ -252,21 +252,25 @@ def reload_plugins? # Holds generators configuration: # - # config.generators.orm :datamapper - # config.generators.test_framework :rspec - # config.generators.template_engine :haml + # config.generators.orm = :datamapper + # config.generators.test_framework = :rspec + # config.generators.template_engine = :haml # # A block can also be given for less verbose configuration: # # config.generators do |g| - # g.orm :datamapper - # g.test_framework :datamapper - # g.template_engine :haml + # g.orm = :datamapper + # g.test_framework = :datamapper + # g.template_engine = :haml # end # # You can also configure/override aliases: # - # config.generators.aliases :test_framework => "-w" + # config.generators.aliases = :test_framework => "-w" + # + # Finally, to disable color in console, do: + # + # config.generators.colorize_logging = false # def generators @generators ||= Generators.new @@ -278,22 +282,19 @@ def generators end class Generators #:nodoc: - def initialize - @aliases, @options = {}, {} - end + attr_accessor :aliases, :options, :colorize_logging - def aliases(values=nil) - @aliases = values if values - @aliases - end - - def options(values=nil) - @options = values if values - @options + def initialize + @aliases, @options, @colorize_logging = {}, {}, true end def method_missing(method, *args, &block) - @options[method.to_sym] = args.first + method = method.to_s + if method.gsub!(/=$/, '') + @options[method.to_sym] = args.first + else + super(method.to_sym, *args, &block) + end end end end diff --git a/railties/test/initializer_test.rb b/railties/test/initializer_test.rb index da78647ab372e9ff4b9e1f16f767652a44650240..0a423b4da269dc75fa245b743e676cb8f9b975fa 100644 --- a/railties/test/initializer_test.rb +++ b/railties/test/initializer_test.rb @@ -1,5 +1,6 @@ require 'abstract_unit' require 'initializer' +require 'generators' require 'action_view' require 'action_mailer' @@ -10,8 +11,19 @@ module Rails def self.configuration Rails::Configuration.new end + + module Generators + def self.clear_aliases! + @aliases = nil + end + + def self.clear_options! + @@options = nil + end + end end + class ConfigurationMock < Rails::Configuration attr_reader :environment_path @@ -279,32 +291,77 @@ def load_plugins! end class InitializerGeneratorsTests < Test::Unit::TestCase - def test_generators_empty_aliases_and_options - assert_equal({}, Rails::Configuration.new.generators.aliases) - assert_equal({}, Rails::Configuration.new.generators.options) + + def setup + @old_env_value = RAILS_ENV.dup + @configuration = Rails::Configuration.new + @initializer = Rails::Initializer.default + @initializer.config = @configuration + end + + def test_generators_default_values + assert_equal(true, @configuration.generators.colorize_logging) + assert_equal({}, @configuration.generators.aliases) + assert_equal({}, @configuration.generators.options) end def test_generators_set_options - config = Rails::Configuration.new - config.generators.orm :datamapper - config.generators.test_framework :rspec - assert_equal({ :orm => :datamapper, :test_framework => :rspec }, config.generators.options) + @configuration.generators.orm = :datamapper + @configuration.generators.test_framework = :rspec + assert_equal({ :orm => :datamapper, :test_framework => :rspec }, @configuration.generators.options) end def test_generators_set_aliases - config = Rails::Configuration.new - config.generators.aliases :test_framework => "-w" - assert_equal({ :test_framework => "-w" }, config.generators.aliases) + @configuration.generators.aliases = { :test_framework => "-w" } + assert_equal({ :test_framework => "-w" }, @configuration.generators.aliases) end def test_generators_with_block - config = Rails::Configuration.new - config.generators do |g| - g.orm :datamapper - g.test_framework :rspec + @configuration.generators do |g| + g.orm = :datamapper + g.test_framework = :rspec end - assert_equal({ :orm => :datamapper, :test_framework => :rspec }, config.generators.options) + assert_equal({ :orm => :datamapper, :test_framework => :rspec }, @configuration.generators.options) end + + def test_generators_aliases_and_options_on_initialization + @configuration.generators.aliases = { :test_framework => "-w" } + @configuration.generators.orm = :datamapper + @configuration.generators.test_framework = :rspec + + RAILS_ENV.replace "generators" + @initializer.run(:initialize_generators) + + assert_equal :rspec, Rails::Generators.options[:test_framework] + assert_equal "-w", Rails::Generators.aliases[:test_framework] + end + + def test_generators_no_color_on_initialization + @configuration.generators.colorize_logging = false + RAILS_ENV.replace "generators" + @initializer.run(:initialize_generators) + assert_equal Thor::Base.shell, Thor::Shell::Basic + end + + def test_generators_raise_no_method_error_non_setters + assert_raise NoMethodError do + @configuration.generators.foo + end + end + + def test_generators_are_not_invoked_with_other_environments + @configuration.generators.test_framework = :rspec + @initializer.run(:initialize_generators) + assert_equal "test_unit", Rails::Generators.options[:test_framework] + end + + protected + + def teardown + RAILS_ENV.replace @old_env_value + Rails::Generators.clear_aliases! + Rails::Generators.clear_options! + end end class InitializerSetupI18nTests < Test::Unit::TestCase