appfog-vmc-plugin 0.1.8 → 0.1.9

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 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: {}