vmc 0.5.0.beta.2 → 0.5.0.beta.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/vmc/cli/app/delete.rb +24 -22
- data/lib/vmc/version.rb +1 -1
- data/spec/vmc/cli/app/delete_spec.rb +198 -0
- metadata +8 -6
data/lib/vmc/cli/app/delete.rb
CHANGED
@@ -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 :
|
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
|
-
|
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
|
-
|
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(
|
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(
|
51
|
-
orphaned =
|
52
|
+
def find_orphaned_services(deleted, all)
|
53
|
+
orphaned = []
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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(
|
65
|
-
return if
|
65
|
+
def delete_orphaned_services(orphans)
|
66
|
+
return if orphans.empty?
|
66
67
|
|
67
68
|
line unless quiet? || force?
|
68
69
|
|
69
|
-
|
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
|
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
@@ -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:
|
4
|
+
hash: 2384138659
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 5
|
9
9
|
- 0
|
10
10
|
- beta
|
11
|
-
-
|
12
|
-
version: 0.5.0.beta.
|
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:
|
77
|
+
hash: 21
|
78
78
|
segments:
|
79
79
|
- 0
|
80
80
|
- 4
|
81
|
-
-
|
82
|
-
version: 0.4.
|
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
|