Avoid duplicated names on help description and show proper error message if trying to load a Rails 2.x generator.
Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
parent
f950d0b4af
commit
e15b5eda2b
|
@ -152,7 +152,18 @@ module Rails
|
||||||
end
|
end
|
||||||
load_paths # Cache load paths. Needed to avoid __FILE__ pointing to wrong paths.
|
load_paths # Cache load paths. Needed to avoid __FILE__ pointing to wrong paths.
|
||||||
|
|
||||||
# Receives a namespace and tries different combinations to find a generator.
|
# Rails finds namespaces exactly as thor, with three conveniences:
|
||||||
|
#
|
||||||
|
# 1) If your generator name ends with generator, as WebratGenerator, it sets
|
||||||
|
# its namespace to "webrat", so it can be invoked as "webrat" and not
|
||||||
|
# "webrat_generator";
|
||||||
|
#
|
||||||
|
# 2) If your generator has a generators namespace, as Rails::Generators::WebratGenerator,
|
||||||
|
# the namespace is set to "rails:generators:webrat", but Rails allows it
|
||||||
|
# to be invoked simply as "rails:webrat". The "generators" is added
|
||||||
|
# automatically when doing the lookup;
|
||||||
|
#
|
||||||
|
# 3) Rails looks in load paths and loads the generator just before it's going to be used.
|
||||||
#
|
#
|
||||||
# ==== Examples
|
# ==== Examples
|
||||||
#
|
#
|
||||||
|
@ -162,30 +173,29 @@ module Rails
|
||||||
#
|
#
|
||||||
# "rails:generators:webrat", "webrat:generators:integration", "webrat"
|
# "rails:generators:webrat", "webrat:generators:integration", "webrat"
|
||||||
#
|
#
|
||||||
# If the namespace has ":" included we consider that a absolute namespace
|
# On the other hand, if "rails:webrat" is given, it will search for:
|
||||||
# was given and the lookup above does not happen. Just the name is searched.
|
|
||||||
#
|
#
|
||||||
# Finally, it deals with one kind of shortcut:
|
# "rails:generators:webrat", "rails:webrat"
|
||||||
#
|
#
|
||||||
# find_by_namespace "test_unit:model"
|
# Notice that the "generators" namespace is handled automatically by Rails,
|
||||||
#
|
# so you don't need to type it when you want to invoke a generator in specific.
|
||||||
# It will search for generators at:
|
|
||||||
#
|
|
||||||
# "test_unit:generators:model", "test_unit:model"
|
|
||||||
#
|
#
|
||||||
def self.find_by_namespace(name, base=nil, context=nil) #:nodoc:
|
def self.find_by_namespace(name, base=nil, context=nil) #:nodoc:
|
||||||
name, attempts = name.to_s, []
|
name, attempts = name.to_s, [ ]
|
||||||
|
|
||||||
case name.count(':')
|
case name.count(':')
|
||||||
when 1
|
when 1
|
||||||
base, name = name.split(':')
|
base, name = name.split(':')
|
||||||
return find_by_namespace(name, base)
|
return find_by_namespace(name, base)
|
||||||
when 0
|
when 0
|
||||||
attempts << "#{base}:generators:#{name}" if base
|
attempts += generator_names(base, name) if base
|
||||||
attempts << "#{name}:generators:#{context}" if context
|
attempts += generator_names(name, context) if context
|
||||||
end
|
end
|
||||||
|
|
||||||
attempts << name
|
attempts << name
|
||||||
|
attempts += generator_names(name, name) unless name.include?(?:)
|
||||||
|
attempts.uniq!
|
||||||
|
|
||||||
unloaded = attempts - namespaces
|
unloaded = attempts - namespaces
|
||||||
lookup(unloaded)
|
lookup(unloaded)
|
||||||
|
|
||||||
|
@ -231,7 +241,10 @@ module Rails
|
||||||
|
|
||||||
until tail.empty?
|
until tail.empty?
|
||||||
others += Dir[File.join(path, *tail)].collect do |file|
|
others += Dir[File.join(path, *tail)].collect do |file|
|
||||||
file.split('/')[-tail.size, 2].join(':').sub(/_generator\.rb$/, '')
|
name = file.split('/')[-tail.size, 2]
|
||||||
|
name.last.sub!(/_generator\.rb$/, '')
|
||||||
|
name.uniq!
|
||||||
|
name.join(':')
|
||||||
end
|
end
|
||||||
tail.shift
|
tail.shift
|
||||||
end
|
end
|
||||||
|
@ -246,7 +259,7 @@ module Rails
|
||||||
# Return all defined namespaces.
|
# Return all defined namespaces.
|
||||||
#
|
#
|
||||||
def self.namespaces #:nodoc:
|
def self.namespaces #:nodoc:
|
||||||
Thor::Base.subclasses.map{ |klass| klass.namespace }
|
Thor::Base.subclasses.map { |klass| klass.namespace }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Keep builtin generators in an Array[Array[group, name]].
|
# Keep builtin generators in an Array[Array[group, name]].
|
||||||
|
@ -257,6 +270,12 @@ module Rails
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# By default, Rails strips the generator namespace to make invocations
|
||||||
|
# easier. This method generaters the both possibilities names.
|
||||||
|
def self.generator_names(first, second)
|
||||||
|
[ "#{first}:generators:#{second}", "#{first}:#{second}" ]
|
||||||
|
end
|
||||||
|
|
||||||
# Try callbacks for the given base.
|
# Try callbacks for the given base.
|
||||||
#
|
#
|
||||||
def self.invoke_fallbacks_for(name, base)
|
def self.invoke_fallbacks_for(name, base)
|
||||||
|
@ -285,6 +304,9 @@ module Rails
|
||||||
Dir[File.join(path, '**', attempts)].each do |file|
|
Dir[File.join(path, '**', attempts)].each do |file|
|
||||||
begin
|
begin
|
||||||
require file
|
require file
|
||||||
|
rescue NameError => e
|
||||||
|
raise unless e.message =~ /Rails::Generator/
|
||||||
|
warn "[WARNING] Could not load generator at #{file.inspect} because it's a Rails 2.x generator, which is not supported anymore"
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
warn "[WARNING] Could not load generator at #{file.inspect}. Error: #{e.message}"
|
warn "[WARNING] Could not load generator at #{file.inspect}. Error: #{e.message}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
module Foobar
|
||||||
|
class FoobarGenerator < Rails::Generators::Base
|
||||||
|
end
|
||||||
|
end
|
|
@ -45,6 +45,12 @@ class GeneratorsTest < GeneratorsTestCase
|
||||||
assert_equal "test_unit:generators:model", klass.namespace
|
assert_equal "test_unit:generators:model", klass.namespace
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_find_by_namespace_with_duplicated_name
|
||||||
|
klass = Rails::Generators.find_by_namespace(:foobar)
|
||||||
|
assert klass
|
||||||
|
assert_equal "foobar:foobar", klass.namespace
|
||||||
|
end
|
||||||
|
|
||||||
def test_find_by_namespace_add_generators_to_raw_lookups
|
def test_find_by_namespace_add_generators_to_raw_lookups
|
||||||
klass = Rails::Generators.find_by_namespace("test_unit:model")
|
klass = Rails::Generators.find_by_namespace("test_unit:model")
|
||||||
assert klass
|
assert klass
|
||||||
|
@ -101,14 +107,15 @@ class GeneratorsTest < GeneratorsTestCase
|
||||||
|
|
||||||
def test_rails_generators_with_others_information
|
def test_rails_generators_with_others_information
|
||||||
output = capture(:stdout){ Rails::Generators.help }.split("\n").last
|
output = capture(:stdout){ Rails::Generators.help }.split("\n").last
|
||||||
assert_equal "Others: active_record:fixjour, fixjour, mspec, rails:javascripts.", output
|
assert_equal "Others: active_record:fixjour, fixjour, foobar, mspec, rails:javascripts.", output
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_warning_is_shown_if_generator_cant_be_loaded
|
def test_warning_is_shown_if_generator_cant_be_loaded
|
||||||
Rails::Generators.load_paths << File.join(Rails.root, "vendor", "gems", "gems", "wrong")
|
Rails::Generators.load_paths << File.join(Rails.root, "vendor", "gems", "gems", "wrong")
|
||||||
output = capture(:stderr){ Rails::Generators.find_by_namespace(:wrong) }
|
output = capture(:stderr){ Rails::Generators.find_by_namespace(:wrong) }
|
||||||
|
|
||||||
assert_match /\[WARNING\] Could not load generator at/, output
|
assert_match /\[WARNING\] Could not load generator at/, output
|
||||||
assert_match /Error: uninitialized constant Rails::Generator/, output
|
assert_match /Rails 2\.x generator/, output
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_no_color_sets_proper_shell
|
def test_no_color_sets_proper_shell
|
||||||
|
|
Loading…
Reference in New Issue