manifests-vmc-plugin 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,161 +1,100 @@
1
1
  require "vmc/plugin"
2
2
  require "manifests-vmc-plugin"
3
3
 
4
- VMC.Plugin do
5
- class_option :manifest,
6
- :aliases => "-m", :desc => "Manifest file"
7
4
 
8
- class_option :path,
9
- :aliases => "-p", :desc => "Application path"
10
- end
11
-
12
- VMC.Plugin(VMC::App) do
5
+ class Manifests < VMC::CLI
13
6
  include VMCManifests
14
7
 
15
- # basic commands that, when given no args, act on the
16
- # app(s) described by the manifest, in dependency-order
17
- [:start, :instances, :logs, :file, :files, :health, :stats].each do |wrap|
18
- around(wrap) do |cmd, args|
19
- if args.empty? && !passed_value(:name)
20
- each_app do |a|
21
- cmd.call(:name => a["name"])
22
- puts "" unless simple_output?
23
- end || err("No applications to act on.")
24
- else
25
- cmd.call
26
- end
27
- end
28
- end
8
+ option :manifest, :aliases => "-m", :value => :file,
9
+ :desc => "Path to manifest file to use"
29
10
 
30
- # same as above but in reverse dependency-order
31
- around(:stop) do |cmd, args|
32
- if args.empty? && !passed_value(:name)
33
- reversed = []
34
- each_app do |a|
35
- reversed.unshift a["name"]
36
- end || err("No applications to act on.")
37
11
 
38
- reversed.each do |name|
39
- cmd.call(:name => name)
40
- puts "" unless simple_output?
41
- end
42
- else
43
- cmd.call
44
- end
12
+ def no_apps
13
+ err "No applications or manifest to operate on."
45
14
  end
46
15
 
47
- around(:delete) do |cmd, args|
48
- if args.empty? && !options[:all] && !passed_value(:name)
49
- reversed = []
50
- has_manifest =
51
- each_app do |a|
52
- reversed.unshift a["name"]
53
- end
54
16
 
55
- if has_manifest
56
- reversed.each do |name|
57
- cmd.call(:name => name)
58
- puts "" unless simple_output?
17
+ # basic commands that, when given no name, act on the
18
+ # app(s) described by the manifest, in dependency-order
19
+ [ :start, :instances, :logs, :file, :files, :env,
20
+ :health, :stats, :scale
21
+ ].each do |wrap|
22
+ change_argument(wrap, :name, :optional)
23
+
24
+ around(wrap) do |cmd, input|
25
+ use_manifest =
26
+ specific_apps_or_all(input) do |app|
27
+ cmd.call(input.merge(:name => app[:name]))
28
+ puts "" unless quiet?
59
29
  end
60
- else
61
- cmd.call
30
+
31
+ # array of unhandled names
32
+ if use_manifest === Array
33
+ cmd.call(input.merge(:names => use_manifest))
34
+
35
+ # no manifest or no apps described by it
36
+ elsif !use_manifest
37
+ no_apps
62
38
  end
63
- else
64
- cmd.call
65
39
  end
66
40
  end
67
41
 
68
- # stop apps in reverse dependency order,
69
- # and then start in dependency order
70
- around(:restart) do |cmd, args|
71
- if args.empty? && !passed_value(:name)
42
+
43
+ # same as above but in reverse dependency-order
44
+ [:stop, :delete].each do |wrap|
45
+ around(wrap) do |cmd, input|
46
+ next cmd.call if input[:all]
47
+
72
48
  reversed = []
73
- forwards = []
74
- each_app do |a|
75
- reversed.unshift a["name"]
76
- forwards << a["name"]
77
- end || err("No applications to act on.")
78
-
79
- reversed.each do |name|
80
- with_inputs(:name => name) do
81
- stop
49
+ use_manifest =
50
+ specific_apps_or_all(input) do |app|
51
+ reversed.unshift app[:name]
82
52
  end
83
- end
84
53
 
85
- puts "" unless simple_output?
54
+ # array of unhandled names
55
+ if use_manifest === Array
56
+ cmd.call(input.merge(:names => use_manifest))
86
57
 
87
- forwards.each do |name|
88
- with_inputs(:name => name) do
89
- start
90
- end
58
+ # no manifest or no apps described by it
59
+ elsif !use_manifest
60
+ next no_apps
91
61
  end
92
- else
93
- cmd.call
62
+
63
+ cmd.call(input.merge(:names => reversed))
94
64
  end
95
65
  end
96
66
 
67
+
97
68
  # push and sync meta changes in the manifest
98
69
  # also sets env data on creation if present in manifest
99
- around(:push) do |push, args|
100
- name = passed_value(:name) || args.first
101
-
102
- use_name =
103
- if manifest && apps = manifest["applications"]
104
- apps.size == 1
105
- else
106
- # legacy single-app manifest
107
- true
108
- end
109
-
110
- all_pushed =
111
- each_app do |info|
112
- next if !use_name && name && info["name"] != name
113
-
114
- app_name = use_name ? name : info["name"]
115
-
116
- app = client.app(app_name)
117
-
118
- sync_changes(info)
119
-
120
- with_filters(:push_app => proc { |a| setup_app(a, info); a }) do
70
+ change_argument(:push, :name, :optional)
71
+ around(:push) do |push, input|
72
+ use_manifest =
73
+ specific_apps_or_all(input, true) do |app|
74
+ sync_changes(app)
75
+
76
+ with_filters(
77
+ :push => {
78
+ :push_app =>
79
+ proc { |a| setup_app(a, app); a }
80
+ }) do
121
81
  push.call(
122
- :name => app_name,
123
- :bind_services => false,
124
- :create_services => false)
82
+ input.merge(app).merge(
83
+ :bind_services => false,
84
+ :create_services => false))
125
85
  end
126
-
127
- puts "" unless simple_output?
128
86
  end
129
87
 
130
- unless all_pushed
88
+ unless use_manifest
131
89
  bound = []
132
90
 
133
- with_filters(:push_app => proc { |a| ask_to_save(a); a}) do
91
+ with_filters(
92
+ :push => {
93
+ :push_app =>
94
+ proc { |a| ask_to_save(input, a); a }
95
+ }) do
134
96
  push.call
135
97
  end
136
98
  end
137
99
  end
138
-
139
- # need to do this specially so it doesn't call it with the instance/memory
140
- # flags set (via each_app), which would cause it to do nothing
141
- around(:scale) do |cmd, args|
142
- if args.empty? && !passed_value(:name)
143
- apps = []
144
- has_manifest =
145
- each_app do |a|
146
- apps << a["name"]
147
- end
148
-
149
- if has_manifest
150
- apps.each do |name|
151
- cmd.call(:name => name)
152
- puts "" unless simple_output?
153
- end
154
- else
155
- cmd.call
156
- end
157
- else
158
- cmd.call
159
- end
160
- end
161
100
  end
@@ -1,3 +1,3 @@
1
1
  module VMCManifests
2
- VERSION = "0.2.4"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -22,7 +22,7 @@ module VMCManifests
22
22
 
23
23
  # find the manifest file to work with
24
24
  def manifest_file
25
- return options[:manifest] if options[:manifest]
25
+ return option(:manifest) if option(:manifest)
26
26
  return @manifest_file if @manifest_file
27
27
 
28
28
  where = Dir.pwd
@@ -188,60 +188,58 @@ module VMCManifests
188
188
  end
189
189
  end
190
190
 
191
- def app_info(find_path)
192
- return unless manifest and manifest["applications"]
193
-
194
- manifest["applications"].each do |path, info|
195
- if info["framework"].is_a?(Hash)
196
- info["framework"] = info["framework"]["name"]
191
+ def app_info(find_path, input = nil)
192
+ return unless manifest
193
+
194
+ mandir = File.dirname(manifest_file)
195
+ full_path = File.expand_path(find_path, mandir)
196
+
197
+ path, info =
198
+ if apps = manifest["applications"]
199
+ manifest["applications"].find do |path, info|
200
+ if info["framework"].is_a?(Hash)
201
+ info["framework"] = info["framework"]["name"]
202
+ end
203
+
204
+ app = File.expand_path(path, mandir)
205
+ File.expand_path(path, mandir) == full_path
206
+ end
207
+ elsif find_path == "."
208
+ [".", {}]
197
209
  end
198
210
 
199
- app = File.expand_path(path, File.dirname(manifest_file))
200
- if find_path == app
201
- return toplevel_attributes.merge info
211
+ return unless info
212
+
213
+ data = { :path => full_path }
214
+
215
+ toplevel_attributes.merge(info).each do |k, v|
216
+ name = k.to_sym
217
+
218
+ if name == :mem
219
+ name = :memory
202
220
  end
221
+
222
+ data[name] = input && input.given(name) || v
203
223
  end
204
224
 
205
- nil
225
+ data
206
226
  end
207
227
 
208
228
  # call a block for each app in a manifest (in dependency order), setting
209
229
  # inputs for each app
210
- def each_app
211
- given_path = passed_value(:path)
212
- full_path = given_path && File.expand_path(given_path)
213
-
230
+ def each_app(input = nil, &blk)
214
231
  if manifest and all_apps = manifest["applications"]
215
232
  use_inputs = all_apps.size == 1
216
233
 
217
- # given a specific application
218
- if given_path
219
- if info = app_info(full_path)
220
- with_app(full_path, info, use_inputs) do
221
- yield info
222
- end
223
- else
224
- raise "Path #{given_path} is not described by the manifest."
225
- end
226
- else
227
- # all apps in the manifest
228
- ordered_by_deps(all_apps).each do |path|
229
- app = File.expand_path(path, File.dirname(manifest_file))
230
- info = app_info(app)
231
-
232
- with_app(app, info, use_inputs) do
233
- yield info
234
- end
235
- end
234
+ ordered_by_deps(all_apps).each do |path|
235
+ yield app_info(path, use_inputs && input)
236
236
  end
237
237
 
238
238
  true
239
-
239
+
240
240
  # manually created or legacy single-app manifest
241
241
  elsif single = toplevel_attributes
242
- with_app(full_path || ".", single, true) do
243
- yield single
244
- end
242
+ yield app_info(".", input)
245
243
 
246
244
  true
247
245
 
@@ -250,24 +248,56 @@ module VMCManifests
250
248
  end
251
249
  end
252
250
 
253
- private
251
+ # like each_app, but only acts on apps specified as paths instead of names
252
+ #
253
+ # returns the names that were not paths
254
+ def specific_apps_or_all(input = nil, use_name = true, &blk)
255
+ return false unless manifest && apps = manifest["applications"]
254
256
 
255
- # call the block as if the app info and path were given as flags
256
- def with_app(path, info, use_inputs = false, &blk)
257
- inputs = {:path => path}
258
- info.each do |k, v|
259
- input = k.to_sym
257
+ use_name = false if apps.size > 1
260
258
 
261
- if input == :mem
262
- input = :memory
259
+ names_or_paths =
260
+ if input.given?(:names)
261
+ input[:names]
262
+ elsif input.given?(:name)
263
+ [input[:name]]
264
+ else
265
+ []
263
266
  end
264
267
 
265
- inputs[input] = use_inputs && passed_value(input) || v
268
+ return each_app(input, &blk) if names_or_paths.empty?
269
+
270
+ input = input.without(:name, :names)
271
+
272
+ paths = []
273
+ names = []
274
+ names_or_paths.each do |x|
275
+ path = File.expand_path(x)
276
+
277
+ if File.exists?(path)
278
+ paths << path
279
+ else
280
+ names << x
281
+ end
266
282
  end
267
283
 
268
- with_inputs(inputs, &blk)
284
+ paths.each do |path|
285
+ blk.call app_info(path, input)
286
+ end
287
+
288
+ if use_name && names.size == 1
289
+ blk.call(
290
+ app_info(
291
+ manifest["applications"].keys.first,
292
+ input.merge(:name => names.first)))
293
+ end
294
+
295
+ names
269
296
  end
270
297
 
298
+
299
+ private
300
+
271
301
  # sort applications in dependency order
272
302
  # e.g. if A depends on B, B will be listed before A
273
303
  def ordered_by_deps(apps, abspaths = nil, processed = Set[])
@@ -313,18 +343,18 @@ module VMCManifests
313
343
  # redeploys the app if necessary (after prompting the user), e.g. for
314
344
  # runtime/framework change
315
345
  def sync_changes(info)
316
- app = client.app(info["name"])
346
+ app = client.app(info[:name])
317
347
  return unless app.exists?
318
348
 
319
349
  diff = {}
320
350
  need_restage = []
321
351
  info.each do |k, v|
322
- case k
352
+ case k.to_s
323
353
  when /ur[li]s?/
324
354
  old = app.urls
325
355
  new = Array(v)
326
356
  if old != new
327
- diff["urls"] = [old.inspect, new.inspect]
357
+ diff[:urls] = [old.inspect, new.inspect]
328
358
  app.urls = new
329
359
  end
330
360
  when "env"
@@ -351,7 +381,7 @@ module VMCManifests
351
381
  new = megabytes(v)
352
382
 
353
383
  if old != new
354
- diff["memory"] = [human_size(old * 1024 * 1024, 0), v]
384
+ diff[:memory] = [human_size(old * 1024 * 1024, 0), v]
355
385
  app.memory = new
356
386
  end
357
387
  end
@@ -359,7 +389,7 @@ module VMCManifests
359
389
 
360
390
  return if diff.empty?
361
391
 
362
- unless simple_output?
392
+ unless quiet?
363
393
  puts "Detected the following changes to #{c(app.name, :name)}:"
364
394
  diff.each do |k, d|
365
395
  old, new = d
@@ -375,7 +405,7 @@ module VMCManifests
375
405
  app.update!
376
406
  end
377
407
  else
378
- unless simple_output?
408
+ unless quiet?
379
409
  puts "The following changes require the app to be recreated:"
380
410
  need_restage.each do |n|
381
411
  puts " #{c(n, :error)}"
@@ -395,7 +425,7 @@ module VMCManifests
395
425
  end
396
426
  end
397
427
 
398
- def ask_to_save(app)
428
+ def ask_to_save(input, app)
399
429
  return if manifest_file
400
430
 
401
431
  services = app.services.collect { |name| client.service(name) }
@@ -427,7 +457,7 @@ module VMCManifests
427
457
  if ask("Save configuration?", :default => false)
428
458
  File.open("manifest.yml", "w") do |io|
429
459
  YAML.dump(
430
- {"applications" => {(options[:path] || ".") => meta}},
460
+ {"applications" => {(input[:path] || ".") => meta}},
431
461
  io)
432
462
  end
433
463
 
@@ -436,13 +466,13 @@ module VMCManifests
436
466
  end
437
467
 
438
468
  def setup_app(app, info)
439
- app.env = info["env"]
469
+ app.env = info[:env]
440
470
 
441
- return if !info["services"] || info["services"].empty?
471
+ return if !info[:services] || info[:services].empty?
442
472
 
443
473
  services = client.system_services
444
474
 
445
- info["services"].each do |name, svc|
475
+ info[:services].each do |name, svc|
446
476
  service = client.service(name)
447
477
 
448
478
  unless service.exists?
@@ -460,6 +490,6 @@ module VMCManifests
460
490
  end
461
491
  end
462
492
 
463
- app.services = info["services"].keys
493
+ app.services = info[:services].keys
464
494
  end
465
495
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manifests-vmc-plugin
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 4
10
- version: 0.2.4
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Alex Suraci
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-06-22 00:00:00 Z
18
+ date: 2012-07-03 00:00:00 Z
19
19
  dependencies: []
20
20
 
21
21
  description: