diff --git a/lib/vagrant/commands/destroy.rb b/lib/vagrant/commands/destroy.rb index a67d61b1d..55c601950 100644 --- a/lib/vagrant/commands/destroy.rb +++ b/lib/vagrant/commands/destroy.rb @@ -11,8 +11,35 @@ module Vagrant description "Destroys the vagrant environment" def execute(args=[]) - env.require_persisted_vm - env.vm.destroy + args = parse_options(args) + + if args[0] + destroy_single(args[0]) + else + destroy_all + end + end + + # Destroys a single VM by name. + def destroy_single(name) + vm = env.vms[name.to_sym] + if vm.nil? + error_and_exit(:unknown_vm, :vm => name) + return # for tests + end + + if vm.created? + vm.destroy + else + logger.info "VM '#{name}' not created. Ignoring." + end + end + + # Destroys all VMs represented by the current environment. + def destroy_all + env.vms.each do |name, vm| + destroy_single(name) + end end def options_spec(opts) @@ -20,4 +47,4 @@ module Vagrant end end end -end \ No newline at end of file +end diff --git a/test/vagrant/commands/destroy_test.rb b/test/vagrant/commands/destroy_test.rb index e3d770563..561695deb 100644 --- a/test/vagrant/commands/destroy_test.rb +++ b/test/vagrant/commands/destroy_test.rb @@ -4,29 +4,58 @@ class CommandsDestroyTest < Test::Unit::TestCase setup do @klass = Vagrant::Commands::Destroy - @persisted_vm = mock("persisted_vm") - @persisted_vm.stubs(:execute!) - @env = mock_environment - @env.stubs(:require_persisted_vm) - @env.stubs(:vm).returns(@persisted_vm) @instance = @klass.new(@env) end context "executing" do + should "call destroy_all if no name is given" do + @instance.expects(:destroy_all).once + @instance.execute + end + + should "call destroy_single if a name is given" do + @instance.expects(:destroy_single).with("foo").once + @instance.execute(["foo"]) + end + end + + context "destroying all" do + should "destroy each VM" do + vms = { :foo => nil, :bar => nil, :baz => nil } + @env.stubs(:vms).returns(vms) + + vms.each do |name, value| + @instance.expects(:destroy_single).with(name).once + end + + @instance.destroy_all + end + end + + context "destroying a single VM" do setup do - @persisted_vm.stubs(:destroy) + @foo_vm = mock("vm") + vms = { :foo => @foo_vm } + @env.stubs(:vms).returns(vms) + end + should "error and exit if the VM doesn't exist" do + @env.stubs(:vms).returns({}) + @instance.expects(:error_and_exit).with(:unknown_vm, :vm => :foo).once + @instance.destroy_single(:foo) end - should "require a persisted VM" do - @env.expects(:require_persisted_vm).once - @instance.execute + should "destroy if its created" do + @foo_vm.stubs(:created?).returns(true) + @foo_vm.expects(:destroy).once + @instance.destroy_single(:foo) end - should "destroy the persisted VM and the VM image" do - @persisted_vm.expects(:destroy).once - @instance.execute + should "do nothing if its not created" do + @foo_vm.stubs(:created?).returns(false) + @foo_vm.expects(:destroy).never + @instance.destroy_single(:foo) end end end