cf_script 0.0.1.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/CHANGELOG.md +0 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE +22 -0
  6. data/README.md +84 -0
  7. data/Rakefile +33 -0
  8. data/cf_script.gemspec +34 -0
  9. data/lib/cf_script/callbacks.rb +43 -0
  10. data/lib/cf_script/command/base.rb +57 -0
  11. data/lib/cf_script/command/cf/apps/app.rb +19 -0
  12. data/lib/cf_script/command/cf/apps/apps.rb +44 -0
  13. data/lib/cf_script/command/cf/apps/env.rb +20 -0
  14. data/lib/cf_script/command/cf/apps/push.rb +47 -0
  15. data/lib/cf_script/command/cf/apps/restage.rb +19 -0
  16. data/lib/cf_script/command/cf/apps/restart.rb +19 -0
  17. data/lib/cf_script/command/cf/apps/set_env.rb +18 -0
  18. data/lib/cf_script/command/cf/apps/start.rb +19 -0
  19. data/lib/cf_script/command/cf/apps/stop.rb +19 -0
  20. data/lib/cf_script/command/cf/apps/unset_env.rb +18 -0
  21. data/lib/cf_script/command/cf/apps.rb +55 -0
  22. data/lib/cf_script/command/cf/general/api.rb +36 -0
  23. data/lib/cf_script/command/cf/general/auth.rb +28 -0
  24. data/lib/cf_script/command/cf/general/login.rb +42 -0
  25. data/lib/cf_script/command/cf/general/logout.rb +15 -0
  26. data/lib/cf_script/command/cf/general/target.rb +64 -0
  27. data/lib/cf_script/command/cf/general.rb +15 -0
  28. data/lib/cf_script/command/cf/routes/check_route.rb +17 -0
  29. data/lib/cf_script/command/cf/routes/create_route.rb +19 -0
  30. data/lib/cf_script/command/cf/routes/delete_route.rb +19 -0
  31. data/lib/cf_script/command/cf/routes/map_route.rb +30 -0
  32. data/lib/cf_script/command/cf/routes/routes.rb +40 -0
  33. data/lib/cf_script/command/cf/routes/unmap_route.rb +30 -0
  34. data/lib/cf_script/command/cf/routes.rb +17 -0
  35. data/lib/cf_script/command/cf/spaces/space.rb +36 -0
  36. data/lib/cf_script/command/cf/spaces/spaces.rb +23 -0
  37. data/lib/cf_script/command/cf/spaces.rb +9 -0
  38. data/lib/cf_script/command/error.rb +5 -0
  39. data/lib/cf_script/command/line.rb +105 -0
  40. data/lib/cf_script/command/registry.rb +50 -0
  41. data/lib/cf_script/command/runner.rb +97 -0
  42. data/lib/cf_script/command.rb +44 -0
  43. data/lib/cf_script/config.rb +60 -0
  44. data/lib/cf_script/executor/non_blocking.rb +107 -0
  45. data/lib/cf_script/executor/recorder.rb +16 -0
  46. data/lib/cf_script/executor/simple.rb +17 -0
  47. data/lib/cf_script/executor.rb +5 -0
  48. data/lib/cf_script/manifest.rb +38 -0
  49. data/lib/cf_script/object/api_endpoint.rb +10 -0
  50. data/lib/cf_script/object/app_info.rb +69 -0
  51. data/lib/cf_script/object/app_list.rb +24 -0
  52. data/lib/cf_script/object/app_spec.rb +55 -0
  53. data/lib/cf_script/object/attribute.rb +18 -0
  54. data/lib/cf_script/object/attribute_list.rb +40 -0
  55. data/lib/cf_script/object/instance_status.rb +29 -0
  56. data/lib/cf_script/object/route_info.rb +14 -0
  57. data/lib/cf_script/object/space.rb +17 -0
  58. data/lib/cf_script/object/target.rb +23 -0
  59. data/lib/cf_script/object.rb +24 -0
  60. data/lib/cf_script/output/buffer.rb +74 -0
  61. data/lib/cf_script/output/parser/attributes.rb +44 -0
  62. data/lib/cf_script/output/parser/section.rb +15 -0
  63. data/lib/cf_script/output/parser/table.rb +46 -0
  64. data/lib/cf_script/output/parser.rb +15 -0
  65. data/lib/cf_script/output/tests.rb +51 -0
  66. data/lib/cf_script/output/utils.rb +13 -0
  67. data/lib/cf_script/output.rb +62 -0
  68. data/lib/cf_script/scope/app/env.rb +15 -0
  69. data/lib/cf_script/scope/app/routes.rb +21 -0
  70. data/lib/cf_script/scope/app/state.rb +33 -0
  71. data/lib/cf_script/scope/app/utils.rb +32 -0
  72. data/lib/cf_script/scope/app.rb +94 -0
  73. data/lib/cf_script/scope/proxy.rb +36 -0
  74. data/lib/cf_script/scope/script.rb +59 -0
  75. data/lib/cf_script/scope/space.rb +9 -0
  76. data/lib/cf_script/scope/target.rb +90 -0
  77. data/lib/cf_script/scope.rb +68 -0
  78. data/lib/cf_script/ui.rb +261 -0
  79. data/lib/cf_script/utils.rb +19 -0
  80. data/lib/cf_script/version.rb +3 -0
  81. data/lib/cf_script.rb +105 -0
  82. data/test/fixtures/commands/apps/app/good.yml +18 -0
  83. data/test/fixtures/commands/apps/app/not_found.yml +8 -0
  84. data/test/fixtures/commands/apps/app/running.yml +19 -0
  85. data/test/fixtures/commands/apps/apps/good.yml +14 -0
  86. data/test/fixtures/commands/apps/apps/no_apps.yml +10 -0
  87. data/test/fixtures/commands/apps/env/empty.yml +37 -0
  88. data/test/fixtures/commands/apps/env/good.yml +41 -0
  89. data/test/fixtures/commands/apps/push/good.yml +60 -0
  90. data/test/fixtures/commands/apps/restage/good.yml +48 -0
  91. data/test/fixtures/commands/apps/restage/not_found.yml +8 -0
  92. data/test/fixtures/commands/apps/restart/good.yml +35 -0
  93. data/test/fixtures/commands/apps/restart/not_found.yml +8 -0
  94. data/test/fixtures/commands/apps/set_env/empty.yml +5 -0
  95. data/test/fixtures/commands/apps/set_env/good.yml +9 -0
  96. data/test/fixtures/commands/apps/set_env/not_found.yml +8 -0
  97. data/test/fixtures/commands/apps/start/good.yml +32 -0
  98. data/test/fixtures/commands/apps/start/not_found.yml +8 -0
  99. data/test/fixtures/commands/apps/start/with_container.yml +98 -0
  100. data/test/fixtures/commands/apps/stop/good.yml +8 -0
  101. data/test/fixtures/commands/apps/stop/not_found.yml +8 -0
  102. data/test/fixtures/commands/apps/unset_env/empty.yml +5 -0
  103. data/test/fixtures/commands/apps/unset_env/good.yml +9 -0
  104. data/test/fixtures/commands/apps/unset_env/not_found.yml +8 -0
  105. data/test/fixtures/commands/common/fail.yml +5 -0
  106. data/test/fixtures/commands/common/no_endpoint.yml +11 -0
  107. data/test/fixtures/commands/common/no_login.yml +8 -0
  108. data/test/fixtures/commands/general/api/bad_argument.yml +9 -0
  109. data/test/fixtures/commands/general/api/bad_endpoint.yml +9 -0
  110. data/test/fixtures/commands/general/api/good.yml +7 -0
  111. data/test/fixtures/commands/general/api/not_set.yml +7 -0
  112. data/test/fixtures/commands/general/api/set.yml +7 -0
  113. data/test/fixtures/commands/general/auth/empty.yml +5 -0
  114. data/test/fixtures/commands/general/auth/good.yml +10 -0
  115. data/test/fixtures/commands/general/auth/rejected.yml +10 -0
  116. data/test/fixtures/commands/general/login/good.yml +8 -0
  117. data/test/fixtures/commands/general/login/rejected.yml +23 -0
  118. data/test/fixtures/commands/general/logout/good.yml +8 -0
  119. data/test/fixtures/commands/general/target/empty.yml +5 -0
  120. data/test/fixtures/commands/general/target/good.yml +11 -0
  121. data/test/fixtures/commands/general/target/no_space.yml +10 -0
  122. data/test/fixtures/commands/general/target/not_found.yml +9 -0
  123. data/test/fixtures/commands/general/target/production.yml +11 -0
  124. data/test/fixtures/commands/general/target/staging.yml +11 -0
  125. data/test/fixtures/commands/general/target/staging_org.yml +11 -0
  126. data/test/fixtures/commands/general/target/test.yml +11 -0
  127. data/test/fixtures/commands/routes/check_route/good.yml +9 -0
  128. data/test/fixtures/commands/routes/check_route/no_domain.yml +9 -0
  129. data/test/fixtures/commands/routes/check_route/no_route.yml +9 -0
  130. data/test/fixtures/commands/routes/create_route/exists.yml +9 -0
  131. data/test/fixtures/commands/routes/create_route/good.yml +8 -0
  132. data/test/fixtures/commands/routes/delete_route/good.yml +8 -0
  133. data/test/fixtures/commands/routes/delete_route/not_exist.yml +8 -0
  134. data/test/fixtures/commands/routes/map_route/good.yml +10 -0
  135. data/test/fixtures/commands/routes/map_route/host_taken.yml +10 -0
  136. data/test/fixtures/commands/routes/map_route/invalid.yml +9 -0
  137. data/test/fixtures/commands/routes/map_route/no_app.yml +8 -0
  138. data/test/fixtures/commands/routes/map_route/no_domain.yml +9 -0
  139. data/test/fixtures/commands/routes/routes/good.yml +14 -0
  140. data/test/fixtures/commands/routes/unmap_route/good.yml +8 -0
  141. data/test/fixtures/commands/routes/unmap_route/no_app.yml +8 -0
  142. data/test/fixtures/commands/routes/unmap_route/no_domain.yml +9 -0
  143. data/test/fixtures/commands/spaces/space/empty.yml +5 -0
  144. data/test/fixtures/commands/spaces/space/good.yml +16 -0
  145. data/test/fixtures/commands/spaces/space/staging.yml +16 -0
  146. data/test/fixtures/commands/spaces/spaces/empty.yml +5 -0
  147. data/test/fixtures/commands/spaces/spaces/good.yml +12 -0
  148. data/test/lib/cf_script/command/base_test.rb +21 -0
  149. data/test/lib/cf_script/command/cf/apps/app_test.rb +56 -0
  150. data/test/lib/cf_script/command/cf/apps/apps_test.rb +81 -0
  151. data/test/lib/cf_script/command/cf/apps/env_test.rb +55 -0
  152. data/test/lib/cf_script/command/cf/apps/push_test.rb +46 -0
  153. data/test/lib/cf_script/command/cf/apps/restage_test.rb +47 -0
  154. data/test/lib/cf_script/command/cf/apps/restart_test.rb +47 -0
  155. data/test/lib/cf_script/command/cf/apps/set_env_test.rb +38 -0
  156. data/test/lib/cf_script/command/cf/apps/start_test.rb +55 -0
  157. data/test/lib/cf_script/command/cf/apps/stop_test.rb +35 -0
  158. data/test/lib/cf_script/command/cf/apps/unset_env_test.rb +38 -0
  159. data/test/lib/cf_script/command/cf/general/api_test.rb +55 -0
  160. data/test/lib/cf_script/command/cf/general/auth_test.rb +76 -0
  161. data/test/lib/cf_script/command/cf/general/login_test.rb +80 -0
  162. data/test/lib/cf_script/command/cf/general/logout_test.rb +34 -0
  163. data/test/lib/cf_script/command/cf/general/target_test.rb +110 -0
  164. data/test/lib/cf_script/command/cf/routes/check_route_test.rb +31 -0
  165. data/test/lib/cf_script/command/cf/routes/create_route_test.rb +19 -0
  166. data/test/lib/cf_script/command/cf/routes/delete_route_test.rb +19 -0
  167. data/test/lib/cf_script/command/cf/routes/map_route_test.rb +56 -0
  168. data/test/lib/cf_script/command/cf/routes/routes_test.rb +24 -0
  169. data/test/lib/cf_script/command/cf/routes/unmap_route_test.rb +36 -0
  170. data/test/lib/cf_script/command/cf/spaces/space_test.rb +55 -0
  171. data/test/lib/cf_script/command/cf/spaces/spaces_test.rb +47 -0
  172. data/test/lib/cf_script/command/line_test.rb +59 -0
  173. data/test/lib/cf_script/object/api_endpoint_test.rb +19 -0
  174. data/test/lib/cf_script/object/app_info_test.rb +127 -0
  175. data/test/lib/cf_script/object/app_list_test.rb +51 -0
  176. data/test/lib/cf_script/object/attribute_list_test.rb +42 -0
  177. data/test/lib/cf_script/object/attribute_test.rb +29 -0
  178. data/test/lib/cf_script/object/instance_status_test.rb +37 -0
  179. data/test/lib/cf_script/object/space_test.rb +31 -0
  180. data/test/lib/cf_script/object/target_test.rb +41 -0
  181. data/test/lib/cf_script/output/buffer_test.rb +73 -0
  182. data/test/lib/cf_script/output/parser/attributes_test.rb +102 -0
  183. data/test/lib/cf_script/output/parser/section_test.rb +60 -0
  184. data/test/lib/cf_script/output/parser/table_test.rb +108 -0
  185. data/test/lib/cf_script/output/tests_test.rb +91 -0
  186. data/test/lib/cf_script/output_test.rb +134 -0
  187. data/test/lib/cf_script/scope/app/state_test.rb +61 -0
  188. data/test/lib/cf_script/scope/app_test.rb +101 -0
  189. data/test/lib/cf_script/scope/script_test.rb +88 -0
  190. data/test/lib/cf_script/scope/space_test.rb +27 -0
  191. data/test/lib/cf_script/scope/target_test.rb +158 -0
  192. data/test/lib/cf_script/scope_test.rb +41 -0
  193. data/test/lib/cf_script/utils_test.rb +20 -0
  194. data/test/lib/cf_script_test.rb +73 -0
  195. data/test/support/assertions.rb +14 -0
  196. data/test/support/helpers/config_context.rb +19 -0
  197. data/test/support/helpers/fixture_executor.rb +79 -0
  198. data/test/support/helpers/mock_execution.rb +58 -0
  199. data/test/support/helpers/object_helpers.rb +29 -0
  200. data/test/support/helpers/output_sink.rb +25 -0
  201. data/test/support/helpers.rb +3 -0
  202. data/test/support/shared_examples/command_object.rb +38 -0
  203. data/test/support/shared_examples.rb +30 -0
  204. data/test/test_helper.rb +34 -0
  205. metadata +321 -0
@@ -0,0 +1,44 @@
1
+ module CfScript::Command
2
+ # TODO: decide which is better, @_registry or @@_registry
3
+ class << self
4
+ attr_reader :_registry
5
+ end
6
+
7
+ extend CfScript::UI
8
+
9
+ module_function
10
+
11
+ def registry
12
+ @_registry ||= Registry.new
13
+ end
14
+
15
+ def register(command_class)
16
+ registry.add!(command_class)
17
+ end
18
+
19
+ def run(command_name, *args, &block)
20
+ registry.check!(command_name)
21
+
22
+ begin
23
+ registry[command_name].run(*args, &block)
24
+ rescue StandardError => e
25
+ error command_name, e.message
26
+ end
27
+ end
28
+
29
+ def method_missing(m, *args, &block)
30
+ run(m, *args, &block)
31
+ end
32
+ end
33
+
34
+ require 'cf_script/command/registry'
35
+ require 'cf_script/command/runner'
36
+
37
+ require 'cf_script/command/base'
38
+ require 'cf_script/command/error'
39
+ require 'cf_script/command/line'
40
+
41
+ require 'cf_script/command/cf/general'
42
+ require 'cf_script/command/cf/apps'
43
+ require 'cf_script/command/cf/spaces'
44
+ require 'cf_script/command/cf/routes'
@@ -0,0 +1,60 @@
1
+ class CfScript::Config
2
+ attr_reader :io
3
+ attr_reader :ui
4
+ attr_reader :runtime
5
+
6
+ def initialize
7
+ @io = CfScript::Config::IO.new
8
+ @ui = CfScript::Config::UI.new
9
+
10
+ @runtime = CfScript::Config::Runtime.new
11
+ end
12
+
13
+ class IO
14
+ attr_accessor :stdout
15
+ attr_accessor :stderr
16
+
17
+ def initialize
18
+ @stdout = $stdout
19
+ @stderr = $stderr
20
+ end
21
+ end
22
+
23
+ class UI
24
+ attr_accessor :tags
25
+ attr_accessor :emoji
26
+ attr_reader :color # Special case for String.disable_colorization
27
+
28
+ def initialize
29
+ @tags = true
30
+ @emoji = false
31
+ @color = true
32
+ end
33
+
34
+ def color=(state)
35
+ @color = state
36
+
37
+ if String.respond_to?(:disable_colorization)
38
+ String.disable_colorization = @color ? false : true
39
+ end
40
+ end
41
+ end
42
+
43
+ class Runtime
44
+ attr_accessor :trace
45
+ attr_accessor :color
46
+
47
+ attr_accessor :executor
48
+
49
+ def initialize
50
+ @trace = ENV['TRACE'] || false
51
+ @color = true
52
+
53
+ @executor = ENV['NON_BLOCKING_EXECUTOR'] ? CfScript::Executor::NonBlocking.new : default_executor
54
+ end
55
+
56
+ def default_executor
57
+ CfScript::Executor::Simple.new
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,107 @@
1
+ require 'open3'
2
+
3
+ class CfScript::Executor::NonBlocking
4
+ include CfScript::UI
5
+
6
+ READ_SIZE = 1024
7
+
8
+ PROGRESS_CHARS = ['|', '/', '-', '\\']
9
+
10
+ def initialize
11
+ @executions = 0
12
+ @spin_count = 0
13
+ end
14
+
15
+ def execute(env, command_line)
16
+ @spin_count = 0
17
+ @executions += 1
18
+
19
+ print " ... "
20
+ stdout, stderr, status = execute_internal(env, command_line)
21
+
22
+ report_exit(status.exitstatus == 0 ? :success : :error)
23
+
24
+ [stdout, stderr, status]
25
+ end
26
+
27
+ def spin
28
+ char = PROGRESS_CHARS[(@spin_count += 1) % PROGRESS_CHARS.length]
29
+
30
+ print "\b#{char}".colorize(with_color_of(:step))
31
+ end
32
+
33
+ def got(c = '@')
34
+ print "\b#{c}".colorize(with_color_of(:info))
35
+ end
36
+
37
+ def report_exit(type)
38
+ icon = "#{emoji_for(type)} "
39
+ text = case type
40
+ when :success
41
+ CfScript.config.ui.emoji ? icon : 'DONE '
42
+ else
43
+ CfScript.config.ui.emoji ? icon : 'ERROR'
44
+ end
45
+
46
+ puts "\b\b\b\b\b#{text}".colorize(with_color_of(type))
47
+ end
48
+
49
+ def execute_internal(env, command_line)
50
+ out_stdout = ''
51
+ out_stderr = ''
52
+ out_status = nil
53
+
54
+ Open3.popen3(env, command_line.to_s) do |stdin, stdout, stderr, wait|
55
+ stdin.close_write
56
+
57
+ begin
58
+ streams = [stdout, stderr]
59
+
60
+ #until streams.empty? do
61
+ loop do
62
+ ready = IO.select(streams, [], [], 0.1)
63
+ spin
64
+
65
+ if ready
66
+ readable = ready[0]
67
+
68
+ readable.each do |stream|
69
+ fileno = stream.fileno
70
+
71
+ begin
72
+ data = stream.read_nonblock(READ_SIZE)
73
+
74
+ if fileno == stdout.fileno
75
+ got ; out_stdout << data
76
+ elsif fileno == stderr.fileno
77
+ got ; out_stderr << data
78
+ else
79
+ fileno_error(fileno, stdin, stdout, stderr)
80
+ end
81
+ rescue EOFError => e
82
+ # puts "EOF-ERROR".colorize(with_color_of(:error))
83
+ # streams.delete(stream)
84
+ end
85
+ end
86
+ end
87
+
88
+ break if stdout.eof? && stderr.eof?
89
+ end
90
+
91
+ out_status = wait.value
92
+ rescue IOError => e
93
+ puts "IOError: #{e}"
94
+ end
95
+ end
96
+
97
+ [out_stdout, out_stderr, out_status]
98
+ end
99
+
100
+ def fileno_error(fileno, stdin, stdout, stderr)
101
+ puts "ERROR: unexpected fileno: #{fileno} [" +
102
+ "stdin: #{stdin.fileno}, " +
103
+ "stdout: #{stdout.fileno}, " +
104
+ "stderr: #{stderr.fileno}" +
105
+ "]"
106
+ end
107
+ end
@@ -0,0 +1,16 @@
1
+ class CfScript::Executor::Recorder
2
+ def initialize(executor = nil)
3
+ @executions = []
4
+ @executor = executor || CfScript::Executor::Simple.new
5
+ end
6
+
7
+ def execute(env, command_line)
8
+ @executions << command_line
9
+
10
+ @executor.execute(env, command_line)
11
+ end
12
+
13
+ def dump
14
+ puts @executions.join("\n")
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ require 'open3'
2
+
3
+ class CfScript::Executor::Simple
4
+ def initialize
5
+ @executions = 0
6
+ end
7
+
8
+ def execute(env, command_line)
9
+ @executions += 1
10
+
11
+ out, err, status = Open3.capture3(env, command_line.to_s)
12
+
13
+ puts if CfScript.config.runtime.trace
14
+
15
+ [out, err, status]
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ CfScript.const_set(:Executor, Module.new)
2
+
3
+ require 'cf_script/executor/recorder'
4
+ require 'cf_script/executor/simple'
5
+ require 'cf_script/executor/non_blocking'
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ class CfScript::Manifest
6
+ attr_reader :filename
7
+ attr_reader :applications
8
+
9
+ include CfScript::Utils
10
+
11
+ FILENAME = 'manifest.yml'
12
+
13
+ def initialize(filename = FILENAME)
14
+ @filename = filename
15
+
16
+ @applications = load_file
17
+ end
18
+
19
+ def each
20
+ applications.each do |app|
21
+ yield app
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def load_file
28
+ data = if File.exist?(filename)
29
+ YAML.load(File.open(filename))
30
+ else
31
+ { 'applications' => [] }
32
+ end
33
+
34
+ data['applications'].map do |app|
35
+ OpenStruct.new(symbolize_keys(app))
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,10 @@
1
+ class CfScript::ApiEndpoint < CfScript::Object
2
+ attr_reader :url
3
+ attr_reader :version
4
+
5
+ def initialize(url = nil, version = nil)
6
+ @url = url
7
+ @version = version
8
+ end
9
+ end
10
+
@@ -0,0 +1,69 @@
1
+ class CfScript::AppInfo < CfScript::Object
2
+ # These are always available
3
+ attr_reader :name
4
+ attr_reader :requested_state
5
+ attr_reader :instances
6
+ attr_reader :urls
7
+
8
+ # These are available from `cf app` only
9
+ attr_reader :usage
10
+ attr_reader :last_uploaded
11
+ attr_reader :stack
12
+ attr_reader :buildpack
13
+
14
+ # These are available from `cf apps` only
15
+ attr_reader :memory # patched from :usage
16
+ attr_reader :disk
17
+
18
+ # This gets set after some commands, like push and start
19
+ attr_reader :instance_status
20
+
21
+ def initialize(name, attrs)
22
+ @name = name
23
+
24
+ update(attrs)
25
+ end
26
+
27
+ def state
28
+ requested_state
29
+ end
30
+
31
+ def started?
32
+ state == 'started'
33
+ end
34
+
35
+ alias :hot? :started?
36
+
37
+ def stopped?
38
+ state == 'stopped'
39
+ end
40
+
41
+ alias :cold? :stopped?
42
+
43
+ def update(attrs)
44
+ @requested_state = attrs[:requested_state].value if attrs.key?(:requested_state)
45
+ @instances = attrs[:instances].value if attrs.key?(:instances)
46
+
47
+ @urls = attrs.key?(:urls) ? attrs[:urls].to_a : []
48
+
49
+ @usage = attrs[:usage].value if attrs.key?(:usage)
50
+ @last_uploaded = attrs[:last_uploaded].value if attrs.key?(:last_uploaded)
51
+ @stack = attrs[:stack].value if attrs.key?(:stack)
52
+ @buildpack = attrs[:buildpack].value if attrs.key?(:buildpack)
53
+
54
+ @memory = attrs[:memory].value if attrs.key?(:memory)
55
+ @disk = attrs[:disk].value if attrs.key?(:disk)
56
+
57
+ if @memory.nil? and @usage
58
+ @memory = @usage.split(' ').first
59
+ end
60
+ end
61
+
62
+ def set_instance_status(instance_statuses)
63
+ @instance_status = []
64
+
65
+ instance_statuses.each do |instance_status|
66
+ @instance_status << CfScript::InstanceStatus.new(instance_status)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,24 @@
1
+ class CfScript::AppList < CfScript::Object
2
+ extend Forwardable
3
+ include Enumerable
4
+
5
+ def initialize(list = [])
6
+ @list = list
7
+ end
8
+
9
+ def_delegators :@list, :<<, :[], :clear, :length, :each, :select
10
+
11
+ def select!(options)
12
+ if options[:starting_with]
13
+ @list.reject! { |app_info| app_info.name !~ /\A#{options[:starting_with]}/ }
14
+ end
15
+
16
+ if options[:state]
17
+ @list.reject! { |app_info| app_info.requested_state !~ /\A#{options[:state]}\z/ }
18
+ end
19
+
20
+ if options[:ending_with]
21
+ @list.reject! { |app_info| app_info.name !~ /#{options[:ending_with]}\z/ }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,55 @@
1
+ class CfScript::AppSpec < CfScript::Object
2
+ include CfScript::Callbacks
3
+ include CfScript::UI
4
+
5
+ def initialize(spec)
6
+ @org = spec[:org]
7
+ @env = spec[:env]
8
+ @domain = spec[:domain]
9
+ @name = spec[:name]
10
+ @type = spec[:type]
11
+ @phase = spec[:phase]
12
+ @memory = spec[:memory] || '2GB'
13
+ @instances = spec[:instances] || 1
14
+ end
15
+
16
+ def push_options
17
+ {
18
+ #domain: @domain,
19
+ #hostname: hostname,
20
+ memory: @memory,
21
+ instances: @instances,
22
+ health_check_type: @health_check,
23
+ flags: [
24
+ :no_route,
25
+ :no_start,
26
+ :no_manifest,
27
+ ]
28
+ }
29
+ end
30
+
31
+ def method_missing(m, *args, &block)
32
+ if args.empty? && block.nil?
33
+ instance_variable_get("@#{m}")
34
+ elsif !args.empty? && block.nil?
35
+ instance_variable_set("@#{m}", args.first)
36
+ elsif args.empty? && !block.nil?
37
+ instance_variable_set("@#{m}", yield)
38
+ else
39
+ raise "Can not accept arguments and a block. " +
40
+ "Pass arguments or a block, not both."
41
+ end
42
+ end
43
+
44
+ def full_name
45
+ [name, type, phase].compact.join('-')
46
+ end
47
+
48
+ def hostname
49
+ [org, env, name, type, phase].compact.join('-')
50
+ end
51
+
52
+ def fqdn
53
+ [hostname, domain].compact.join('.')
54
+ end
55
+ end
@@ -0,0 +1,18 @@
1
+ class CfScript::Attribute < CfScript::Object
2
+ attr_reader :name, :value
3
+
4
+ def initialize(name, value)
5
+ @name = name
6
+ @value = value
7
+ end
8
+
9
+ def to_a
10
+ value ? value.split(/,\s*/) : []
11
+ end
12
+
13
+ def to_s
14
+ "#{name}: #{value}"
15
+ end
16
+
17
+ alias :inspect :to_s
18
+ end
@@ -0,0 +1,40 @@
1
+ class CfScript::AttributeList < CfScript::Object
2
+ extend Forwardable
3
+ include Enumerable
4
+
5
+ def_delegators :@list, :[], :key?, :empty?, :length, :clear, :each
6
+
7
+ def initialize(attributes = [])
8
+ @list = {}
9
+
10
+ attributes.each do |attribute|
11
+ self << attribute
12
+ end
13
+ end
14
+
15
+ def names
16
+ @list.keys
17
+ end
18
+
19
+ def values
20
+ @list.values.map { |attr| attr.value }
21
+ end
22
+
23
+ def <<(attr)
24
+ if @list.key?(attr.name)
25
+ raise "Duplicate attribute '#{attr.name}'"
26
+ end
27
+
28
+ @list[attr.name] = attr
29
+ end
30
+
31
+ def to_h
32
+ hash = {}
33
+
34
+ @list.each do |name, attr|
35
+ hash[name] = attr.value
36
+ end
37
+
38
+ hash
39
+ end
40
+ end
@@ -0,0 +1,29 @@
1
+ class CfScript::InstanceStatus < CfScript::Object
2
+ attr_reader :index
3
+ attr_reader :state
4
+ attr_reader :since
5
+ attr_reader :cpu
6
+ attr_reader :memory
7
+ attr_reader :disk
8
+ attr_reader :details
9
+
10
+ def initialize(attrs = {})
11
+ @index = attrs[:index] ? attrs[:index].value : nil
12
+ @state = attrs[:state] ? attrs[:state].value : nil
13
+ @since = attrs[:since] ? attrs[:since].value : nil
14
+ @cpu = attrs[:cpu] ? attrs[:cpu].value : nil
15
+ @memory = attrs[:memory] ? attrs[:memory].value : nil
16
+ @disk = attrs[:disk] ? attrs[:disk].value : nil
17
+ @details = attrs[:details] ? attrs[:details].value : nil
18
+ end
19
+
20
+ def show(*attrs)
21
+ line = []
22
+
23
+ attrs.each do |attr|
24
+ line << "#{attr}: #{send(attr)}"
25
+ end
26
+
27
+ line.join(', ')
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ class CfScript::RouteInfo < CfScript::Object
2
+ attr_reader :space
3
+ attr_reader :host
4
+ attr_reader :domain
5
+ attr_reader :apps
6
+
7
+ def initialize(space = nil, host = nil, domain = nil, apps = [])
8
+ @space = space
9
+ @host = host
10
+ @domain = domain
11
+ @apps = apps
12
+ end
13
+ end
14
+
@@ -0,0 +1,17 @@
1
+ class CfScript::Space < CfScript::Object
2
+ attr_reader :name
3
+ attr_reader :org
4
+ attr_reader :apps
5
+ attr_reader :domains
6
+ attr_reader :services
7
+ attr_reader :security_groups
8
+
9
+ def initialize(name, org = nil, apps = [], domains = [], services = [], security_groups = [])
10
+ @name = name
11
+ @org = org
12
+ @apps = apps
13
+ @domains = domains
14
+ @services = services
15
+ @security_groups = security_groups
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ class CfScript::Target < CfScript::Object
2
+ attr_reader :api_endpoint
3
+ attr_reader :user
4
+ attr_reader :org
5
+
6
+ attr_accessor :space
7
+
8
+ def initialize(api_endpoint = '', org = '', space = '', user = nil)
9
+ @api_endpoint = api_endpoint
10
+ @org = org
11
+ @space = space
12
+ @user = user
13
+ end
14
+
15
+ def to_options
16
+ options = {}
17
+
18
+ options[:o] = @org if @org and not @org.empty?
19
+ options[:s] = @space if @space and not @space.empty?
20
+
21
+ options
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ require 'ostruct'
2
+ require 'forwardable'
3
+
4
+ class CfScript::Object
5
+ class << self
6
+ attr_reader :_cf_script_object_count
7
+ end
8
+
9
+ def initialize
10
+ @@_cf_script_object_count += 1
11
+ end
12
+ end
13
+
14
+ require 'cf_script/object/attribute'
15
+ require 'cf_script/object/attribute_list'
16
+
17
+ require 'cf_script/object/api_endpoint'
18
+ require 'cf_script/object/app_spec'
19
+ require 'cf_script/object/app_info'
20
+ require 'cf_script/object/app_list'
21
+ require 'cf_script/object/instance_status'
22
+ require 'cf_script/object/space'
23
+ require 'cf_script/object/target'
24
+ require 'cf_script/object/route_info'
@@ -0,0 +1,74 @@
1
+ module CfScript
2
+ class Output::Buffer
3
+ attr_reader :raw
4
+
5
+ ANSI_ESCAPE_SEQUENCE_REGEXP = /\e\[(\d+)(;\d+)*m/
6
+
7
+ def initialize(buffer = nil)
8
+ @raw = buffer
9
+ end
10
+
11
+ def content
12
+ @clean_content ||= sanitize
13
+ end
14
+
15
+ def lines
16
+ @clean_lines ||= sanitize_lines
17
+ end
18
+
19
+ def last_line
20
+ lines.last
21
+ end
22
+
23
+ def [](arg)
24
+ content[arg]
25
+ end
26
+
27
+ def each_line(&block)
28
+ content.each_line(&block)
29
+ end
30
+
31
+ def from(pattern)
32
+ lines_from(pattern).join("\n")
33
+ end
34
+
35
+ def lines_from(pattern)
36
+ index = lines.find_index { |line| line =~ /#{pattern}/ }
37
+ index ? lines[index..-1] : []
38
+ end
39
+
40
+ def match(regexp)
41
+ content.match(regexp)
42
+ end
43
+
44
+ def matches?(regexp)
45
+ content =~ regexp ? true : false
46
+ end
47
+
48
+ def contains?(text)
49
+ matches? /#{text}/
50
+ end
51
+
52
+ def last_line_matches?(regexp)
53
+ last_line =~ regexp ? true : false
54
+ end
55
+
56
+ private
57
+
58
+ def sanitize
59
+ raw.gsub ANSI_ESCAPE_SEQUENCE_REGEXP, ''
60
+ end
61
+
62
+ def sanitize_line(line)
63
+ line.gsub! ANSI_ESCAPE_SEQUENCE_REGEXP, ''
64
+ line.strip!
65
+ line
66
+ end
67
+
68
+ def sanitize_lines
69
+ raw.lines.map! do |line|
70
+ sanitize_line(line)
71
+ end
72
+ end
73
+ end
74
+ end