cf_script 0.0.1.beta.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 (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