cloulu 0.0.0 → 0.1.1

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 (152) hide show
  1. data/bin/{cloulu → cl} +0 -0
  2. data/lib/cc_api_stub/applications.rb +53 -0
  3. data/lib/cc_api_stub/domains.rb +16 -0
  4. data/lib/cc_api_stub/frameworks.rb +22 -0
  5. data/lib/cc_api_stub/helper.rb +131 -0
  6. data/lib/cc_api_stub/login.rb +21 -0
  7. data/lib/cc_api_stub/organization_users.rb +21 -0
  8. data/lib/cc_api_stub/organizations.rb +70 -0
  9. data/lib/cc_api_stub/routes.rb +26 -0
  10. data/lib/cc_api_stub/runtimes.rb +22 -0
  11. data/lib/cc_api_stub/service_bindings.rb +22 -0
  12. data/lib/cc_api_stub/service_instances.rb +22 -0
  13. data/lib/cc_api_stub/services.rb +25 -0
  14. data/lib/cc_api_stub/spaces.rb +49 -0
  15. data/lib/cc_api_stub/users.rb +84 -0
  16. data/lib/cc_api_stub.rb +17 -0
  17. data/lib/cfoundry/auth_token.rb +63 -0
  18. data/lib/cfoundry/baseclient.rb +201 -0
  19. data/lib/cfoundry/chatty_hash.rb +46 -0
  20. data/lib/cfoundry/client.rb +46 -0
  21. data/lib/cfoundry/concerns/login_helpers.rb +13 -0
  22. data/lib/cfoundry/errors.rb +160 -0
  23. data/lib/cfoundry/rest_client.rb +299 -0
  24. data/lib/cfoundry/test_support.rb +3 -0
  25. data/lib/cfoundry/trace_helpers.rb +40 -0
  26. data/lib/cfoundry/uaaclient.rb +112 -0
  27. data/lib/cfoundry/upload_helpers.rb +187 -0
  28. data/lib/cfoundry/v1/app.rb +363 -0
  29. data/lib/cfoundry/v1/base.rb +72 -0
  30. data/lib/cfoundry/v1/client.rb +193 -0
  31. data/lib/cfoundry/v1/framework.rb +21 -0
  32. data/lib/cfoundry/v1/model.rb +178 -0
  33. data/lib/cfoundry/v1/model_magic.rb +129 -0
  34. data/lib/cfoundry/v1/runtime.rb +24 -0
  35. data/lib/cfoundry/v1/service.rb +39 -0
  36. data/lib/cfoundry/v1/service_instance.rb +32 -0
  37. data/lib/cfoundry/v1/service_plan.rb +19 -0
  38. data/lib/cfoundry/v1/user.rb +22 -0
  39. data/lib/cfoundry/v2/app.rb +392 -0
  40. data/lib/cfoundry/v2/base.rb +83 -0
  41. data/lib/cfoundry/v2/client.rb +138 -0
  42. data/lib/cfoundry/v2/domain.rb +11 -0
  43. data/lib/cfoundry/v2/framework.rb +14 -0
  44. data/lib/cfoundry/v2/model.rb +148 -0
  45. data/lib/cfoundry/v2/model_magic.rb +449 -0
  46. data/lib/cfoundry/v2/organization.rb +16 -0
  47. data/lib/cfoundry/v2/route.rb +15 -0
  48. data/lib/cfoundry/v2/runtime.rb +12 -0
  49. data/lib/cfoundry/v2/service.rb +19 -0
  50. data/lib/cfoundry/v2/service_auth_token.rb +9 -0
  51. data/lib/cfoundry/v2/service_binding.rb +10 -0
  52. data/lib/cfoundry/v2/service_instance.rb +14 -0
  53. data/lib/cfoundry/v2/service_plan.rb +12 -0
  54. data/lib/cfoundry/v2/space.rb +18 -0
  55. data/lib/cfoundry/v2/user.rb +64 -0
  56. data/lib/cfoundry/validator.rb +39 -0
  57. data/lib/cfoundry/version.rb +4 -0
  58. data/lib/cfoundry/zip.rb +56 -0
  59. data/lib/cfoundry.rb +2 -0
  60. data/lib/manifests-vmc-plugin/errors.rb +21 -0
  61. data/lib/manifests-vmc-plugin/loader/builder.rb +34 -0
  62. data/lib/manifests-vmc-plugin/loader/normalizer.rb +149 -0
  63. data/lib/manifests-vmc-plugin/loader/resolver.rb +79 -0
  64. data/lib/manifests-vmc-plugin/loader.rb +31 -0
  65. data/lib/manifests-vmc-plugin/plugin.rb +145 -0
  66. data/lib/manifests-vmc-plugin/version.rb +3 -0
  67. data/lib/manifests-vmc-plugin.rb +313 -0
  68. data/lib/mothership/base.rb +99 -0
  69. data/lib/mothership/callbacks.rb +85 -0
  70. data/lib/mothership/command.rb +146 -0
  71. data/lib/mothership/errors.rb +38 -0
  72. data/lib/mothership/help/commands.rb +53 -0
  73. data/lib/mothership/help/printer.rb +170 -0
  74. data/lib/mothership/help.rb +64 -0
  75. data/lib/mothership/inputs.rb +189 -0
  76. data/lib/mothership/parser.rb +182 -0
  77. data/lib/mothership/version.rb +3 -0
  78. data/lib/mothership.rb +64 -0
  79. data/lib/tunnel-vmc-plugin/plugin.rb +178 -0
  80. data/lib/tunnel-vmc-plugin/tunnel.rb +308 -0
  81. data/lib/tunnel-vmc-plugin/version.rb +3 -0
  82. data/lib/uaa/http.rb +168 -0
  83. data/lib/uaa/misc.rb +121 -0
  84. data/lib/uaa/scim.rb +292 -0
  85. data/lib/uaa/token_coder.rb +196 -0
  86. data/lib/uaa/token_issuer.rb +255 -0
  87. data/lib/uaa/util.rb +235 -0
  88. data/lib/uaa/version.rb +19 -0
  89. data/lib/uaa.rb +18 -0
  90. data/lib/vmc/cli/app/app.rb +45 -0
  91. data/lib/vmc/cli/app/apps.rb +99 -0
  92. data/lib/vmc/cli/app/base.rb +90 -0
  93. data/lib/vmc/cli/app/crashes.rb +42 -0
  94. data/lib/vmc/cli/app/delete.rb +95 -0
  95. data/lib/vmc/cli/app/deprecated.rb +11 -0
  96. data/lib/vmc/cli/app/env.rb +78 -0
  97. data/lib/vmc/cli/app/files.rb +137 -0
  98. data/lib/vmc/cli/app/health.rb +26 -0
  99. data/lib/vmc/cli/app/instances.rb +53 -0
  100. data/lib/vmc/cli/app/logs.rb +76 -0
  101. data/lib/vmc/cli/app/push/create.rb +165 -0
  102. data/lib/vmc/cli/app/push/interactions.rb +94 -0
  103. data/lib/vmc/cli/app/push/sync.rb +64 -0
  104. data/lib/vmc/cli/app/push.rb +109 -0
  105. data/lib/vmc/cli/app/rename.rb +35 -0
  106. data/lib/vmc/cli/app/restart.rb +20 -0
  107. data/lib/vmc/cli/app/scale.rb +71 -0
  108. data/lib/vmc/cli/app/start.rb +143 -0
  109. data/lib/vmc/cli/app/stats.rb +67 -0
  110. data/lib/vmc/cli/app/stop.rb +27 -0
  111. data/lib/vmc/cli/help.rb +11 -0
  112. data/lib/vmc/cli/interactive.rb +105 -0
  113. data/lib/vmc/cli/route/base.rb +12 -0
  114. data/lib/vmc/cli/route/map.rb +82 -0
  115. data/lib/vmc/cli/route/routes.rb +25 -0
  116. data/lib/vmc/cli/route/unmap.rb +94 -0
  117. data/lib/vmc/cli/service/base.rb +8 -0
  118. data/lib/vmc/cli/service/bind.rb +44 -0
  119. data/lib/vmc/cli/service/create.rb +126 -0
  120. data/lib/vmc/cli/service/delete.rb +86 -0
  121. data/lib/vmc/cli/service/rename.rb +35 -0
  122. data/lib/vmc/cli/service/service.rb +42 -0
  123. data/lib/vmc/cli/service/services.rb +114 -0
  124. data/lib/vmc/cli/service/unbind.rb +38 -0
  125. data/lib/vmc/cli/start/base.rb +94 -0
  126. data/lib/vmc/cli/start/colors.rb +13 -0
  127. data/lib/vmc/cli/start/info.rb +126 -0
  128. data/lib/vmc/cli/start/login.rb +97 -0
  129. data/lib/vmc/cli/start/logout.rb +17 -0
  130. data/lib/vmc/cli/start/target.rb +60 -0
  131. data/lib/vmc/cli/start/target_interactions.rb +37 -0
  132. data/lib/vmc/cli/start/targets.rb +16 -0
  133. data/lib/vmc/cli/user/base.rb +29 -0
  134. data/lib/vmc/cli/user/create.rb +39 -0
  135. data/lib/vmc/cli/user/delete.rb +27 -0
  136. data/lib/vmc/cli/user/passwd.rb +50 -0
  137. data/lib/vmc/cli/user/register.rb +42 -0
  138. data/lib/vmc/cli/user/users.rb +32 -0
  139. data/lib/vmc/cli/v2_check_cli.rb +16 -0
  140. data/lib/vmc/cli.rb +474 -0
  141. data/lib/vmc/constants.rb +13 -0
  142. data/lib/vmc/detect.rb +129 -0
  143. data/lib/vmc/errors.rb +19 -0
  144. data/lib/vmc/plugin.rb +56 -0
  145. data/lib/vmc/spacing.rb +89 -0
  146. data/lib/vmc/spec_helper.rb +1 -0
  147. data/lib/vmc/test_support.rb +6 -0
  148. data/lib/vmc/version.rb +3 -0
  149. data/lib/vmc.rb +8 -0
  150. data/vendor/errors/v1.yml +189 -0
  151. data/vendor/errors/v2.yml +360 -0
  152. metadata +303 -190
@@ -0,0 +1,18 @@
1
+ require "cfoundry/v2/model"
2
+
3
+ module CFoundry::V2
4
+ class Space < Model
5
+ attribute :name, :string
6
+ to_one :organization
7
+ to_many :developers, :as => :user
8
+ to_many :managers, :as => :user
9
+ to_many :auditors, :as => :user
10
+ to_many :apps
11
+ to_many :domains
12
+ to_many :service_instances
13
+
14
+ scoped_to_organization
15
+
16
+ queryable_by :name, :organization_guid, :developer_guid, :app_guid
17
+ end
18
+ end
@@ -0,0 +1,64 @@
1
+ require "cfoundry/v2/model"
2
+
3
+ module CFoundry::V2
4
+ class User < Model
5
+ to_many :spaces
6
+ to_many :organizations
7
+ to_many :managed_organizations, :as => :organization
8
+ to_many :billing_managed_organizations, :as => :organization
9
+ to_many :audited_organizations, :as => :organization
10
+ to_many :managed_spaces, :as => :space
11
+ to_many :audited_spaces, :as => :space
12
+ attribute :admin, :boolean
13
+ to_one :default_space, :as => :space
14
+
15
+ attribute :guid, :string # guid is explicitly set for users
16
+
17
+ queryable_by :space_guid, :organization_guid, :managed_organization_guid,
18
+ :billing_managed_organization_guid, :audited_organization_guid,
19
+ :managed_space_guid, :audited_space_guid
20
+
21
+ def guid
22
+ @guid
23
+ end
24
+
25
+ alias set_guid_attribute guid=
26
+
27
+ def guid=(x)
28
+ @guid = x
29
+ set_guid_attribute(x)
30
+ end
31
+
32
+ alias :admin? :admin
33
+
34
+ def change_password!(new, old)
35
+ @client.base.uaa.change_password(@guid, new, old)
36
+ end
37
+
38
+ # optional metadata from UAA
39
+ attr_accessor :emails, :name
40
+
41
+ def email
42
+ return unless @emails && @emails.first
43
+ @emails.first[:value]
44
+ end
45
+
46
+ def given_name
47
+ return unless @name && @name[:givenName] != email
48
+ @name[:givenName]
49
+ end
50
+
51
+ def family_name
52
+ return unless @name && @name[:familyName] != email
53
+ @name[:familyName]
54
+ end
55
+
56
+ def full_name
57
+ if @name && @name[:fullName]
58
+ @name[:fullName]
59
+ elsif given_name && family_name
60
+ "#{given_name} #{family_name}"
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,39 @@
1
+ module CFoundry
2
+ module Validator
3
+ class << self
4
+ def value_matches?(val, type)
5
+ case type
6
+ when Class
7
+ val.is_a?(type)
8
+ when Regexp
9
+ val.is_a?(String) && val =~ type
10
+ when :url
11
+ value_matches?(val, URI::regexp(%w(http https)))
12
+ when :https_url
13
+ value_matches?(val, URI::regexp("https"))
14
+ when :boolean
15
+ val.is_a?(TrueClass) || val.is_a?(FalseClass)
16
+ when Array
17
+ val.all? do |x|
18
+ value_matches?(x, type.first)
19
+ end
20
+ when Hash
21
+ val.is_a?(Hash) &&
22
+ type.all? { |name, subtype|
23
+ val.key?(name) && value_matches?(val[name], subtype)
24
+ }
25
+ when nil
26
+ true
27
+ else
28
+ val.is_a?(Object.const_get(type.to_s.capitalize))
29
+ end
30
+ end
31
+
32
+ def validate_type(val, type)
33
+ unless value_matches?(val, type)
34
+ raise CFoundry::Mismatch.new(type, val)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,4 @@
1
+ module CFoundry # :nodoc:
2
+ # CFoundry library version number.
3
+ VERSION = "0.5.2".freeze
4
+ end
@@ -0,0 +1,56 @@
1
+ require "zip/zipfilesystem"
2
+
3
+ module CFoundry
4
+ # Generic Zpi API. Uses rubyzip underneath, but may be changed in the future
5
+ # to use system zip command if necessary.
6
+ module Zip
7
+ # Directory entries to exclude from packing.
8
+ PACK_EXCLUSION_GLOBS = %w(.. . *~ #*# *.log)
9
+
10
+ module_function
11
+
12
+ # Get the entries in the zip file. Returns an array of the entire
13
+ # contents, recursively (not just top-level).
14
+ def entry_lines(file)
15
+ entries = []
16
+ ::Zip::ZipFile.foreach(file) do |zentry|
17
+ entries << zentry
18
+ end
19
+ entries
20
+ end
21
+
22
+ # Unpack a zip +file+ to directory +dest+.
23
+ def unpack(file, dest)
24
+ ::Zip::ZipFile.foreach(file) do |zentry|
25
+ epath = "#{dest}/#{zentry}"
26
+ dirname = File.dirname(epath)
27
+ FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
28
+ zentry.extract(epath) unless File.exists?(epath)
29
+ end
30
+ end
31
+
32
+ # Determine what files in +dir+ to pack.
33
+ def files_to_pack(dir)
34
+ Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).select do |f|
35
+ File.exists?(f) &&
36
+ PACK_EXCLUSION_GLOBS.none? do |e|
37
+ File.fnmatch(e, File.basename(f))
38
+ end
39
+ end
40
+ end
41
+
42
+ # Package directory +dir+ as file +zipfile+.
43
+ def pack(dir, zipfile)
44
+ files = files_to_pack(dir)
45
+ return false if files.empty?
46
+
47
+ ::Zip::ZipFile.open(zipfile, true) do |zf|
48
+ files.each do |f|
49
+ zf.add(f.sub("#{dir}/",''), f)
50
+ end
51
+ end
52
+
53
+ true
54
+ end
55
+ end
56
+ end
data/lib/cfoundry.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "cfoundry/version"
2
+ require "cfoundry/client"
@@ -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,149 @@
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
+
109
+ if app.key?("subdomain")
110
+ if app.key?("host")
111
+ app.delete("subdomain")
112
+ else
113
+ app["host"] = app.delete("subdomain")
114
+ end
115
+ end
116
+ end
117
+
118
+ def toplevel_attributes(manifest)
119
+ top =
120
+ manifest.reject { |k, _|
121
+ MANIFEST_META.include? k
122
+ }
123
+
124
+ # implicit toplevel path of .
125
+ top["path"] ||= "."
126
+
127
+ top
128
+ end
129
+
130
+ def normalize_key_val(val)
131
+ case val
132
+ when Hash
133
+ stringified = {}
134
+
135
+ val.each do |k, v|
136
+ stringified[k.to_sym] = normalize_key_val(v)
137
+ end
138
+
139
+ stringified
140
+ when Array
141
+ val.collect { |x| normalize_key_val(x) }
142
+ when nil
143
+ nil
144
+ else
145
+ val.to_s
146
+ end
147
+ end
148
+ end
149
+ 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,145 @@
1
+ require "pathname"
2
+
3
+ require "vmc/plugin"
4
+ require "manifests-vmc-plugin"
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
+ private
33
+
34
+ def wrap_with_optional_name(name_made_optional, cmd, input)
35
+ return cmd.call if input[:all]
36
+
37
+ unless manifest
38
+ # if the command knows how to handle this
39
+ if input.has?(:app) || !name_made_optional
40
+ return cmd.call
41
+ else
42
+ return no_apps
43
+ end
44
+ end
45
+
46
+ internal, external = apps_in_manifest(input)
47
+
48
+ return cmd.call if internal.empty? && !external.empty?
49
+
50
+ show_manifest_usage
51
+
52
+ if internal.empty? && external.empty?
53
+ internal = current_apps if internal.empty?
54
+ internal = all_apps if internal.empty?
55
+ end
56
+
57
+ internal = internal.collect { |app| app[:name] }
58
+
59
+ apps = internal + external
60
+ return no_apps if apps.empty?
61
+
62
+ apps.each.with_index do |app, num|
63
+ line unless quiet? || num == 0
64
+ cmd.call(input.without(:apps).merge_given(:app => app))
65
+ end
66
+ end
67
+
68
+ def apply_changes(app, input)
69
+ app.memory = megabytes(input[:memory]) if input.has?(:memory)
70
+ app.total_instances = input[:instances] if input.has?(:instances)
71
+ app.command = input[:command] if input.has?(:command)
72
+ app.production = input[:plan].upcase.start_with?("P") if input.has?(:plan)
73
+ app.framework = input[:framework] if input.has?(:framework)
74
+ app.runtime = input[:runtime] if input.has?(:runtime)
75
+ app.buildpack = input[:buildpack] if input.has?(:buildpack)
76
+ end
77
+
78
+ def wrap_push(push, input)
79
+ unless manifest
80
+ create_and_save_manifest(push, input)
81
+ return
82
+ end
83
+
84
+ particular, external = apps_in_manifest(input)
85
+
86
+ unless external.empty?
87
+ fail "Could not find #{b(external.join(", "))}' in the manifest."
88
+ end
89
+
90
+ apps = particular.empty? ? all_apps : particular
91
+
92
+ show_manifest_usage
93
+
94
+ spaced(apps) do |app_manifest|
95
+ push_with_manifest(app_manifest, push, input)
96
+ end
97
+ end
98
+
99
+ def push_with_manifest(app_manifest, push, input)
100
+ with_filters(
101
+ :push => {
102
+ :create_app => proc { |a|
103
+ setup_env(a, app_manifest)
104
+ a
105
+ },
106
+ :push_app => proc { |a|
107
+ setup_services(a, app_manifest)
108
+ a
109
+ }
110
+ }) do
111
+ app_input = push_input_for(app_manifest, input)
112
+
113
+ push.call(app_input)
114
+ end
115
+ end
116
+
117
+ def push_input_for(app_manifest, input)
118
+ existing_app = client.app_by_name(app_manifest[:name])
119
+ rebased_input = input.rebase_given(app_manifest)
120
+
121
+ if !existing_app || input[:reset]
122
+ input = rebased_input
123
+ else
124
+ warn_reset_changes if manifest_differs?(existing_app, rebased_input)
125
+ end
126
+
127
+ input.merge(
128
+ :path => from_manifest(app_manifest[:path]),
129
+ :name => app_manifest[:name],
130
+ :bind_services => false,
131
+ :create_services => false)
132
+ end
133
+
134
+ def manifest_differs?(app, input)
135
+ apply_changes(app, input)
136
+ app.changed?
137
+ end
138
+
139
+ def create_and_save_manifest(push, input)
140
+ with_filters(
141
+ :push => { :push_app => proc { |a| ask_to_save(input, a); a } }) do
142
+ push.call
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,3 @@
1
+ module VMCManifests
2
+ VERSION = "0.6.2".freeze
3
+ end