Skip to content

Commit

Permalink
Merge pull request #312 from JoshCheek/master
Browse files Browse the repository at this point in the history
Make error messages more helpful
  • Loading branch information
sferik committed Mar 13, 2013
2 parents 28201b7 + eb7dd9b commit 09896be
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 26 deletions.
16 changes: 5 additions & 11 deletions lib/thor/base.rb
Expand Up @@ -462,17 +462,11 @@ def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
end
alias handle_no_task_error handle_no_command_error

def handle_argument_error(command, error, arity=nil) #:nodoc:
msg = "#{basename} #{command.name}"
if arity && arity != 0
required = arity < 0 ? (-1 - arity) : arity
msg << " requires at least #{required} argument"
msg << "s" if required > 1
else
msg = "call #{msg} as"
end

msg << ": #{self.banner(command).inspect}."
def handle_argument_error(command, error, args, arity) #:nodoc:
msg = "ERROR: #{basename} #{command.name} was called with "
msg << 'no arguments' if args.empty?
msg << 'arguments ' << args.inspect if !args.empty?
msg << "\nUsage: #{self.banner(command).inspect}."
raise InvocationError, msg
end

Expand Down
2 changes: 1 addition & 1 deletion lib/thor/command.rb
Expand Up @@ -32,7 +32,7 @@ def run(instance, args=[])
end
rescue ArgumentError => e
handle_argument_error?(instance, e, caller) ?
instance.class.handle_argument_error(self, e, arity) : (raise e)
instance.class.handle_argument_error(self, e, args, arity) : (raise e)
rescue NoMethodError => e
handle_no_method_error?(instance, e, caller) ?
instance.class.handle_no_command_error(name) : (raise e)
Expand Down
13 changes: 4 additions & 9 deletions lib/thor/group.rb
Expand Up @@ -205,15 +205,10 @@ def printable_commands(*)
end
alias printable_tasks printable_commands

def handle_argument_error(command, error, arity=nil) #:nodoc:
if arity > 0
msg = "#{basename} #{command.name} takes #{arity} argument"
msg << "s" if arity > 1
msg << ", but it should not."
else
msg = "You should not pass arguments to #{basename} #{command.name}."
end

def handle_argument_error(command, error, args, arity) #:nodoc:
msg = "#{basename} #{command.name} takes #{arity} argument"
msg << "s" if arity > 1
msg << ", but it should not."
raise error, msg
end

Expand Down
2 changes: 1 addition & 1 deletion spec/base_spec.rb
Expand Up @@ -193,7 +193,7 @@ def hello
thorfile = File.join(File.dirname(__FILE__), "fixtures", "script.thor")
expect(Thor::Base.subclass_files[File.expand_path(thorfile)]).to eq([
MyScript, MyScript::AnotherScript, MyChildScript, Barn,
Scripts::MyScript, Scripts::MyDefaults, Scripts::ChildDefault
Scripts::MyScript, Scripts::MyDefaults, Scripts::ChildDefault, Scripts::Arities
])
end

Expand Down
18 changes: 18 additions & 0 deletions spec/fixtures/script.thor
Expand Up @@ -195,5 +195,23 @@ module Scripts
class ChildDefault < Thor
namespace "default:child"
end

class Arities < Thor
desc "zero_args", "takes zero args"
def zero_args
end

desc "one_arg ARG", "takes one arg"
def one_arg(arg)
end

desc "two_args ARG1 ARG2", "takes two args"
def two_args(arg1, arg2)
end

desc "optional_arg [ARG]", "takes an optional arg"
def optional_arg(arg='default')
end
end
end

2 changes: 1 addition & 1 deletion spec/group_spec.rb
Expand Up @@ -17,7 +17,7 @@
expect(MyCounter.start(["1", "--third", "3"])).to eq([ 1, 2, 3, nil, nil, nil ])
end

it "invokes all the commands in the Thor group and his parents" do
it "invokes all the commands in the Thor group and its parents" do
expect(BrokenCounter.start(["1", "2", "--third", "3"])).to eq([ nil, 2, 3, false, 5, nil ])
end

Expand Down
2 changes: 1 addition & 1 deletion spec/runner_spec.rb
Expand Up @@ -112,7 +112,7 @@ def when_no_thorfiles_exist
it "does not swallow Thor InvocationError" do
ARGV.replace ["my_script:animal"]
content = capture(:stderr) { Thor::Runner.start }
expect(content.strip).to eq('thor animal requires at least 1 argument: "thor my_script:animal TYPE".')
expect(content.strip).to eq(%Q'ERROR: thor animal was called with no arguments\nUsage: "thor my_script:animal TYPE".')
end
end

Expand Down
13 changes: 11 additions & 2 deletions spec/thor_spec.rb
Expand Up @@ -237,8 +237,17 @@ def boring(*args)
expect(MyScript.start(["with_optional", "--all"])).to eq([nil, { "all" => true }, []])
end

it "raises an error if a required param is not provided" do
expect(capture(:stderr) { MyScript.start(["animal"]) }.strip).to eq('thor animal requires at least 1 argument: "thor my_script:animal TYPE".')
it "raises an error if the wrong number of params are provided" do
arity_asserter = lambda do |args, msg|
stderr = capture(:stderr) { Scripts::Arities.start(args) }
expect(stderr.strip).to eq(msg)
end
arity_asserter.call ["zero_args", "one" ], %Q'ERROR: thor zero_args was called with arguments ["one"]\nUsage: "thor scripts:arities:zero_args".'
arity_asserter.call ["one_arg" ], %Q'ERROR: thor one_arg was called with no arguments\nUsage: "thor scripts:arities:one_arg ARG".'
arity_asserter.call ["one_arg", "one", "two" ], %Q'ERROR: thor one_arg was called with arguments ["one", "two"]\nUsage: "thor scripts:arities:one_arg ARG".'
arity_asserter.call ["one_arg", "one", "two" ], %Q'ERROR: thor one_arg was called with arguments ["one", "two"]\nUsage: "thor scripts:arities:one_arg ARG".'
arity_asserter.call ["two_args", "one" ], %Q'ERROR: thor two_args was called with arguments ["one"]\nUsage: "thor scripts:arities:two_args ARG1 ARG2".'
arity_asserter.call ["optional_arg", "one", "two" ], %Q'ERROR: thor optional_arg was called with arguments ["one", "two"]\nUsage: "thor scripts:arities:optional_arg [ARG]".'
end

it "raises an error if the invoked command does not exist" do
Expand Down

0 comments on commit 09896be

Please sign in to comment.