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
|
# Dispatches a subcommand to the proper registered command. Otherwise, it
|
||||||
# prints a help message.
|
# prints a help message.
|
||||||
def dispatch(env, name, *args)
|
def dispatch(env, *args)
|
||||||
klass = subcommands[name]
|
klass = subcommands[args[0]] unless args.empty?
|
||||||
if klass.nil?
|
if klass.nil?
|
||||||
puts_help
|
# Run _this_ command!
|
||||||
return # For tests
|
command = self.new(env)
|
||||||
|
command.execute(args)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
command = klass.new(env)
|
# Shift off the front arg, since we just consumed it in finding the
|
||||||
command.execute(args)
|
# subcommand.
|
||||||
|
args.shift
|
||||||
|
|
||||||
|
# Dispatch to the next class
|
||||||
|
klass.dispatch(env, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Prints out the list of supported commands and their descriptions (if
|
# 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
|
# executed. The `args` parameter is an array of parameters to the
|
||||||
# command (similar to ARGV)
|
# command (similar to ARGV)
|
||||||
def execute(args)
|
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
|
end
|
||||||
|
|
||||||
# Parse options out of the command-line. This method uses `optparse`
|
# Parse options out of the command-line. This method uses `optparse`
|
||||||
|
@ -90,10 +98,20 @@ module Vagrant
|
||||||
show_help
|
show_help
|
||||||
end
|
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,
|
# Prints the help for the given command. Prior to calling this method,
|
||||||
# {#parse_options} must be called or a nilerror will be raised. This
|
# {#parse_options} must be called or a nilerror will be raised. This
|
||||||
# is by design.
|
# is by design.
|
||||||
def show_help
|
def show_help
|
||||||
|
if !description.empty?
|
||||||
|
puts "Description: #{description}"
|
||||||
|
end
|
||||||
|
|
||||||
puts @parser.help
|
puts @parser.help
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ module Vagrant
|
||||||
opts.banner = "Usage: vagrant init [name]"
|
opts.banner = "Usage: vagrant init [name]"
|
||||||
end
|
end
|
||||||
|
|
||||||
puts "HEY"
|
show_help
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,7 @@ class CommandsBastTest < Test::Unit::TestCase
|
||||||
|
|
||||||
context "class methods" do
|
context "class methods" do
|
||||||
setup do
|
setup do
|
||||||
|
@env = mock_environment
|
||||||
@klass.subcommands.clear
|
@klass.subcommands.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -35,17 +36,16 @@ class CommandsBastTest < Test::Unit::TestCase
|
||||||
@args = [1,2,3]
|
@args = [1,2,3]
|
||||||
end
|
end
|
||||||
|
|
||||||
should "instantiate and execute on registered subcommands" do
|
should "call dispatch on child if subcommand is found" do
|
||||||
instance = mock("instance")
|
@command_klass.expects(:dispatch).with(@env, *@args)
|
||||||
@command_klass.expects(:new).with(@env).returns(instance)
|
|
||||||
instance.expects(:execute).with(@args)
|
|
||||||
|
|
||||||
@klass.dispatch(@env, @name, *@args)
|
@klass.dispatch(@env, @name, *@args)
|
||||||
end
|
end
|
||||||
|
|
||||||
should "print help if command doesn't exist" do
|
should "instantiate and execute when no subcommand is found" do
|
||||||
@klass.expects(:puts_help).once
|
instance = mock("instance")
|
||||||
@klass.dispatch(@env, "#{@name}foo")
|
@klass.expects(:new).with(@env).returns(instance)
|
||||||
|
instance.expects(:execute).with(@args)
|
||||||
|
@klass.dispatch(@env, *@args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -65,11 +65,7 @@ class CommandsBastTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
context "executing" do
|
context "executing" do
|
||||||
should "raise an error if called (since not a subclass)" do
|
# TODO
|
||||||
assert_raises(RuntimeError) {
|
|
||||||
@instance.execute([])
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "parsing options" do
|
context "parsing options" do
|
||||||
|
|
Loading…
Reference in New Issue