aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2010-01-03 22:27:28 -0800
committerDavid Heinemeier Hansson <david@loudthinking.com>2010-01-03 22:27:28 -0800
commit5e94d3e3ea06e577d97a32eb4b38b61c4ce8ff8f (patch)
treeb89d06302223be67c595e65bffce54357d41a15a /railties/lib/rails
parentd7d917335e242f48fae31bc99e6d4ab381244913 (diff)
parenteca11bfdb5d3cf375faf8a24e2dc0cc5abd20f92 (diff)
downloadrails-5e94d3e3ea06e577d97a32eb4b38b61c4ce8ff8f.tar.gz
rails-5e94d3e3ea06e577d97a32eb4b38b61c4ce8ff8f.tar.bz2
rails-5e94d3e3ea06e577d97a32eb4b38b61c4ce8ff8f.zip
Merge
Diffstat (limited to 'railties/lib/rails')
-rw-r--r--railties/lib/rails/application.rb15
-rw-r--r--railties/lib/rails/generators.rb150
-rw-r--r--railties/lib/rails/generators/base.rb62
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb14
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb2
-rw-r--r--railties/lib/rails/generators/test_case.rb239
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb4
-rw-r--r--railties/lib/rails/vendor/thor-0.12.1/lib/thor/version.rb3
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/CHANGELOG.rdoc (renamed from railties/lib/rails/vendor/thor-0.12.1/CHANGELOG.rdoc)12
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/LICENSE (renamed from railties/lib/rails/vendor/thor-0.12.1/LICENSE)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/README.rdoc (renamed from railties/lib/rails/vendor/thor-0.12.1/README.rdoc)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/Thorfile (renamed from railties/lib/rails/vendor/thor-0.12.1/Thorfile)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor.rb)84
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions.rb)15
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/create_file.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/create_file.rb)4
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/directory.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/directory.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/empty_directory.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/empty_directory.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/file_manipulation.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/file_manipulation.rb)8
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/inject_into_file.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/inject_into_file.rb)4
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/base.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/base.rb)62
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/file_binary_read.rb9
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/hash_with_indifferent_access.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/hash_with_indifferent_access.rb)2
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/ordered_hash.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/ordered_hash.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/error.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/error.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/group.rb)46
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/invocation.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/invocation.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/argument.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/argument.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/arguments.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/arguments.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/option.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/option.rb)2
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/options.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/options.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/rake_compat.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/rake_compat.rb)0
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/runner.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/runner.rb)86
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell.rb)2
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/basic.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/basic.rb)76
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/color.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/color.rb)2
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/task.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/task.rb)75
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/util.rb (renamed from railties/lib/rails/vendor/thor-0.12.1/lib/thor/util.rb)26
-rw-r--r--railties/lib/rails/vendor/thor-0.12.3/lib/thor/version.rb3
39 files changed, 606 insertions, 401 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 5e68c05d7c..3fb4b723ab 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -8,7 +8,7 @@ module Rails
class << self
attr_writer :config
alias configure class_eval
- delegate :initialize!, :load_tasks, :to => :instance
+ delegate :initialize!, :load_tasks, :root, :to => :instance
private :new
def instance
@@ -267,18 +267,5 @@ module Rails
ActiveSupport::Dependencies.unhook!
end
end
-
- # For each framework, search for instrument file with Notifications hooks.
- #
- initializer :load_notifications_hooks do
- frameworks = [ :active_record, :action_controller, :action_view,
- :action_mailer, :active_resource ]
- frameworks.each do |framework|
- begin
- require "#{framework}/notifications"
- rescue LoadError => e
- end
- end
- end
end
end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 2ba56bc3c5..3713a38b33 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -10,7 +10,7 @@ require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/string/inflections'
# TODO: Do not always push on vendored thor
-$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/vendor/thor-0.12.1/lib")
+$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/vendor/thor-0.12.3/lib")
require 'rails/generators/base'
require 'rails/generators/named_base'
@@ -117,11 +117,15 @@ module Rails
end
# Remove the color from output.
- #
def self.no_color!
Thor::Base.shell = Thor::Shell::Basic
end
+ # Track all generators subclasses.
+ def self.subclasses
+ @subclasses ||= []
+ end
+
# Generators load paths used on lookup. The lookup happens as:
#
# 1) lib generators
@@ -147,18 +151,10 @@ module Rails
end
load_paths # Cache load paths. Needed to avoid __FILE__ pointing to wrong paths.
- # 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";
+ # Rails finds namespaces similar to thor, it only adds one rule:
#
- # 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.
+ # Generators names must end with "_generator.rb". This is required because Rails
+ # looks in load paths and loads the generator just before it's going to be used.
#
# ==== Examples
#
@@ -166,113 +162,81 @@ module Rails
#
# Will search for the following generators:
#
- # "rails:generators:webrat", "webrat:generators:integration", "webrat"
- #
- # On the other hand, if "rails:webrat" is given, it will search for:
+ # "rails:webrat", "webrat:integration", "webrat"
#
- # "rails:generators:webrat", "rails:webrat"
- #
- # 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.
+ # Notice that "rails:generators:webrat" could be loaded as well, what
+ # Rails looks for is the first and last parts of the namespace.
#
def self.find_by_namespace(name, base=nil, context=nil) #:nodoc:
- name, attempts = name.to_s, [ ]
-
- case name.count(':')
- when 1
- base, name = name.split(':')
- return find_by_namespace(name, base)
- when 0
- attempts += generator_names(base, name) if base
- attempts += generator_names(name, context) if context
- end
-
- attempts << name
- attempts += generator_names(name, name) unless name.include?(?:)
- attempts.uniq!
-
- unloaded = attempts - namespaces
- lookup(unloaded)
+ # Mount regexps to lookup
+ regexps = []
+ regexps << /^#{base}:[\w:]*#{name}$/ if base
+ regexps << /^#{name}:[\w:]*#{context}$/ if context
+ regexps << /^[(#{name}):]+$/
+ regexps.uniq!
+
+ # Check if generator happens to be loaded
+ checked = subclasses.dup
+ klass = find_by_regexps(regexps, checked)
+ return klass if klass
+
+ # Try to require other generators by looking in load_paths
+ lookup(name, context)
+ unchecked = subclasses - checked
+ klass = find_by_regexps(regexps, unchecked)
+ return klass if klass
+
+ # Invoke fallbacks
+ invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name)
+ end
- attempts.each do |namespace|
- klass = Thor::Util.find_by_namespace(namespace)
- return klass if klass
+ # Tries to find a generator which the namespace match the regexp.
+ def self.find_by_regexps(regexps, klasses)
+ klasses.find do |klass|
+ namespace = klass.namespace
+ regexps.find { |r| namespace =~ r }
end
-
- invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name)
end
# Receives a namespace, arguments and the behavior to invoke the generator.
# It's used as the default entry point for generate, destroy and update
# commands.
- #
def self.invoke(namespace, args=ARGV, config={})
- if klass = find_by_namespace(namespace, "rails")
+ names = namespace.to_s.split(':')
+
+ if klass = find_by_namespace(names.pop, names.shift || "rails")
args << "--help" if klass.arguments.any? { |a| a.required? } && args.empty?
- klass.start args, config
+ klass.start(args, config)
else
puts "Could not find generator #{namespace}."
end
end
# Show help message with available generators.
- #
def self.help
- rails = Rails::Generators.builtin.map do |group, name|
- name if group == "rails"
- end
- rails.compact!
- rails.sort!
-
- puts "Please select a generator."
- puts "Builtin: #{rails.join(', ')}."
-
- # Load paths and remove builtin
- paths, others = load_paths.dup, []
- paths.pop
-
- paths.each do |path|
- tail = [ "*", "*", "*_generator.rb" ]
-
- until tail.empty?
- others += Dir[File.join(path, *tail)].collect do |file|
- name = file.split('/')[-tail.size, 2]
- name.last.sub!(/_generator\.rb$/, '')
- name.uniq!
- name.join(':')
- end
- tail.shift
- end
- end
+ builtin = Rails::Generators.builtin.each { |n| n.sub!(/^rails:/, '') }
+ builtin.sort!
+ lookup("*")
+ others = subclasses.map{ |k| k.namespace.gsub(':generators:', ':') }
+ others -= Rails::Generators.builtin
others.sort!
+
+ puts "Please select a generator."
+ puts "Builtin: #{builtin.join(', ')}."
puts "Others: #{others.join(', ')}." unless others.empty?
end
protected
- # Return all defined namespaces.
- #
- def self.namespaces #:nodoc:
- Thor::Base.subclasses.map { |klass| klass.namespace }
- end
-
- # Keep builtin generators in an Array[Array[group, name]].
- #
+ # Keep builtin generators in an Array.
def self.builtin #:nodoc:
Dir[File.dirname(__FILE__) + '/generators/*/*'].collect do |file|
- file.split('/')[-2, 2]
+ file.split('/')[-2, 2].join(':')
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) #:nodoc:
- [ "#{first}:generators:#{second}", "#{first}:#{second}" ]
- end
-
- # Try callbacks for the given base.
- #
+ # Try fallbacks for the given base.
def self.invoke_fallbacks_for(name, base) #:nodoc:
return nil unless base && fallbacks[base.to_sym]
invoked_fallbacks = []
@@ -290,10 +254,10 @@ module Rails
# Receives namespaces in an array and tries to find matching generators
# in the load path.
- #
- def self.lookup(attempts) #:nodoc:
- attempts = attempts.map { |a| "#{a.split(":").last}_generator" }.uniq
- attempts = "{#{attempts.join(',')}}.rb"
+ def self.lookup(*attempts) #:nodoc:
+ attempts.compact!
+ attempts.uniq!
+ attempts = "{#{attempts.join(',')}}_generator.rb"
self.load_paths.each do |path|
Dir[File.join(path, '**', attempts)].each do |file|
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index 226ae63963..5e8c2730fd 100644
--- a/railties/lib/rails/generators/base.rb
+++ b/railties/lib/rails/generators/base.rb
@@ -76,17 +76,18 @@ module Rails
#
# The controller generator will then try to invoke the following generators:
#
- # "rails:generators:test_unit", "test_unit:generators:controller", "test_unit"
+ # "rails:test_unit", "test_unit:controller", "test_unit"
#
- # In this case, the "test_unit:generators:controller" is available and is
- # invoked. This allows any test framework to hook into Rails as long as it
- # provides any of the hooks above.
+ # Notice that "rails:generators:test_unit" could be loaded as well, what
+ # Rails looks for is the first and last parts of the namespace. This is what
+ # allows any test framework to hook into Rails as long as it provides any
+ # of the hooks above.
#
# ==== Options
#
- # This lookup can be customized with two options: :base and :as. The first
- # is the root module value and in the example above defaults to "rails".
- # The later defaults to the generator name, without the "Generator" ending.
+ # The first and last part used to find the generator to be invoked are
+ # guessed based on class invokes hook_for, as noticed in the example above.
+ # This can be customized with two options: :base and :as.
#
# Let's suppose you are creating a generator that needs to invoke the
# controller generator from test unit. Your first attempt is:
@@ -97,7 +98,7 @@ module Rails
#
# The lookup in this case for test_unit as input is:
#
- # "test_unit:generators:awesome", "test_unit"
+ # "test_unit:awesome", "test_unit"
#
# Which is not the desired the lookup. You can change it by providing the
# :as option:
@@ -108,18 +109,18 @@ module Rails
#
# And now it will lookup at:
#
- # "test_unit:generators:awesome", "test_unit"
+ # "test_unit:controller", "test_unit"
#
# Similarly, if you want it to also lookup in the rails namespace, you just
# need to provide the :base value:
#
# class AwesomeGenerator < Rails::Generators::Base
- # hook_for :test_framework, :base => :rails, :as => :controller
+ # hook_for :test_framework, :in => :rails, :as => :controller
# end
#
# And the lookup is exactly the same as previously:
#
- # "rails:generators:test_unit", "test_unit:generators:controller", "test_unit"
+ # "rails:test_unit", "test_unit:controller", "test_unit"
#
# ==== Switches
#
@@ -151,11 +152,11 @@ module Rails
# ==== Custom invocations
#
# You can also supply a block to hook_for to customize how the hook is
- # going to be invoked. The block receives two parameters, an instance
+ # going to be invoked. The block receives two arguments, an instance
# of the current class and the klass to be invoked.
#
# For example, in the resource generator, the controller should be invoked
- # with a pluralized class name. By default, it is invoked with the same
+ # with a pluralized class name. But by default it is invoked with the same
# name as the resource generator, which is singular. To change this, we
# can give a block to customize how the controller can be invoked.
#
@@ -178,11 +179,11 @@ module Rails
end
unless class_options.key?(name)
- class_option name, defaults.merge!(options)
+ class_option(name, defaults.merge!(options))
end
hooks[name] = [ in_base, as_hook ]
- invoke_from_option name, options, &block
+ invoke_from_option(name, options, &block)
end
end
@@ -193,7 +194,7 @@ module Rails
# remove_hook_for :orm
#
def self.remove_hook_for(*names)
- remove_invocation *names
+ remove_invocation(*names)
names.each do |name|
hooks.delete(name)
@@ -219,12 +220,16 @@ module Rails
# and can point to wrong directions when inside an specified directory.
base.source_root
- if base.name && base.name !~ /Base$/ && base.base_name && base.generator_name && defined?(Rails.root) && Rails.root
- path = File.expand_path(File.join(Rails.root, 'lib', 'templates'))
- if base.name.include?('::')
- base.source_paths << File.join(path, base.base_name, base.generator_name)
- else
- base.source_paths << File.join(path, base.generator_name)
+ if base.name && base.name !~ /Base$/
+ Rails::Generators.subclasses << base
+
+ if defined?(Rails.root) && Rails.root
+ path = File.expand_path(File.join(Rails.root, 'lib', 'templates'))
+ if base.name.include?('::')
+ base.source_paths << File.join(path, base.base_name, base.generator_name)
+ else
+ base.source_paths << File.join(path, base.generator_name)
+ end
end
end
end
@@ -267,7 +272,7 @@ module Rails
# parameters.
#
def invoked?(args)
- args.last.is_a?(Hash) && args.last.key?(:invocations)
+ args.last.is_a?(Hash) && (args.last.key?(:invocations) || args.last.key?(:destination_root))
end
# Use Rails default banner.
@@ -290,12 +295,10 @@ module Rails
# Rails::Generators::MetalGenerator will return "metal" as generator name.
#
def self.generator_name
- if name
- @generator_name ||= begin
- if klass_name = name.to_s.split('::').last
- klass_name.sub!(/Generator$/, '')
- klass_name.underscore
- end
+ @generator_name ||= begin
+ if generator = name.to_s.split('::').last
+ generator.sub!(/Generator$/, '')
+ generator.underscore
end
end
end
@@ -339,6 +342,7 @@ module Rails
#
def self.prepare_for_invocation(name, value) #:nodoc:
if value && constants = self.hooks[name]
+ value = name if TrueClass === value
Rails::Generators.find_by_namespace(value, *constants)
else
super
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index ee401b1fde..fc6a3cdee8 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -46,15 +46,16 @@ module Rails::Generators
def initialize(*args)
super
- if !options[:no_activerecord] && !DATABASES.include?(options[:database])
+ if !options[:skip_activerecord] && !DATABASES.include?(options[:database])
raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
end
end
def create_root
self.destination_root = File.expand_path(app_path, destination_root)
- empty_directory '.'
+ valid_app_const?
+ empty_directory '.'
set_default_accessors!
FileUtils.cd(destination_root)
end
@@ -193,7 +194,14 @@ module Rails::Generators
end
def app_const
- @app_const ||= "#{app_name.classify}::Application"
+ @app_const ||= "#{app_name.gsub(/\W/, '_').squeeze('_').classify}::Application"
+ end
+
+ def valid_app_const?
+ case app_const
+ when /^\d/
+ raise Error, "Invalid application name #{app_name}. Please give a name which does not start with numbers."
+ end
end
def app_secret
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index b6c1cef8cd..dce5b55d86 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -7,7 +7,7 @@ module <%= app_name.classify %>
# -- all .rb files in that directory are automatically loaded.
# Add additional load paths for your own custom dirs
- # config.load_paths += %W( #{root}/extras )
+ # config.load_paths += %W( #{config.root}/extras )
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named
diff --git a/railties/lib/rails/generators/test_case.rb b/railties/lib/rails/generators/test_case.rb
new file mode 100644
index 0000000000..643d7856c5
--- /dev/null
+++ b/railties/lib/rails/generators/test_case.rb
@@ -0,0 +1,239 @@
+require 'active_support/test_case'
+require 'active_support/core_ext/class/inheritable_attributes'
+require 'active_support/core_ext/hash/reverse_merge'
+require 'rails/generators'
+require 'fileutils'
+
+module Rails
+ module Generators
+ # Disable color in output. Easier to debug.
+ no_color!
+
+ # This class provides a TestCase for testing generators. To setup, you need
+ # just to configure the destination and set which generator is being tested:
+ #
+ # class AppGeneratorTest < Rails::Generators::TestCase
+ # tests AppGenerator
+ # destination File.expand_path("../tmp", File.dirname(__FILE__))
+ # end
+ #
+ # If you want to ensure your destination root is clean before running each test,
+ # you can set a setup callback:
+ #
+ # class AppGeneratorTest < Rails::Generators::TestCase
+ # tests AppGenerator
+ # destination File.expand_path("../tmp", File.dirname(__FILE__))
+ # setup :prepare_destination
+ # end
+ #
+ class TestCase < ActiveSupport::TestCase
+ include FileUtils
+
+ extlib_inheritable_accessor :destination_root, :current_path, :generator_class,
+ :default_arguments, :instance_writer => false
+
+ # Generators frequently change the current path using +FileUtils.cd+.
+ # So we need to store the path at file load and revert back to it after each test.
+ self.current_path = File.expand_path(Dir.pwd)
+ self.default_arguments = []
+
+ setup :destination_root_is_set?, :ensure_current_path
+ teardown :ensure_current_path
+
+ # Sets which generator should be tested:
+ #
+ # tests AppGenerator
+ #
+ def self.tests(klass)
+ self.generator_class = klass
+ end
+
+ # Sets default arguments on generator invocation. This can be overwritten when
+ # invoking it.
+ #
+ # arguments %w(app_name --skip-activerecord)
+ #
+ def self.arguments(array)
+ self.default_arguments = array
+ end
+
+ # Sets the destination of generator files:
+ #
+ # destination File.expand_path("../tmp", File.dirname(__FILE__))
+ #
+ def self.destination(path)
+ self.destination_root = path
+ end
+
+ # Captures the given stream and returns it:
+ #
+ # stream = capture(:stdout){ puts "Cool" }
+ # stream #=> "Cool\n"
+ #
+ def capture(stream)
+ begin
+ stream = stream.to_s
+ eval "$#{stream} = StringIO.new"
+ yield
+ result = eval("$#{stream}").string
+ ensure
+ eval("$#{stream} = #{stream.upcase}")
+ end
+
+ result
+ end
+ alias :silence :capture
+
+ # Asserts a given file exists. You need to supply an absolute path or a path relative
+ # to the configured destination:
+ #
+ # assert_file "config/environment.rb"
+ #
+ # You can also give extra arguments. If the argument is a regexp, it will check if the
+ # regular expression matches the given file content. If it's a string, it compares the
+ # file with the given string:
+ #
+ # assert_file "config/environment.rb", /initialize/
+ #
+ # Finally, when a block is given, it yields the file content:
+ #
+ # assert_file "app/controller/products_controller.rb" do |controller|
+ # assert_instance_method :index, content do |index|
+ # assert_match /Product\.all/, index
+ # end
+ # end
+ #
+ def assert_file(relative, *contents)
+ absolute = File.expand_path(relative, destination_root)
+ assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not"
+
+ read = File.read(absolute) if block_given? || !contents.empty?
+ yield read if block_given?
+
+ contents.each do |content|
+ case content
+ when String
+ assert_equal content, read
+ when Regexp
+ assert_match content, read
+ end
+ end
+ end
+ alias :assert_directory :assert_file
+
+ # Asserts a given file does not exist. You need to supply an absolute path or a
+ # path relative to the configured destination:
+ #
+ # assert_no_file "config/random.rb"
+ #
+ def assert_no_file(relative)
+ absolute = File.expand_path(relative, destination_root)
+ assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does"
+ end
+ alias :assert_no_directory :assert_no_file
+
+ # Asserts a given file does not exist. You need to supply an absolute path or a
+ # path relative to the configured destination:
+ #
+ # assert_migration "db/migrate/create_products.rb"
+ #
+ # This method manipulates the given path and tries to find any migration which
+ # matches the migration name. For example, the call above is converted to:
+ #
+ # assert_file "db/migrate/003_create_products.rb"
+ #
+ # Consequently, assert_migration accepts the same arguments has assert_file.
+ #
+ def assert_migration(relative, *contents, &block)
+ file_name = migration_file_name(relative)
+ assert file_name, "Expected migration #{relative} to exist, but was not found"
+ assert_file file_name, *contents, &block
+ end
+
+ # Asserts a given migration does not exist. You need to supply an absolute path or a
+ # path relative to the configured destination:
+ #
+ # assert_no_file "config/random.rb"
+ #
+ def assert_no_migration(relative)
+ file_name = migration_file_name(relative)
+ assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}"
+ end
+
+ # Asserts the given class method exists in the given content. This method does not detect
+ # class methods inside (class << self), only class methods which starts with "self.".
+ # When a block is given, it yields the content of the method.
+ #
+ # assert_migration "db/migrate/create_products.rb" do |migration|
+ # assert_class_method :up, migration do |up|
+ # assert_match /create_table/, up
+ # end
+ # end
+ #
+ def assert_class_method(method, content, &block)
+ assert_instance_method "self.#{method}", content, &block
+ end
+
+ # Asserts the given method exists in the given content. When a block is given,
+ # it yields the content of the method.
+ #
+ # assert_file "app/controller/products_controller.rb" do |controller|
+ # assert_instance_method :index, content do |index|
+ # assert_match /Product\.all/, index
+ # end
+ # end
+ #
+ def assert_instance_method(method, content)
+ assert content =~ /def #{method}(\(.+\))?(.*?)\n end/m, "Expected to have method #{method}"
+ yield $2.strip if block_given?
+ end
+ alias :assert_method :assert_instance_method
+
+ # Runs the generator configured for this class. The first argument is an array like
+ # command line arguments:
+ #
+ # class AppGeneratorTest < Rails::Generators::TestCase
+ # tests AppGenerator
+ # destination File.expand_path("../tmp", File.dirname(__FILE__))
+ # teardown :cleanup_destination_root
+ #
+ # test "database.yml is not created when skipping activerecord" do
+ # run_generator %w(myapp --skip-activerecord)
+ # assert_no_file "config/database.yml"
+ # end
+ # end
+ #
+ # You can provide a configuration hash as second argument. This method returns the output
+ # printed by the generator.
+ def run_generator(args=self.default_arguments, config={})
+ capture(:stdout) { self.generator_class.start(args, config.reverse_merge(:destination_root => destination_root)) }
+ end
+
+ # Instantiate the generator.
+ def generator(args=self.default_arguments, options={}, config={})
+ @generator ||= self.generator_class.new(args, options, config.reverse_merge(:destination_root => destination_root))
+ end
+
+ protected
+
+ def destination_root_is_set? #:nodoc:
+ raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root
+ end
+
+ def ensure_current_path #:nodoc:
+ cd current_path
+ end
+
+ def prepare_destination
+ rm_rf(destination_root)
+ mkdir_p(destination_root)
+ end
+
+ def migration_file_name(relative) #:nodoc:
+ absolute = File.expand_path(relative, destination_root)
+ dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '')
+ Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
index e4bf4035da..9380aa49b6 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -16,7 +16,7 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
test "should create <%= file_name %>" do
assert_difference('<%= class_name %>.count') do
- post :create, :<%= file_name %> => { }
+ post :create, :<%= file_name %> => <%= table_name %>(:one).attributes
end
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
@@ -33,7 +33,7 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
end
test "should update <%= file_name %>" do
- put :update, :id => <%= table_name %>(:one).to_param, :<%= file_name %> => { }
+ put :update, :id => <%= table_name %>(:one).to_param, :<%= file_name %> => <%= table_name %>(:one).attributes
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/version.rb b/railties/lib/rails/vendor/thor-0.12.1/lib/thor/version.rb
deleted file mode 100644
index 650253d648..0000000000
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/version.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class Thor
- VERSION = "0.12.1".freeze
-end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/CHANGELOG.rdoc b/railties/lib/rails/vendor/thor-0.12.3/CHANGELOG.rdoc
index 606a0cdb52..d02fc43e84 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/CHANGELOG.rdoc
+++ b/railties/lib/rails/vendor/thor-0.12.3/CHANGELOG.rdoc
@@ -1,9 +1,7 @@
-== TODO
-
-* Improve spec coverage for Thor::Runner
-
-== 0.12, released 2009-11-06
+== 0.12, released 2010-01-02
+* Removed rr in favor to rspec mock framework
+* Improved output for thor -T
* [#7] Do not force white color on status
* [#8] Yield a block with the filename on directory
@@ -17,7 +15,7 @@
* thor help now show information about any class/task. All those calls are
possible:
-
+
thor help describe
thor help describe:amazing
@@ -47,7 +45,7 @@
are in the 'standard' group. Running 'thor -T' will only show the standard
tasks - adding --all will show all tasks. You can also filter on a specific
group using the --group option: thor -T --group advanced
-
+
== 0.9.6, released 2008-09-13
* Generic improvements
diff --git a/railties/lib/rails/vendor/thor-0.12.1/LICENSE b/railties/lib/rails/vendor/thor-0.12.3/LICENSE
index 98722da459..98722da459 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/LICENSE
+++ b/railties/lib/rails/vendor/thor-0.12.3/LICENSE
diff --git a/railties/lib/rails/vendor/thor-0.12.1/README.rdoc b/railties/lib/rails/vendor/thor-0.12.3/README.rdoc
index ee545f3d97..ee545f3d97 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/README.rdoc
+++ b/railties/lib/rails/vendor/thor-0.12.3/README.rdoc
diff --git a/railties/lib/rails/vendor/thor-0.12.1/Thorfile b/railties/lib/rails/vendor/thor-0.12.3/Thorfile
index ff1cb4498a..ff1cb4498a 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/Thorfile
+++ b/railties/lib/rails/vendor/thor-0.12.3/Thorfile
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor.rb
index 68944f140d..d4d8fbd64d 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor.rb
@@ -78,14 +78,14 @@ class Thor
@method_options
end
- # Adds an option to the set of class options. If :for is given as option,
+ # Adds an option to the set of method options. If :for is given as option,
# it allows you to change the options from a previous defined task.
#
# def previous_task
# # magic
# end
#
- # method_options :foo => :bar, :for => :previous_task
+ # method_option :foo => :bar, :for => :previous_task
#
# def next_task
# # magic
@@ -101,7 +101,6 @@ class Thor
# :default - Default value for this argument. It cannot be required and have default values.
# :aliases - Aliases for this option.
# :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
- # :group - The group for this options. Use by class options to output options in different levels.
# :banner - String to show on usage notes.
#
def method_option(name, options={})
@@ -140,49 +139,48 @@ class Thor
end
end
- # Prints help information. If a task name is given, it shows information
- # only about the specific task.
+ # Prints help information for the given task.
#
# ==== Parameters
- # meth<String>:: An optional task name to print usage information about.
+ # shell<Thor::Shell>
+ # task_name<String>
+ #
+ def task_help(shell, task_name)
+ task = all_tasks[task_name]
+ raise UndefinedTaskError, "task '#{task_name}' could not be found in namespace '#{self.namespace}'" unless task
+
+ shell.say "Usage:"
+ shell.say " #{banner(task)}"
+ shell.say
+ class_options_help(shell, nil => task.options.map { |_, o| o })
+ shell.say task.description
+ end
+
+ # Prints help information for this class.
#
- # ==== Options
- # namespace:: When true, shows the namespace in the output before the usage.
- # skip_inherited:: When true, does not show tasks from superclass.
+ # ==== Parameters
+ # shell<Thor::Shell>
#
- def help(shell, meth=nil, options={})
- meth, options = nil, meth if meth.is_a?(Hash)
-
- if meth
- task = all_tasks[meth]
- raise UndefinedTaskError, "task '#{meth}' could not be found in namespace '#{self.namespace}'" unless task
-
- shell.say "Usage:"
- shell.say " #{banner(task, options[:namespace], false)}"
- shell.say
- class_options_help(shell, "Class", :Method => task.options.map { |_, o| o })
- shell.say task.description
- else
- list = (options[:short] ? tasks : all_tasks).map do |_, task|
- item = [ banner(task, options[:namespace]) ]
- item << "# #{task.short_description}" if task.short_description
- item << " "
- end
-
- options[:ident] ||= 2
- if options[:short]
- shell.print_list(list, :ident => options[:ident])
- else
- shell.say "Tasks:"
- shell.print_list(list, :ident => options[:ident])
- end
+ def help(shell)
+ list = printable_tasks
+ Thor::Util.thor_classes_in(self).each do |klass|
+ list += klass.printable_tasks(false)
+ end
+ list.sort!{ |a,b| a[0] <=> b[0] }
- Thor::Util.thor_classes_in(self).each do |subclass|
- namespace = options[:namespace] == true || subclass.namespace.gsub(/^#{self.namespace}:/, '')
- subclass.help(shell, options.merge(:short => true, :namespace => namespace))
- end
+ shell.say "Tasks:"
+ shell.print_table(list, :ident => 2, :truncate => true)
+ shell.say
+ class_options_help(shell)
+ end
- class_options_help(shell, "Class") unless options[:short]
+ # Returns tasks ready to be printed.
+ def printable_tasks(all=true)
+ (all ? all_tasks : tasks).map do |_, task|
+ item = []
+ item << banner(task)
+ item << (task.description ? "# #{task.description.gsub(/\s+/m,' ')}" : "")
+ item
end
end
@@ -193,8 +191,8 @@ class Thor
# the task that is going to be invoked and a boolean which indicates if
# the namespace should be displayed as arguments.
#
- def banner(task, namespace=true, show_options=true)
- task.formatted_usage(self, namespace, show_options)
+ def banner(task)
+ "thor " + task.formatted_usage(self)
end
def baseclass #:nodoc:
@@ -237,6 +235,6 @@ class Thor
desc "help [TASK]", "Describe available tasks or one specific task"
def help(task=nil)
- self.class.help(shell, task, :namespace => task && task.include?(?:))
+ task ? self.class.task_help(shell, task) : self.class.help(shell)
end
end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions.rb
index 4bfb7c2870..da98444bf2 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions.rb
@@ -1,4 +1,5 @@
require 'fileutils'
+require 'thor/core_ext/file_binary_read'
Dir[File.join(File.dirname(__FILE__), "actions", "*.rb")].each do |action|
require action
@@ -38,17 +39,17 @@ class Thor
# Add runtime options that help actions execution.
#
def add_runtime_options!
- class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
- :desc => "Run but do not make any changes"
-
class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime,
:desc => "Overwrite files that already exist"
- class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
- :desc => "Skip files that already exist"
+ class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
+ :desc => "Run but do not make any changes"
class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime,
:desc => "Supress status output"
+
+ class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
+ :desc => "Skip files that already exist"
end
end
@@ -114,7 +115,7 @@ class Thor
@source_paths ||= self.class.source_paths_for_search
end
- # Receives a file or directory and search for it in the source paths.
+ # 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)
@@ -222,7 +223,7 @@ class Thor
run "#{command}", config.merge(:with => Thor::Util.ruby_command)
end
- # Run a thor command. A hash of options can be given and it's converted to
+ # Run a thor command. A hash of options can be given and it's converted to
# switches.
#
# ==== Parameters
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/create_file.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/create_file.rb
index a3d9296823..6e0eeb43e2 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/create_file.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/create_file.rb
@@ -42,7 +42,7 @@ class Thor
# Boolean:: true if it is identical, false otherwise.
#
def identical?
- exists? && File.read(destination) == render
+ exists? && File.binread(destination) == render
end
# Holds the content to be added to the file.
@@ -58,7 +58,7 @@ class Thor
def invoke!
invoke_with_conflict_check do
FileUtils.mkdir_p(File.dirname(destination))
- File.open(destination, 'w'){ |f| f.write render }
+ File.open(destination, 'wb') { |f| f.write render }
end
given_destination
end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/directory.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/directory.rb
index 2e0b459fa3..2e0b459fa3 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/directory.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/directory.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/empty_directory.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/empty_directory.rb
index 484cb820f8..484cb820f8 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/empty_directory.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/empty_directory.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/file_manipulation.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/file_manipulation.rb
index 8a45c83f25..44d6836c10 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/file_manipulation.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/file_manipulation.rb
@@ -23,7 +23,7 @@ class Thor
source = File.expand_path(find_in_source_paths(source.to_s))
create_file destination, nil, config do
- content = File.read(source)
+ content = File.binread(source)
content = block.call(content) if block
content
end
@@ -48,7 +48,7 @@ class Thor
#
def get(source, destination=nil, config={}, &block)
source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^http\:\/\//
- render = open(source).read
+ render = File.binread(source)
destination ||= if block_given?
block.arity == 1 ? block.call(render) : block.call
@@ -80,7 +80,7 @@ class Thor
context = instance_eval('binding')
create_file destination, nil, config do
- content = ERB.new(::File.read(source), nil, '-').result(context)
+ content = ERB.new(::File.binread(source), nil, '-').result(context)
content = block.call(content) if block
content
end
@@ -193,7 +193,7 @@ class Thor
say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
unless options[:pretend]
- content = File.read(path)
+ content = File.binread(path)
content.gsub!(flag, *args, &block)
File.open(path, 'wb') { |file| file.write(content) }
end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/inject_into_file.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/inject_into_file.rb
index 6b0b42ea02..350ab73862 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/inject_into_file.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/inject_into_file.rb
@@ -11,7 +11,7 @@ class Thor
# data<String>:: Data to add to the file. Can be given as a block.
# config<Hash>:: give :verbose => false to not log the status and the flag
# for injection (:after or :before).
- #
+ #
# ==== Examples
#
# inject_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
@@ -90,7 +90,7 @@ class Thor
#
def replace!(regexp, string)
unless base.options[:pretend]
- content = File.read(destination)
+ content = File.binread(destination)
content.gsub!(regexp, string)
File.open(destination, 'wb') { |file| file.write(content) }
end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/base.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/base.rb
index 700d794123..aae4cdb89c 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/base.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/base.rb
@@ -92,6 +92,8 @@ class Thor
end
module ClassMethods
+ attr_accessor :debugging
+
# Adds an argument to the class and creates an attr_accessor for it.
#
# Arguments are different from options in several aspects. The first one
@@ -347,10 +349,11 @@ class Thor
# Default way to start generators from the command line.
#
def start(given_args=ARGV, config={})
+ self.debugging = given_args.include?("--debug")
config[:shell] ||= Thor::Base.shell.new
yield
rescue Thor::Error => e
- if given_args.include?("--debug")
+ if debugging
raise e
else
config[:shell].error e.message
@@ -361,48 +364,43 @@ class Thor
protected
# Prints the class options per group. If an option does not belong to
- # any group, it uses the ungrouped name value. This method provide to
- # hooks to add extra options, one of them if the third argument called
- # extra_group that should be a hash in the format :group => Array[Options].
- #
- # The second is by returning a lambda used to print values. The lambda
- # requires two options: the group name and the array of options.
+ # any group, it's printed as Class option.
#
- def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc:
- groups = {}
-
+ def class_options_help(shell, groups={}) #:nodoc:
+ # Group options by group
class_options.each do |_, value|
groups[value.group] ||= []
groups[value.group] << value
end
- printer = proc do |group_name, options|
- list = []
- padding = options.collect{ |o| o.aliases.size }.max.to_i * 4
+ # Deal with default group
+ global_options = groups.delete(nil) || []
+ print_options(shell, global_options)
+
+ # Print all others
+ groups.each do |group_name, options|
+ print_options(shell, options, group_name)
+ end
+ end
+
+ # Receives a set of options and print them.
+ def print_options(shell, options, group_name=nil)
+ return if options.empty?
- options.each do |option|
- item = [ option.usage(padding) ]
- item.push(option.description ? "# #{option.description}" : "")
+ list = []
+ padding = options.collect{ |o| o.aliases.size }.max.to_i * 4
- list << item
- list << [ "", "# Default: #{option.default}" ] if option.show_default?
- end
+ options.each do |option|
+ item = [ option.usage(padding) ]
+ item.push(option.description ? "# #{option.description}" : "")
- unless list.empty?
- shell.say(group_name ? "#{group_name} options:" : "Options:")
- shell.print_table(list, :ident => 2)
- shell.say ""
- end
+ list << item
+ list << [ "", "# Default: #{option.default}" ] if option.show_default?
end
- # Deal with default group
- global_options = groups.delete(nil) || []
- printer.call(ungrouped_name, global_options) if global_options
-
- # Print all others
- groups = extra_group.merge(groups) if extra_group
- groups.each(&printer)
- printer
+ shell.say(group_name ? "#{group_name} options:" : "Options:")
+ shell.print_table(list, :ident => 2)
+ shell.say ""
end
# Raises an error if the word given is a Thor reserved word.
diff --git a/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/file_binary_read.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/file_binary_read.rb
new file mode 100644
index 0000000000..d6af7e44b0
--- /dev/null
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/file_binary_read.rb
@@ -0,0 +1,9 @@
+class File #:nodoc:
+
+ unless File.respond_to?(:binread)
+ def self.binread(file)
+ File.open(file, 'rb') { |f| f.read }
+ end
+ end
+
+end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/hash_with_indifferent_access.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/hash_with_indifferent_access.rb
index 40d201d9e4..78bc5cf4bf 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/hash_with_indifferent_access.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/hash_with_indifferent_access.rb
@@ -65,7 +65,7 @@ class Thor
else
self[$1] == args.first
end
- else
+ else
self[method]
end
end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/ordered_hash.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/ordered_hash.rb
index 27fea5bb35..27fea5bb35 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/ordered_hash.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/ordered_hash.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/error.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/error.rb
index f9b31a35d1..f9b31a35d1 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/error.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/error.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/group.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb
index 021a067a3e..a585b37b73 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/group.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb
@@ -41,16 +41,12 @@ class Thor::Group
# ==== Options
# short:: When true, shows only usage.
#
- def help(shell, options={})
- if options[:short]
- shell.say banner
- else
- shell.say "Usage:"
- shell.say " #{banner}"
- shell.say
- class_options_help(shell)
- shell.say self.desc if self.desc
- end
+ def help(shell)
+ shell.say "Usage:"
+ shell.say " #{banner}\n"
+ shell.say
+ class_options_help(shell)
+ shell.say self.desc if self.desc
end
# Stores invocations for this class merging with superclass values.
@@ -132,7 +128,7 @@ class Thor::Group
names.each do |name|
unless class_options.key?(name)
- raise ArgumentError, "You have to define the option #{name.inspect} " <<
+ raise ArgumentError, "You have to define the option #{name.inspect} " <<
"before setting invoke_from_option."
end
@@ -177,15 +173,11 @@ class Thor::Group
# Overwrite class options help to allow invoked generators options to be
# shown recursively when invoking a generator.
#
- def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc:
- group_options = {}
-
- get_options_from_invocations(group_options, class_options) do |klass|
- klass.send(:get_options_from_invocations, group_options, class_options)
+ def class_options_help(shell, groups={}) #:nodoc:
+ get_options_from_invocations(groups, class_options) do |klass|
+ klass.send(:get_options_from_invocations, groups, class_options)
end
-
- group_options.merge!(extra_group) if extra_group
- super(shell, ungrouped_name, group_options)
+ super(shell, groups)
end
# Get invocations array and merge options from invocations. Those
@@ -218,13 +210,26 @@ class Thor::Group
end
end
+ # Returns tasks ready to be printed.
+ def printable_tasks(*)
+ item = []
+ item << banner
+ item << (desc ? "# #{desc.gsub(/\s+/m,' ')}" : "")
+ [item]
+ end
+
protected
# The banner for this class. You can customize it if you are invoking the
# thor class by another ways which is not the Thor::Runner.
#
def banner
- "#{self.namespace} #{self.arguments.map {|a| a.usage }.join(' ')}"
+ "thor #{self_task.formatted_usage(self, false)}"
+ end
+
+ # Represents the whole class as a task.
+ def self_task #:nodoc:
+ Thor::Task::Dynamic.new(self.namespace, class_options)
end
def baseclass #:nodoc:
@@ -243,7 +248,6 @@ class Thor::Group
# Shortcut to invoke with padding and block handling. Use internally by
# invoke and invoke_from_option class methods.
- #
def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc:
shell.padding += 1
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/invocation.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/invocation.rb
index 32e6a72454..32e6a72454 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/invocation.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/invocation.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser.rb
index 57a3f6e1a5..57a3f6e1a5 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/argument.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/argument.rb
index aa8ace4719..aa8ace4719 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/argument.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/argument.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/arguments.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/arguments.rb
index fb5d965e06..fb5d965e06 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/arguments.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/arguments.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/option.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/option.rb
index e09b4901e2..9e40ec73fa 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/option.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/option.rb
@@ -36,7 +36,7 @@ class Thor
# string (--foo=value) or booleans (just --foo).
#
# By default all options are optional, unless :required is given.
- #
+ #
def self.parse(key, value)
if key.is_a?(Array)
name, *aliases = key
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/options.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/options.rb
index 75092308b5..75092308b5 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/options.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/options.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/rake_compat.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/rake_compat.rb
index 0d0757fdda..0d0757fdda 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/rake_compat.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/rake_compat.rb
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/runner.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/runner.rb
index 079f9e0c65..f197081e3f 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/runner.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/runner.rb
@@ -36,7 +36,7 @@ class Thor::Runner < Thor #:nodoc:
def install(name)
initialize_thorfiles
- # If a directory name is provided as the argument, look for a 'main.thor'
+ # If a directory name is provided as the argument, look for a 'main.thor'
# task in said directory.
begin
if File.directory?(File.expand_path(name))
@@ -124,11 +124,7 @@ class Thor::Runner < Thor #:nodoc:
method_options :internal => :boolean
def installed
initialize_thorfiles(nil, true)
-
- klasses = Thor::Base.subclasses
- klasses -= [Thor, Thor::Runner] unless options["internal"]
-
- display_klasses(true, klasses)
+ display_klasses(true, options["internal"])
end
desc "list [SEARCH]", "List the available thor tasks (--substring means .*SEARCH)"
@@ -144,11 +140,15 @@ class Thor::Runner < Thor #:nodoc:
(options[:all] || k.group == group) && k.namespace =~ search
end
- display_klasses(false, klasses)
+ display_klasses(false, false, klasses)
end
private
+ def self.banner(task)
+ "thor " + task.formatted_usage(self, false)
+ end
+
def thor_root
Thor::Util.thor_root
end
@@ -156,7 +156,7 @@ class Thor::Runner < Thor #:nodoc:
def thor_yaml
@thor_yaml ||= begin
yaml_file = File.join(thor_root, "thor.yml")
- yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file)
+ yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file)
yaml || {}
end
end
@@ -215,9 +215,6 @@ class Thor::Runner < Thor #:nodoc:
# 5. c:\ <-- no Thorfiles found!
#
def thorfiles(relevant_to=nil, skip_lookup=false)
- # TODO Remove this dealing with deprecated thor when :namespaces: is available as constants
- save_yaml(thor_yaml) if Thor::Util.convert_constants_to_namespaces(thor_yaml)
-
thorfiles = []
unless skip_lookup
@@ -253,47 +250,54 @@ class Thor::Runner < Thor #:nodoc:
# Display information about the given klasses. If with_module is given,
# it shows a table with information extracted from the yaml file.
#
- def display_klasses(with_modules=false, klasses=Thor.subclasses)
- klasses -= [Thor, Thor::Runner] unless with_modules
+ def display_klasses(with_modules=false, show_internal=false, klasses=Thor::Base.subclasses)
+ klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal
+
raise Error, "No Thor tasks available" if klasses.empty?
+ show_modules if with_modules && !thor_yaml.empty?
- if with_modules && !thor_yaml.empty?
- info = []
- labels = ["Modules", "Namespaces"]
+ # Remove subclasses
+ klasses.dup.each do |klass|
+ klasses -= Thor::Util.thor_classes_in(klass)
+ end
- info << labels
- info << [ "-" * labels[0].size, "-" * labels[1].size ]
+ list = Hash.new { |h,k| h[k] = [] }
+ groups = klasses.select { |k| k.ancestors.include?(Thor::Group) }
- thor_yaml.each do |name, hash|
- info << [ name, hash[:namespaces].join(", ") ]
- end
+ # Get classes which inherit from Thor
+ (klasses - groups).each { |k| list[k.namespace] += k.printable_tasks(false) }
- print_table info
- say ""
- end
+ # Get classes which inherit from Thor::Base
+ groups.map! { |k| k.printable_tasks(false).first }
+ list["root"] = groups
- unless klasses.empty?
- klasses.dup.each do |klass|
- klasses -= Thor::Util.thor_classes_in(klass)
- end
+ # Order namespaces with default coming first
+ list = list.sort{ |a,b| a[0].sub(/^default/, '') <=> b[0].sub(/^default/, '') }
+ list.each { |n, tasks| display_tasks(n, tasks) unless tasks.empty? }
+ end
- klasses.each { |k| display_tasks(k) }
- else
- say "\033[1;34mNo Thor tasks available\033[0m"
- end
+ def display_tasks(namespace, list) #:nodoc:
+ list.sort!{ |a,b| a[0] <=> b[0] }
+
+ say shell.set_color(namespace, :blue, true)
+ say "-" * namespace.size
+
+ print_table(list, :truncate => true)
+ say
end
- # Display tasks from the given Thor class.
- #
- def display_tasks(klass)
- unless klass.tasks.empty?
- base = klass.namespace
+ def show_modules #:nodoc:
+ info = []
+ labels = ["Modules", "Namespaces"]
- color = base == "default" ? :magenta : :blue
- say shell.set_color(base, color, true)
- say "-" * base.length
+ info << labels
+ info << [ "-" * labels[0].size, "-" * labels[1].size ]
- klass.help(shell, :short => true, :ident => 0, :namespace => true)
+ thor_yaml.each do |name, hash|
+ info << [ name, hash[:namespaces].join(", ") ]
end
+
+ print_table info
+ say ""
end
end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell.rb
index 1dc8f0e5b4..64a173de83 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell.rb
@@ -22,7 +22,7 @@ class Thor
end
module Shell
- SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :print_list, :print_table]
+ SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :print_table]
# Add shell to initialize config values.
#
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/basic.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/basic.rb
index f6be3575ca..a11f45b4e9 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/basic.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/basic.rb
@@ -75,30 +75,6 @@ class Thor
!yes?(statement, color)
end
- # Prints a list of items.
- #
- # ==== Parameters
- # list<Array[String, String, ...]>
- #
- # ==== Options
- # mode:: Can be :rows or :inline. Defaults to :rows.
- # ident:: Ident each item with the value given.
- #
- def print_list(list, options={})
- return if list.empty?
-
- ident = " " * (options[:ident] || 0)
- content = case options[:mode]
- when :inline
- last = list.pop
- "#{list.join(", ")}, and #{last}"
- else # rows
- ident + list.join("\n#{ident}")
- end
-
- $stdout.puts content
- end
-
# Prints a table.
#
# ==== Parameters
@@ -110,20 +86,26 @@ class Thor
def print_table(table, options={})
return if table.empty?
- formats = []
+ formats, ident = [], options[:ident].to_i
+ options[:truncate] = terminal_width if options[:truncate] == true
+
0.upto(table.first.length - 2) do |i|
maxima = table.max{ |a,b| a[i].size <=> b[i].size }[i].size
formats << "%-#{maxima + 2}s"
end
- formats[0] = formats[0].insert(0, " " * options[:ident]) if options[:ident]
+ formats[0] = formats[0].insert(0, " " * ident)
formats << "%s"
table.each do |row|
+ sentence = ""
+
row.each_with_index do |column, i|
- $stdout.print formats[i] % column.to_s
+ sentence << formats[i] % column.to_s
end
- $stdout.puts
+
+ sentence = truncate(sentence, options[:truncate]) if options[:truncate]
+ $stdout.puts sentence
end
end
@@ -214,6 +196,44 @@ HELP
base && base.options[:quiet]
end
+ # This code was copied from Rake, available under MIT-LICENSE
+ # Copyright (c) 2003, 2004 Jim Weirich
+ def terminal_width
+ if ENV['THOR_COLUMNS']
+ result = ENV['THOR_COLUMNS'].to_i
+ else
+ result = unix? ? dynamic_width : 80
+ end
+ (result < 10) ? 80 : result
+ rescue
+ 80
+ end
+
+ # Calculate the dynamic width of the terminal
+ def dynamic_width
+ @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
+ end
+
+ def dynamic_width_stty
+ %x{stty size 2>/dev/null}.split[1].to_i
+ end
+
+ def dynamic_width_tput
+ %x{tput cols 2>/dev/null}.to_i
+ end
+
+ def unix?
+ RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
+ end
+
+ def truncate(string, width)
+ if string.length <= width
+ string
+ else
+ ( string[0, width-3] || "" ) + "..."
+ end
+ end
+
end
end
end
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/color.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/color.rb
index 24704f7885..b2bc66dfba 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/color.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/color.rb
@@ -63,7 +63,7 @@ class Thor
#
def show_diff(destination, content) #:nodoc:
if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil?
- actual = File.read(destination).to_s.split("\n")
+ actual = File.binread(destination).to_s.split("\n")
content = content.to_s.split("\n")
Diff::LCS.sdiff(actual, content).each do |diff|
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/task.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/task.rb
index 91c7564d3f..5c8877591b 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/task.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/task.rb
@@ -1,11 +1,11 @@
class Thor
class Task < Struct.new(:name, :description, :usage, :options)
+ FILE_REGEXP = /^#{Regexp.escape(File.expand_path(__FILE__))}:[\w:]+ `run'$/
# A dynamic task that handles method missing scenarios.
- #
class Dynamic < Task
- def initialize(name)
- super(name.to_s, "A dynamically-generated task", name.to_s)
+ def initialize(name, options=nil)
+ super(name.to_s, "A dynamically-generated task", name.to_s, options)
end
def run(instance, args=[])
@@ -25,84 +25,73 @@ class Thor
self.options = other.options.dup if other.options
end
- def short_description
- description.split("\n").first if description
- end
-
# By default, a task invokes a method in the thor class. You can change this
# implementation to create custom tasks.
- #
def run(instance, args=[])
raise UndefinedTaskError, "the '#{name}' task of #{instance.class} is private" unless public_method?(instance)
instance.send(name, *args)
rescue ArgumentError => e
+ raise e if instance.class.respond_to?(:debugging) && instance.class.debugging
parse_argument_error(instance, e, caller)
rescue NoMethodError => e
+ raise e if instance.class.respond_to?(:debugging) && instance.class.debugging
parse_no_method_error(instance, e)
end
- # Returns the formatted usage. If a class is given, the class arguments are
- # injected in the usage.
- #
- def formatted_usage(klass=nil, namespace=false, show_options=true)
- formatted = if namespace.is_a?(String)
- "#{namespace}:"
- elsif klass && namespace
- "#{klass.namespace.gsub(/^default/,'')}:"
+ # Returns the formatted usage by injecting given required arguments
+ # and required options into the given usage.
+ def formatted_usage(klass, namespace=nil)
+ namespace = klass.namespace if namespace.nil?
+
+ # Add namespace
+ formatted = if namespace
+ "#{namespace.gsub(/^(default|thor:runner:)/,'')}:"
else
""
end
- formatted << formatted_arguments(klass)
- formatted << " #{formatted_options}" if show_options
- formatted.strip!
- formatted
- end
-
- # Injects the class arguments into the task usage.
- #
- def formatted_arguments(klass)
- if klass && !klass.arguments.empty?
+ # Add usage with required arguments
+ formatted << if klass && !klass.arguments.empty?
usage.to_s.gsub(/^#{name}/) do |match|
- match << " " << klass.arguments.map{ |a| a.usage }.join(' ')
+ match << " " << klass.arguments.map{ |a| a.usage }.compact.join(' ')
end
else
usage.to_s
end
- end
- # Returns the options usage for this task.
- #
- def formatted_options
- @formatted_options ||= options.map{ |_, o| o.usage }.sort.join(" ")
+ # Add required options
+ formatted << " #{required_options}"
+
+ # Strip and go!
+ formatted.strip
end
protected
+ def required_options
+ @required_options ||= options.map{ |_, o| o.usage if o.required? }.compact.sort.join(" ")
+ end
+
# Given a target, checks if this class name is not a private/protected method.
- #
def public_method?(instance) #:nodoc:
collection = instance.private_methods + instance.protected_methods
(collection & [name.to_s, name.to_sym]).empty?
end
- # Clean everything that comes from the Thor gempath and remove the caller.
- #
- def sans_backtrace(backtrace, caller) #:nodoc:
- dirname = /^#{Regexp.escape(File.dirname(__FILE__))}/
- saned = backtrace.reject { |frame| frame =~ dirname }
- saned -= caller
+ # For Ruby <= 1.8.7, we have to match the method name that we are trying to call.
+ # In Ruby >= 1.9.1, we have to match the method run in this file.
+ def backtrace_match?(backtrace) #:nodoc:
+ method_name = /`#{Regexp.escape(name.split(':').last)}'/
+ backtrace =~ method_name || backtrace =~ FILE_REGEXP
end
def parse_argument_error(instance, e, caller) #:nodoc:
- backtrace = sans_backtrace(e.backtrace, caller)
-
- if backtrace.empty? && e.message =~ /wrong number of arguments/
+ if e.message =~ /wrong number of arguments/ && backtrace_match?(e.backtrace.first.to_s)
if instance.is_a?(Thor::Group)
raise e, "'#{name}' was called incorrectly. Are you sure it has arity equals to 0?"
else
raise InvocationError, "'#{name}' was called incorrectly. Call as " <<
- "'#{formatted_usage(instance.class, true)}'"
+ "'#{formatted_usage(instance.class)}'"
end
else
raise e
diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/util.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/util.rb
index ebae0a3193..c2aed89ccf 100644
--- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/util.rb
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/util.rb
@@ -76,8 +76,10 @@ class Thor
# Returns the thor classes declared inside the given class.
#
def self.thor_classes_in(klass)
+ stringfied_constants = klass.constants.map { |c| c.to_s }
Thor::Base.subclasses.select do |subclass|
- klass.constants.include?(subclass.name.gsub("#{klass.name}::", ''))
+ next unless subclass.name
+ stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", ''))
end
end
@@ -155,7 +157,7 @@ class Thor
# inside the sandbox to avoid namespacing conflicts.
#
def self.load_thorfile(path, content=nil)
- content ||= File.read(path)
+ content ||= File.binread(path)
begin
Thor::Sandbox.class_eval(content, path)
@@ -164,26 +166,6 @@ class Thor
end
end
- # Receives a yaml (hash) and updates all constants entries to namespace.
- # This was added to deal with deprecated versions of Thor.
- #
- # TODO Deprecate this method in the future.
- #
- # ==== Returns
- # TrueClass|FalseClass:: Returns true if any change to the yaml file was made.
- #
- def self.convert_constants_to_namespaces(yaml)
- yaml_changed = false
-
- yaml.each do |k, v|
- next unless v[:constants] && v[:namespaces].nil?
- yaml_changed = true
- yaml[k][:namespaces] = v[:constants].map{|c| Thor::Util.namespace_from_thor_class(c)}
- end
-
- yaml_changed
- end
-
def self.user_home
@@user_home ||= if ENV["HOME"]
ENV["HOME"]
diff --git a/railties/lib/rails/vendor/thor-0.12.3/lib/thor/version.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/version.rb
new file mode 100644
index 0000000000..3c9dd6f808
--- /dev/null
+++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/version.rb
@@ -0,0 +1,3 @@
+class Thor
+ VERSION = "0.12.3".freeze
+end