Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add terminal_width and format tables nicelly.

  • Loading branch information...
commit 1f91d12fce7aef74028e2423e991c6c34036d731 1 parent 9f6073a
@josevalim josevalim authored
View
4 lib/thor.rb
@@ -169,10 +169,10 @@ def help(shell, options={})
list.sort!{ |a,b| a[0] <=> b[0] }
if options[:short]
- shell.print_table(list)
+ shell.print_table(list, :truncate => true)
else
shell.say "Tasks:"
- shell.print_table(list, :ident => 2)
+ shell.print_table(list, :ident => 2, :truncate => true)
shell.say
class_options_help(shell)
end
View
5 lib/thor/base.rb
@@ -92,6 +92,8 @@ def register_klass_file(klass) #:nodoc:
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 @@ def namespace(name=nil)
# 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
View
52 lib/thor/shell/basic.rb
@@ -86,20 +86,26 @@ def no?(statement, color=nil)
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
@@ -190,6 +196,44 @@ def quiet? #:nodoc:
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
View
14 lib/thor/task.rb
@@ -32,8 +32,10 @@ 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
@@ -82,18 +84,10 @@ def public_method?(instance) #:nodoc:
(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
- end
-
def parse_argument_error(instance, e, caller) #:nodoc:
- backtrace = sans_backtrace(e.backtrace, caller)
+ method_name = /`#{Regexp.escape(name.split(':').last)}'/
- if backtrace.empty? && e.message =~ /wrong number of arguments/
+ if e.message =~ /wrong number of arguments/ && e.backtrace.first.to_s =~ method_name
if instance.is_a?(Thor::Group)
raise e, "'#{name}' was called incorrectly. Are you sure it has arity equals to 0?"
else
View
6 spec/fixtures/script.thor
@@ -40,11 +40,15 @@ END
call_myself_with_wrong_arity(4)
end
- desc "call unexistent method", "Call unexistent method inside a task"
+ desc "call_unexistent_method", "Call unexistent method inside a task"
def call_unexistent_method
boom!
end
+ desc "long_description", "a" * 80
+ def long_description
+ end
+
method_options :all => :boolean
desc "with_optional NAME", "invoke with optional name"
def with_optional(name=nil)
View
10 spec/shell/basic_spec.rb
@@ -121,6 +121,16 @@ def shell
xyz #786 last three
TABLE
end
+
+ it "uses maximum terminal width" do
+ mock(shell).terminal_width { 20 }
+ content = capture(:stdout){ shell.print_table(@table, :ident => 2, :truncate => true) }
+ content.must == <<-TABLE
+ abc #123 firs...
+ #0 empty
+ xyz #786 last...
+TABLE
+ end
end
describe "#file_collision" do
View
16 spec/thor_spec.rb
@@ -133,7 +133,7 @@
end
it "raises when an exception happens within the task call" do
- lambda { MyScript.start(["call_myself_with_wrong_arity"]) }.must raise_error
+ lambda { MyScript.start(["call_myself_with_wrong_arity", "--debug"]) }.must raise_error
end
end
@@ -148,20 +148,26 @@ def shell
end
it "provides useful help info for the help method itself" do
- @content.must =~ /help \[TASK\]\s+# Describe available tasks/m
+ @content.must =~ /help \[TASK\]\s+# Describe available tasks/
end
it "provides useful help info for a method with params" do
- @content.must =~ /animal TYPE\s+# horse around/m
+ @content.must =~ /animal TYPE\s+# horse around/
+ end
+
+ it "uses the maximum terminal size to show tasks" do
+ mock(@shell).terminal_width { 80 }
+ @content = capture(:stdout){ MyScript.help(shell) }
+ @content.must =~ /aaa\.\.\.$/
end
it "provides description for tasks from classes in the same namespace" do
- @content.must =~ /baz\s+# do some bazing/m
+ @content.must =~ /baz\s+# do some bazing/
end
it "shows superclass tasks" do
content = capture(:stdout){ MyChildScript.help(shell) }
- content.must =~ /foo BAR \s+# do some fooing/m
+ content.must =~ /foo BAR \s+# do some fooing/
end
it "shows class options information" do
Please sign in to comment.
Something went wrong with that request. Please try again.