Skip to content

Commit

Permalink
Generators: look for generators in all gems, not just those suffixed …
Browse files Browse the repository at this point in the history
…with _generator, in the gem's generators or rails_generators directory. Allow use of the rails_generators directory instead of the standard generators directory in plugins also. Closes #8730.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7139 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
jeremy committed Jun 27, 2007
1 parent 557e193 commit 868e6b0
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
2 changes: 2 additions & 0 deletions railties/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*

* Generators: look for generators in all gems, not just those suffixed with _generator, in the gem's generators or rails_generators directory. Allow use of the rails_generators directory instead of the standard generators directory in plugins also. #8730 [Dr Nic, topfunky]

* MySQL, PostgreSQL: database.yml defaults to utf-8. #8701 [matt]

* Added db:version to get the current schema number [via Err The Blog]
Expand Down
43 changes: 37 additions & 6 deletions railties/lib/rails_generator/lookup.rb
Expand Up @@ -46,7 +46,7 @@ module Generator
#
# A spec is not a generator: it's a description of where to find
# the generator and how to create it. A source is anything that
# yields generators from #each. PathSource and GemSource are provided.
# yields generators from #each. PathSource and GemGeneratorSource are provided.
module Lookup
def self.included(base)
base.extend(ClassMethods)
Expand Down Expand Up @@ -101,9 +101,13 @@ def use_component_sources!
sources << PathSource.new(:lib, "#{::RAILS_ROOT}/lib/generators")
sources << PathSource.new(:vendor, "#{::RAILS_ROOT}/vendor/generators")
sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/*/**/generators")
sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/*/**/rails_generators")
end
sources << PathSource.new(:user, "#{Dir.user_home}/.rails/generators")
sources << GemSource.new if Object.const_defined?(:Gem)
if Object.const_defined?(:Gem)
sources << GemGeneratorSource.new
sources << GemPathSource.new
end
sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/components")
end

Expand Down Expand Up @@ -185,14 +189,15 @@ def each
end
end


# GemSource hits the mines to quarry for generators. The latest versions
# of gems named *_generator are selected.
class GemSource < Source
class AbstractGemSource < Source
def initialize
super :RubyGems
end
end

# GemGeneratorSource hits the mines to quarry for generators. The latest versions
# of gems named *_generator are selected.
class GemGeneratorSource < AbstractGemSource
# Yield latest versions of generator gems.
def each
Gem::cache.search(/_generator$/).inject({}) { |latest, gem|
Expand All @@ -205,5 +210,31 @@ def each
end
end

# GemPathSource looks for generators within any RubyGem's /rails_generators/<generator_name>_generator.rb file.
class GemPathSource < AbstractGemSource
# Yield each generator within rails_generator subdirectories.
def each
generator_full_paths.each do |generator|
yield Spec.new(File.basename(generator).sub(/_generator.rb$/, ''), File.dirname(generator), label)
end
end

private
def generator_full_paths
@generator_full_paths ||=
Gem::cache.inject({}) do |latest, name_gem|
name, gem = name_gem
hem = latest[gem.name]
latest[gem.name] = gem if hem.nil? or gem.version > hem.version
latest
end.values.inject([]) do |mem, gem|
Dir[gem.full_gem_path + '/{rails_,}generators/**/*_generator.rb'].each do |generator|
mem << generator
end
mem
end
end
end

end
end
7 changes: 5 additions & 2 deletions railties/lib/rails_generator/scripts.rb
Expand Up @@ -43,9 +43,12 @@ def banner

def usage_message
usage = "\nInstalled Generators\n"
Rails::Generator::Base.sources.each do |source|
Rails::Generator::Base.sources.inject({}) do |mem, source|
label = source.label.to_s.capitalize
names = source.names
mem[label] ||= []
mem[label] |= source.names
mem
end.each_pair do |label, names|
usage << " #{label}: #{names.join(', ')}\n" unless names.empty?
end

Expand Down
2 changes: 1 addition & 1 deletion railties/lib/rails_generator/spec.rb
Expand Up @@ -2,7 +2,7 @@ module Rails
module Generator
# A spec knows where a generator was found and how to instantiate it.
# Metadata include the generator's name, its base path, and the source
# which yielded it (PathSource, GemSource, etc.)
# which yielded it (PathSource, GemPathSource, etc.)
class Spec
attr_reader :name, :path, :source

Expand Down

0 comments on commit 868e6b0

Please sign in to comment.