vmc 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/lib/vmc.rb +2 -5
  2. data/lib/vmc/cli/app/apps.rb +4 -1
  3. data/lib/vmc/cli/app/push.rb +38 -221
  4. data/lib/vmc/cli/app/push/create.rb +125 -0
  5. data/lib/vmc/cli/app/push/interaction.rb +64 -0
  6. data/lib/vmc/cli/app/push/sync.rb +59 -0
  7. data/lib/vmc/cli/app/rename.rb +1 -1
  8. data/lib/vmc/cli/organization/base.rb +14 -0
  9. data/lib/vmc/cli/organization/create_org.rb +28 -0
  10. data/lib/vmc/cli/organization/delete_org.rb +65 -0
  11. data/lib/vmc/cli/organization/org.rb +46 -0
  12. data/lib/vmc/cli/organization/orgs.rb +35 -0
  13. data/lib/vmc/cli/organization/rename.rb +32 -0
  14. data/lib/vmc/cli/service/base.rb +8 -0
  15. data/lib/vmc/cli/service/binding.rb +66 -0
  16. data/lib/vmc/cli/service/create.rb +104 -0
  17. data/lib/vmc/cli/service/delete.rb +84 -0
  18. data/lib/vmc/cli/service/rename.rb +32 -0
  19. data/lib/vmc/cli/service/service.rb +45 -0
  20. data/lib/vmc/cli/service/services.rb +118 -0
  21. data/lib/vmc/cli/space/base.rb +21 -0
  22. data/lib/vmc/cli/space/create.rb +57 -0
  23. data/lib/vmc/cli/space/delete.rb +92 -0
  24. data/lib/vmc/cli/space/rename.rb +36 -0
  25. data/lib/vmc/cli/space/space.rb +67 -0
  26. data/lib/vmc/cli/space/spaces.rb +57 -0
  27. data/lib/vmc/cli/space/take.rb +18 -0
  28. data/lib/vmc/cli/start/base.rb +100 -0
  29. data/lib/vmc/cli/start/colors.rb +14 -0
  30. data/lib/vmc/cli/start/info.rb +124 -0
  31. data/lib/vmc/cli/start/login.rb +94 -0
  32. data/lib/vmc/cli/start/logout.rb +14 -0
  33. data/lib/vmc/cli/start/register.rb +38 -0
  34. data/lib/vmc/cli/start/target.rb +68 -0
  35. data/lib/vmc/cli/start/targets.rb +17 -0
  36. data/lib/vmc/version.rb +1 -1
  37. data/spec/factories/app_factory.rb +5 -0
  38. data/spec/factories/client_factory.rb +10 -1
  39. data/spec/factories/domain_factory.rb +2 -1
  40. data/spec/factories/factory.rb +1 -0
  41. data/spec/factories/framework_factory.rb +1 -0
  42. data/spec/factories/organization_factory.rb +18 -0
  43. data/spec/factories/route_factory.rb +1 -0
  44. data/spec/factories/runtime_factory.rb +10 -0
  45. data/spec/factories/service_binding_factory.rb +9 -0
  46. data/spec/factories/service_factory.rb +17 -0
  47. data/spec/factories/service_instance_factory.rb +10 -0
  48. data/spec/factories/service_plan_factory.rb +11 -0
  49. data/spec/factories/space_factory.rb +10 -0
  50. data/spec/support/interact_helpers.rb +7 -3
  51. data/spec/vmc/cli/app/push/create_spec.rb +450 -0
  52. data/spec/vmc/cli/app/push_spec.rb +303 -9
  53. data/spec/vmc/cli/app/rename_spec.rb +9 -4
  54. data/spec/vmc/cli/organization/rename_spec.rb +113 -0
  55. data/spec/vmc/cli/route/delete_route_spec.rb +2 -2
  56. data/spec/vmc/cli/service/rename_spec.rb +114 -0
  57. data/spec/vmc/cli/space/rename_spec.rb +114 -0
  58. metadata +109 -64
  59. data/lib/vmc/cli/organization.rb +0 -176
  60. data/lib/vmc/cli/service.rb +0 -387
  61. data/lib/vmc/cli/space.rb +0 -284
  62. data/lib/vmc/cli/start.rb +0 -432
  63. data/spec/assets/hello-sinatra/Gemfile.lock +0 -17
data/lib/vmc.rb CHANGED
@@ -1,12 +1,9 @@
1
1
  require "vmc/version"
2
2
 
3
3
  require "vmc/cli"
4
- require "vmc/cli/start"
5
- require "vmc/cli/service"
6
4
  require "vmc/cli/user"
7
- require "vmc/cli/space"
8
- require "vmc/cli/organization"
9
5
 
10
- Dir[File.expand_path("../vmc/cli/{app,route,domain}/*.rb", __FILE__)].each do |file|
6
+ command_files = "../vmc/cli/{app,route,domain,organization,space,service,start}/*.rb"
7
+ Dir[File.expand_path(command_files, __FILE__)].each do |file|
11
8
  require file unless File.basename(file) == 'base.rb'
12
9
  end
@@ -15,7 +15,10 @@ module VMC::App
15
15
  :desc => "Verbose output format"
16
16
  def apps
17
17
  if space = input[:space]
18
- space.summarize! rescue CFoundry::APIError
18
+ begin
19
+ space.summarize!
20
+ rescue CFoundry::APIError
21
+ end
19
22
 
20
23
  apps =
21
24
  with_progress("Getting applications in #{c(space.name, :name)}") do
@@ -1,9 +1,13 @@
1
1
  require "vmc/detect"
2
-
3
2
  require "vmc/cli/app/base"
3
+ require "vmc/cli/app/push/sync"
4
+ require "vmc/cli/app/push/create"
4
5
 
5
6
  module VMC::App
6
7
  class Push < Base
8
+ include Sync
9
+ include Create
10
+
7
11
  desc "Push an application, syncing changes if it exists"
8
12
  group :apps, :manage
9
13
  input(:name, :argument => true, :desc => "Application name") {
@@ -37,13 +41,13 @@ module VMC::App
37
41
  :desc => "Number of instances to run") {
38
42
  ask("Instances", :default => 1)
39
43
  }
40
- input(:framework, :from_given => find_by_name("framework"),
41
- :desc => "Framework to use") { |all, choices, default, other|
42
- ask_with_other("Framework", all, choices, default, other)
44
+ input(:framework, :from_given => by_name("framework"),
45
+ :desc => "Framework to use") { |choices, default, other|
46
+ ask_with_other("Framework", client.frameworks, choices, default, other)
43
47
  }
44
- input(:runtime, :from_given => find_by_name("runtime"),
45
- :desc => "Runtime to use") { |all, choices, default, other|
46
- ask_with_other("Runtime", all, choices, default, other)
48
+ input(:runtime, :from_given => by_name("runtime"),
49
+ :desc => "Runtime to use") { |choices, default, other|
50
+ ask_with_other("Runtime", client.runtimes, choices, default, other)
47
51
  }
48
52
  input(:command, :desc => "Startup command for standalone app") {
49
53
  ask("Startup command")
@@ -55,242 +59,50 @@ module VMC::App
55
59
  input :restart, :type => :boolean, :default => true,
56
60
  :desc => "Restart app after updating?"
57
61
  input(:create_services, :type => :boolean,
62
+ :default => proc { force? ? false : interact },
58
63
  :desc => "Interactively create services?") {
59
64
  line unless quiet?
60
65
  ask "Create services for application?", :default => false
61
66
  }
62
67
  input(:bind_services, :type => :boolean,
68
+ :default => proc { force? ? false : interact },
63
69
  :desc => "Interactively bind services?") {
64
- ask "Bind other services to application?", :default => false
70
+ unless all_instances.empty?
71
+ ask "Bind other services to application?", :default => false
72
+ end
65
73
  }
66
74
  def push
67
75
  name = input[:name]
68
76
  path = File.expand_path(input[:path])
77
+ app = client.app_by_name(name)
69
78
 
70
- if app = client.app_by_name(name)
79
+ if app
71
80
  sync_app(app, path)
72
81
  else
73
- create_app(name, path)
82
+ setup_new_app(path)
74
83
  end
75
84
  end
76
85
 
77
86
  def sync_app(app, path)
78
87
  upload_app(app, path)
79
-
80
- diff = {}
81
-
82
- if input.given?(:memory)
83
- mem = megabytes(input[:memory])
84
-
85
- if mem != app.memory
86
- diff[:memory] = [app.memory, mem]
87
- app.memory = mem
88
- end
89
- end
90
-
91
- if input.given?(:instances)
92
- instances = input[:instances]
93
-
94
- if instances != app.total_instances
95
- diff[:instances] = [app.total_instances, instances]
96
- app.total_instances = instances
97
- end
98
- end
99
-
100
- if input.given?(:framework)
101
- all_frameworks = client.frameworks
102
-
103
- framework = input[:framework, all_frameworks, all_frameworks]
104
-
105
- if framework != app.framework
106
- diff[:framework] = [app.framework.name, framework.name]
107
- app.framework = framework
108
- end
109
- end
110
-
111
- if input.given?(:runtime)
112
- all_runtimes = client.runtimes
113
-
114
- runtime = input[:runtime, all_runtimes, all_runtimes]
115
-
116
- if runtime != app.runtime
117
- diff[:runtime] = [app.runtime.name, runtime.name]
118
- app.runtime = runtime
119
- end
120
- end
121
-
122
- if input.given?(:command) && input[:command] != app.command
123
- command = input[:command]
124
-
125
- if command != app.command
126
- diff[:command] = [app.command, command]
127
- app.command = command
128
- end
129
- end
130
-
131
- if input.given?(:plan) && v2?
132
- production = !!(input[:plan] =~ /^p/i)
133
-
134
- if production != app.production
135
- diff[:production] = [bool(app.production), bool(production)]
136
- app.production = production
137
- end
138
- end
139
-
140
- unless diff.empty?
141
- line "Changes:"
142
-
143
- indented do
144
- diff.each do |name, change|
145
- old, new = change
146
- line "#{c(name, :name)}: #{old} #{c("->", :dim)} #{new}"
147
- end
148
- end
149
-
150
- with_progress("Updating #{c(app.name, :name)}") do
151
- app.update!
152
- end
153
- end
154
-
155
- if input[:restart] && app.started?
156
- invoke :restart, :app => app
157
- end
88
+ apply_changes(app)
89
+ display_changes(app)
90
+ commit_changes(app)
158
91
  end
159
92
 
160
- def create_app(name, path)
161
- app = client.app
162
- app.name = name
163
- app.space = client.current_space if client.current_space
164
- app.total_instances = input[:instances]
165
- app.production = !!(input[:plan] =~ /^p/i) if v2?
166
-
167
- detector = VMC::Detector.new(client, path)
168
- all_frameworks = detector.all_frameworks
169
- all_runtimes = detector.all_runtimes
170
-
171
- if detected_framework = detector.detect_framework
172
- framework = input[
173
- :framework,
174
- all_frameworks,
175
- [detected_framework],
176
- detected_framework,
177
- :other
178
- ]
179
- else
180
- framework = input[:framework, all_frameworks, all_frameworks]
181
- end
182
-
183
-
184
- if framework.name == "standalone"
185
- detected_runtimes = detector.detect_runtimes
186
- else
187
- detected_runtimes = detector.runtimes(framework)
188
- end
189
-
190
- if detected_runtimes.size == 1
191
- default_runtime = detected_runtimes.first
192
- end
193
-
194
- if detected_runtimes.empty?
195
- runtime = input[:runtime, all_runtimes, all_runtimes]
196
- else
197
- runtime = input[
198
- :runtime,
199
- all_runtimes,
200
- detected_runtimes,
201
- default_runtime,
202
- :other
203
- ]
204
- end
205
-
206
-
207
- fail "Invalid framework '#{input[:framework]}'" unless framework
208
- fail "Invalid runtime '#{input[:runtime]}'" unless runtime
209
-
210
- app.framework = framework
211
- app.runtime = runtime
212
-
213
- app.command = input[:command] if framework.name == "standalone"
214
-
215
- default_memory = detector.suggested_memory(framework) || 64
216
- app.memory = megabytes(input[:memory, human_mb(default_memory)])
217
-
218
- app = filter(:create_app, app)
219
-
220
- with_progress("Creating #{c(app.name, :name)}") do
221
- app.create!
222
- end
223
-
224
- line unless quiet?
225
-
226
- url = input[:url, name]
227
-
228
- mapped_url = false
229
- until !url || mapped_url
230
- begin
231
- invoke :map, :app => app, :url => url
232
- mapped_url = true
233
- rescue CFoundry::RouteHostTaken, CFoundry::UriAlreadyTaken => e
234
- line c(e.description, :bad)
235
- line
236
-
237
- input.forget(:url)
238
- url = input[:url, name]
239
-
240
- # version bumps on v1 even though mapping fails
241
- app.invalidate! unless v2?
242
- end
243
- end
244
-
245
- bindings = []
246
-
247
- if input[:create_services] && !force?
248
- while true
249
- invoke :create_service, { :app => app }, :plan => :interact
250
- break unless ask "Create another service?", :default => false
251
- end
252
- end
253
-
254
- if input[:bind_services] && !force?
255
- instances = client.service_instances
256
-
257
- while true
258
- invoke :bind_service, :app => app
259
-
260
- break if (instances - app.services).empty?
261
-
262
- break unless ask("Bind another service?", :default => false)
263
- end
264
- end
265
-
93
+ def setup_new_app(path)
94
+ self.path = path
95
+ app = create_app(get_inputs)
96
+ map_url(app)
97
+ create_services(app)
98
+ bind_services(app)
266
99
  app = filter(:push_app, app)
267
-
268
- begin
269
- upload_app(app, path)
270
- rescue
271
- err "Upload failed. Try again with 'vmc push'."
272
- raise
273
- end
274
-
275
- invoke :start, :app => app if input[:start]
100
+ upload_app(app, path)
101
+ start_app(app)
276
102
  end
277
103
 
278
104
  private
279
105
 
280
- def upload_app(app, path)
281
- with_progress("Uploading #{c(app.name, :name)}") do
282
- app.upload(path)
283
- end
284
- end
285
-
286
- def bool(b)
287
- if b
288
- c("true", :yes)
289
- else
290
- c("false", :no)
291
- end
292
- end
293
-
294
106
  def url_choices(name)
295
107
  if v2?
296
108
  client.current_space.domains.sort_by(&:name).collect do |d|
@@ -298,12 +110,17 @@ module VMC::App
298
110
  "#{name}.#{d.name}"
299
111
  end
300
112
  else
301
- ["#{name}.#{target_base}"]
113
+ %W(#{name}.#{target_base})
302
114
  end
303
115
  end
304
116
 
305
- def target_base
306
- client.target.sub(/^https?:\/\/([^\.]+\.)?(.+)\/?/, '\2')
117
+ def upload_app(app, path)
118
+ with_progress("Uploading #{c(app.name, :name)}") do
119
+ app.upload(path)
120
+ end
121
+ rescue
122
+ err "Upload failed. Try again with 'vmc push'."
123
+ raise
307
124
  end
308
125
 
309
126
  def ask_with_other(message, all, choices, default, other)
@@ -0,0 +1,125 @@
1
+ module VMC::App
2
+ module Create
3
+ attr_accessor :input
4
+ attr_writer :path
5
+
6
+ def get_inputs
7
+ inputs = {}
8
+ inputs[:name] = input[:name]
9
+ inputs[:total_instances] = input[:instances]
10
+ inputs[:space] = client.current_space if client.current_space
11
+ inputs[:production] = !!(input[:plan] =~ /^p/i) if v2?
12
+ inputs[:framework] = framework = determine_framework
13
+ inputs[:command] = input[:command] if framework.name == "standalone"
14
+ inputs[:runtime] = determine_runtime(framework)
15
+
16
+ human_mb = human_mb(detector.suggested_memory(framework) || 64)
17
+ inputs[:memory] = megabytes(input[:memory, human_mb])
18
+
19
+ inputs
20
+ end
21
+
22
+ def determine_framework
23
+ return input[:framework] if input.given?(:framework)
24
+
25
+ if (detected_framework = detector.detect_framework)
26
+ input[:framework, [detected_framework], detected_framework, :other]
27
+ else
28
+ input[:framework, detector.all_frameworks, nil, nil]
29
+ end
30
+ end
31
+
32
+ def determine_runtime(framework)
33
+ return input[:runtime] if input.given?(:runtime)
34
+
35
+ detected_runtimes =
36
+ if framework.name == "standalone"
37
+ detector.detect_runtimes
38
+ else
39
+ detector.runtimes(framework)
40
+ end
41
+
42
+ default_runtime = detected_runtimes.size == 1 ? detected_runtimes.first : nil
43
+
44
+ if detected_runtimes.empty?
45
+ input[:runtime, detector.all_runtimes, nil, nil]
46
+ else
47
+ input[:runtime, detected_runtimes, default_runtime, :other]
48
+ end
49
+ end
50
+
51
+ def create_app(inputs)
52
+ app = client.app
53
+
54
+ inputs.each { |key, value| app.send(:"#{key}=", value) }
55
+
56
+ app = filter(:create_app, app)
57
+
58
+ with_progress("Creating #{c(app.name, :name)}") do
59
+ app.create!
60
+ end
61
+
62
+ app
63
+ end
64
+
65
+ def map_url(app)
66
+ line unless quiet?
67
+
68
+ url = input[:url, app.name]
69
+
70
+ mapped_url = false
71
+ until !url || mapped_url
72
+ begin
73
+ invoke :map, :app => app, :url => url
74
+ mapped_url = true
75
+ rescue CFoundry::RouteHostTaken, CFoundry::UriAlreadyTaken => e
76
+ line c(e.description, :bad)
77
+ line
78
+
79
+ input.forget(:url)
80
+ url = input[:url, app.name]
81
+
82
+ # version bumps on v1 even though mapping fails
83
+ app.invalidate! unless v2?
84
+ end
85
+ end
86
+ end
87
+
88
+ def create_services(app)
89
+ return unless input[:create_services]
90
+
91
+ while true
92
+ invoke :create_service, { :app => app }, :plan => :interact
93
+ break unless ask("Create another service?", :default => false)
94
+ end
95
+ end
96
+
97
+ def bind_services(app)
98
+ return unless input[:bind_services]
99
+
100
+ while true
101
+ invoke :bind_service, :app => app
102
+ break if (all_instances - app.services).empty?
103
+ break unless ask("Bind another service?", :default => false)
104
+ end
105
+ end
106
+
107
+ def start_app(app)
108
+ invoke :start, :app => app if input[:start]
109
+ end
110
+
111
+ private
112
+
113
+ def all_instances
114
+ @all_instances ||= client.service_instances
115
+ end
116
+
117
+ def detector
118
+ @detector ||= VMC::Detector.new(client, @path)
119
+ end
120
+
121
+ def target_base
122
+ client.target.sub(/^https?:\/\/([^\.]+\.)?(.+)\/?/, '\2')
123
+ end
124
+ end
125
+ end