appfog-vmc-plugin 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjhlY2VkZTAwMmY1NzA0OWMwYWEyMzg3Mjk4YzkyZTAwMmEzZTVkOA==
4
+ MzFlNWE1ZGY2M2RhYzE5YzhhMDQ0YzlmZTU1NTdhNDE3MjY5MTEzZg==
5
5
  data.tar.gz: !binary |-
6
- ZWFlODc0OTkxMTBlNjM3NmExMTBjMDRiYjZmNzQ1ZTAxNzA0MmExNQ==
6
+ MGVhMzA0NTE3MzcxMjhiYjZiY2E0YTczYWEzNzZiZGU1ODY5ZjU2Ng==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZTEzZDAxYTUyOTNkMmNlYTY4MWQ4MWVkOWQ2Mjc0NmYzNmI4MWVjODVlOTA2
10
- OTZiMjAyYTZhZTE2MjEwZDIxNjBhMWFhN2ZkZjM1MjNlODAyNmE4N2NiMWYw
11
- ZGMzZjM3MDVmNDIyNzBiZTIwN2RlMmZjYjRjNGVmNWNhMGNmYzQ=
9
+ MmU1YmM0MWE0MGQ5YWEwMDIwZTczOTMyNWRmMTUxYWQ4YzVjYzdlM2IwZmE0
10
+ MTZjNjYwYmUyNTk2ODYxMGE4OTg4MjkzZDBmYTkxOWRjN2U0ZTc3OWY2YTI2
11
+ NjIyZmI1OTMxNzgzOGZmMThiYjIwODQ1MDk5ZDhjMDhlMmU4ZWI=
12
12
  data.tar.gz: !binary |-
13
- OTFhNzExNmI3ZTVmYTg3YzA3NzAwMGVhZThjYWIwNDk0NWI4OTI4NTYwOWYz
14
- M2JjNjM2ZjFkZWY0YzViYzc4YTgzNzJhYjg1NTg4YWViN2E1NWE1OTJiMTcz
15
- MGMwMmVhM2Q1NDE1OWUyNzk5YmQ2NTUzZmVkMjk1ZGFiNTAwNzk=
13
+ Mzg3NDllNWE0ZjNhZTdmMzc1Y2QzOTBhMmY2NGEyMGEyYTU0NDE0ZDczNDE2
14
+ NWM2OGE2ZjgzYjQ0ODgxMjY0NWNkMTI5MTViNTc0ZTFkNzNiMTAwMTViMDZl
15
+ YTI3MTEzMGQ1MjBhODM2ZDUwNjYzOWNmMTAwMjM1MWMyNDhlOWE=
@@ -7,7 +7,7 @@ module CFoundry
7
7
  elsif war_file = Dir.glob("#{path}/*.war").first
8
8
  CFoundry::Zip.unpack(war_file, to)
9
9
  else
10
- check_unreachable_links(path)
10
+ #check_unreachable_links(path)
11
11
 
12
12
  FileUtils.mkdir(to)
13
13
 
@@ -9,6 +9,8 @@ module VMCAppfog
9
9
  app = input[:app]
10
10
  path = File.expand_path(input[:path] || app.name)
11
11
 
12
+ app = filter(:pull_app, app)
13
+
12
14
  with_progress("Pulling last pushed source code to #{c(app.name, :name)}") do
13
15
  client.app_pull(app.name, path)
14
16
  end
@@ -4,6 +4,8 @@ require "appfog-vmc-plugin/cfoundry"
4
4
  require "appfog-vmc-plugin/vmc"
5
5
  require "appfog-vmc-plugin/help"
6
6
  require "appfog-vmc-plugin/net_http"
7
+ require "manifests-vmc-plugin/plugin"
8
+
7
9
 
8
10
  command_files = "../deprecated/**/*.rb"
9
11
  Dir[File.expand_path(command_files, __FILE__)].each do |file|
@@ -1,3 +1,3 @@
1
1
  module VMCAppfog
2
- VERSION = "0.1.8".freeze
2
+ VERSION = "0.1.9".freeze
3
3
  end
@@ -17,7 +17,7 @@ module VMC::App
17
17
  inst = input[:inst, app.total_instances]
18
18
  end
19
19
 
20
- app.total_instances = inst if input.has?(:inst)
20
+ app.total_instances = inst.to_i if input.has?(:inst)
21
21
  fail "No changes!" unless app.changed?
22
22
 
23
23
  with_progress("Scaling #{c(app.name, :name)}") do
@@ -0,0 +1,21 @@
1
+ module VMCManifests
2
+ class CircularDependency < RuntimeError
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def to_s
8
+ "Circular dependency in application '#@app'"
9
+ end
10
+ end
11
+
12
+ class UnknownSymbol < RuntimeError
13
+ def initialize(sym)
14
+ @sym = sym
15
+ end
16
+
17
+ def to_s
18
+ "Undefined symbol in manifest: '#@sym'"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ module VMCManifests
2
+ module Builder
3
+ # parse a manifest and merge with its inherited manifests
4
+ def build(file)
5
+ manifest = YAML.load_file file
6
+
7
+ Array(manifest["inherit"]).each do |path|
8
+ manifest = merge_parent(path, manifest)
9
+ end
10
+
11
+ manifest
12
+ end
13
+
14
+ private
15
+
16
+ # merge the manifest at `parent_path' into the `child'
17
+ def merge_parent(parent_path, child)
18
+ merge_manifest(build(from_manifest(parent_path)), child)
19
+ end
20
+
21
+ # deep hash merge
22
+ def merge_manifest(parent, child)
23
+ merge = proc do |_, old, new|
24
+ if new.is_a?(Hash) && old.is_a?(Hash)
25
+ old.merge(new, &merge)
26
+ else
27
+ new
28
+ end
29
+ end
30
+
31
+ parent.merge(child, &merge)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,141 @@
1
+ module VMCManifests
2
+ module Normalizer
3
+ MANIFEST_META = ["applications", "properties"]
4
+
5
+ def normalize!(manifest)
6
+ toplevel = toplevel_attributes(manifest)
7
+
8
+ apps = manifest["applications"]
9
+ apps ||= [{}]
10
+
11
+ default_paths_to_keys!(apps)
12
+
13
+ apps = convert_to_array(apps)
14
+
15
+ merge_toplevel!(toplevel, manifest, apps)
16
+ normalize_apps!(apps)
17
+
18
+ manifest["applications"] = apps
19
+
20
+ normalize_paths!(apps)
21
+
22
+ keyval = normalize_key_val(manifest)
23
+ manifest.clear.merge!(keyval)
24
+
25
+ nil
26
+ end
27
+
28
+ private
29
+
30
+ def normalize_paths!(apps)
31
+ apps.each do |app|
32
+ app["path"] = from_manifest(app["path"])
33
+ end
34
+ end
35
+
36
+ def convert_to_array(apps)
37
+ return apps if apps.is_a?(Array)
38
+
39
+ ordered_by_deps(apps)
40
+ end
41
+
42
+ # sort applications in dependency order
43
+ # e.g. if A depends on B, B will be listed before A
44
+ def ordered_by_deps(apps, processed = Set[])
45
+ ordered = []
46
+ apps.each do |tag, info|
47
+ next if processed.include?(tag)
48
+
49
+ if deps = Array(info["depends-on"])
50
+ dep_apps = {}
51
+ deps.each do |dep|
52
+ dep_apps[dep] = apps[dep]
53
+ end
54
+
55
+ processed.add(tag)
56
+
57
+ ordered += ordered_by_deps(dep_apps, processed)
58
+ ordered << info
59
+ else
60
+ ordered << info
61
+ processed.add(tag)
62
+ end
63
+ end
64
+
65
+ ordered.each { |app| app.delete("depends-on") }
66
+
67
+ ordered
68
+ end
69
+
70
+ def default_paths_to_keys!(apps)
71
+ return if apps.is_a?(Array)
72
+
73
+ apps.each do |tag, app|
74
+ app["path"] ||= tag
75
+ end
76
+ end
77
+
78
+ def normalize_apps!(apps)
79
+ apps.each do |app|
80
+ normalize_app!(app)
81
+ end
82
+ end
83
+
84
+ def merge_toplevel!(toplevel, manifest, apps)
85
+ return if toplevel.empty?
86
+
87
+ apps.collect! do |a|
88
+ toplevel.merge(a)
89
+ end
90
+
91
+ toplevel.each do |k, _|
92
+ manifest.delete k
93
+ end
94
+ end
95
+
96
+ def normalize_app!(app)
97
+ if app["framework"].is_a?(Hash)
98
+ app["framework"] = app["framework"]["name"]
99
+ end
100
+
101
+ if app.key?("mem")
102
+ app["memory"] = app.delete("mem")
103
+ end
104
+
105
+ if app.key?("url") && app["url"].nil?
106
+ app["url"] = "none"
107
+ end
108
+ end
109
+
110
+ def toplevel_attributes(manifest)
111
+ top =
112
+ manifest.reject { |k, _|
113
+ MANIFEST_META.include? k
114
+ }
115
+
116
+ # implicit toplevel path of .
117
+ top["path"] ||= "."
118
+
119
+ top
120
+ end
121
+
122
+ def normalize_key_val(val)
123
+ case val
124
+ when Hash
125
+ stringified = {}
126
+
127
+ val.each do |k, v|
128
+ stringified[k.to_sym] = normalize_key_val(v)
129
+ end
130
+
131
+ stringified
132
+ when Array
133
+ val.collect { |x| normalize_key_val(x) }
134
+ when nil
135
+ nil
136
+ else
137
+ val.to_s
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,79 @@
1
+ module VMCManifests
2
+ module Resolver
3
+ def resolve(manifest, resolver)
4
+ new = {}
5
+
6
+ new[:applications] = manifest[:applications].collect do |app|
7
+ resolve_lexically(resolver, app, [manifest])
8
+ end
9
+
10
+ resolve_lexically(resolver, new, [new])
11
+ end
12
+
13
+ private
14
+
15
+ # resolve symbols, with hashes introducing new lexical symbols
16
+ def resolve_lexically(resolver, val, ctx)
17
+ case val
18
+ when Hash
19
+ new = {}
20
+
21
+ val.each do |k, v|
22
+ new[k] = resolve_lexically(resolver, v, [val] + ctx)
23
+ end
24
+
25
+ new
26
+ when Array
27
+ val.collect do |v|
28
+ resolve_lexically(resolver, v, ctx)
29
+ end
30
+ when String
31
+ val.gsub(/\$\{([^\}]+)\}/) do
32
+ resolve_symbol(resolver, $1, ctx)
33
+ end
34
+ else
35
+ val
36
+ end
37
+ end
38
+
39
+ # resolve a symbol to its value, and then resolve that value
40
+ def resolve_symbol(resolver, sym, ctx)
41
+ if found = find_symbol(sym.to_sym, ctx)
42
+ resolve_lexically(resolver, found, ctx)
43
+ found
44
+ elsif dynamic = resolver.resolve_symbol(sym)
45
+ dynamic
46
+ else
47
+ fail("Unknown symbol in manifest: #{sym}")
48
+ end
49
+ end
50
+
51
+ # search for a symbol introduced in the lexical context
52
+ def find_symbol(sym, ctx)
53
+ ctx.each do |h|
54
+ if val = resolve_in(h, sym)
55
+ return val
56
+ end
57
+ end
58
+
59
+ nil
60
+ end
61
+
62
+ # find a value, searching in explicit properties first
63
+ def resolve_in(hash, *where)
64
+ find_in_hash(hash, [:properties] + where) ||
65
+ find_in_hash(hash, where)
66
+ end
67
+
68
+ # helper for following a path of values in a hash
69
+ def find_in_hash(hash, where)
70
+ what = hash
71
+ where.each do |x|
72
+ return nil unless what.is_a?(Hash)
73
+ what = what[x]
74
+ end
75
+
76
+ what
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,31 @@
1
+ require "manifests-vmc-plugin/loader/builder"
2
+ require "manifests-vmc-plugin/loader/normalizer"
3
+ require "manifests-vmc-plugin/loader/resolver"
4
+
5
+ module VMCManifests
6
+ class Loader
7
+ include Builder
8
+ include Normalizer
9
+ include Resolver
10
+
11
+ def initialize(file, resolver)
12
+ @file = file
13
+ @resolver = resolver
14
+ end
15
+
16
+ def manifest
17
+ info = build(@file)
18
+ normalize! info
19
+ resolve info, @resolver
20
+ end
21
+
22
+ private
23
+
24
+ # expand a path relative to the manifest file's directory
25
+ def from_manifest(path)
26
+ return path unless @file
27
+
28
+ File.expand_path(path, File.dirname(@file))
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,315 @@
1
+ require "yaml"
2
+ require "set"
3
+
4
+ require "manifests-vmc-plugin/loader"
5
+
6
+
7
+ module VMCManifests
8
+ MANIFEST_FILE = "manifest.yml"
9
+
10
+ @@showed_manifest_usage = false
11
+
12
+ def manifest
13
+ return @manifest if @manifest
14
+
15
+ if manifest_file && File.exists?(manifest_file)
16
+ @manifest = load_manifest(manifest_file)
17
+ end
18
+ end
19
+
20
+ def save_manifest(save_to = manifest_file)
21
+ fail "No manifest to save!" unless @manifest
22
+
23
+ File.open(save_to, "w") do |io|
24
+ YAML.dump(@manifest, io)
25
+ end
26
+ end
27
+
28
+ # find the manifest file to work with
29
+ def manifest_file
30
+ return @manifest_file if @manifest_file
31
+
32
+ unless path = input[:manifest]
33
+ where = Dir.pwd
34
+ while true
35
+ if File.exists?(File.join(where, MANIFEST_FILE))
36
+ path = File.join(where, MANIFEST_FILE)
37
+ break
38
+ elsif File.basename(where) == "/"
39
+ path = nil
40
+ break
41
+ else
42
+ where = File.expand_path("../", where)
43
+ end
44
+ end
45
+ end
46
+
47
+ return unless path
48
+
49
+ @manifest_file = File.expand_path(path)
50
+ end
51
+
52
+ # load and resolve a given manifest file
53
+ def load_manifest(file)
54
+ Loader.new(file, self).manifest
55
+ end
56
+
57
+ # dynamic symbol resolution
58
+ def resolve_symbol(sym)
59
+ case sym
60
+ when "target-url"
61
+ client_target
62
+
63
+ when "target-base"
64
+ target_base
65
+
66
+ when "random-word"
67
+ sprintf("%04x", rand(0x0100000))
68
+
69
+ when /^ask (.+)/
70
+ ask($1)
71
+ end
72
+ end
73
+
74
+ # find apps by an identifier, which may be either a tag, a name, or a path
75
+ def find_apps(identifier)
76
+ return [] unless manifest
77
+
78
+ apps = apps_by(:name, identifier)
79
+
80
+ if apps.empty?
81
+ apps = apps_by(:path, from_manifest(identifier))
82
+ end
83
+
84
+ apps
85
+ end
86
+
87
+ # return all the apps described by the manifest
88
+ def all_apps
89
+ manifest[:applications]
90
+ end
91
+
92
+ def current_apps
93
+ manifest[:applications].select do |app|
94
+ next unless app[:path]
95
+ from_manifest(app[:path]) == Dir.pwd
96
+ end
97
+ end
98
+
99
+ # splits the user's input, resolving paths with the manifest,
100
+ # into internal/external apps
101
+ #
102
+ # internal apps are returned as their data in the manifest
103
+ #
104
+ # external apps are the strings that the user gave, to be
105
+ # passed along wholesale to the wrapped command
106
+ def apps_in_manifest(input = nil, use_name = true, &blk)
107
+ names_or_paths =
108
+ if input.has?(:apps)
109
+ # names may be given but be [], which will still cause
110
+ # interaction, so use #direct instead of #[] here
111
+ input.direct(:apps)
112
+ elsif input.has?(:app)
113
+ [input.direct(:app)]
114
+ elsif input.has?(:name)
115
+ [input.direct(:name)]
116
+ else
117
+ []
118
+ end
119
+
120
+ internal = []
121
+ external = []
122
+
123
+ names_or_paths.each do |x|
124
+ if x.is_a?(String)
125
+ if x =~ %r([/\\])
126
+ apps = find_apps(File.expand_path(x))
127
+
128
+ if apps.empty?
129
+ fail("Path #{b(x)} is not present in manifest #{b(relative_manifest_file)}.")
130
+ end
131
+ else
132
+ apps = find_apps(x)
133
+ end
134
+
135
+ if !apps.empty?
136
+ internal += apps
137
+ else
138
+ external << x
139
+ end
140
+ else
141
+ external << x
142
+ end
143
+ end
144
+
145
+ [internal, external]
146
+ end
147
+
148
+ def create_manifest_for(app, path)
149
+ meta = {
150
+ "name" => app.name,
151
+ "infra" => app.infra.name,
152
+ "framework" => app.framework.name,
153
+ "runtime" => app.runtime.name,
154
+ "memory" => human_size(app.memory * 1024 * 1024, 0),
155
+ "instances" => app.total_instances,
156
+ "url" => app.url ? app.url.sub(target_base, '${target-base}') : "none",
157
+ "path" => path
158
+ }
159
+
160
+ services = app.services
161
+
162
+ unless services.empty?
163
+ meta["services"] = {}
164
+
165
+ services.each do |i|
166
+ if v2?
167
+ p = i.service_plan
168
+ s = p.service
169
+
170
+ meta["services"][i.name] = {
171
+ "label" => s.label,
172
+ "provider" => s.provider,
173
+ "version" => s.version,
174
+ "plan" => p.name
175
+ }
176
+ else
177
+ meta["services"][i.name] = {
178
+ "infra" => i.infra.name,
179
+ "vendor" => i.vendor,
180
+ "version" => i.version,
181
+ "tier" => i.tier
182
+ }
183
+ end
184
+ end
185
+ end
186
+
187
+ if cmd = app.command
188
+ meta["command"] = cmd
189
+ end
190
+
191
+ meta
192
+ end
193
+
194
+ private
195
+
196
+ def relative_manifest_file
197
+ Pathname.new(manifest_file).relative_path_from(Pathname.pwd)
198
+ end
199
+
200
+ def show_manifest_usage
201
+ return if @@showed_manifest_usage
202
+
203
+ path = relative_manifest_file
204
+ line "Using manifest file #{c(path, :name)}"
205
+ line
206
+
207
+ @@showed_manifest_usage = true
208
+ end
209
+
210
+ def no_apps
211
+ fail "No applications or manifest to operate on."
212
+ end
213
+
214
+ def warn_reset_changes
215
+ line c("Not applying manifest changes without --reset", :warning)
216
+ line "See `vmc diff` for more details."
217
+ line
218
+ end
219
+
220
+ def apps_by(attr, val)
221
+ manifest[:applications].select do |info|
222
+ info[attr] == val
223
+ end
224
+ end
225
+
226
+ # expand a path relative to the manifest file's directory
227
+ def from_manifest(path)
228
+ File.expand_path(path, File.dirname(manifest_file))
229
+ end
230
+
231
+
232
+ def ask_to_save(input, app)
233
+ return if manifest_file
234
+ return unless ask("Save configuration?", :default => false)
235
+
236
+ manifest = create_manifest_for(app, input[:path])
237
+
238
+ with_progress("Saving to #{c("manifest.yml", :name)}") do
239
+ File.open("manifest.yml", "w") do |io|
240
+ YAML.dump(
241
+ { "applications" => [manifest] },
242
+ io)
243
+ end
244
+ end
245
+ end
246
+
247
+ def env_hash(val)
248
+ if val.is_a?(Hash)
249
+ val
250
+ else
251
+ hash = {}
252
+
253
+ val.each do |pair|
254
+ name, val = pair.split("=", 2)
255
+ hash[name] = val
256
+ end
257
+
258
+ hash
259
+ end
260
+ end
261
+
262
+ def setup_env(app, info)
263
+ return unless info[:env]
264
+ app.env = env_hash(info[:env])
265
+ end
266
+
267
+ def setup_services(app, info)
268
+ return if !info[:services] || info[:services].empty?
269
+
270
+ offerings = client.services
271
+
272
+ to_bind = []
273
+
274
+ info[:services].each do |name, svc|
275
+ name = name.to_s
276
+
277
+ if instance = client.service_instance_by_name(name)
278
+ to_bind << instance
279
+ else
280
+ offering = offerings.find { |o|
281
+ o.label == (svc[:label] || svc[:type] || svc[:vendor]) &&
282
+ (!svc[:version] || o.version == svc[:version]) &&
283
+ (o.provider == (svc[:provider] || "core"))
284
+ }
285
+
286
+ fail "Unknown service offering: #{svc.inspect}." unless offering
287
+
288
+ if v2?
289
+ plan = offering.service_plans.find { |p|
290
+ p.name == (svc[:plan] || "D100")
291
+ }
292
+
293
+ fail "Unknown service plan: #{svc[:plan]}." unless plan
294
+ end
295
+
296
+ invoke :create_service,
297
+ :name => name,
298
+ :offering => offering,
299
+ :plan => plan,
300
+ :app => app
301
+ end
302
+ end
303
+
304
+ to_bind.each do |s|
305
+ next if app.binds?(s)
306
+
307
+ # TODO: splat
308
+ invoke :bind_service, :app => app, :service => s
309
+ end
310
+ end
311
+
312
+ def target_base
313
+ client_target.sub(/^[^\.]+\./, "")
314
+ end
315
+ end
@@ -0,0 +1,149 @@
1
+ require "pathname"
2
+
3
+ require "vmc/plugin"
4
+ require "manifests-vmc-plugin/manifests"
5
+
6
+
7
+ class ManifestsPlugin < VMC::App::Base
8
+ include VMCManifests
9
+
10
+ option :manifest, :aliases => "-m", :value => :file,
11
+ :desc => "Path to manifest file to use"
12
+
13
+
14
+ [ :start, :restart, :instances, :logs, :env, :health, :stats,
15
+ :scale, :app, :stop, :delete
16
+ ].each do |wrap|
17
+ name_made_optional = change_argument(wrap, :app, :optional)
18
+
19
+ around(wrap) do |cmd, input|
20
+ wrap_with_optional_name(name_made_optional, cmd, input)
21
+ end
22
+ end
23
+
24
+
25
+ add_input :push, :reset, :desc => "Reset to values in the manifest",
26
+ :default => false
27
+
28
+ around(:push) do |push, input|
29
+ wrap_push(push, input)
30
+ end
31
+
32
+ # around(:pull) do |push, input|
33
+ # wrap_push(push, input)
34
+ # end
35
+
36
+ private
37
+
38
+ def wrap_with_optional_name(name_made_optional, cmd, input)
39
+ return cmd.call if input[:all]
40
+
41
+ unless manifest
42
+ # if the command knows how to handle this
43
+ if input.has?(:app) || !name_made_optional
44
+ return cmd.call
45
+ else
46
+ return no_apps
47
+ end
48
+ end
49
+
50
+ internal, external = apps_in_manifest(input)
51
+
52
+ return cmd.call if internal.empty? && !external.empty?
53
+
54
+ show_manifest_usage
55
+
56
+ if internal.empty? && external.empty?
57
+ internal = current_apps if internal.empty?
58
+ internal = all_apps if internal.empty?
59
+ end
60
+
61
+ internal = internal.collect { |app| app[:name] }
62
+
63
+ apps = internal + external
64
+ return no_apps if apps.empty?
65
+
66
+ apps.each.with_index do |app, num|
67
+ line unless quiet? || num == 0
68
+ cmd.call(input.without(:apps).merge_given(:app => app))
69
+ end
70
+ end
71
+
72
+ def apply_changes(app, input)
73
+ app.memory = megabytes(input[:memory]) if input.has?(:memory)
74
+ app.total_instances = input[:instances] if input.has?(:instances)
75
+ app.command = input[:command] if input.has?(:command)
76
+ app.production = input[:plan].upcase.start_with?("P") if input.has?(:plan)
77
+ app.infra = input[:infra] if input.has?(:infra)
78
+ app.framework = input[:framework] if input.has?(:framework)
79
+ app.runtime = input[:runtime] if input.has?(:runtime)
80
+ app.buildpack = input[:buildpack] if input.has?(:buildpack)
81
+ end
82
+
83
+ def wrap_push(push, input)
84
+ unless manifest
85
+ create_and_save_manifest(push, input)
86
+ return
87
+ end
88
+
89
+ particular, external = apps_in_manifest(input)
90
+
91
+ unless external.empty?
92
+ fail "Could not find #{b(external.join(", "))}' in the manifest."
93
+ end
94
+
95
+ apps = particular.empty? ? all_apps : particular
96
+
97
+ show_manifest_usage
98
+
99
+ spaced(apps) do |app_manifest|
100
+ push_with_manifest(app_manifest, push, input)
101
+ end
102
+ end
103
+
104
+ def push_with_manifest(app_manifest, push, input)
105
+ with_filters(
106
+ :push => {
107
+ :create_app => proc { |a|
108
+ setup_env(a, app_manifest)
109
+ a
110
+ },
111
+ :push_app => proc { |a|
112
+ setup_services(a, app_manifest)
113
+ a
114
+ }
115
+ }) do
116
+ app_input = push_input_for(app_manifest, input)
117
+
118
+ push.call(app_input)
119
+ end
120
+ end
121
+
122
+ def push_input_for(app_manifest, input)
123
+ existing_app = client.app_by_name(app_manifest[:name])
124
+
125
+ if !existing_app || input[:reset]
126
+ input = input.rebase_given(app_manifest)
127
+ else
128
+ warn_reset_changes if manifest_differs?(existing_app, input)
129
+ end
130
+
131
+ input.merge(
132
+ :path => from_manifest(app_manifest[:path]),
133
+ :name => app_manifest[:name],
134
+ :bind_services => false,
135
+ :create_services => false)
136
+ end
137
+
138
+ def manifest_differs?(app, input)
139
+ apply_changes(app, input)
140
+ app.changed?
141
+ end
142
+
143
+ def create_and_save_manifest(push, input)
144
+ with_filters(
145
+ :push => { :push_app => proc { |a| ask_to_save(input, a); a } }) do
146
+ push.call
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,3 @@
1
+ module VMCManifests
2
+ VERSION = "0.6.1".freeze
3
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appfog-vmc-plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Santeford
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-20 00:00:00.000000000 Z
12
+ date: 2013-04-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cfoundry
@@ -65,6 +65,14 @@ files:
65
65
  - lib/appfog-vmc-plugin/vmc/start/login.rb
66
66
  - lib/appfog-vmc-plugin/vmc/user/base.rb
67
67
  - lib/appfog-vmc-plugin/vmc.rb
68
+ - lib/manifests-vmc-plugin/errors.rb
69
+ - lib/manifests-vmc-plugin/loader/builder.rb
70
+ - lib/manifests-vmc-plugin/loader/normalizer.rb
71
+ - lib/manifests-vmc-plugin/loader/resolver.rb
72
+ - lib/manifests-vmc-plugin/loader.rb
73
+ - lib/manifests-vmc-plugin/manifests.rb
74
+ - lib/manifests-vmc-plugin/plugin.rb
75
+ - lib/manifests-vmc-plugin/version.rb
68
76
  homepage: http://www.appfog.com/
69
77
  licenses: []
70
78
  metadata: {}