vmc 0.4.0.beta.5 → 0.4.0.beta.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/{vmc-ng/LICENSE → LICENSE} +0 -0
  2. data/{vmc-ng/Rakefile → Rakefile} +0 -0
  3. data/bin/vmc +10 -11
  4. data/{vmc-ng/lib → lib}/vmc.rb +0 -0
  5. data/{vmc-ng/lib → lib}/vmc/cli.rb +17 -9
  6. data/{vmc-ng/lib → lib}/vmc/cli/app.rb +31 -31
  7. data/{vmc-ng/lib → lib}/vmc/cli/better_help.rb +0 -0
  8. data/{vmc-ng/lib → lib}/vmc/cli/command.rb +6 -6
  9. data/{vmc-ng/lib → lib}/vmc/cli/dots.rb +63 -8
  10. data/{vmc-ng/lib → lib}/vmc/cli/service.rb +6 -6
  11. data/{vmc-ng/lib → lib}/vmc/cli/user.rb +2 -2
  12. data/{vmc-ng/lib → lib}/vmc/constants.rb +1 -0
  13. data/{vmc-ng/lib → lib}/vmc/detect.rb +0 -0
  14. data/{vmc-ng/lib → lib}/vmc/errors.rb +0 -0
  15. data/{vmc-ng/lib → lib}/vmc/plugin.rb +0 -0
  16. data/lib/vmc/version.rb +3 -0
  17. metadata +33 -281
  18. data/vmc-ng/bin/vmc +0 -14
  19. data/vmc-ng/lib/vmc/version.rb +0 -3
  20. data/vmc/LICENSE +0 -24
  21. data/vmc/README.md +0 -102
  22. data/vmc/Rakefile +0 -101
  23. data/vmc/bin/vmc +0 -6
  24. data/vmc/caldecott_helper/Gemfile +0 -10
  25. data/vmc/caldecott_helper/Gemfile.lock +0 -48
  26. data/vmc/caldecott_helper/server.rb +0 -43
  27. data/vmc/config/clients.yml +0 -17
  28. data/vmc/config/micro/offline.conf +0 -2
  29. data/vmc/config/micro/paths.yml +0 -22
  30. data/vmc/config/micro/refresh_ip.rb +0 -20
  31. data/vmc/lib/cli.rb +0 -47
  32. data/vmc/lib/cli/commands/admin.rb +0 -80
  33. data/vmc/lib/cli/commands/apps.rb +0 -1126
  34. data/vmc/lib/cli/commands/base.rb +0 -227
  35. data/vmc/lib/cli/commands/manifest.rb +0 -56
  36. data/vmc/lib/cli/commands/micro.rb +0 -115
  37. data/vmc/lib/cli/commands/misc.rb +0 -129
  38. data/vmc/lib/cli/commands/services.rb +0 -180
  39. data/vmc/lib/cli/commands/user.rb +0 -65
  40. data/vmc/lib/cli/config.rb +0 -173
  41. data/vmc/lib/cli/console_helper.rb +0 -160
  42. data/vmc/lib/cli/core_ext.rb +0 -122
  43. data/vmc/lib/cli/errors.rb +0 -19
  44. data/vmc/lib/cli/frameworks.rb +0 -265
  45. data/vmc/lib/cli/manifest_helper.rb +0 -302
  46. data/vmc/lib/cli/runner.rb +0 -531
  47. data/vmc/lib/cli/services_helper.rb +0 -84
  48. data/vmc/lib/cli/tunnel_helper.rb +0 -332
  49. data/vmc/lib/cli/usage.rb +0 -115
  50. data/vmc/lib/cli/version.rb +0 -7
  51. data/vmc/lib/cli/zip_util.rb +0 -77
  52. data/vmc/lib/vmc.rb +0 -3
  53. data/vmc/lib/vmc/client.rb +0 -471
  54. data/vmc/lib/vmc/const.rb +0 -22
  55. data/vmc/lib/vmc/micro.rb +0 -56
  56. data/vmc/lib/vmc/micro/switcher/base.rb +0 -97
  57. data/vmc/lib/vmc/micro/switcher/darwin.rb +0 -19
  58. data/vmc/lib/vmc/micro/switcher/dummy.rb +0 -15
  59. data/vmc/lib/vmc/micro/switcher/linux.rb +0 -16
  60. data/vmc/lib/vmc/micro/switcher/windows.rb +0 -31
  61. data/vmc/lib/vmc/micro/vmrun.rb +0 -158
@@ -1,122 +0,0 @@
1
- module VMCExtensions
2
-
3
- def say(message)
4
- VMC::Cli::Config.output.puts(message) if VMC::Cli::Config.output
5
- end
6
-
7
- def header(message, filler = '-')
8
- say "\n"
9
- say message
10
- say filler.to_s * message.size
11
- end
12
-
13
- def banner(message)
14
- say "\n"
15
- say message
16
- end
17
-
18
- def display(message, nl=true)
19
- if nl
20
- say message
21
- else
22
- if VMC::Cli::Config.output
23
- VMC::Cli::Config.output.print(message)
24
- VMC::Cli::Config.output.flush
25
- end
26
- end
27
- end
28
-
29
- def clear(size=80)
30
- return unless VMC::Cli::Config.output
31
- VMC::Cli::Config.output.print("\r")
32
- VMC::Cli::Config.output.print(" " * size)
33
- VMC::Cli::Config.output.print("\r")
34
- #VMC::Cli::Config.output.flush
35
- end
36
-
37
- def err(message, prefix='Error: ')
38
- raise VMC::Cli::CliExit, "#{prefix}#{message}"
39
- end
40
-
41
- def warn(msg)
42
- say "#{"[WARNING]".yellow} #{msg}"
43
- end
44
-
45
- def quit(message = nil)
46
- raise VMC::Cli::GracefulExit, message
47
- end
48
-
49
- def blank?
50
- self.to_s.blank?
51
- end
52
-
53
- def uptime_string(delta)
54
- num_seconds = delta.to_i
55
- days = num_seconds / (60 * 60 * 24);
56
- num_seconds -= days * (60 * 60 * 24);
57
- hours = num_seconds / (60 * 60);
58
- num_seconds -= hours * (60 * 60);
59
- minutes = num_seconds / 60;
60
- num_seconds -= minutes * 60;
61
- "#{days}d:#{hours}h:#{minutes}m:#{num_seconds}s"
62
- end
63
-
64
- def pretty_size(size, prec=1)
65
- return 'NA' unless size
66
- return "#{size}B" if size < 1024
67
- return sprintf("%.#{prec}fK", size/1024.0) if size < (1024*1024)
68
- return sprintf("%.#{prec}fM", size/(1024.0*1024.0)) if size < (1024*1024*1024)
69
- return sprintf("%.#{prec}fG", size/(1024.0*1024.0*1024.0))
70
- end
71
- end
72
-
73
- module VMCStringExtensions
74
-
75
- def red
76
- colorize("\e[0m\e[31m")
77
- end
78
-
79
- def green
80
- colorize("\e[0m\e[32m")
81
- end
82
-
83
- def yellow
84
- colorize("\e[0m\e[33m")
85
- end
86
-
87
- def bold
88
- colorize("\e[0m\e[1m")
89
- end
90
-
91
- def colorize(color_code)
92
- if VMC::Cli::Config.colorize
93
- "#{color_code}#{self}\e[0m"
94
- else
95
- self
96
- end
97
- end
98
-
99
- def blank?
100
- self =~ /^\s*$/
101
- end
102
-
103
- def truncate(limit = 30)
104
- return "" if self.blank?
105
- etc = "..."
106
- stripped = self.strip[0..limit]
107
- if stripped.length > limit
108
- stripped.gsub(/\s+?(\S+)?$/, "") + etc
109
- else
110
- stripped
111
- end
112
- end
113
-
114
- end
115
-
116
- class Object
117
- include VMCExtensions
118
- end
119
-
120
- class String
121
- include VMCStringExtensions
122
- end
@@ -1,19 +0,0 @@
1
- module VMC::Cli
2
-
3
- class CliError < StandardError
4
- def self.error_code(code = nil)
5
- define_method(:error_code) { code }
6
- end
7
- end
8
-
9
- class UnknownCommand < CliError; error_code(100); end
10
- class TargetMissing < CliError; error_code(102); end
11
- class TargetInaccessible < CliError; error_code(103); end
12
-
13
- class TargetError < CliError; error_code(201); end
14
- class AuthError < TargetError; error_code(202); end
15
-
16
- class CliExit < CliError; error_code(400); end
17
- class GracefulExit < CliExit; error_code(401); end
18
-
19
- end
@@ -1,265 +0,0 @@
1
- module VMC::Cli
2
-
3
- class Framework
4
-
5
- DEFAULT_FRAMEWORK = "http://b20nine.com/unknown"
6
- DEFAULT_MEM = '256M'
7
-
8
- FRAMEWORKS = {
9
- 'Rails' => ['rails3', { :mem => '256M', :description => 'Rails Application', :console=>true}],
10
- 'Spring' => ['spring', { :mem => '512M', :description => 'Java SpringSource Spring Application'}],
11
- 'Grails' => ['grails', { :mem => '512M', :description => 'Java SpringSource Grails Application'}],
12
- 'Lift' => ['lift', { :mem => '512M', :description => 'Scala Lift Application'}],
13
- 'JavaWeb' => ['java_web',{ :mem => '512M', :description => 'Java Web Application'}],
14
- 'Standalone' => ['standalone', { :mem => '64M', :description => 'Standalone Application'}],
15
- 'Sinatra' => ['sinatra', { :mem => '128M', :description => 'Sinatra Application'}],
16
- 'Node' => ['node', { :mem => '64M', :description => 'Node.js Application'}],
17
- 'PHP' => ['php', { :mem => '128M', :description => 'PHP Application'}],
18
- 'Erlang/OTP Rebar' => ['otp_rebar', { :mem => '64M', :description => 'Erlang/OTP Rebar Application'}],
19
- 'WSGI' => ['wsgi', { :mem => '64M', :description => 'Python WSGI Application'}],
20
- 'Django' => ['django', { :mem => '128M', :description => 'Python Django Application'}],
21
- 'dotNet' => ['dotNet', { :mem => '128M', :description => '.Net Web Application'}],
22
- 'Rack' => ['rack', { :mem => '128M', :description => 'Rack Application'}],
23
- 'Play' => ['play', { :mem => '256M', :description => 'Play Framework Application'}]
24
- }
25
-
26
- class << self
27
-
28
- def known_frameworks(available_frameworks)
29
- frameworks = []
30
- FRAMEWORKS.each do |key,fw|
31
- frameworks << key if available_frameworks.include? [fw[0]]
32
- end
33
- frameworks
34
- end
35
-
36
- def lookup(name)
37
- return create(*FRAMEWORKS[name])
38
- end
39
-
40
- def lookup_by_framework(name)
41
- FRAMEWORKS.each do |key,fw|
42
- return create(fw[0],fw[1]) if fw[0] == name
43
- end
44
- end
45
-
46
- def create(name,opts)
47
- if name == "standalone"
48
- return StandaloneFramework.new(name, opts)
49
- else
50
- return Framework.new(name,opts)
51
- end
52
- end
53
-
54
- def detect(path, available_frameworks)
55
- if !File.directory? path
56
- if path.end_with?('.war')
57
- return detect_framework_from_war path
58
- elsif path.end_with?('.zip')
59
- return detect_framework_from_zip path, available_frameworks
60
- elsif available_frameworks.include?(["standalone"])
61
- return Framework.lookup('Standalone')
62
- else
63
- return nil
64
- end
65
- end
66
- Dir.chdir(path) do
67
- # Rails
68
- if File.exist?('config/environment.rb')
69
- return Framework.lookup('Rails')
70
-
71
- # Rack
72
- elsif File.exist?('config.ru') && available_frameworks.include?(["rack"])
73
- return Framework.lookup('Rack')
74
-
75
- # Java Web Apps
76
- elsif Dir.glob('*.war').first
77
- return detect_framework_from_war(Dir.glob('*.war').first)
78
-
79
- elsif File.exist?('WEB-INF/web.xml')
80
- return detect_framework_from_war
81
-
82
- # Simple Ruby Apps
83
- elsif !Dir.glob('*.rb').empty?
84
- matched_file = nil
85
- Dir.glob('*.rb').each do |fname|
86
- next if matched_file
87
- File.open(fname, 'r') do |f|
88
- str = f.read # This might want to be limited
89
- matched_file = fname if (str && str.match(/^\s*require[\s\(]*['"]sinatra['"]/))
90
- end
91
- end
92
- if matched_file
93
- # Sinatra apps
94
- f = Framework.lookup('Sinatra')
95
- f.exec = "ruby #{matched_file}"
96
- return f
97
- end
98
-
99
- # PHP
100
- elsif !Dir.glob('*.php').empty?
101
- return Framework.lookup('PHP')
102
-
103
- # Erlang/OTP using Rebar
104
- elsif !Dir.glob('releases/*/*.rel').empty? && !Dir.glob('releases/*/*.boot').empty?
105
- return Framework.lookup('Erlang/OTP Rebar')
106
-
107
- # Python Django
108
- # XXX: not all django projects keep settings.py in top-level directory
109
- elsif File.exist?('manage.py') && File.exist?('settings.py')
110
- return Framework.lookup('Django')
111
-
112
- # Python
113
- elsif !Dir.glob('wsgi.py').empty?
114
- return Framework.lookup('WSGI')
115
-
116
- # .Net
117
- elsif !Dir.glob('web.config').empty?
118
- return Framework.lookup('dotNet')
119
-
120
- # Node.js
121
- elsif !Dir.glob('*.js').empty?
122
- if File.exist?('server.js') || File.exist?('app.js') || File.exist?('index.js') || File.exist?('main.js')
123
- return Framework.lookup('Node')
124
- end
125
-
126
- # Play or Standalone Apps
127
- elsif Dir.glob('*.zip').first
128
- zip_file = Dir.glob('*.zip').first
129
- return detect_framework_from_zip zip_file, available_frameworks
130
- end
131
-
132
- # Default to Standalone if no other match was made
133
- return Framework.lookup('Standalone') if available_frameworks.include?(["standalone"])
134
- end
135
- end
136
-
137
- def detect_framework_from_war(war_file=nil)
138
- if war_file
139
- contents = ZipUtil.entry_lines(war_file)
140
- else
141
- #assume we are working with current dir
142
- contents = Dir['**/*'].join("\n")
143
- end
144
-
145
- # Spring/Lift Variations
146
- if contents =~ /WEB-INF\/lib\/grails-web.*\.jar/
147
- return Framework.lookup('Grails')
148
- elsif contents =~ /WEB-INF\/lib\/lift-webkit.*\.jar/
149
- return Framework.lookup('Lift')
150
- elsif contents =~ /WEB-INF\/classes\/org\/springframework/
151
- return Framework.lookup('Spring')
152
- elsif contents =~ /WEB-INF\/lib\/spring-core.*\.jar/
153
- return Framework.lookup('Spring')
154
- elsif contents =~ /WEB-INF\/lib\/org\.springframework\.core.*\.jar/
155
- return Framework.lookup('Spring')
156
- else
157
- return Framework.lookup('JavaWeb')
158
- end
159
- end
160
-
161
- def detect_framework_from_zip(zip_file, available_frameworks)
162
- contents = ZipUtil.entry_lines(zip_file)
163
- detect_framework_from_zip_contents(contents, available_frameworks)
164
- end
165
-
166
- def detect_framework_from_zip_contents(contents, available_frameworks)
167
- if available_frameworks.include?(["play"]) && contents =~ /lib\/play\..*\.jar/
168
- return Framework.lookup('Play')
169
- elsif available_frameworks.include?(["standalone"])
170
- return Framework.lookup('Standalone')
171
- end
172
- end
173
- end
174
-
175
- attr_reader :name, :description, :console
176
- attr_accessor :exec
177
-
178
- def initialize(framework=nil, opts={})
179
- @name = framework || DEFAULT_FRAMEWORK
180
- @memory = opts[:mem] || DEFAULT_MEM
181
- @description = opts[:description] || 'Unknown Application Type'
182
- @exec = opts[:exec]
183
- @console = opts[:console] || false
184
- end
185
-
186
- def to_s
187
- description
188
- end
189
-
190
- def require_url?
191
- true
192
- end
193
-
194
- def require_start_command?
195
- false
196
- end
197
-
198
- def prompt_for_runtime?
199
- false
200
- end
201
-
202
- def default_runtime(path)
203
- nil
204
- end
205
-
206
- def memory(runtime=nil)
207
- @memory
208
- end
209
-
210
- alias :mem :memory
211
- end
212
-
213
- class StandaloneFramework < Framework
214
- def require_url?
215
- false
216
- end
217
-
218
- def require_start_command?
219
- true
220
- end
221
-
222
- def prompt_for_runtime?
223
- true
224
- end
225
-
226
- def default_runtime(path)
227
- if !File.directory? path
228
- if path =~ /\.(jar|class)$/
229
- return "java"
230
- elsif path =~ /\.(rb)$/
231
- return "ruby18"
232
- elsif path =~ /\.(zip)$/
233
- return detect_runtime_from_zip path
234
- end
235
- else
236
- Dir.chdir(path) do
237
- return "ruby18" if not Dir.glob('**/*.rb').empty?
238
- if !Dir.glob('**/*.class').empty? || !Dir.glob('**/*.jar').empty?
239
- return "java"
240
- elsif Dir.glob('*.zip').first
241
- zip_file = Dir.glob('*.zip').first
242
- return detect_runtime_from_zip zip_file
243
- end
244
- end
245
- end
246
- return nil
247
- end
248
-
249
- def memory(runtime=nil)
250
- default_mem = @memory
251
- default_mem = '128M' if runtime =~ /\Aruby/ || runtime == "php"
252
- default_mem = '512M' if runtime == "java" || runtime == "java7"
253
- default_mem
254
- end
255
-
256
- private
257
- def detect_runtime_from_zip(zip_file)
258
- contents = ZipUtil.entry_lines(zip_file)
259
- if contents =~ /\.(jar)$/
260
- return "java"
261
- end
262
- end
263
- end
264
-
265
- end
@@ -1,302 +0,0 @@
1
- require "set"
2
-
3
- module VMC::Cli::ManifestHelper
4
- include VMC::Cli::ServicesHelper
5
-
6
- DEFAULTS = {
7
- "url" => "${name}.${target-base}",
8
- "mem" => "128M",
9
- "instances" => 1
10
- }
11
-
12
- MANIFEST = "manifest.yml"
13
-
14
- YES_SET = Set.new(["y", "Y", "yes", "YES"])
15
-
16
- # take a block and call it once for each app to push/update.
17
- # with @application and @app_info set appropriately
18
- def each_app(panic=true)
19
- if @manifest and all_apps = @manifest["applications"]
20
- where = File.expand_path(@path)
21
- single = false
22
-
23
- all_apps.each do |path, info|
24
- app = File.expand_path("../" + path, manifest_file)
25
- if where.start_with?(app)
26
- @application = app
27
- @app_info = info
28
- yield info["name"]
29
- single = true
30
- break
31
- end
32
- end
33
-
34
- unless single
35
- if where == File.expand_path("../", manifest_file)
36
- ordered_by_deps(all_apps).each do |path, info|
37
- app = File.expand_path("../" + path, manifest_file)
38
- @application = app
39
- @app_info = info
40
- yield info["name"]
41
- end
42
- else
43
- err "Path '#{@path}' is not known to manifest '#{manifest_file}'."
44
- end
45
- end
46
- else
47
- @application = @path
48
- @app_info = @manifest
49
- if @app_info
50
- yield @app_info["name"]
51
- elsif panic
52
- err "No applications."
53
- end
54
- end
55
-
56
- nil
57
- ensure
58
- @application = nil
59
- @app_info = nil
60
- end
61
-
62
- def interact(many=false)
63
- @manifest ||= {}
64
- configure_app(many)
65
- end
66
-
67
- def target_manifest
68
- @options[:manifest] || MANIFEST
69
- end
70
-
71
- def save_manifest(save_to = nil)
72
- save_to ||= target_manifest
73
-
74
- File.open(save_to, "w") do |f|
75
- f.write @manifest.to_yaml
76
- end
77
-
78
- say "Manifest written to #{save_to}."
79
- end
80
-
81
- def configure_app(many=false)
82
- name = manifest("name") ||
83
- set(ask("Application Name", :default => manifest("name")), "name")
84
-
85
-
86
-
87
- if manifest "framework"
88
- framework = VMC::Cli::Framework.lookup_by_framework manifest("framework","name")
89
- else
90
- framework = detect_framework
91
- set framework.name, "framework", "name"
92
- set(
93
- { "mem" => framework.mem,
94
- "description" => framework.description,
95
- "exec" => framework.exec
96
- },
97
- "framework",
98
- "info"
99
- )
100
- end
101
-
102
- default_runtime = manifest "runtime"
103
- if not default_runtime
104
- default_runtime = framework.default_runtime(@application)
105
- set(detect_runtime(default_runtime), "runtime") if framework.prompt_for_runtime?
106
- end
107
- default_command = manifest "command"
108
- set ask("Start Command", :default => default_command), "command" if framework.require_start_command?
109
-
110
- url_template = manifest("url") || DEFAULTS["url"]
111
- url_resolved = url_template.dup
112
- resolve_lexically(url_resolved)
113
-
114
- if !framework.require_url?
115
- url_resolved = "None"
116
- end
117
- url = ask("Application Deployed URL", :default => url_resolved)
118
-
119
- if url == url_resolved && url != "None"
120
- url = url_template
121
- end
122
-
123
- # common error case is for prompted users to answer y or Y or yes or
124
- # YES to this ask() resulting in an unintended URL of y. Special
125
- # case this common error
126
- url = url_resolved if YES_SET.member? url
127
-
128
- if(url == "None")
129
- url = nil
130
- end
131
-
132
- set url, "url"
133
-
134
- default_mem = manifest("mem")
135
- default_mem = framework.memory(manifest("runtime")) if not default_mem
136
- set ask(
137
- "Memory reservation",
138
- :default =>
139
- default_mem ||
140
- DEFAULTS["mem"],
141
- :choices => ["128M", "256M", "512M", "1G", "2G"]
142
- ), "mem"
143
-
144
- set ask(
145
- "How many instances?",
146
- :default => manifest("instances") || DEFAULTS["instances"]
147
- ), "instances"
148
-
149
- unless manifest "services"
150
- user_services = client.services
151
- user_services.sort! {|a, b| a[:name] <=> b[:name] }
152
-
153
- unless user_services.empty?
154
- if ask "Bind existing services to '#{name}'?", :default => false
155
- bind_services(user_services)
156
- end
157
- end
158
-
159
- services = client.services_info
160
- unless services.empty?
161
- if ask "Create services to bind to '#{name}'?", :default => false
162
- create_services(services.values.collect(&:keys).flatten)
163
- end
164
- end
165
- end
166
-
167
- if many and ask("Configure for another application?", :default => false)
168
- @application = ask "Application path?"
169
- configure_app
170
- end
171
- end
172
-
173
- def set(what, *where)
174
- where.unshift "applications", @application
175
-
176
- which = @manifest
177
- where.each_with_index do |k, i|
178
- if i + 1 == where.size
179
- which[k] = what
180
- else
181
- which = (which[k] ||= {})
182
- end
183
- end
184
-
185
- what
186
- end
187
-
188
- # Detect the appropriate framework.
189
- def detect_framework(prompt_ok = true)
190
- framework = VMC::Cli::Framework.detect(@application, frameworks_info)
191
- framework_correct = ask("Detected a #{framework}, is this correct?", :default => true) if prompt_ok && framework
192
- if prompt_ok && (framework.nil? || !framework_correct)
193
- display "#{"[WARNING]".yellow} Can't determine the Application Type." unless framework
194
- framework = nil if !framework_correct
195
- framework = VMC::Cli::Framework.lookup(
196
- ask(
197
- "Select Application Type",
198
- :indexed => true,
199
- :default => framework,
200
- :choices => VMC::Cli::Framework.known_frameworks(frameworks_info)
201
- )
202
- )
203
- display "Selected #{framework}"
204
- end
205
-
206
- framework
207
- end
208
-
209
- # Detect the appropriate runtime.
210
- def detect_runtime(default, prompt_ok=true)
211
- runtime = nil
212
- runtime_keys=[]
213
- runtimes_info.keys.each {|runtime_key| runtime_keys << runtime_key.dup }
214
- runtime_keys.sort!
215
- if prompt_ok
216
- runtime = ask(
217
- "Select Runtime",
218
- :indexed => true,
219
- :default => default,
220
- :choices => runtime_keys
221
- )
222
- display "Selected #{runtime}"
223
- end
224
- runtime
225
- end
226
-
227
- def bind_services(user_services, chosen = 0)
228
- svcname = ask(
229
- "Which one?",
230
- :indexed => true,
231
- :choices => user_services.collect { |p| p[:name] })
232
-
233
- svc = user_services.find { |p| p[:name] == svcname }
234
-
235
- set svc[:vendor], "services", svcname, "type"
236
-
237
- if chosen + 1 < user_services.size && ask("Bind another?", :default => false)
238
- bind_services(user_services, chosen + 1)
239
- end
240
- end
241
-
242
- def create_services(services)
243
- svcs = services.collect(&:to_s).sort!
244
-
245
- configure_service(
246
- ask(
247
- "What kind of service?",
248
- :indexed => true,
249
- :choices => svcs
250
- )
251
- )
252
-
253
- if ask "Create another?", :default => false
254
- create_services(services)
255
- end
256
- end
257
-
258
- def configure_service(vendor)
259
- default_name = random_service_name(vendor)
260
- name = ask "Specify the name of the service", :default => default_name
261
-
262
- set vendor, "services", name, "type"
263
- end
264
-
265
- private
266
- def ordered_by_deps(apps, abspaths = nil, processed = Set[])
267
- unless abspaths
268
- abspaths = {}
269
- apps.each do |p, i|
270
- ep = File.expand_path("../" + p, manifest_file)
271
- abspaths[ep] = i
272
- end
273
- end
274
-
275
- ordered = []
276
- apps.each do |path, info|
277
- epath = File.expand_path("../" + path, manifest_file)
278
-
279
- if deps = info["depends-on"]
280
- dep_apps = {}
281
- deps.each do |dep|
282
- edep = File.expand_path("../" + dep, manifest_file)
283
-
284
- err "Circular dependency detected." if processed.include? edep
285
-
286
- dep_apps[dep] = abspaths[edep]
287
- end
288
-
289
- processed.add(epath)
290
-
291
- ordered += ordered_by_deps(dep_apps, abspaths, processed)
292
- ordered << [path, info]
293
- elsif not processed.include? epath
294
- ordered << [path, info]
295
- processed.add(epath)
296
- end
297
- end
298
-
299
- ordered
300
- end
301
-
302
- end