summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Lerche <carllerche@mac.com>2010-07-13 14:21:09 -0700
committerCarl Lerche <carllerche@mac.com>2010-07-13 14:21:48 -0700
commitfecd2db7273621ea347517bdb5d158af5a61ca0b (patch)
tree42ffe587e8d262f78dbcf3e78acee441261e6117
parentc5985e429785062a6556c1dd67b31828fd481ba2 (diff)
downloadbundler-fecd2db7273621ea347517bdb5d158af5a61ca0b.tar.gz
Update the vendored thor library
-rw-r--r--lib/bundler/vendor/thor.rb44
-rw-r--r--lib/bundler/vendor/thor/base.rb13
-rw-r--r--lib/bundler/vendor/thor/parser/argument.rb30
-rw-r--r--lib/bundler/vendor/thor/parser/option.rb84
-rw-r--r--lib/bundler/vendor/thor/parser/options.rb2
-rw-r--r--lib/bundler/vendor/thor/shell.rb9
-rw-r--r--lib/bundler/vendor/thor/shell/basic.rb14
-rw-r--r--lib/bundler/vendor/thor/shell/html.rb121
-rw-r--r--lib/bundler/vendor/thor/task.rb19
-rw-r--r--lib/bundler/vendor/thor/version.rb2
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