cf 0.1.5 → 0.6.0.rc1

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 (140) hide show
  1. data/LICENSE +1277 -30
  2. data/Rakefile +12 -1
  3. data/bin/cf +0 -3
  4. data/lib/cf.rb +6 -0
  5. data/lib/cf/cli.rb +389 -190
  6. data/lib/cf/cli/app/app.rb +45 -0
  7. data/lib/cf/cli/app/apps.rb +99 -0
  8. data/lib/cf/cli/app/base.rb +90 -0
  9. data/lib/cf/cli/app/crashes.rb +42 -0
  10. data/lib/cf/cli/app/delete.rb +95 -0
  11. data/lib/cf/cli/app/deprecated.rb +11 -0
  12. data/lib/cf/cli/app/env.rb +78 -0
  13. data/lib/cf/cli/app/files.rb +137 -0
  14. data/lib/cf/cli/app/health.rb +26 -0
  15. data/lib/cf/cli/app/instances.rb +53 -0
  16. data/lib/cf/cli/app/logs.rb +76 -0
  17. data/lib/cf/cli/app/push.rb +105 -0
  18. data/lib/cf/cli/app/push/create.rb +149 -0
  19. data/lib/cf/cli/app/push/interactions.rb +94 -0
  20. data/lib/cf/cli/app/push/sync.rb +64 -0
  21. data/lib/cf/cli/app/rename.rb +35 -0
  22. data/lib/cf/cli/app/restart.rb +20 -0
  23. data/lib/cf/cli/app/scale.rb +69 -0
  24. data/lib/cf/cli/app/start.rb +143 -0
  25. data/lib/cf/cli/app/stats.rb +67 -0
  26. data/lib/cf/cli/app/stop.rb +27 -0
  27. data/lib/cf/cli/domain/base.rb +8 -0
  28. data/lib/cf/cli/domain/domains.rb +40 -0
  29. data/lib/cf/cli/domain/map.rb +55 -0
  30. data/lib/cf/cli/domain/unmap.rb +56 -0
  31. data/lib/cf/cli/help.rb +15 -0
  32. data/lib/cf/cli/interactive.rb +105 -0
  33. data/lib/cf/cli/organization/base.rb +12 -0
  34. data/lib/cf/cli/organization/create.rb +32 -0
  35. data/lib/cf/cli/organization/delete.rb +73 -0
  36. data/lib/cf/cli/organization/org.rb +45 -0
  37. data/lib/cf/cli/organization/orgs.rb +35 -0
  38. data/lib/cf/cli/organization/rename.rb +36 -0
  39. data/lib/cf/cli/route/base.rb +8 -0
  40. data/lib/cf/cli/route/map.rb +70 -0
  41. data/lib/cf/cli/route/routes.rb +26 -0
  42. data/lib/cf/cli/route/unmap.rb +62 -0
  43. data/lib/cf/cli/service/base.rb +8 -0
  44. data/lib/cf/cli/service/bind.rb +44 -0
  45. data/lib/cf/cli/service/create.rb +107 -0
  46. data/lib/cf/cli/service/delete.rb +82 -0
  47. data/lib/cf/cli/service/rename.rb +35 -0
  48. data/lib/cf/cli/service/service.rb +40 -0
  49. data/lib/cf/cli/service/services.rb +99 -0
  50. data/lib/cf/cli/service/unbind.rb +38 -0
  51. data/lib/cf/cli/space/base.rb +19 -0
  52. data/lib/cf/cli/space/create.rb +63 -0
  53. data/lib/cf/cli/space/delete.rb +95 -0
  54. data/lib/cf/cli/space/rename.rb +39 -0
  55. data/lib/cf/cli/space/space.rb +64 -0
  56. data/lib/cf/cli/space/spaces.rb +55 -0
  57. data/lib/cf/cli/space/switch.rb +16 -0
  58. data/lib/cf/cli/start/base.rb +93 -0
  59. data/lib/cf/cli/start/colors.rb +13 -0
  60. data/lib/cf/cli/start/info.rb +124 -0
  61. data/lib/cf/cli/start/login.rb +94 -0
  62. data/lib/cf/cli/start/logout.rb +17 -0
  63. data/lib/cf/cli/start/target.rb +69 -0
  64. data/lib/cf/cli/start/target_interactions.rb +37 -0
  65. data/lib/cf/cli/start/targets.rb +16 -0
  66. data/lib/cf/cli/user/base.rb +29 -0
  67. data/lib/cf/cli/user/create.rb +39 -0
  68. data/lib/cf/cli/user/passwd.rb +43 -0
  69. data/lib/cf/cli/user/register.rb +42 -0
  70. data/lib/cf/cli/user/users.rb +32 -0
  71. data/lib/cf/constants.rb +10 -7
  72. data/lib/cf/detect.rb +113 -48
  73. data/lib/cf/errors.rb +17 -0
  74. data/lib/cf/plugin.rb +28 -12
  75. data/lib/cf/spacing.rb +89 -0
  76. data/lib/cf/spec_helper.rb +1 -0
  77. data/lib/cf/test_support.rb +6 -0
  78. data/lib/cf/version.rb +1 -1
  79. data/spec/assets/hello-sinatra/Gemfile +3 -0
  80. data/spec/assets/hello-sinatra/Gemfile.lock +17 -0
  81. data/spec/assets/hello-sinatra/config.ru +3 -0
  82. data/spec/assets/hello-sinatra/fat-cat-makes-app-larger.png +0 -0
  83. data/spec/assets/hello-sinatra/main.rb +6 -0
  84. data/spec/assets/specker_runner/specker_runner_input.rb +6 -0
  85. data/spec/assets/specker_runner/specker_runner_pause.rb +5 -0
  86. data/spec/cf/cli/app/base_spec.rb +17 -0
  87. data/spec/cf/cli/app/delete_spec.rb +188 -0
  88. data/spec/cf/cli/app/instances_spec.rb +65 -0
  89. data/spec/cf/cli/app/push/create_spec.rb +661 -0
  90. data/spec/cf/cli/app/push_spec.rb +369 -0
  91. data/spec/cf/cli/app/rename_spec.rb +104 -0
  92. data/spec/cf/cli/app/scale_spec.rb +75 -0
  93. data/spec/cf/cli/app/start_spec.rb +208 -0
  94. data/spec/cf/cli/app/stats_spec.rb +68 -0
  95. data/spec/cf/cli/domain/map_spec.rb +130 -0
  96. data/spec/cf/cli/domain/unmap_spec.rb +69 -0
  97. data/spec/cf/cli/organization/orgs_spec.rb +108 -0
  98. data/spec/cf/cli/organization/rename_spec.rb +113 -0
  99. data/spec/cf/cli/route/map_spec.rb +121 -0
  100. data/spec/cf/cli/route/unmap_spec.rb +155 -0
  101. data/spec/cf/cli/service/bind_spec.rb +25 -0
  102. data/spec/cf/cli/service/delete_spec.rb +22 -0
  103. data/spec/cf/cli/service/rename_spec.rb +105 -0
  104. data/spec/cf/cli/service/service_spec.rb +23 -0
  105. data/spec/cf/cli/service/unbind_spec.rb +25 -0
  106. data/spec/cf/cli/space/create_spec.rb +93 -0
  107. data/spec/cf/cli/space/rename_spec.rb +102 -0
  108. data/spec/cf/cli/space/spaces_spec.rb +104 -0
  109. data/spec/cf/cli/space/switch_space_spec.rb +55 -0
  110. data/spec/cf/cli/start/info_spec.rb +160 -0
  111. data/spec/cf/cli/start/login_spec.rb +142 -0
  112. data/spec/cf/cli/start/logout_spec.rb +50 -0
  113. data/spec/cf/cli/start/target_spec.rb +123 -0
  114. data/spec/cf/cli/user/create_spec.rb +54 -0
  115. data/spec/cf/cli/user/passwd_spec.rb +102 -0
  116. data/spec/cf/cli/user/register_spec.rb +140 -0
  117. data/spec/cf/cli_spec.rb +442 -0
  118. data/spec/cf/detect_spec.rb +54 -0
  119. data/spec/console_app_specker/console_app_specker_matchers_spec.rb +173 -0
  120. data/spec/console_app_specker/specker_runner_spec.rb +167 -0
  121. data/spec/features/account_lifecycle_spec.rb +85 -0
  122. data/spec/features/login_spec.rb +66 -0
  123. data/spec/features/push_flow_spec.rb +125 -0
  124. data/spec/features/switching_targets_spec.rb +32 -0
  125. data/spec/spec_helper.rb +72 -0
  126. data/spec/support/command_helper.rb +81 -0
  127. data/spec/support/config_helper.rb +15 -0
  128. data/spec/support/console_app_specker_matchers.rb +86 -0
  129. data/spec/support/fake_home_dir.rb +55 -0
  130. data/spec/support/interact_helper.rb +29 -0
  131. data/spec/support/shared_examples/errors.rb +40 -0
  132. data/spec/support/shared_examples/input.rb +14 -0
  133. data/spec/support/specker_runner.rb +80 -0
  134. data/spec/support/tracking_expector.rb +71 -0
  135. metadata +427 -66
  136. data/lib/cf/cli/app.rb +0 -595
  137. data/lib/cf/cli/command.rb +0 -444
  138. data/lib/cf/cli/dots.rb +0 -133
  139. data/lib/cf/cli/service.rb +0 -112
  140. data/lib/cf/cli/user.rb +0 -71
@@ -1,444 +0,0 @@
1
- require "thor"
2
- require "interact"
3
- require "yaml"
4
-
5
- require "cfoundry"
6
-
7
- require "cf/constants"
8
- require "cf/cli/dots"
9
-
10
-
11
- module CF
12
- module Interactive
13
- include ::Interactive::Rewindable
14
- include Dots
15
-
16
- class InteractiveDefault
17
- def initialize(query)
18
- @query = query
19
- end
20
-
21
- def to_s
22
- "(interaction)"
23
- end
24
-
25
- def to_proc
26
- @query
27
- end
28
- end
29
-
30
- def force?
31
- false
32
- end
33
-
34
- def ask(question, options = {})
35
- if force? and options.key?(:default)
36
- options[:default]
37
- else
38
- super
39
- end
40
- end
41
-
42
- def list_choices(choices, options)
43
- choices.each_with_index do |o, i|
44
- puts "#{c(i + 1, :green)}: #{o}"
45
- end
46
- end
47
-
48
- def input_state(options)
49
- CFState.new(options)
50
- end
51
-
52
- def prompt(question, options)
53
- value =
54
- case options[:default]
55
- when true
56
- "y"
57
- when false
58
- "n"
59
- when nil
60
- ""
61
- else
62
- options[:default].to_s
63
- end
64
-
65
- print "#{question}"
66
- print c("> ", :blue)
67
-
68
- unless value.empty?
69
- print "#{c(value, :black) + "\b" * value.size}"
70
- end
71
- end
72
-
73
- def handler(which, state)
74
- ans = state.answer
75
- pos = state.position
76
-
77
- if state.default?
78
- if which.is_a?(Array) and which[0] == :key
79
- # initial non-movement keypress clears default answer
80
- clear_input(state)
81
- else
82
- # wipe away any coloring
83
- redraw_input(state)
84
- end
85
-
86
- state.clear_default!
87
- end
88
-
89
- super
90
-
91
- print "\n" if which == :enter
92
- end
93
-
94
- class CFState < Interactive::InputState
95
- def initialize(options = {}, answer = nil, position = 0)
96
- @options = options
97
-
98
- if answer
99
- @answer = answer
100
- elsif options[:default]
101
- case options[:default]
102
- when true
103
- @answer = "y"
104
- when false
105
- @answer = "n"
106
- else
107
- @answer = options[:default].to_s
108
- end
109
-
110
- @default = true
111
- else
112
- @answer = ""
113
- end
114
-
115
- @position = position
116
- @done = false
117
- end
118
-
119
- def clear_default!
120
- @default = false
121
- end
122
-
123
- def default?
124
- @default
125
- end
126
- end
127
- end
128
-
129
- class Command < Thor
130
- include Interactive
131
-
132
- def self.flag(name, options = {}, &query)
133
- if query
134
- options[:default] ||= InteractiveDefault.new(query)
135
- end
136
-
137
- method_option(name, options)
138
- end
139
-
140
- def self.callbacks_for(name)
141
- cs = callbacks[name]
142
- if superclass.respond_to? :callbacks
143
- cs.merge superclass.callbacks_for(name)
144
- else
145
- cs
146
- end
147
- end
148
-
149
- def self.callbacks
150
- @callbacks ||= Hash.new do |h, name|
151
- h[name] = Hash.new do |h, task|
152
- h[task] = []
153
- end
154
- end
155
- end
156
-
157
- def self.add_callback(name, task, callback)
158
- callbacks[name][task] << callback
159
- end
160
-
161
- def self.before(task, &callback)
162
- add_callback(:before, task, callback)
163
- end
164
-
165
- def self.after(task, &callback)
166
- add_callback(:after, task, callback)
167
- end
168
-
169
- def self.ensuring(task, &callback)
170
- add_callback(:ensuring, task, callback)
171
- end
172
-
173
- def self.around(task, &callback)
174
- add_callback(:around, task, callback)
175
- end
176
-
177
- private
178
-
179
- def callbacks_for(what)
180
- self.class.callbacks_for(what)
181
- end
182
-
183
- def passed_value(flag)
184
- if (val = options[flag]) && \
185
- !val.is_a?(CF::Interactive::InteractiveDefault)
186
- val
187
- end
188
- end
189
-
190
- def input(name, *args)
191
- @inputs ||= {}
192
- return @inputs[name] if @inputs.key?(name)
193
-
194
- if options[name].respond_to? :to_proc
195
- @inputs[name] = instance_exec(*args, &options[name])
196
- else
197
- @inputs[name] = options[name]
198
- end
199
- end
200
-
201
- def forget(name)
202
- @inputs.delete name
203
- end
204
-
205
- def script?
206
- if options.key?("script")
207
- options["script"]
208
- else
209
- !$stdout.tty?
210
- end
211
- end
212
-
213
- def force?
214
- if options.key?("force")
215
- options["force"]
216
- else
217
- script?
218
- end
219
- end
220
-
221
- def simple_output?
222
- if options.key?("simple_output")
223
- options["simple_output"]
224
- else
225
- script?
226
- end
227
- end
228
-
229
- def color?
230
- if options.key?("color")
231
- options["color"]
232
- else
233
- !simple_output?
234
- end
235
- end
236
-
237
- def err(msg, exit_status = 1)
238
- if script?
239
- $stderr.puts(msg)
240
- else
241
- puts c(msg, :red)
242
- end
243
-
244
- $exit_status = 1
245
- end
246
-
247
- def invoke_task(task, args)
248
- callbacks_for(:before)[task.name.to_sym].each do |c|
249
- c.call
250
- end
251
-
252
- action = proc do |*new_args|
253
- if new_args.empty?
254
- task.run(self, args)
255
- elsif new_args.first.is_a? Array
256
- task.run(self, new_args.first)
257
- else
258
- task.run(self, new_args)
259
- end
260
- end
261
-
262
- callbacks_for(:around)[task.name.to_sym].each do |a|
263
- before = action
264
- action = proc do |passed_args|
265
- # with more than one wrapper, when the outer wrapper passes args to
266
- # inner wrapper, which calls the next inner with no args, it should
267
- # get the args passed to it by outer
268
- args = passed_args if passed_args
269
- instance_exec(before, args, &a)
270
- end
271
- end
272
-
273
- res = instance_exec(args, &action)
274
-
275
- callbacks_for(:after)[task.name.to_sym].each do |c|
276
- c.call
277
- end
278
-
279
- res
280
- rescue Interrupt
281
- $exit_status = 130
282
- rescue Thor::Error
283
- raise
284
- rescue Exception => e
285
- msg = e.class.name
286
- msg << ": #{e}" unless e.to_s.empty?
287
- err msg
288
-
289
- ensure_config_dir
290
-
291
- File.open(File.expand_path(CF::CRASH_FILE), "w") do |f|
292
- f.print "Time of crash:\n "
293
- f.puts Time.now
294
- f.puts ""
295
- f.puts msg
296
- f.puts ""
297
-
298
- e.backtrace.each do |loc|
299
- if loc =~ /\/gems\//
300
- f.puts loc.sub(/.*\/gems\//, "")
301
- else
302
- f.puts loc.sub(File.expand_path("../../../..", __FILE__) + "/", "")
303
- end
304
- end
305
- end
306
- ensure
307
- callbacks_for(:ensuring)[task.name.to_sym].each do |c|
308
- c.call
309
- end
310
- end
311
- public :invoke_task
312
-
313
- def sane_target_url(url)
314
- unless url =~ /^https?:\/\//
315
- url = "http://#{url}"
316
- end
317
-
318
- url.gsub(/\/$/, "")
319
- end
320
-
321
- def target_file
322
- one_of(CF::TARGET_FILE, CF::OLD_TARGET_FILE)
323
- end
324
-
325
- def tokens_file
326
- one_of(CF::TOKENS_FILE, CF::OLD_TOKENS_FILE)
327
- end
328
-
329
- def one_of(*paths)
330
- paths.each do |p|
331
- exp = File.expand_path(p)
332
- return exp if File.exist? exp
333
- end
334
-
335
- paths.first
336
- end
337
-
338
- def client_target
339
- File.read(target_file).chomp
340
- end
341
-
342
- def ensure_config_dir
343
- config = File.expand_path(CF::CONFIG_DIR)
344
- Dir.mkdir(config) unless File.exist? config
345
- end
346
-
347
- def set_target(url)
348
- ensure_config_dir
349
-
350
- File.open(File.expand_path(CF::TARGET_FILE), "w") do |f|
351
- f.write(sane_target_url(url))
352
- end
353
-
354
- @client = nil
355
- end
356
-
357
- def tokens
358
- new_toks = File.expand_path(CF::TOKENS_FILE)
359
- old_toks = File.expand_path(CF::OLD_TOKENS_FILE)
360
-
361
- if File.exist? new_toks
362
- YAML.load_file(new_toks)
363
- elsif File.exist? old_toks
364
- JSON.load(File.read(old_toks))
365
- else
366
- {}
367
- end
368
- end
369
-
370
- def client_token
371
- tokens[client_target]
372
- end
373
-
374
- def save_tokens(ts)
375
- ensure_config_dir
376
-
377
- File.open(File.expand_path(CF::TOKENS_FILE), "w") do |io|
378
- YAML.dump(ts, io)
379
- end
380
- end
381
-
382
- def save_token(token)
383
- ts = tokens
384
- ts[client_target] = token
385
- save_tokens(ts)
386
- end
387
-
388
- def remove_token
389
- ts = tokens
390
- ts.delete client_target
391
- save_tokens(ts)
392
- end
393
-
394
- def client
395
- return @client if @client
396
-
397
- @client = CFoundry::Client.new(client_target, client_token)
398
- @client.proxy = options[:proxy]
399
- @client
400
- end
401
-
402
- def usage(used, limit)
403
- "#{b(human_size(used))} of #{b(human_size(limit, 0))}"
404
- end
405
-
406
- def percentage(num, low = 50, mid = 70)
407
- color =
408
- if num <= low
409
- :green
410
- elsif num <= mid
411
- :yellow
412
- else
413
- :red
414
- end
415
-
416
- c(format("%.1f\%", num), color)
417
- end
418
-
419
- def megabytes(str)
420
- if str =~ /T$/i
421
- str.to_i * 1024 * 1024
422
- elsif str =~ /G$/i
423
- str.to_i * 1024
424
- elsif str =~ /M$/i
425
- str.to_i
426
- elsif str =~ /K$/i
427
- str.to_i / 1024
428
- end
429
- end
430
-
431
- def human_size(num, precision = 1)
432
- sizes = ["G", "M", "K"]
433
- sizes.each.with_index do |suf, i|
434
- pow = sizes.size - i
435
- unit = 1024 ** pow
436
- if num >= unit
437
- return format("%.#{precision}f%s", num / unit, suf)
438
- end
439
- end
440
-
441
- format("%.#{precision}fB", num)
442
- end
443
- end
444
- end
@@ -1,133 +0,0 @@
1
- module CF
2
- module Dots
3
- DOT_COUNT = 3
4
- DOT_TICK = 0.15
5
-
6
- class Skipper
7
- def initialize(&ret)
8
- @return = ret
9
- end
10
-
11
- def skip(&callback)
12
- @return.call("SKIPPED", :yellow, callback)
13
- end
14
-
15
- def give_up(&callback)
16
- @return.call("GAVE UP", :red, callback)
17
- end
18
-
19
- def fail(&callback)
20
- @return.call("FAILED", :red, callback)
21
- end
22
- end
23
-
24
- def with_progress(message)
25
- unless simple_output?
26
- print message
27
- dots!
28
- end
29
-
30
- skipper = Skipper.new do |status, color, callback|
31
- unless simple_output?
32
- stop_dots!
33
- puts "... #{c(status, color)}"
34
- end
35
-
36
- return callback && callback.call
37
- end
38
-
39
- begin
40
- res = yield skipper
41
- unless simple_output?
42
- stop_dots!
43
- puts "... #{c("OK", :green)}"
44
- end
45
- res
46
- rescue
47
- unless simple_output?
48
- stop_dots!
49
- puts "... #{c("FAILED", :red)}"
50
- end
51
-
52
- raise
53
- end
54
- end
55
-
56
- def color?
57
- $stdout.tty?
58
- end
59
-
60
- COLOR_CODES = {
61
- :black => 0,
62
- :red => 1,
63
- :green => 2,
64
- :yellow => 3,
65
- :blue => 4,
66
- :magenta => 5,
67
- :cyan => 6,
68
- :white => 7
69
- }
70
-
71
- # colored text
72
- #
73
- # shouldn't use bright colors, as some color themes abuse
74
- # the bright palette (I'm looking at you, Solarized)
75
- def c(str, color)
76
- return str unless color?
77
- "\e[3#{COLOR_CODES[color]}m#{str}\e[0m"
78
- end
79
- module_function :c
80
-
81
- # bold text
82
- def b(str)
83
- return str unless color?
84
- "\e[1m#{str}\e[0m"
85
- end
86
- module_function :b
87
-
88
- def dots!
89
- @dots ||=
90
- Thread.new do
91
- before_sync = $stdout.sync
92
-
93
- $stdout.sync = true
94
-
95
- printed = false
96
- i = 1
97
- until @stop_dots
98
- if printed
99
- print "\b" * DOT_COUNT
100
- end
101
-
102
- print ("." * i).ljust(DOT_COUNT)
103
- printed = true
104
-
105
- if i == DOT_COUNT
106
- i = 0
107
- else
108
- i += 1
109
- end
110
-
111
- sleep DOT_TICK
112
- end
113
-
114
- if printed
115
- print "\b" * DOT_COUNT
116
- print " " * DOT_COUNT
117
- print "\b" * DOT_COUNT
118
- end
119
-
120
- $stdout.sync = before_sync
121
- @stop_dots = nil
122
- end
123
- end
124
-
125
- def stop_dots!
126
- return unless @dots
127
- return if @stop_dots
128
- @stop_dots = true
129
- @dots.join
130
- @dots = nil
131
- end
132
- end
133
- end