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:
parent
b4ef958de6
commit
8d47078a49
3 changed files with 55 additions and 41 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue