Base command now recursively dispatches, allowing for arbitrarily complex commands such as `vagrant a b c`
This commit is contained in:
parent
aec05eff0d
commit
bb0d3f7f93
|
@ -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
|
||||
|
|
|
@ -9,7 +9,7 @@ module Vagrant
|
|||
opts.banner = "Usage: vagrant init [name]"
|
||||
end
|
||||
|
||||
puts "HEY"
|
||||
show_help
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue