vmc 0.4.2 → 0.4.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.
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