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.
- 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
|