1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Added source_paths to rails generators. If a template is added to RAILS_ROOT/lib/templates/base/generator it will be used. For example, to customize edit.html.erb template on scaffold, just add a customized copy at RAILS_ROOT/lib/templates/erb/scaffold.

This commit is contained in:
José Valim 2009-07-15 22:37:22 +02:00
parent b4ef958de6
commit 8d47078a49
3 changed files with 55 additions and 41 deletions

View file

@ -6,15 +6,16 @@ module Rails
end
class Base < Thor::Group
include Thor::Actions
include Rails::Generators::Actions
# Automatically sets the source root based on the class name.
#
def self.source_root
File.expand_path(File.join(File.dirname(__FILE__), base_name, generator_name, 'templates'))
@_rails_source_root ||= File.expand_path(File.join(File.dirname(__FILE__),
base_name, generator_name, 'templates'))
end
include Thor::Actions
include Rails::Generators::Actions
# Tries to get the description from a USAGE file one folder above the source
# root otherwise uses a default description.
#
@ -148,6 +149,19 @@ module Rails
super(name, options)
end
# Cache source root and add lib/generators/base/generator/templates to
# source paths.
#
def self.inherited(base) #:nodoc:
super
base.source_root # Cache source root
if defined?(RAILS_ROOT) && base.name !~ /Base$/
path = File.expand_path(File.join(RAILS_ROOT, 'lib', 'templates'))
base.source_paths << File.join(path, base.base_name, base.generator_name)
end
end
protected
# Check whether the given class names are already taken by user

View file

@ -28,45 +28,27 @@ class Thor
end
module ClassMethods
# Hold source paths used by Thor::Actions.
# Hold source paths for one Thor instance. source_paths_for_search is the
# method responsible to gather source_paths from this current class,
# inherited paths and the source root.
#
def source_paths
@source_paths ||= from_superclass(:source_paths, [])
@source_paths ||= []
end
# On inheritance, add source root to source paths so dynamic source_root
# (that depends on the class name, for example) are cached properly.
# Returns the source paths in the following order:
#
def inherited(base) #:nodoc:
super
base.source_paths
if base.respond_to?(:source_root) && !base.source_paths.include?(base.source_root)
base.source_paths.unshift(base.source_root)
end
end
# Deal with source root cache in source_paths. source_paths in the
# inheritance chain are tricky to implement because:
# 1) This class source paths
# 2) Source root
# 3) Parents source paths
#
# 1) We have to ensure that paths from the parent class appears later in
# the source paths array.
#
# 2) Whenever source_root is added, it has to be cached because __FILE__
# in ruby returns relative locations.
#
# 3) If someone wants to add source paths dinamically, added paths have
# to come before the source root.
#
# This method basically check if source root was added and put it between
# the inherited paths and the user added paths.
#
def singleton_method_added(method) #:nodoc:
if method == :source_root
inherited_paths = from_superclass(:source_paths, [])
self.source_paths.reject!{ |path| inherited_paths.include?(path) }
self.source_paths.push(*self.source_root)
self.source_paths.concat(inherited_paths)
def source_paths_for_search
@source_paths_for_search ||= begin
paths = []
paths += self.source_paths
paths << self.source_root if self.respond_to?(:source_root)
paths += from_superclass(:source_paths, [])
paths
end
end
end
@ -132,14 +114,14 @@ class Thor
#
def find_in_source_paths(file)
relative_root = relative_to_original_destination_root(destination_root, false)
source_file = nil
paths = self.class.source_paths_for_search
self.class.source_paths.each do |source|
paths.each do |source|
source_file = File.expand_path(file, File.join(source, relative_root))
return source_file if File.exists?(source_file)
end
if self.class.source_paths.empty?
if paths.empty?
raise Error, "You don't have any source path defined for class #{self.class.name}. To fix this, " <<
"you can define a source_root in your class."
else

View file

@ -84,7 +84,7 @@ class GeneratorsTest < GeneratorsTestCase
assert_equal "Others: active_record:fixjour, fixjour, mspec, rails:javascripts, wrong.", output
end
def test_warning_is_raised_if_generator_cant_be_loaded
def test_warning_is_shown_if_generator_cant_be_loaded
output = capture(:stderr){ Rails::Generators.find_by_namespace(:wrong) }
assert_match /\[WARNING\] Could not load generator at/, output
assert_match /Error: uninitialized constant Rails::Generator/, output
@ -96,4 +96,22 @@ class GeneratorsTest < GeneratorsTestCase
ensure
Thor::Base.shell = Thor::Shell::Color
end
def test_rails_root_templates
template = File.join(RAILS_ROOT, "lib", "templates", "active_record", "model", "model.rb")
# Create template
mkdir_p(File.dirname(template))
File.open(template, 'w'){ |f| f.write "empty" }
output = capture(:stdout) do
Rails::Generators.invoke :model, ["user"], :destination_root => destination_root
end
assert_file "app/models/user.rb" do |content|
assert_equal "empty", content
end
ensure
rm_rf File.dirname(template)
end
end