vmc 0.5.0.beta.2 → 0.5.0.beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,8 +9,9 @@ module VMC::App
9
9
  input :apps, :desc => "Applications to delete", :argument => :splat,
10
10
  :singular => :app, :from_given => by_name(:app)
11
11
  input :routes, :desc => "Delete associated routes", :default => false
12
- input :orphaned, :desc => "Delete orphaned services", :aliases => "-o",
13
- :default => false
12
+ input :delete_orphaned, :desc => "Delete orphaned services",
13
+ :aliases => "-o", :default => proc { force? ? false : interact },
14
+ :forget => true
14
15
  input :all, :desc => "Delete all applications", :default => false
15
16
  input :really, :type => :boolean, :forget => true, :hidden => true,
16
17
  :default => proc { force? || interact }
@@ -27,14 +28,14 @@ module VMC::App
27
28
  others = apps - to_delete
28
29
  end
29
30
 
30
- orphaned = find_orphaned_services(to_delete, others)
31
+ all_services = apps.collect(&:services).flatten
32
+ deleted_app_services = []
31
33
 
32
- deleted = []
33
34
  spaced(to_delete) do |app|
34
35
  really = input[:all] || input[:really, app.name, :name]
35
36
  next unless really
36
37
 
37
- deleted << app
38
+ deleted_app_services += app.services
38
39
 
39
40
  with_progress("Deleting #{c(app.name, :name)}") do
40
41
  app.routes.collect(&:delete!) if input[:routes]
@@ -42,35 +43,31 @@ module VMC::App
42
43
  end
43
44
  end
44
45
 
45
- delete_orphaned_services(orphaned, input[:orphaned])
46
+ delete_orphaned_services(
47
+ find_orphaned_services(deleted_app_services, all_services))
46
48
 
47
49
  to_delete
48
50
  end
49
51
 
50
- def find_orphaned_services(apps, others = [])
51
- orphaned = Set.new
52
+ def find_orphaned_services(deleted, all)
53
+ orphaned = []
52
54
 
53
- apps.each do |a|
54
- a.services.each do |i|
55
- if others.none? { |x| x.binds?(i) }
56
- orphaned << i
57
- end
58
- end
55
+ leftover = all.dup
56
+ deleted.each do |svc|
57
+ leftover.slice!(leftover.index(svc))
58
+ orphaned << svc unless leftover.include?(svc)
59
59
  end
60
60
 
61
+ # clear out the relationships as the apps are now deleted
61
62
  orphaned.each(&:invalidate!)
62
63
  end
63
64
 
64
- def delete_orphaned_services(service, orphaned)
65
- return if service.empty?
65
+ def delete_orphaned_services(orphans)
66
+ return if orphans.empty?
66
67
 
67
68
  line unless quiet? || force?
68
69
 
69
- service.select { |i|
70
- orphaned ||
71
- ask("Delete orphaned service #{c(i.name, :name)}?",
72
- :default => false)
73
- }.each do |service|
70
+ orphans.select { |o| input[:delete_orphaned, o] }.each do |service|
74
71
  # TODO: splat
75
72
  invoke :delete_service, :service => service, :really => true
76
73
  end
@@ -78,7 +75,7 @@ module VMC::App
78
75
 
79
76
  private
80
77
 
81
- def ask_app
78
+ def ask_apps
82
79
  apps = client.apps
83
80
  fail "No applications." if apps.empty?
84
81
 
@@ -89,5 +86,10 @@ module VMC::App
89
86
  def ask_really(name, color)
90
87
  ask("Really delete #{c(name, color)}?", :default => false)
91
88
  end
89
+
90
+ def ask_delete_orphaned(service)
91
+ ask("Delete orphaned service #{c(service.name, :name)}?",
92
+ :default => false)
93
+ end
92
94
  end
93
95
  end
data/lib/vmc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module VMC
2
- VERSION = "0.5.0.beta.2".freeze
2
+ VERSION = "0.5.0.beta.3".freeze
3
3
  end
@@ -0,0 +1,198 @@
1
+ require 'spec_helper'
2
+ require "vmc/cli/app/delete"
3
+
4
+ describe VMC::App::Delete do
5
+ let(:global) { { :color => false, :quiet => true } }
6
+ let(:inputs) { {} }
7
+ let(:given) { {} }
8
+ let(:client) { FactoryGirl.build(:client) }
9
+ let(:app) {}
10
+ let(:new_name) { "some-new-name" }
11
+
12
+ before do
13
+ any_instance_of(VMC::CLI) do |cli|
14
+ stub(cli).client { client }
15
+ stub(cli).precondition { nil }
16
+ end
17
+ end
18
+
19
+ subject { Mothership.new.invoke(:delete, inputs, given, global) }
20
+
21
+ describe 'metadata' do
22
+ let(:command) { Mothership.commands[:delete] }
23
+
24
+ describe 'command' do
25
+ subject { command }
26
+ its(:description) { should eq "Delete an application" }
27
+ it { expect(Mothership::Help.group(:apps, :manage)).to include(subject) }
28
+ end
29
+
30
+ describe 'inputs' do
31
+ subject { command.inputs }
32
+
33
+ it "is not missing any descriptions" do
34
+ subject.each do |input, attrs|
35
+ next if attrs[:hidden]
36
+
37
+ expect(attrs[:description]).to be
38
+ expect(attrs[:description].strip).to_not be_empty
39
+ end
40
+ end
41
+ end
42
+
43
+ describe 'arguments' do
44
+ subject { command.arguments }
45
+ it 'has the correct argument order' do
46
+ should eq([{ :type => :splat, :value => nil, :name => :apps }])
47
+ end
48
+ end
49
+ end
50
+
51
+ context 'when there are no apps' do
52
+ context 'and an app is given' do
53
+ let(:given) { { :app => "some-app" } }
54
+ it { expect { subject }.to raise_error(VMC::UserError, "Unknown app 'some-app'.") }
55
+ end
56
+
57
+ context 'and an app is not given' do
58
+ it { expect { subject }.to raise_error(VMC::UserError, "No applications.") }
59
+ end
60
+ end
61
+
62
+ context 'when there are apps' do
63
+ let(:client) { FactoryGirl.build(:client, :apps => apps) }
64
+ let(:apps) { [basic_app, app_with_orphans, app_without_orphans] }
65
+ let(:service_1) { FactoryGirl.build(:service_instance) }
66
+ let(:service_2) { FactoryGirl.build(:service_instance) }
67
+ let(:basic_app) { FactoryGirl.build(:app, :name => "basic_app") }
68
+ let(:app_with_orphans) {
69
+ FactoryGirl.build(:app,
70
+ :name => "app_with_orphans",
71
+ :service_bindings => [
72
+ FactoryGirl.build(:service_binding,
73
+ :service_instance => service_1),
74
+ FactoryGirl.build(:service_binding,
75
+ :service_instance => service_2)
76
+ ])
77
+ }
78
+ let(:app_without_orphans) {
79
+ FactoryGirl.build(:app,
80
+ :name => "app_without_orphans",
81
+ :service_bindings => [
82
+ FactoryGirl.build(:service_binding,
83
+ :service_instance => service_1)
84
+ ])
85
+ }
86
+
87
+ context 'and no app is given' do
88
+ it 'asks for the app' do
89
+ mock_ask("Delete which application?", anything) { basic_app }
90
+ stub_ask { true }
91
+ stub(basic_app).delete!
92
+ subject
93
+ end
94
+ end
95
+
96
+ context 'and a basic app is given' do
97
+ let(:deleted_app) { basic_app }
98
+ let(:given) { { :app => deleted_app.name } }
99
+
100
+ context 'and it asks for confirmation' do
101
+ context 'and the user answers no' do
102
+ it 'does not delete the application' do
103
+ mock_ask("Really delete #{deleted_app.name}?", anything) { false }
104
+ dont_allow(deleted_app).delete!
105
+ subject
106
+ end
107
+ end
108
+
109
+ context 'and the user answers yes' do
110
+ it 'deletes the application' do
111
+ mock_ask("Really delete #{deleted_app.name}?", anything) { true }
112
+ mock(deleted_app).delete!
113
+ subject
114
+ end
115
+ end
116
+ end
117
+
118
+ context 'and --force is given' do
119
+ let(:global) { { :force => true, :color => false, :quiet => true } }
120
+
121
+ it 'deletes the application without asking to confirm' do
122
+ dont_allow_ask
123
+ mock(deleted_app).delete!
124
+ subject
125
+ end
126
+ end
127
+ end
128
+
129
+ context 'and an app with orphaned services is given' do
130
+ let(:deleted_app) { app_with_orphans }
131
+ let(:inputs) { { :app => deleted_app } }
132
+
133
+ context 'and it asks for confirmation' do
134
+ context 'and the user answers yes' do
135
+ it 'asks to delete orphaned services' do
136
+ stub_ask("Really delete #{deleted_app.name}?", anything) { true }
137
+ stub(deleted_app).delete!
138
+
139
+ mock_ask("Delete orphaned service #{service_2.name}?", anything) { true }
140
+
141
+ any_instance_of(VMC::App::Delete) do |del|
142
+ mock(del).invoke :delete_service, :service => service_2,
143
+ :really => true
144
+ end
145
+
146
+ subject
147
+ end
148
+ end
149
+
150
+ context 'and the user answers no' do
151
+ it 'does not ask to delete orphaned serivces, or delete them' do
152
+ stub_ask("Really delete #{deleted_app.name}?", anything) { false }
153
+ dont_allow(deleted_app).delete!
154
+
155
+ dont_allow_ask("Delete orphaned service #{service_2.name}?")
156
+
157
+ any_instance_of(VMC::App::Delete) do |del|
158
+ dont_allow(del).invoke(:delete_service, anything)
159
+ end
160
+
161
+ subject
162
+ end
163
+ end
164
+ end
165
+
166
+ context 'and --force is given' do
167
+ let(:global) { { :force => true, :color => false, :quiet => true } }
168
+
169
+ it 'does not delete orphaned services' do
170
+ dont_allow_ask
171
+ stub(deleted_app).delete!
172
+
173
+ any_instance_of(VMC::App::Delete) do |del|
174
+ dont_allow(del).invoke(:delete_service, anything)
175
+ end
176
+
177
+ subject
178
+ end
179
+ end
180
+
181
+ context 'and --delete-orphaned is given' do
182
+ let(:inputs) { { :app => deleted_app, :delete_orphaned => true } }
183
+
184
+ it 'deletes the orphaned services' do
185
+ stub_ask("Really delete #{deleted_app.name}?", anything) { true }
186
+ stub(deleted_app).delete!
187
+
188
+ any_instance_of(VMC::App::Delete) do |del|
189
+ mock(del).invoke :delete_service, :service => service_2,
190
+ :really => true
191
+ end
192
+
193
+ subject
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vmc
3
3
  version: !ruby/object:Gem::Version
4
- hash: -2770117636
4
+ hash: 2384138659
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
9
  - 0
10
10
  - beta
11
- - 2
12
- version: 0.5.0.beta.2
11
+ - 3
12
+ version: 0.5.0.beta.3
13
13
  platform: ruby
14
14
  authors:
15
15
  - Alex Suraci
@@ -74,12 +74,12 @@ dependencies:
74
74
  requirements:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
- hash: 25
77
+ hash: 21
78
78
  segments:
79
79
  - 0
80
80
  - 4
81
- - 11
82
- version: 0.4.11
81
+ - 13
82
+ version: 0.4.13
83
83
  type: :runtime
84
84
  version_requirements: *id004
85
85
  - !ruby/object:Gem::Dependency
@@ -322,6 +322,7 @@ files:
322
322
  - spec/vmc/cli/route/delete_route_spec.rb
323
323
  - spec/vmc/cli/app/push_spec.rb
324
324
  - spec/vmc/cli/app/push/create_spec.rb
325
+ - spec/vmc/cli/app/delete_spec.rb
325
326
  - spec/vmc/cli/app/rename_spec.rb
326
327
  - spec/vmc/cli/space/spaces_spec.rb
327
328
  - spec/vmc/cli/space/rename_spec.rb
@@ -383,6 +384,7 @@ test_files:
383
384
  - spec/vmc/cli/route/delete_route_spec.rb
384
385
  - spec/vmc/cli/app/push_spec.rb
385
386
  - spec/vmc/cli/app/push/create_spec.rb
387
+ - spec/vmc/cli/app/delete_spec.rb
386
388
  - spec/vmc/cli/app/rename_spec.rb
387
389
  - spec/vmc/cli/space/spaces_spec.rb
388
390
  - spec/vmc/cli/space/rename_spec.rb