diff options
author | Andre Arko <andre@arko.net> | 2011-09-17 18:51:14 -0700 |
---|---|---|
committer | Andre Arko <andre@arko.net> | 2011-09-17 18:51:14 -0700 |
commit | 2eb123ab46877354d8a86e6bba6537568c768e4f (patch) | |
tree | f31b286ed4f43b6fb823c35a43b4461bca9715ab | |
parent | c46d91421c7f838c3db9f64e1c35eee601a0255a (diff) | |
download | bundler-2eb123ab46877354d8a86e6bba6537568c768e4f.tar.gz |
Update to Thor 0.15.2.rc
-rw-r--r-- | lib/bundler/vendor/thor.rb | 70 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/actions/create_link.rb | 2 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/actions/file_manipulation.rb | 2 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/base.rb | 34 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/group.rb | 14 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/invocation.rb | 4 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/parser/arguments.rb | 4 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/parser/options.rb | 20 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/rake_compat.rb | 21 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/runner.rb | 2 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/shell.rb | 2 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/shell/basic.rb | 4 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/task.rb | 20 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/version.rb | 2 |
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 |