summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Arko <andre@arko.net>2011-09-17 18:51:14 -0700
committerAndre Arko <andre@arko.net>2011-09-17 18:51:14 -0700
commit2eb123ab46877354d8a86e6bba6537568c768e4f (patch)
treef31b286ed4f43b6fb823c35a43b4461bca9715ab
parentc46d91421c7f838c3db9f64e1c35eee601a0255a (diff)
downloadbundler-2eb123ab46877354d8a86e6bba6537568c768e4f.tar.gz
Update to Thor 0.15.2.rc
-rw-r--r--lib/bundler/vendor/thor.rb70
-rw-r--r--lib/bundler/vendor/thor/actions/create_link.rb2
-rw-r--r--lib/bundler/vendor/thor/actions/file_manipulation.rb2
-rw-r--r--lib/bundler/vendor/thor/base.rb34
-rw-r--r--lib/bundler/vendor/thor/group.rb14
-rw-r--r--lib/bundler/vendor/thor/invocation.rb4
-rw-r--r--lib/bundler/vendor/thor/parser/arguments.rb4
-rw-r--r--lib/bundler/vendor/thor/parser/options.rb20
-rw-r--r--lib/bundler/vendor/thor/rake_compat.rb21
-rw-r--r--lib/bundler/vendor/thor/runner.rb2
-rw-r--r--lib/bundler/vendor/thor/shell.rb2
-rw-r--r--lib/bundler/vendor/thor/shell/basic.rb4
-rw-r--r--lib/bundler/vendor/thor/task.rb20
-rw-r--r--lib/bundler/vendor/thor/version.rb2
14 files changed, 141 insertions, 60 deletions
diff --git a/lib/bundler/vendor/thor.rb b/lib/bundler/vendor/thor.rb
index 92b24342e8..c7ba3e15a4 100644
--- a/lib/bundler/vendor/thor.rb
+++ b/lib/bundler/vendor/thor.rb
@@ -5,7 +5,7 @@ class Thor
# Sets the default task when thor is executed without an explicit task to be called.
#
# ==== Parameters
- # meth<Symbol>:: name of the defaut task
+ # meth<Symbol>:: name of the default task
#
def default_task(meth=nil)
case meth
@@ -108,6 +108,8 @@ class Thor
@method_options
end
+ alias options method_options
+
# 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.
#
@@ -143,6 +145,8 @@ class Thor
build_option(name, options, scope)
end
+ alias option method_option
+
# Prints help information for the given task.
#
# ==== Parameters
@@ -202,7 +206,11 @@ class Thor
def subcommand(subcommand, subcommand_class)
self.subcommands << subcommand.to_s
subcommand_class.subcommand_help subcommand
- define_method(subcommand) { |*args| invoke subcommand_class, args }
+
+ define_method(subcommand) do |*args|
+ args, opts = Thor::Arguments.split(args)
+ invoke subcommand_class, args, opts
+ end
end
# Extend check unknown options to accept a hash of conditions.
@@ -259,8 +267,11 @@ class Thor
opts = given_opts || opts || []
config.merge!(:current_task => task, :task_options => task.options)
+ instance = new(args, opts, config)
+ yield instance if block_given?
+ args = instance.args
trailing = args[Range.new(arguments.size, -1)]
- new(args, opts, config).invoke_task(task, trailing || [])
+ instance.invoke_task(task, trailing || [])
end
# The banner for this class. You can customize it if you are invoking the
@@ -300,7 +311,6 @@ class Thor
# Retrieve the task name from given args.
def retrieve_task_name(args) #:nodoc:
meth = args.first.to_s unless args.empty?
-
if meth && (map[meth] || meth !~ /^\-/)
args.shift
else
@@ -308,35 +318,45 @@ class Thor
end
end
- # Receives a task name (can be nil), and try to get a map from it.
- # If a map can't be found use the sent name or the default task.
+ # receives a (possibly nil) task name and returns a name that is in
+ # the tasks hash. In addition to normalizing aliases, this logic
+ # will determine if a shortened command is an unambiguous prefix of
+ # a task or alias.
+ #
+ # +normalize_task_name+ also converts names like +animal-prison+
+ # into +animal_prison+.
def normalize_task_name(meth) #:nodoc:
- meth = map[meth.to_s] || find_subcommand_and_update_argv(meth) || meth || default_task
- meth.to_s.gsub('-','_') # treat foo-bar > foo_bar
- end
-
- # terrible hack that overwrites ARGV
- def find_subcommand_and_update_argv(subcmd_name) #:nodoc:
- return unless subcmd_name
- cmd = find_subcommand(subcmd_name)
- ARGV[0] = cmd if cmd
- cmd
- end
+ return default_task.to_s.gsub('-', '_') unless meth
- def find_subcommand(subcmd_name)
- possibilities = find_subcommand_possibilities subcmd_name
+ possibilities = find_task_possibilities(meth)
if possibilities.size > 1
- raise "Ambiguous subcommand #{subcmd_name} matches [#{possibilities.join(', ')}]"
+ raise ArgumentError, "Ambiguous task #{meth} matches [#{possibilities.join(', ')}]"
elsif possibilities.size < 1
- return nil
+ meth = meth || default_task
+ elsif map[meth]
+ meth = map[meth]
+ else
+ meth = possibilities.first
end
- possibilities.first
+ meth.to_s.gsub('-','_') # treat foo-bar as foo_bar
end
- def find_subcommand_possibilities(subcmd_name)
- len = subcmd_name.length
- all_tasks.map {|t| t.first}.select { |n| subcmd_name == n[0, len] }
+ # this is the logic that takes the task name passed in by the user
+ # and determines whether it is an unambiguous prefix of a task or
+ # alias name.
+ def find_task_possibilities(meth)
+ len = meth.to_s.length
+ possibilities = all_tasks.merge(map).keys.select { |n| meth == n[0, len] }.sort
+ unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
+
+ if possibilities.include?(meth)
+ [meth]
+ elsif unique_possibilities.size == 1
+ unique_possibilities
+ else
+ possibilities
+ end
end
def subcommand_help(cmd)
diff --git a/lib/bundler/vendor/thor/actions/create_link.rb b/lib/bundler/vendor/thor/actions/create_link.rb
index 1975644a00..864a1e9923 100644
--- a/lib/bundler/vendor/thor/actions/create_link.rb
+++ b/lib/bundler/vendor/thor/actions/create_link.rb
@@ -41,7 +41,7 @@ class Thor
invoke_with_conflict_check do
FileUtils.mkdir_p(File.dirname(destination))
# Create a symlink by default
- config[:symbolic] ||= true
+ config[:symbolic] = true if config[:symbolic].nil?
File.unlink(destination) if exists?
if config[:symbolic]
File.symlink(render, destination)
diff --git a/lib/bundler/vendor/thor/actions/file_manipulation.rb b/lib/bundler/vendor/thor/actions/file_manipulation.rb
index ad049b3cf8..dee9fbdd8e 100644
--- a/lib/bundler/vendor/thor/actions/file_manipulation.rb
+++ b/lib/bundler/vendor/thor/actions/file_manipulation.rb
@@ -187,7 +187,7 @@ class Thor
#
# ==== Examples
#
- # inject_into_class "app/controllers/application_controller.rb", " filter_parameter :password\n"
+ # inject_into_class "app/controllers/application_controller.rb", ApplicationController, " filter_parameter :password\n"
#
# inject_into_class "app/controllers/application_controller.rb", ApplicationController do
# " filter_parameter :password\n"
diff --git a/lib/bundler/vendor/thor/base.rb b/lib/bundler/vendor/thor/base.rb
index 65399ffbe6..62706f727d 100644
--- a/lib/bundler/vendor/thor/base.rb
+++ b/lib/bundler/vendor/thor/base.rb
@@ -19,7 +19,7 @@ class Thor
action add_file create_file in_root inside run run_ruby_script)
module Base
- attr_accessor :options
+ attr_accessor :options, :parent_options, :args
# It receives arguments in an Array and two hashes, one for options and
# other for configuration.
@@ -38,22 +38,43 @@ class Thor
# config<Hash>:: Configuration for this Thor class.
#
def initialize(args=[], options={}, config={})
- args = Thor::Arguments.parse(self.class.arguments, args)
- args.each { |key, value| send("#{key}=", value) }
-
parse_options = self.class.class_options
+ # The start method splits inbound arguments at the first argument
+ # that looks like an option (starts with - or --). It then calls
+ # new, passing in the two halves of the arguments Array as the
+ # first two parameters.
+
if options.is_a?(Array)
task_options = config.delete(:task_options) # hook for start
parse_options = parse_options.merge(task_options) if task_options
array_options, hash_options = options, {}
else
+ # Handle the case where the class was explicitly instantiated
+ # with pre-parsed options.
array_options, hash_options = [], options
end
+ # Let Thor::Options parse the options first, so it can remove
+ # declared options from the array. This will leave us with
+ # a list of arguments that weren't declared.
opts = Thor::Options.new(parse_options, hash_options)
self.options = opts.parse(array_options)
+
+ # If unknown options are disallowed, make sure that none of the
+ # remaining arguments looks like an option.
opts.check_unknown! if self.class.check_unknown_options?(config)
+
+ # Add the remaining arguments from the options parser to the
+ # arguments passed in to initialize. Then remove any positional
+ # arguments declared using #argument (this is primarily used
+ # by Thor::Group). Tis will leave us with the remaining
+ # positional arguments.
+ thor_args = Thor::Arguments.new(self.class.arguments)
+ thor_args.parse(args + opts.remaining).each { |k,v| send("#{k}=", v) }
+ args = thor_args.remaining
+
+ @args = args
end
class << self
@@ -405,8 +426,8 @@ class Thor
end
end
- def handle_no_task_error(task) #:nodoc:
- if $thor_runner
+ def handle_no_task_error(task, has_namespace = $thor_runner) #:nodoc:
+ if has_namespace
raise UndefinedTaskError, "Could not find task #{task.inspect} in #{namespace.inspect} namespace."
else
raise UndefinedTaskError, "Could not find task #{task.inspect}."
@@ -506,6 +527,7 @@ class Thor
# and file into baseclass.
def inherited(klass)
Thor::Base.register_klass_file(klass)
+ klass.instance_variable_set(:@no_tasks, false)
end
# Fire this callback whenever a method is added. Added methods are
diff --git a/lib/bundler/vendor/thor/group.rb b/lib/bundler/vendor/thor/group.rb
index 3dbab98afe..e948b9aefd 100644
--- a/lib/bundler/vendor/thor/group.rb
+++ b/lib/bundler/vendor/thor/group.rb
@@ -187,9 +187,9 @@ class Thor::Group
human_name = value.respond_to?(:classify) ? value.classify : value
group_options[human_name] ||= []
- group_options[human_name] += klass.class_options.values.select do |option|
- base_options[option.name.to_sym].nil? && option.group.nil? &&
- !group_options.values.flatten.any? { |i| i.name == option.name }
+ group_options[human_name] += klass.class_options.values.select do |class_option|
+ base_options[class_option.name.to_sym].nil? && class_option.group.nil? &&
+ !group_options.values.flatten.any? { |i| i.name == class_option.name }
end
yield klass if block_given?
@@ -220,10 +220,14 @@ class Thor::Group
args, opts = Thor::Options.split(given_args)
opts = given_opts || opts
+ instance = new(args, opts, config)
+ yield instance if block_given?
+ args = instance.args
+
if task
- new(args, opts, config).invoke_task(all_tasks[task])
+ instance.invoke_task(all_tasks[task])
else
- new(args, opts, config).invoke_all
+ instance.invoke_all
end
end
diff --git a/lib/bundler/vendor/thor/invocation.rb b/lib/bundler/vendor/thor/invocation.rb
index 6315dd4296..9c64547228 100644
--- a/lib/bundler/vendor/thor/invocation.rb
+++ b/lib/bundler/vendor/thor/invocation.rb
@@ -106,7 +106,9 @@ class Thor
raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base
args, opts, config = _parse_initialization_options(args, opts, config)
- klass.send(:dispatch, task, args, opts, config)
+ klass.send(:dispatch, task, args, opts, config) do |instance|
+ instance.parent_options = options
+ end
end
# Invoke the given task if the given args.
diff --git a/lib/bundler/vendor/thor/parser/arguments.rb b/lib/bundler/vendor/thor/parser/arguments.rb
index 888ef69246..12db2b2348 100644
--- a/lib/bundler/vendor/thor/parser/arguments.rb
+++ b/lib/bundler/vendor/thor/parser/arguments.rb
@@ -49,6 +49,10 @@ class Thor
@assigns
end
+ def remaining
+ @pile
+ end
+
private
def no_or_skip?(arg)
diff --git a/lib/bundler/vendor/thor/parser/options.rb b/lib/bundler/vendor/thor/parser/options.rb
index 9b1d042d10..c6829c0bb5 100644
--- a/lib/bundler/vendor/thor/parser/options.rb
+++ b/lib/bundler/vendor/thor/parser/options.rb
@@ -38,7 +38,7 @@ class Thor
@non_assigned_required.delete(hash_options[key])
end
- @shorts, @switches, @unknown = {}, {}, []
+ @shorts, @switches, @extra = {}, {}, []
options.each do |option|
@switches[option.switch_name] = option
@@ -49,14 +49,19 @@ class Thor
end
end
+ def remaining
+ @extra
+ end
+
def parse(args)
@pile = args.dup
while peek
match, is_switch = current_is_switch?
+ shifted = shift
if is_switch
- case shift
+ case shifted
when SHORT_SQ_RE
unshift($1.split('').map { |f| "-#{f}" })
next
@@ -71,9 +76,10 @@ class Thor
option = switch_option(switch)
@assigns[option.human_name] = parse_peek(switch, option)
elsif match
- @unknown << shift
+ @extra << shifted
+ @extra << shift while peek && peek !~ /^-/
else
- shift
+ @extra << shifted
end
end
@@ -85,9 +91,9 @@ class Thor
end
def check_unknown!
- unless ARGV.include?("exec") || ARGV.include?("config")
- raise UnknownArgumentError, "Unknown switches '#{@unknown.join(', ')}'" unless @unknown.empty?
- end
+ # an unknown option starts with - or -- and has no more --'s afterward.
+ unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
+ raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
end
protected
diff --git a/lib/bundler/vendor/thor/rake_compat.rb b/lib/bundler/vendor/thor/rake_compat.rb
index 0d0757fdda..c86e840578 100644
--- a/lib/bundler/vendor/thor/rake_compat.rb
+++ b/lib/bundler/vendor/thor/rake_compat.rb
@@ -1,4 +1,5 @@
require 'rake'
+require 'rake/dsl_definition'
class Thor
# Adds a compatibility layer to your Thor classes which allows you to use
@@ -16,6 +17,8 @@ class Thor
# end
#
module RakeCompat
+ include Rake::DSL if defined?(Rake::DSL)
+
def self.rake_classes
@rake_classes ||= []
end
@@ -29,12 +32,12 @@ class Thor
end
end
-class Object #:nodoc:
- alias :rake_task :task
- alias :rake_namespace :namespace
+# override task on (main), for compatibility with Rake 0.9
+self.instance_eval do
+ alias rake_namespace namespace
- def task(*args, &block)
- task = rake_task(*args, &block)
+ def task(*)
+ task = super
if klass = Thor::RakeCompat.rake_classes.last
non_namespaced_name = task.name.split(':').last
@@ -43,7 +46,8 @@ class Object #:nodoc:
description << task.arg_names.map{ |n| n.to_s.upcase }.join(' ')
description.strip!
- klass.desc description, task.comment || non_namespaced_name
+ klass.desc description, Rake.application.last_description || non_namespaced_name
+ Rake.application.last_description = nil
klass.send :define_method, non_namespaced_name do |*args|
Rake::Task[task.name.to_sym].invoke(*args)
end
@@ -52,7 +56,7 @@ class Object #:nodoc:
task
end
- def namespace(name, &block)
+ def namespace(name)
if klass = Thor::RakeCompat.rake_classes.last
const_name = Thor::Util.camel_case(name.to_s).to_sym
klass.const_set(const_name, Class.new(Thor))
@@ -60,7 +64,8 @@ class Object #:nodoc:
Thor::RakeCompat.rake_classes << new_klass
end
- rake_namespace(name, &block)
+ super
Thor::RakeCompat.rake_classes.pop
end
end
+
diff --git a/lib/bundler/vendor/thor/runner.rb b/lib/bundler/vendor/thor/runner.rb
index 0d9e3c05e8..18c63c438e 100644
--- a/lib/bundler/vendor/thor/runner.rb
+++ b/lib/bundler/vendor/thor/runner.rb
@@ -17,6 +17,7 @@ class Thor::Runner < Thor #:nodoc:
if meth && !self.respond_to?(meth)
initialize_thorfiles(meth)
klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
+ self.class.handle_no_task_error(task, false) if klass.nil?
klass.start(["-h", task].compact, :shell => self.shell)
else
super
@@ -30,6 +31,7 @@ class Thor::Runner < Thor #:nodoc:
meth = meth.to_s
initialize_thorfiles(meth)
klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
+ self.class.handle_no_task_error(task, false) if klass.nil?
args.unshift(task) if task
klass.start(args, :shell => self.shell)
end
diff --git a/lib/bundler/vendor/thor/shell.rb b/lib/bundler/vendor/thor/shell.rb
index b52c9da2e0..784fde95a3 100644
--- a/lib/bundler/vendor/thor/shell.rb
+++ b/lib/bundler/vendor/thor/shell.rb
@@ -8,7 +8,7 @@ class Thor
def self.shell
@shell ||= if ENV['THOR_SHELL'] && ENV['THOR_SHELL'].size > 0
Thor::Shell.const_get(ENV['THOR_SHELL'])
- elsif RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
+ elsif ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) && !(ENV['ANSICON']))
Thor::Shell::Basic
else
Thor::Shell::Color
diff --git a/lib/bundler/vendor/thor/shell/basic.rb b/lib/bundler/vendor/thor/shell/basic.rb
index c8411d3d3d..a7c464ada3 100644
--- a/lib/bundler/vendor/thor/shell/basic.rb
+++ b/lib/bundler/vendor/thor/shell/basic.rb
@@ -5,10 +5,10 @@ class Thor
class Basic
attr_accessor :base, :padding
- # Initialize base and padding to nil.
+ # Initialize base, mute and padding to nil.
#
def initialize #:nodoc:
- @base, @padding = nil, 0
+ @base, @mute, @padding = nil, false, 0
end
# Mute everything that's inside given block
diff --git a/lib/bundler/vendor/thor/task.rb b/lib/bundler/vendor/thor/task.rb
index 6db3b60817..f94d5b6b7f 100644
--- a/lib/bundler/vendor/thor/task.rb
+++ b/lib/bundler/vendor/thor/task.rb
@@ -18,8 +18,15 @@ class Thor
# By default, a task invokes a method in the thor class. You can change this
# implementation to create custom tasks.
def run(instance, args=[])
- public_method?(instance) ?
- instance.send(name, *args) : instance.class.handle_no_task_error(name)
+ if private_method?(instance)
+ instance.class.handle_no_task_error(name)
+ elsif public_method?(instance)
+ instance.send(name, *args)
+ elsif local_method?(instance, :method_missing)
+ instance.send(:method_missing, name.to_sym, *args)
+ else
+ instance.class.handle_no_task_error(name)
+ end
rescue ArgumentError => e
handle_argument_error?(instance, e, caller) ?
instance.class.handle_argument_error(self, e) : (raise e)
@@ -70,6 +77,15 @@ class Thor
!(instance.public_methods & [name.to_s, name.to_sym]).empty?
end
+ def private_method?(instance)
+ !(instance.private_methods & [name.to_s, name.to_sym]).empty?
+ end
+
+ def local_method?(instance, name)
+ methods = instance.public_methods(false) + instance.private_methods(false) + instance.protected_methods(false)
+ !(methods & [name.to_s, name.to_sym]).empty?
+ end
+
def sans_backtrace(backtrace, caller) #:nodoc:
saned = backtrace.reject { |frame| frame =~ FILE_REGEXP }
saned -= caller
diff --git a/lib/bundler/vendor/thor/version.rb b/lib/bundler/vendor/thor/version.rb
index 7de92f164a..4a0e37ad7f 100644
--- a/lib/bundler/vendor/thor/version.rb
+++ b/lib/bundler/vendor/thor/version.rb
@@ -1,3 +1,3 @@
class Thor
- VERSION = "0.14.6".freeze
+ VERSION = "0.15.0.rc2".freeze
end