Permalink
Browse files

Refactored some generators to make use of improved invocations on thor.

  • Loading branch information...
1 parent a06c825 commit 0702e04e0d671227259f71f614adfe3f35f88b48 @josevalim josevalim committed Jul 15, 2009
View
2 railties/Rakefile
@@ -83,7 +83,7 @@ task :create_rails do
require File.join(File.dirname(__FILE__), 'lib', 'generators')
require 'generators/rails/app/app_generator'
Rails::Generators::AppGenerator.start [ File.basename(PKG_DESTINATION), "--quiet" ],
- :root => File.expand_path(File.dirname(PKG_DESTINATION))
+ :destination_root => File.expand_path(File.dirname(PKG_DESTINATION))
end
# Copy Vendors ----------------------------------------------------------------------------
View
8 railties/lib/generators/base.rb
@@ -6,15 +6,15 @@ class Error < Thor::Error
end
class Base < Thor::Group
- include Rails::Generators::Actions
- include Thor::Actions
-
# Automatically sets the source root based on the class name.
#
def self.source_root
- @_rails_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), base_name, generator_name, 'templates'))
+ 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.
#
View
21 railties/lib/generators/rails/generator/generator_generator.rb
@@ -3,22 +3,21 @@ module Generators
class GeneratorGenerator < NamedBase
check_class_collision :suffix => "Generator"
- def copy_generator_file
- template "generator.rb", generator_dir("#{file_name}_generator.rb")
- end
-
- def copy_usage_file
- template "USAGE", generator_dir("USAGE")
- end
+ class_option :namespace, :type => :boolean, :default => true,
+ :desc => "Namespace generator under lib/generators/name"
- def create_templates_dir
- empty_directory generator_dir("templates")
+ def craete_generator_files
+ directory '.', generator_dir
end
protected
- def generator_dir(join)
- File.join("lib", "generators", file_name, join)
+ def generator_dir
+ if options[:namespace]
+ File.join("lib", "generators", file_name)
+ else
+ File.join("lib", "generators")
+ end
end
end
View
0 ...ib/generators/%file_name%_generator.rb.tt → ...tor/templates/%file_name%_generator.rb.tt
File renamed without changes.
View
8 railties/lib/generators/rails/generator/templates/USAGE
@@ -1,8 +0,0 @@
-Description:
- Explain the generator
-
-Example:
- ./script/generate <%= file_name %> Thing
-
- This will create:
- what/will/it/create
View
0 .../plugin/templates/lib/generators/USAGE.tt → ...rators/rails/generator/templates/USAGE.tt
File renamed without changes.
View
5 railties/lib/generators/rails/generator/templates/generator.rb
@@ -1,5 +0,0 @@
-class <%= class_name %>Generator < Rails::Generators::NamedBase
- def self.source_root
- @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
- end
-end
View
0 ...lib/generators/templates/.empty_directory → ...ator/templates/templates/.empty_directory
File renamed without changes.
View
20 railties/lib/generators/rails/plugin/plugin_generator.rb
@@ -1,12 +1,11 @@
+require 'generators/rails/generator/generator_generator'
+
module Rails
module Generators
class PluginGenerator < NamedBase
class_option :tasks, :type => :boolean, :aliases => "-t", :default => false,
:desc => "When supplied creates tasks base files."
- class_option :generator, :type => :boolean, :aliases => "-g", :default => false,
- :desc => "When supplied creates generator base files."
-
check_class_collision
def create_root_files
@@ -17,16 +16,21 @@ def create_lib_files
directory 'lib', plugin_dir('lib'), false # non-recursive
end
- hook_for :test_framework
-
def create_tasks_files
return unless options[:tasks]
directory 'tasks', plugin_dir('tasks')
end
- def create_generator_files
- return unless options[:generator]
- directory 'lib/generators', plugin_dir('lib/generators')
+ hook_for :generator, :aliases => "-g", :type => :boolean do |instance, generator|
+ instance.inside_with_padding instance.send(:plugin_dir) do
+ instance.invoke generator, [ instance.name ], :namespace => false
+ end
+ end
+
+ hook_for :test_framework do |instance, test_framework|
+ instance.inside_with_padding instance.send(:plugin_dir) do
+ instance.invoke test_framework
+ end
end
protected
View
2 railties/lib/generators/test_unit/plugin/plugin_generator.rb
@@ -6,7 +6,7 @@ class PluginGenerator < Base
check_class_collision :suffix => "Test"
def create_test_files
- directory 'test', "vendor/plugins/#{file_name}/test"
+ directory '.', 'test'
end
end
end
View
0 ...gin/templates/test/%file_name%_test.rb.tt → ...t/plugin/templates/%file_name%_test.rb.tt
File renamed without changes.
View
0 ...unit/plugin/templates/test/test_helper.rb → ...test_unit/plugin/templates/test_helper.rb
File renamed without changes.
View
64 railties/lib/vendor/thor-0.11.1/lib/thor/actions.rb
@@ -5,17 +5,13 @@
end
class Thor
- # Some actions require that a class method called source root is defined in
- # the class. Remember to always cache the source root value, because Ruby
- # __FILE__ always return the relative path, which may lead to mistakes if you
- # are calling an action inside the "inside(path)" method.
- #
module Actions
attr_accessor :behavior
# On inclusion, add some options to base.
#
def self.included(base) #:nodoc:
+ base.extend ClassMethods
return unless base.respond_to?(:class_option)
base.class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
@@ -31,6 +27,50 @@ def self.included(base) #:nodoc:
:desc => "Supress status output"
end
+ module ClassMethods
+ # Hold source paths used by Thor::Actions.
+ #
+ def source_paths
+ @source_paths ||= from_superclass(: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.
+ #
+ 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) 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)
+ end
+ end
+ end
+
# Extends initializer to add more configuration options.
#
# ==== Configuration
@@ -88,14 +128,13 @@ def relative_to_original_destination_root(path, remove_dot=true)
remove_dot ? (path[2..-1] || '') : path
end
- # Receives a file or directory and serach for it in the source paths. Paths
- # added for last are the one searched first.
+ # Receives a file or directory and search for it in the source paths.
#
def find_in_source_paths(file)
relative_root = relative_to_original_destination_root(destination_root, false)
source_file = nil
- self.class.source_paths.reverse_each do |source|
+ self.class.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
@@ -123,6 +162,15 @@ def inside(dir='', &block)
@destination_stack.pop
end
+ # Same as inside, but log status and use padding.
+ #
+ def inside_with_padding(dir='', log_status=true, &block)
+ say_status :inside, dir, log_status
+ shell.padding += 1
+ inside(dir, &block)
+ shell.padding -= 1
+ end
+
# Goes to the root and execute the given block.
#
def in_root
View
21 railties/lib/vendor/thor-0.11.1/lib/thor/base.rb
@@ -37,15 +37,17 @@ def initialize(args=[], options={}, config={})
parse_options = self.class.class_options
- options = if options.is_a?(Array)
+ if options.is_a?(Array)
task_options = config.delete(:task_options) # hook for start
parse_options = parse_options.merge(task_options) if task_options
- Thor::Options.parse(parse_options, options)
+ array_options, hash_options = options, {}
else
- Thor::Options.parse(parse_options, []).merge(options)
+ array_options, hash_options = [], options
end
- self.options = Thor::CoreExt::HashWithIndifferentAccess.new(options).freeze
+ options = Thor::Options.parse(parse_options, array_options)
+ self.options = Thor::CoreExt::HashWithIndifferentAccess.new(options).merge!(hash_options)
+ self.options.freeze
end
class << self
@@ -81,10 +83,6 @@ def register_klass_file(klass) #:nodoc:
file = caller[1].match(/(.*):\d+/)[1]
Thor::Base.subclasses << klass unless Thor::Base.subclasses.include?(klass)
- if klass.respond_to?(:source_root) && !klass.source_paths.include?(klass.source_root)
- klass.source_paths.unshift(klass.source_root)
- end
-
file_subclasses = Thor::Base.subclass_files[File.expand_path(file)]
file_subclasses << klass unless file_subclasses.include?(klass)
end
@@ -341,13 +339,6 @@ def namespace(name=nil)
end
end
- # Hold source paths used by Thor::Actions. Paths added for last are the
- # one searched first.
- #
- def source_paths
- @source_paths ||= []
- end
-
# Default way to start generators from the command line.
#
def start(given_args=ARGV, config={}) #:nodoc:
View
11 railties/test/generators/generators_test_helper.rb
@@ -12,19 +12,18 @@
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../lib"
require 'generators'
+CURRENT_PATH = File.expand_path(Dir.pwd)
+
class GeneratorsTestCase < Test::Unit::TestCase
include FileUtils
- def self.test_dir
- @@test_dir = File.expand_path("#{File.dirname(__FILE__)}/../../")
- end
-
def destination_root
- @destination_root ||= File.join(self.class.test_dir, 'fixtures', 'tmp')
+ @destination_root ||= File.expand_path(File.join(File.dirname(__FILE__),
+ '..', '..', 'fixtures', 'tmp'))
end
def setup
- cd self.class.test_dir
+ cd CURRENT_PATH
rm_rf(destination_root)
mkdir_p(destination_root)
end

0 comments on commit 0702e04

Please sign in to comment.