Base command now recursively dispatches, allowing for arbitrarily complex commands such as `vagrant a b c`

This commit is contained in:
Mitchell Hashimoto 2010-04-13 13:53:27 -07:00
parent aec05eff0d
commit bb0d3f7f93
3 changed files with 35 additions and 21 deletions

View File

@ -28,15 +28,21 @@ module Vagrant
# Dispatches a subcommand to the proper registered command. Otherwise, it
# prints a help message.
def dispatch(env, name, *args)
klass = subcommands[name]
def dispatch(env, *args)
klass = subcommands[args[0]] unless args.empty?
if klass.nil?
puts_help
return # For tests
# Run _this_ command!
command = self.new(env)
command.execute(args)
return
end
command = klass.new(env)
command.execute(args)
# Shift off the front arg, since we just consumed it in finding the
# subcommand.
args.shift
# Dispatch to the next class
klass.dispatch(env, *args)
end
# Prints out the list of supported commands and their descriptions (if
@ -71,7 +77,9 @@ module Vagrant
# executed. The `args` parameter is an array of parameters to the
# command (similar to ARGV)
def execute(args)
raise "Subcommands should implement the execute method properly."
# Just print out the help, since this top-level command does nothing
# on its own
self.class.puts_help
end
# Parse options out of the command-line. This method uses `optparse`
@ -90,10 +98,20 @@ module Vagrant
show_help
end
# Gets the description of the command. This is similar grabbed from the
# class level.
def description
self.class.description
end
# Prints the help for the given command. Prior to calling this method,
# {#parse_options} must be called or a nilerror will be raised. This
# is by design.
def show_help
if !description.empty?
puts "Description: #{description}"
end
puts @parser.help
exit
end

View File

@ -9,7 +9,7 @@ module Vagrant
opts.banner = "Usage: vagrant init [name]"
end
puts "HEY"
show_help
end
end
end

View File

@ -15,6 +15,7 @@ class CommandsBastTest < Test::Unit::TestCase
context "class methods" do
setup do
@env = mock_environment
@klass.subcommands.clear
end
@ -35,17 +36,16 @@ class CommandsBastTest < Test::Unit::TestCase
@args = [1,2,3]
end
should "instantiate and execute on registered subcommands" do
instance = mock("instance")
@command_klass.expects(:new).with(@env).returns(instance)
instance.expects(:execute).with(@args)
should "call dispatch on child if subcommand is found" do
@command_klass.expects(:dispatch).with(@env, *@args)
@klass.dispatch(@env, @name, *@args)
end
should "print help if command doesn't exist" do
@klass.expects(:puts_help).once
@klass.dispatch(@env, "#{@name}foo")
should "instantiate and execute when no subcommand is found" do
instance = mock("instance")
@klass.expects(:new).with(@env).returns(instance)
instance.expects(:execute).with(@args)
@klass.dispatch(@env, *@args)
end
end
@ -65,11 +65,7 @@ class CommandsBastTest < Test::Unit::TestCase
end
context "executing" do
should "raise an error if called (since not a subclass)" do
assert_raises(RuntimeError) {
@instance.execute([])
}
end
# TODO
end
context "parsing options" do