af 0.3.22 → 0.5.0.beta.1
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.
- checksums.yaml +14 -6
- data/LICENSE +1277 -24
- data/Rakefile +24 -87
- data/bin/af +7 -2
- data/lib/af/version.rb +3 -0
- data/lib/vmc.rb +7 -2
- data/lib/vmc/cli.rb +475 -0
- data/lib/vmc/cli/app/app.rb +45 -0
- data/lib/vmc/cli/app/apps.rb +105 -0
- data/lib/vmc/cli/app/base.rb +82 -0
- data/lib/vmc/cli/app/crashes.rb +46 -0
- data/lib/vmc/cli/app/delete.rb +95 -0
- data/lib/vmc/cli/app/deprecated.rb +11 -0
- data/lib/vmc/cli/app/env.rb +78 -0
- data/lib/vmc/cli/app/files.rb +137 -0
- data/lib/vmc/cli/app/health.rb +26 -0
- data/lib/vmc/cli/app/instances.rb +53 -0
- data/lib/vmc/cli/app/logs.rb +76 -0
- data/lib/vmc/cli/app/push.rb +107 -0
- data/lib/vmc/cli/app/push/create.rb +150 -0
- data/lib/vmc/cli/app/push/interactions.rb +100 -0
- data/lib/vmc/cli/app/push/sync.rb +64 -0
- data/lib/vmc/cli/app/rename.rb +39 -0
- data/lib/vmc/cli/app/restart.rb +20 -0
- data/lib/vmc/cli/app/scale.rb +71 -0
- data/lib/vmc/cli/app/start.rb +93 -0
- data/lib/vmc/cli/app/stats.rb +67 -0
- data/lib/vmc/cli/app/stop.rb +27 -0
- data/lib/vmc/cli/domain/base.rb +12 -0
- data/lib/vmc/cli/domain/domains.rb +40 -0
- data/lib/vmc/cli/domain/map.rb +55 -0
- data/lib/vmc/cli/domain/unmap.rb +56 -0
- data/lib/vmc/cli/help.rb +16 -0
- data/lib/vmc/cli/interactive.rb +105 -0
- data/lib/vmc/cli/organization/base.rb +14 -0
- data/lib/vmc/cli/organization/create.rb +32 -0
- data/lib/vmc/cli/organization/delete.rb +73 -0
- data/lib/vmc/cli/organization/org.rb +45 -0
- data/lib/vmc/cli/organization/orgs.rb +35 -0
- data/lib/vmc/cli/organization/rename.rb +36 -0
- data/lib/vmc/cli/route/base.rb +12 -0
- data/lib/vmc/cli/route/map.rb +80 -0
- data/lib/vmc/cli/route/routes.rb +26 -0
- data/lib/vmc/cli/route/unmap.rb +94 -0
- data/lib/vmc/cli/service/base.rb +8 -0
- data/lib/vmc/cli/service/bind.rb +44 -0
- data/lib/vmc/cli/service/create.rb +126 -0
- data/lib/vmc/cli/service/delete.rb +86 -0
- data/lib/vmc/cli/service/rename.rb +35 -0
- data/lib/vmc/cli/service/service.rb +42 -0
- data/lib/vmc/cli/service/services.rb +115 -0
- data/lib/vmc/cli/service/unbind.rb +38 -0
- data/lib/vmc/cli/space/base.rb +21 -0
- data/lib/vmc/cli/space/create.rb +56 -0
- data/lib/vmc/cli/space/delete.rb +95 -0
- data/lib/vmc/cli/space/rename.rb +39 -0
- data/lib/vmc/cli/space/space.rb +64 -0
- data/lib/vmc/cli/space/spaces.rb +55 -0
- data/lib/vmc/cli/space/take.rb +16 -0
- data/lib/vmc/cli/start/base.rb +80 -0
- data/lib/vmc/cli/start/colors.rb +13 -0
- data/lib/vmc/cli/start/info.rb +122 -0
- data/lib/vmc/cli/start/login.rb +92 -0
- data/lib/vmc/cli/start/logout.rb +13 -0
- data/lib/vmc/cli/start/target.rb +64 -0
- data/lib/vmc/cli/start/target_interactions.rb +37 -0
- data/lib/vmc/cli/start/targets.rb +16 -0
- data/lib/vmc/cli/user/base.rb +29 -0
- data/lib/vmc/cli/user/create.rb +39 -0
- data/lib/vmc/cli/user/delete.rb +25 -0
- data/lib/vmc/cli/user/passwd.rb +50 -0
- data/lib/vmc/cli/user/register.rb +42 -0
- data/lib/vmc/cli/user/users.rb +32 -0
- data/lib/vmc/constants.rb +13 -0
- data/lib/vmc/detect.rb +134 -0
- data/lib/vmc/errors.rb +17 -0
- data/lib/vmc/plugin.rb +56 -0
- data/lib/vmc/spacing.rb +89 -0
- data/lib/vmc/spec_helper.rb +1 -0
- data/lib/vmc/test_support.rb +4 -0
- data/lib/vmc/test_support/command_helper.rb +32 -0
- data/lib/vmc/test_support/common_input_examples.rb +14 -0
- data/lib/vmc/test_support/fake_home_dir.rb +16 -0
- data/lib/vmc/test_support/interact_helper.rb +29 -0
- data/lib/vmc/version.rb +3 -0
- data/spec/assets/hello-sinatra/Gemfile +3 -0
- data/spec/assets/hello-sinatra/main.rb +6 -0
- data/spec/features/new_user_flow_spec.rb +71 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/vmc/cli/app/base_spec.rb +17 -0
- data/spec/vmc/cli/app/delete_spec.rb +188 -0
- data/spec/vmc/cli/app/instances_spec.rb +65 -0
- data/spec/vmc/cli/app/push/create_spec.rb +571 -0
- data/spec/vmc/cli/app/push_spec.rb +369 -0
- data/spec/vmc/cli/app/rename_spec.rb +104 -0
- data/spec/vmc/cli/app/scale_spec.rb +81 -0
- data/spec/vmc/cli/app/stats_spec.rb +62 -0
- data/spec/vmc/cli/domain/map_spec.rb +140 -0
- data/spec/vmc/cli/domain/unmap_spec.rb +73 -0
- data/spec/vmc/cli/organization/orgs_spec.rb +108 -0
- data/spec/vmc/cli/organization/rename_spec.rb +113 -0
- data/spec/vmc/cli/route/map_spec.rb +138 -0
- data/spec/vmc/cli/route/unmap_spec.rb +215 -0
- data/spec/vmc/cli/service/bind_spec.rb +25 -0
- data/spec/vmc/cli/service/delete_spec.rb +22 -0
- data/spec/vmc/cli/service/rename_spec.rb +105 -0
- data/spec/vmc/cli/service/service_spec.rb +23 -0
- data/spec/vmc/cli/service/unbind_spec.rb +25 -0
- data/spec/vmc/cli/space/rename_spec.rb +102 -0
- data/spec/vmc/cli/space/spaces_spec.rb +104 -0
- data/spec/vmc/cli/start/info_spec.rb +153 -0
- data/spec/vmc/cli/start/login_spec.rb +71 -0
- data/spec/vmc/cli/user/create_spec.rb +54 -0
- data/spec/vmc/cli/user/passwd_spec.rb +102 -0
- data/spec/vmc/cli/user/register_spec.rb +148 -0
- data/spec/vmc/cli_spec.rb +448 -0
- data/spec/vmc/detect_spec.rb +54 -0
- metadata +231 -124
- data/README.md +0 -155
- data/caldecott_helper/Gemfile +0 -10
- data/caldecott_helper/Gemfile.lock +0 -48
- data/caldecott_helper/server.rb +0 -43
- data/config/clients.yml +0 -17
- data/config/micro/offline.conf +0 -2
- data/config/micro/paths.yml +0 -22
- data/config/micro/refresh_ip.rb +0 -20
- data/lib/cli.rb +0 -48
- data/lib/cli/commands/admin.rb +0 -81
- data/lib/cli/commands/apps.rb +0 -1358
- data/lib/cli/commands/base.rb +0 -233
- data/lib/cli/commands/manifest.rb +0 -56
- data/lib/cli/commands/micro.rb +0 -115
- data/lib/cli/commands/misc.rb +0 -147
- data/lib/cli/commands/services.rb +0 -217
- data/lib/cli/commands/user.rb +0 -70
- data/lib/cli/config.rb +0 -176
- data/lib/cli/console_helper.rb +0 -163
- data/lib/cli/core_ext.rb +0 -122
- data/lib/cli/errors.rb +0 -19
- data/lib/cli/file_helper.rb +0 -123
- data/lib/cli/frameworks.rb +0 -265
- data/lib/cli/manifest_helper.rb +0 -316
- data/lib/cli/runner.rb +0 -633
- data/lib/cli/services_helper.rb +0 -104
- data/lib/cli/tunnel_helper.rb +0 -336
- data/lib/cli/usage.rb +0 -129
- data/lib/cli/version.rb +0 -7
- data/lib/cli/zip_util.rb +0 -102
- data/lib/vmc/client.rb +0 -574
- data/lib/vmc/const.rb +0 -27
- data/lib/vmc/micro.rb +0 -56
- data/lib/vmc/micro/switcher/base.rb +0 -97
- data/lib/vmc/micro/switcher/darwin.rb +0 -19
- data/lib/vmc/micro/switcher/dummy.rb +0 -15
- data/lib/vmc/micro/switcher/linux.rb +0 -16
- data/lib/vmc/micro/switcher/windows.rb +0 -31
- data/lib/vmc/micro/vmrun.rb +0 -158
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require "vmc/cli/app/push"
|
|
3
|
+
|
|
4
|
+
describe VMC::App::Push do
|
|
5
|
+
let(:global) { { :color => false, :quiet => true } }
|
|
6
|
+
let(:inputs) { {} }
|
|
7
|
+
let(:given) { {} }
|
|
8
|
+
let(:path) { "somepath" }
|
|
9
|
+
let(:client) { fake_client }
|
|
10
|
+
let(:push) { VMC::App::Push.new(Mothership.commands[:push]) }
|
|
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
|
+
describe 'metadata' do
|
|
20
|
+
let(:command) { Mothership.commands[:push] }
|
|
21
|
+
|
|
22
|
+
describe 'command' do
|
|
23
|
+
subject { command }
|
|
24
|
+
its(:description) { should eq "Push an application, syncing changes if it exists" }
|
|
25
|
+
it { expect(Mothership::Help.group(:apps, :manage)).to include(subject) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
include_examples 'inputs must have descriptions'
|
|
29
|
+
|
|
30
|
+
describe 'arguments' do
|
|
31
|
+
subject { command.arguments }
|
|
32
|
+
it 'has the correct argument order' do
|
|
33
|
+
should eq([{ :type => :optional, :value => nil, :name => :name }])
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe '#sync_app' do
|
|
39
|
+
let(:app) { fake(:app) }
|
|
40
|
+
|
|
41
|
+
before do
|
|
42
|
+
stub(app).upload
|
|
43
|
+
app.changes = {}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
subject do
|
|
47
|
+
push.input = Mothership::Inputs.new(nil, push, inputs, {}, global)
|
|
48
|
+
push.sync_app(app, path)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
shared_examples 'common tests for inputs' do |*args|
|
|
52
|
+
context 'when the new input is the same as the old' do
|
|
53
|
+
type, input = args
|
|
54
|
+
input ||= type
|
|
55
|
+
|
|
56
|
+
let(:inputs) { {input => old} }
|
|
57
|
+
|
|
58
|
+
it "does not update the app's #{type}" do
|
|
59
|
+
dont_allow(push).line
|
|
60
|
+
dont_allow(app).update!
|
|
61
|
+
expect { subject }.not_to change { app.send(type) }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'triggers the :push_app filter' do
|
|
67
|
+
mock(push).filter(:push_app, app) { app }
|
|
68
|
+
subject
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'uploads the app' do
|
|
72
|
+
mock(app).upload(path)
|
|
73
|
+
subject
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'when no inputs are given' do
|
|
77
|
+
let(:inputs) { {} }
|
|
78
|
+
|
|
79
|
+
it 'should not update the app' do
|
|
80
|
+
dont_allow(app).update!
|
|
81
|
+
subject
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
[:memory=, :framework=].each do |property|
|
|
85
|
+
it "should not set #{property} on the app" do
|
|
86
|
+
dont_allow(app).__send__(property)
|
|
87
|
+
subject
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
context 'when memory is given' do
|
|
93
|
+
let(:old) { 1024 }
|
|
94
|
+
let(:new) { "2G" }
|
|
95
|
+
let(:app) { fake(:app, :memory => old) }
|
|
96
|
+
let(:inputs) { { :memory => new } }
|
|
97
|
+
|
|
98
|
+
it 'updates the app memory, converting to megabytes' do
|
|
99
|
+
stub(push).line(anything)
|
|
100
|
+
mock(app).update!
|
|
101
|
+
expect { subject }.to change { app.memory }.from(old).to(2048)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'outputs the changed memory in human readable sizes' do
|
|
105
|
+
mock(push).line("Changes:")
|
|
106
|
+
mock(push).line("memory: 1G -> 2G")
|
|
107
|
+
stub(app).update!
|
|
108
|
+
subject
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
include_examples 'common tests for inputs', :memory
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
context 'when instances is given' do
|
|
115
|
+
let(:old) { 1 }
|
|
116
|
+
let(:new) { 2 }
|
|
117
|
+
let(:app) { fake(:app, :total_instances => old) }
|
|
118
|
+
let(:inputs) { { :instances => new } }
|
|
119
|
+
|
|
120
|
+
it 'updates the app instances' do
|
|
121
|
+
stub(push).line(anything)
|
|
122
|
+
mock(app).update!
|
|
123
|
+
expect { subject }.to change { app.total_instances }.from(old).to(new)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'outputs the changed instances' do
|
|
127
|
+
mock(push).line("Changes:")
|
|
128
|
+
mock(push).line("total_instances: 1 -> 2")
|
|
129
|
+
stub(app).update!
|
|
130
|
+
subject
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
include_examples 'common tests for inputs', :total_instances, :instances
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context 'when framework is given' do
|
|
137
|
+
let(:old) { fake(:framework, :name => "Old Framework") }
|
|
138
|
+
let(:new) { fake(:framework, :name => "New Framework") }
|
|
139
|
+
let(:app) { fake(:app, :framework => old) }
|
|
140
|
+
let(:inputs) { { :framework => new } }
|
|
141
|
+
|
|
142
|
+
it 'updates the app framework' do
|
|
143
|
+
stub(push).line(anything)
|
|
144
|
+
mock(app).update!
|
|
145
|
+
expect { subject }.to change { app.framework }.from(old).to(new)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'outputs the changed framework using the name' do
|
|
149
|
+
mock(push).line("Changes:")
|
|
150
|
+
mock(push).line("framework: Old Framework -> New Framework")
|
|
151
|
+
stub(app).update!
|
|
152
|
+
subject
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
include_examples 'common tests for inputs', :framework
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
context 'when runtime is given' do
|
|
159
|
+
let(:old) { fake(:runtime, :name => "Old Runtime") }
|
|
160
|
+
let(:new) { fake(:runtime, :name => "New Runtime") }
|
|
161
|
+
let(:app) { fake(:app, :runtime => old) }
|
|
162
|
+
let(:inputs) { { :runtime => new } }
|
|
163
|
+
|
|
164
|
+
it 'updates the app runtime' do
|
|
165
|
+
stub(push).line(anything)
|
|
166
|
+
mock(app).update!
|
|
167
|
+
expect { subject }.to change { app.runtime }.from(old).to(new)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'outputs the changed runtime using the name' do
|
|
171
|
+
mock(push).line("Changes:")
|
|
172
|
+
mock(push).line("runtime: Old Runtime -> New Runtime")
|
|
173
|
+
stub(app).update!
|
|
174
|
+
subject
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
include_examples 'common tests for inputs', :runtime
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
context 'when command is given' do
|
|
181
|
+
let(:old) { "./start" }
|
|
182
|
+
let(:new) { "./start foo " }
|
|
183
|
+
let(:app) { fake(:app, :command => old) }
|
|
184
|
+
let(:inputs) { { :command => new } }
|
|
185
|
+
|
|
186
|
+
it 'updates the app command' do
|
|
187
|
+
stub(push).line(anything)
|
|
188
|
+
mock(app).update!
|
|
189
|
+
expect { subject }.to change { app.command }.from("./start").to("./start foo ")
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it 'outputs the changed command in single quotes' do
|
|
193
|
+
mock(push).line("Changes:")
|
|
194
|
+
mock(push).line("command: './start' -> './start foo '")
|
|
195
|
+
stub(app).update!
|
|
196
|
+
subject
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
include_examples 'common tests for inputs', :command
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
context 'when plan is given' do
|
|
203
|
+
let(:old) { "d100" }
|
|
204
|
+
let(:new) { "p100" }
|
|
205
|
+
let(:inputs) { { :plan => new } }
|
|
206
|
+
|
|
207
|
+
include_examples 'common tests for inputs', :production, :plan
|
|
208
|
+
|
|
209
|
+
%w{p100 P100 P200}.each do |plan|
|
|
210
|
+
context "when the given plan is #{plan}" do
|
|
211
|
+
let(:inputs) { { :plan => plan } }
|
|
212
|
+
|
|
213
|
+
it 'sets production to true' do
|
|
214
|
+
stub(push).line(anything)
|
|
215
|
+
mock(app).update!
|
|
216
|
+
expect { subject }.to change { app.production }.from(false).to(true)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
it 'outputs the changed plan in single quotes' do
|
|
220
|
+
mock(push).line("Changes:")
|
|
221
|
+
mock(push).line("production: false -> true")
|
|
222
|
+
stub(app).update!
|
|
223
|
+
subject
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
%w{d100 D100 D200 fizzbuzz}.each do |plan|
|
|
229
|
+
context "when the given plan is #{plan}" do
|
|
230
|
+
let(:app) { fake(:app, :production => true) }
|
|
231
|
+
|
|
232
|
+
let(:inputs) { { :plan => plan } }
|
|
233
|
+
|
|
234
|
+
it 'sets production to false' do
|
|
235
|
+
stub(push).line(anything)
|
|
236
|
+
mock(app).update!
|
|
237
|
+
expect { subject }.to change { app.production }.from(true).to(false)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it 'outputs the changed plan in single quotes' do
|
|
241
|
+
mock(push).line("Changes:")
|
|
242
|
+
mock(push).line("production: true -> false")
|
|
243
|
+
stub(app).update!
|
|
244
|
+
subject
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
context 'when restart is given' do
|
|
251
|
+
let(:inputs) { { :restart => true, :memory => 4096 } }
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
context 'when the app is already started' do
|
|
255
|
+
let(:app) { fake(:app, :state => "STARTED") }
|
|
256
|
+
|
|
257
|
+
it 'invokes the restart command' do
|
|
258
|
+
stub(push).line
|
|
259
|
+
mock(app).update!
|
|
260
|
+
mock(push).invoke(:restart, :app => app)
|
|
261
|
+
subject
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
context 'but there are no changes' do
|
|
265
|
+
let(:inputs) { { :restart => true } }
|
|
266
|
+
|
|
267
|
+
it 'invokes the restart command' do
|
|
268
|
+
stub(push).line
|
|
269
|
+
dont_allow(app).update!
|
|
270
|
+
mock(push).invoke(:restart, :app => app)
|
|
271
|
+
subject
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
context 'when the app is not already started' do
|
|
277
|
+
let(:app) { fake(:app, :state => "STOPPED") }
|
|
278
|
+
|
|
279
|
+
it 'does not invoke the restart command' do
|
|
280
|
+
stub(push).line
|
|
281
|
+
mock(app).update!
|
|
282
|
+
dont_allow(push).invoke(:restart, :app => app)
|
|
283
|
+
subject
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
context "when buildpack is given" do
|
|
289
|
+
let(:old) { nil }
|
|
290
|
+
let(:app) { fake(:app, :buildpack => old) }
|
|
291
|
+
let(:inputs) { { :buildpack => new } }
|
|
292
|
+
|
|
293
|
+
context "and it's an invalid URL" do
|
|
294
|
+
let(:new) { "git@github.com:foo/bar.git" }
|
|
295
|
+
|
|
296
|
+
before do
|
|
297
|
+
stub(app).update! do
|
|
298
|
+
raise CFoundry::MessageParseError.new(
|
|
299
|
+
"Request invalid due to parse error: Field: buildpack, Error: Value git@github.com:cloudfoundry/heroku-buildpack-ruby.git doesn't match regexp String /GIT_URL_REGEX/",
|
|
300
|
+
1001)
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it "fails and prints a pretty message" do
|
|
305
|
+
stub(push).line(anything)
|
|
306
|
+
expect { subject }.to raise_error(
|
|
307
|
+
VMC::UserError, "Buildpack must be a public git repository URI.")
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
context "and it's a valid URL" do
|
|
312
|
+
let(:new) { "git://github.com/foo/bar.git" }
|
|
313
|
+
|
|
314
|
+
it "updates the app's buildpack" do
|
|
315
|
+
stub(push).line(anything)
|
|
316
|
+
mock(app).update!
|
|
317
|
+
expect { subject }.to change { app.buildpack }.from(old).to(new)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
it "outputs the changed buildpack with single quotes" do
|
|
321
|
+
mock(push).line("Changes:")
|
|
322
|
+
mock(push).line("buildpack: '' -> '#{new}'")
|
|
323
|
+
stub(app).update!
|
|
324
|
+
subject
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
include_examples 'common tests for inputs', :buildpack
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
describe '#setup_new_app (integration spec!!)' do
|
|
333
|
+
let(:app) { fake(:app, :guid => nil) }
|
|
334
|
+
let(:framework) { fake(:framework) }
|
|
335
|
+
let(:runtime) { fake(:runtime) }
|
|
336
|
+
let(:host) { "" }
|
|
337
|
+
let(:domain) { fake(:domain, :name => "example.com") }
|
|
338
|
+
let(:inputs) do
|
|
339
|
+
{ :name => "some-app",
|
|
340
|
+
:instances => 2,
|
|
341
|
+
:framework => framework,
|
|
342
|
+
:runtime => runtime,
|
|
343
|
+
:memory => 1024,
|
|
344
|
+
:host => host,
|
|
345
|
+
:domain => domain
|
|
346
|
+
}
|
|
347
|
+
end
|
|
348
|
+
let(:global) { {:quiet => true, :color => false, :force => true} }
|
|
349
|
+
|
|
350
|
+
before do
|
|
351
|
+
stub(client).app { app }
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
subject do
|
|
355
|
+
push.input = Mothership::Inputs.new(Mothership.commands[:push], push, inputs, global, global)
|
|
356
|
+
push.setup_new_app(path)
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it 'creates the app' do
|
|
360
|
+
mock(app).create!
|
|
361
|
+
mock(app).upload(path)
|
|
362
|
+
mock(push).filter(:create_app, app) { app }
|
|
363
|
+
mock(push).filter(:push_app, app) { app }
|
|
364
|
+
mock(push).invoke :map, :app => app, :host => host, :domain => domain
|
|
365
|
+
mock(push).invoke :start, :app => app
|
|
366
|
+
subject
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require "vmc/cli/app/rename"
|
|
3
|
+
|
|
4
|
+
describe VMC::App::Rename do
|
|
5
|
+
let(:global) { { :color => false, :quiet => true } }
|
|
6
|
+
let(:inputs) { {} }
|
|
7
|
+
let(:given) { {} }
|
|
8
|
+
let(:client) { fake_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(:rename, inputs, given, global) }
|
|
20
|
+
|
|
21
|
+
describe 'metadata' do
|
|
22
|
+
let(:command) { Mothership.commands[:rename] }
|
|
23
|
+
|
|
24
|
+
describe 'command' do
|
|
25
|
+
subject { command }
|
|
26
|
+
its(:description) { should eq "Rename an application" }
|
|
27
|
+
it { expect(Mothership::Help.group(:apps, :manage)).to include(subject) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
include_examples 'inputs must have descriptions'
|
|
31
|
+
|
|
32
|
+
describe 'arguments' do
|
|
33
|
+
subject { command.arguments }
|
|
34
|
+
it 'has the correct argument order' do
|
|
35
|
+
should eq([
|
|
36
|
+
{ :type => :optional, :value => nil, :name => :app },
|
|
37
|
+
{ :type => :optional, :value => nil, :name => :name }
|
|
38
|
+
])
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context 'when there are no apps' do
|
|
44
|
+
context 'and an app is given' do
|
|
45
|
+
let(:given) { { :app => "some-app" } }
|
|
46
|
+
it { expect { subject }.to raise_error(VMC::UserError, "Unknown app 'some-app'.") }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context 'and an app is not given' do
|
|
50
|
+
it { expect { subject }.to raise_error(VMC::UserError, "No applications.") }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context 'when there are apps' do
|
|
55
|
+
let(:client) { fake_client(:apps => apps) }
|
|
56
|
+
let(:apps) { fake_list(:app, 2) }
|
|
57
|
+
let(:renamed_app) { apps.first }
|
|
58
|
+
|
|
59
|
+
context 'when the defaults are used' do
|
|
60
|
+
it 'asks for the app and new name and renames' do
|
|
61
|
+
mock_ask("Rename which application?", anything) { renamed_app }
|
|
62
|
+
mock_ask("New name") { new_name }
|
|
63
|
+
mock(renamed_app).name=(new_name)
|
|
64
|
+
mock(renamed_app).update!
|
|
65
|
+
subject
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context 'when no name is provided, but a app is' do
|
|
70
|
+
let(:given) { { :app => renamed_app.name } }
|
|
71
|
+
|
|
72
|
+
it 'asks for the new name and renames' do
|
|
73
|
+
dont_allow_ask("Rename which application?", anything)
|
|
74
|
+
mock_ask("New name") { new_name }
|
|
75
|
+
mock(renamed_app).name=(new_name)
|
|
76
|
+
mock(renamed_app).update!
|
|
77
|
+
subject
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context 'when an app is provided and a name' do
|
|
82
|
+
let(:inputs) { { :app => renamed_app, :name => new_name } }
|
|
83
|
+
|
|
84
|
+
it 'renames the app' do
|
|
85
|
+
mock(renamed_app).update!
|
|
86
|
+
subject
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'displays the progress' do
|
|
90
|
+
mock_with_progress("Renaming to #{new_name}")
|
|
91
|
+
mock(renamed_app).update!
|
|
92
|
+
|
|
93
|
+
subject
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context 'and the name already exists' do
|
|
97
|
+
it 'fails' do
|
|
98
|
+
mock(renamed_app).update! { raise CFoundry::AppNameTaken.new("Bad Name", 404) }
|
|
99
|
+
expect { subject }.to raise_error(CFoundry::AppNameTaken)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|