diff options
author | Carl Lerche <carllerche@mac.com> | 2010-07-13 14:21:09 -0700 |
---|---|---|
committer | Carl Lerche <carllerche@mac.com> | 2010-07-13 14:21:48 -0700 |
commit | fecd2db7273621ea347517bdb5d158af5a61ca0b (patch) | |
tree | 42ffe587e8d262f78dbcf3e78acee441261e6117 | |
parent | c5985e429785062a6556c1dd67b31828fd481ba2 (diff) | |
download | bundler-fecd2db7273621ea347517bdb5d158af5a61ca0b.tar.gz |
Update the vendored thor library
-rw-r--r-- | lib/bundler/vendor/thor.rb | 44 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/base.rb | 13 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/parser/argument.rb | 30 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/parser/option.rb | 84 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/parser/options.rb | 2 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/shell.rb | 9 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/shell/basic.rb | 14 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/shell/html.rb | 121 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/task.rb | 19 | ||||
-rw-r--r-- | lib/bundler/vendor/thor/version.rb | 2 |
10 files changed, 240 insertions, 98 deletions
diff --git a/lib/bundler/vendor/thor.rb b/lib/bundler/vendor/thor.rb index 0048c1be57..c2a1d325bd 100644 --- a/lib/bundler/vendor/thor.rb +++ b/lib/bundler/vendor/thor.rb @@ -1,6 +1,5 @@ require 'thor/base' -# TODO: Update thor to allow for git-style CLI (git bisect run) class Thor class << self # Sets the default task when thor is executed without an explicit task to be called. @@ -135,6 +134,7 @@ class Thor # script.invoke(:task, first_arg, second_arg, third_arg) # def start(original_args=ARGV, config={}) + @@original_args = original_args super do |given_args| meth = given_args.first.to_s @@ -188,8 +188,8 @@ class Thor # ==== Parameters # shell<Thor::Shell> # - def help(shell) - list = printable_tasks + def help(shell, subcommand = false) + list = printable_tasks(true, subcommand) Thor::Util.thor_classes_in(self).each do |klass| list += klass.printable_tasks(false) end @@ -202,17 +202,24 @@ class Thor end # Returns tasks ready to be printed. - def printable_tasks(all=true) + def printable_tasks(all = true, subcommand = false) (all ? all_tasks : tasks).map do |_, task| item = [] - item << banner(task) + item << banner(task, false, subcommand) item << (task.description ? "# #{task.description.gsub(/\s+/m,' ')}" : "") item end end - def handle_argument_error(task, error) #:nodoc: - raise InvocationError, "#{task.name.inspect} was called incorrectly. Call as #{task.formatted_usage(self, banner_base == "thor").inspect}." + def subcommands + @@subcommands ||= {} + end + + def subcommand(subcommand, subcommand_class) + subcommand = subcommand.to_s + subcommands[subcommand] = subcommand_class + subcommand_class.subcommand_help subcommand + define_method(subcommand) { |*_| subcommand_class.start(subcommand_args) } end protected @@ -222,8 +229,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) - "#{banner_base} #{task.formatted_usage(self, banner_base == "thor")}" + def banner(task, namespace = nil, subcommand = false) + "#{$0} #{task.formatted_usage(self, $thor_runner, subcommand)}" end def baseclass #:nodoc: @@ -254,10 +261,21 @@ class Thor # If a map can't be found use the sent name or the default task. # def normalize_task_name(meth) #:nodoc: - mapping = map[meth.to_s] - meth = mapping || meth || default_task + meth = map[meth.to_s] || meth || default_task meth.to_s.gsub('-','_') # treat foo-bar > foo_bar end + + def subcommand_help(cmd) + desc "help [COMMAND]", "Describe subcommands or one specific subcommand" + class_eval <<-RUBY + def help(task = nil, subcommand = true); super; end + RUBY + end + + end + + def subcommand_args + @@original_args[1..-1] end include Thor::Base @@ -265,7 +283,7 @@ class Thor map HELP_MAPPINGS => :help desc "help [TASK]", "Describe available tasks or one specific task" - def help(task=nil) - task ? self.class.task_help(shell, task) : self.class.help(shell) + def help(task = nil, subcommand = false) + task ? self.class.task_help(shell, task) : self.class.help(shell, subcommand) end end diff --git a/lib/bundler/vendor/thor/base.rb b/lib/bundler/vendor/thor/base.rb index 8d0312c9ce..08a234d1dd 100644 --- a/lib/bundler/vendor/thor/base.rb +++ b/lib/bundler/vendor/thor/base.rb @@ -382,13 +382,17 @@ class Thor end def handle_no_task_error(task) #:nodoc: - if self.banner_base == "thor" + if $thor_runner raise UndefinedTaskError, "Could not find task #{task.inspect} in #{namespace.inspect} namespace." else raise UndefinedTaskError, "Could not find task #{task.inspect}." end end + def handle_argument_error(task, error) #:nodoc: + raise InvocationError, "#{task.name.inspect} was called incorrectly. Call as #{self.banner(task).inspect}." + end + protected # Prints the class options per group. If an option does not belong to @@ -445,7 +449,7 @@ class Thor def build_option(name, options, scope) #:nodoc: scope[name] = Thor::Option.new(name, options[:desc], options[:required], options[:type], options[:default], options[:banner], - options[:group], options[:aliases]) + options[:lazy_default], options[:group], options[:aliases]) end # Receives a hash of options, parse them and add to the scope. This is a @@ -516,11 +520,6 @@ class Thor false end - # Returns the base for banner. - def banner_base - @banner_base ||= $thor_runner ? "thor" : File.basename($0.split(" ").first) - end - # SIGNATURE: Sets the baseclass. This is where the superclass lookup # finishes. def baseclass #:nodoc: diff --git a/lib/bundler/vendor/thor/parser/argument.rb b/lib/bundler/vendor/thor/parser/argument.rb index aa8ace4719..68c2e08610 100644 --- a/lib/bundler/vendor/thor/parser/argument.rb +++ b/lib/bundler/vendor/thor/parser/argument.rb @@ -31,10 +31,10 @@ class Thor def show_default? case default - when Array, String, Hash - !default.empty? - else - default + when Array, String, Hash + !default.empty? + else + default end end @@ -45,21 +45,21 @@ class Thor end def valid_type?(type) - VALID_TYPES.include?(type.to_sym) + self.class::VALID_TYPES.include?(type.to_sym) end def default_banner case type - when :boolean - nil - when :string, :default - human_name.upcase - when :numeric - "N" - when :hash - "key:value" - when :array - "one two three" + when :boolean + nil + when :string, :default + human_name.upcase + when :numeric + "N" + when :hash + "key:value" + when :array + "one two three" end end diff --git a/lib/bundler/vendor/thor/parser/option.rb b/lib/bundler/vendor/thor/parser/option.rb index fee89067b8..496756db44 100644 --- a/lib/bundler/vendor/thor/parser/option.rb +++ b/lib/bundler/vendor/thor/parser/option.rb @@ -1,13 +1,14 @@ class Thor class Option < Argument #:nodoc: - attr_reader :aliases, :group + attr_reader :aliases, :group, :lazy_default VALID_TYPES = [:boolean, :numeric, :hash, :array, :string] - def initialize(name, description=nil, required=nil, type=nil, default=nil, banner=nil, group=nil, aliases=nil) + def initialize(name, description=nil, required=nil, type=nil, default=nil, banner=nil, lazy_default=nil, group=nil, aliases=nil) super(name, description, required, type, default, banner) - @aliases = [*aliases].compact - @group = group.to_s.capitalize if group + @lazy_default = lazy_default + @group = group.to_s.capitalize if group + @aliases = [*aliases].compact end # This parse quick options given as method_options. It makes several @@ -48,23 +49,22 @@ class Thor default = value type = case value - when Symbol - default = nil - - if VALID_TYPES.include?(value) - value - elsif required = (value == :required) - :string - end - when TrueClass, FalseClass - :boolean - when Numeric - :numeric - when Hash, Array, String - value.class.name.downcase.to_sym + when Symbol + default = nil + if VALID_TYPES.include?(value) + value + elsif required = (value == :required) + :string + end + when TrueClass, FalseClass + :boolean + when Numeric + :numeric + when Hash, Array, String + value.class.name.downcase.to_sym end - self.new(name.to_s, nil, required, type, default, nil, nil, aliases) + self.new(name.to_s, nil, required, type, default, nil, nil, nil, aliases) end def switch_name @@ -91,38 +91,30 @@ class Thor end end - # Allow some type predicates as: boolean?, string? and etc. - # - def method_missing(method, *args, &block) - given = method.to_s.sub(/\?$/, '').to_sym - if valid_type?(given) - self.type == given - else - super - end + VALID_TYPES.each do |type| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{type}? + self.type == #{type.inspect} + end + RUBY end - protected - - def validate! - raise ArgumentError, "An option cannot be boolean and required." if boolean? && required? - end - - def valid_type?(type) - VALID_TYPES.include?(type.to_sym) - end + protected - def dasherized? - name.index('-') == 0 - end + def validate! + raise ArgumentError, "An option cannot be boolean and required." if boolean? && required? + end - def undasherize(str) - str.sub(/^-{1,2}/, '') - end + def dasherized? + name.index('-') == 0 + end - def dasherize(str) - (str.length > 1 ? "--" : "-") + str.gsub('_', '-') - end + def undasherize(str) + str.sub(/^-{1,2}/, '') + end + def dasherize(str) + (str.length > 1 ? "--" : "-") + str.gsub('_', '-') + end end end diff --git a/lib/bundler/vendor/thor/parser/options.rb b/lib/bundler/vendor/thor/parser/options.rb index dda23f9ea1..8da20f6b16 100644 --- a/lib/bundler/vendor/thor/parser/options.rb +++ b/lib/bundler/vendor/thor/parser/options.rb @@ -150,7 +150,7 @@ class Thor return nil # User set value to nil elsif option.string? && !option.required? # Return the default if there is one, else the human name - return option.default || option.human_name + return option.lazy_default || option.default || option.human_name else raise MalformattedArgumentError, "No value provided for option '#{switch}'" end diff --git a/lib/bundler/vendor/thor/shell.rb b/lib/bundler/vendor/thor/shell.rb index cd4291b1d8..58bde8b35f 100644 --- a/lib/bundler/vendor/thor/shell.rb +++ b/lib/bundler/vendor/thor/shell.rb @@ -1,5 +1,4 @@ require 'rbconfig' -require 'thor/shell/color' class Thor module Base @@ -7,7 +6,9 @@ class Thor # it will use a colored log, otherwise it will use a basic one without color. # def self.shell - @shell ||= if Config::CONFIG['host_os'] =~ /mswin|mingw/ + @shell ||= if ENV['THOR_SHELL'] && ENV['THOR_SHELL'].size > 0 + Thor::Shell.const_get(ENV['THOR_SHELL']) + elsif Config::CONFIG['host_os'] =~ /mswin|mingw/ Thor::Shell::Basic else Thor::Shell::Color @@ -24,6 +25,10 @@ class Thor module Shell SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :print_table] + autoload :Basic, 'thor/shell/basic' + autoload :Color, 'thor/shell/color' + autoload :HTML, 'thor/shell/HTML' + # Add shell to initialize config values. # # ==== Configuration diff --git a/lib/bundler/vendor/thor/shell/basic.rb b/lib/bundler/vendor/thor/shell/basic.rb index 2cf4d5309e..85d8a1d408 100644 --- a/lib/bundler/vendor/thor/shell/basic.rb +++ b/lib/bundler/vendor/thor/shell/basic.rb @@ -42,8 +42,8 @@ class Thor $stdout.puts(message) else $stdout.print(message) - $stdout.flush end + $stdout.flush end # Say a status with the given color and appends the message. Since this @@ -81,16 +81,20 @@ class Thor # Array[Array[String, String, ...]] # # ==== Options - # ident<Integer>:: Ident the first column by ident value. + # ident<Integer>:: Indent the first column by ident value. + # colwidth<Integer>:: Force the first column to colwidth spaces wide. # def print_table(table, options={}) return if table.empty? - formats, ident = [], options[:ident].to_i + formats, ident, colwidth = [], options[:ident].to_i, options[:colwidth] 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 << "%-#{colwidth + 2}s" if colwidth + start = colwidth ? 1 : 0 + + start.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 diff --git a/lib/bundler/vendor/thor/shell/html.rb b/lib/bundler/vendor/thor/shell/html.rb new file mode 100644 index 0000000000..b8b3f9c5cd --- /dev/null +++ b/lib/bundler/vendor/thor/shell/html.rb @@ -0,0 +1,121 @@ +require 'thor/shell/basic' + +class Thor + module Shell + # Inherit from Thor::Shell::Basic and add set_color behavior. Check + # Thor::Shell::Basic to see all available methods. + # + class HTML < Basic + # The start of an HTML bold sequence. + BOLD = "<strong>" + # The end of an HTML bold sequence. + END_BOLD = "</strong>" + + # Embed in a String to clear previous color selection. + CLEAR = "</span>" + + # Set the terminal's foreground HTML color to black. + BLACK = '<span style="color: black;">' + # Set the terminal's foreground HTML color to red. + RED = '<span style="color: red;">' + # Set the terminal's foreground HTML color to green. + GREEN = '<span style="color: green;">' + # Set the terminal's foreground HTML color to yellow. + YELLOW = '<span style="color: yellow;">' + # Set the terminal's foreground HTML color to blue. + BLUE = '<span style="color: blue;">' + # Set the terminal's foreground HTML color to magenta. + MAGENTA = '<span style="color: magenta;">' + # Set the terminal's foreground HTML color to cyan. + CYAN = '<span style="color: cyan;">' + # Set the terminal's foreground HTML color to white. + WHITE = '<span style="color: white;">' + + # Set the terminal's background HTML color to black. + ON_BLACK = '<span style="background-color: black">' + # Set the terminal's background HTML color to red. + ON_RED = '<span style="background-color: red">' + # Set the terminal's background HTML color to green. + ON_GREEN = '<span style="background-color: green">' + # Set the terminal's background HTML color to yellow. + ON_YELLOW = '<span style="background-color: yellow">' + # Set the terminal's background HTML color to blue. + ON_BLUE = '<span style="background-color: blue">' + # Set the terminal's background HTML color to magenta. + ON_MAGENTA = '<span style="background-color: magenta">' + # Set the terminal's background HTML color to cyan. + ON_CYAN = '<span style="background-color: cyan">' + # Set the terminal's background HTML color to white. + ON_WHITE = '<span style="background-color: white">' + + # Set color by using a string or one of the defined constants. If a third + # option is set to true, it also adds bold to the string. This is based + # on Highline implementation and it automatically appends CLEAR to the end + # of the returned String. + # + def set_color(string, color, bold=false) + color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol) + bold, end_bold = bold ? [BOLD, END_BOLD] : ['', ''] + "#{bold}#{color}#{string}#{CLEAR}#{end_bold}" + end + + # Ask something to the user and receives a response. + # + # ==== Example + # ask("What is your name?") + # + # TODO: Implement #ask for Thor::Shell::HTML + def ask(statement, color=nil) + raise NotImplementedError, "Implement #ask for Thor::Shell::HTML" + end + + protected + + # Overwrite show_diff to show diff with colors if Diff::LCS is + # available. + # + def show_diff(destination, content) #:nodoc: + if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil? + actual = File.binread(destination).to_s.split("\n") + content = content.to_s.split("\n") + + Diff::LCS.sdiff(actual, content).each do |diff| + output_diff_line(diff) + end + else + super + end + end + + def output_diff_line(diff) #:nodoc: + case diff.action + when '-' + say "- #{diff.old_element.chomp}", :red, true + when '+' + say "+ #{diff.new_element.chomp}", :green, true + when '!' + say "- #{diff.old_element.chomp}", :red, true + say "+ #{diff.new_element.chomp}", :green, true + else + say " #{diff.old_element.chomp}", nil, true + end + end + + # Check if Diff::LCS is loaded. If it is, use it to create pretty output + # for diff. + # + def diff_lcs_loaded? #:nodoc: + return true if defined?(Diff::LCS) + return @diff_lcs_loaded unless @diff_lcs_loaded.nil? + + @diff_lcs_loaded = begin + require 'diff/lcs' + true + rescue LoadError + false + end + end + + end + end +end diff --git a/lib/bundler/vendor/thor/task.rb b/lib/bundler/vendor/thor/task.rb index ebb2d5a556..2576c75285 100644 --- a/lib/bundler/vendor/thor/task.rb +++ b/lib/bundler/vendor/thor/task.rb @@ -41,16 +41,16 @@ class Thor # Returns the formatted usage by injecting given required arguments # and required options into the given usage. - def formatted_usage(klass, namespace=true) + def formatted_usage(klass, namespace = true, subcommand = false) namespace = klass.namespace unless namespace == false - # Add namespace - formatted = if namespace - "#{namespace.gsub(/^(default|thor:runner:)/,'')}:" - else - "" + if namespace + formatted = "#{namespace.gsub(/^(default)/,'')}:" + formatted.sub!(/.$/, ' ') if subcommand end + formatted ||= "" + # Add usage with required arguments formatted << if klass && !klass.arguments.empty? usage.to_s.gsub(/^#{name}/) do |match| @@ -89,8 +89,11 @@ class Thor end def handle_argument_error?(instance, error, caller) - not_debugging?(instance) && error.message =~ /wrong number of arguments/ && - sans_backtrace(error.backtrace, caller).empty? + not_debugging?(instance) && error.message =~ /wrong number of arguments/ && begin + saned = sans_backtrace(error.backtrace, caller) + # Ruby 1.9 always include the called method in the backtrace + saned.empty? || (saned.size == 1 && RUBY_VERSION >= "1.9") + end end def handle_no_method_error?(instance, error, caller) diff --git a/lib/bundler/vendor/thor/version.rb b/lib/bundler/vendor/thor/version.rb index 5bd0788897..aba08b72e8 100644 --- a/lib/bundler/vendor/thor/version.rb +++ b/lib/bundler/vendor/thor/version.rb @@ -1,3 +1,3 @@ class Thor - VERSION = "0.13.6".freeze + VERSION = "0.13.7".freeze end |