rhc 1.6.8 → 1.7.8

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 (85) hide show
  1. data/autocomplete/rhc_bash +1167 -0
  2. data/features/README.md +1 -1
  3. data/features/domain.feature +1 -1
  4. data/features/lib/rhc_helper/persistable.rb +4 -1
  5. data/features/multiple_cartridge.feature +4 -3
  6. data/features/sshkey.feature +3 -3
  7. data/features/support/assumptions.rb +3 -3
  8. data/features/support/env.rb +10 -0
  9. data/features/support/platform_support.rb +2 -2
  10. data/lib/rhc.rb +6 -0
  11. data/lib/rhc/auth/token.rb +4 -0
  12. data/lib/rhc/autocomplete.rb +50 -52
  13. data/lib/rhc/autocomplete_templates/{rhc.erb → bash.erb} +8 -2
  14. data/lib/rhc/cartridge_helpers.rb +1 -1
  15. data/lib/rhc/cli.rb +1 -7
  16. data/lib/rhc/command_runner.rb +45 -16
  17. data/lib/rhc/commands.rb +75 -55
  18. data/lib/rhc/commands/account.rb +7 -51
  19. data/lib/rhc/commands/alias.rb +26 -17
  20. data/lib/rhc/commands/app.rb +75 -39
  21. data/lib/rhc/commands/authorization.rb +4 -2
  22. data/lib/rhc/commands/base.rb +31 -29
  23. data/lib/rhc/commands/cartridge.rb +66 -44
  24. data/lib/rhc/commands/domain.rb +20 -8
  25. data/lib/rhc/commands/git_clone.rb +3 -3
  26. data/lib/rhc/commands/logout.rb +51 -0
  27. data/lib/rhc/commands/port_forward.rb +15 -11
  28. data/lib/rhc/commands/setup.rb +25 -0
  29. data/lib/rhc/commands/snapshot.rb +20 -10
  30. data/lib/rhc/commands/sshkey.rb +21 -7
  31. data/lib/rhc/commands/tail.rb +2 -2
  32. data/lib/rhc/commands/threaddump.rb +2 -2
  33. data/lib/rhc/context_helper.rb +0 -4
  34. data/lib/rhc/core_ext.rb +96 -76
  35. data/lib/rhc/exceptions.rb +6 -0
  36. data/lib/rhc/help_formatter.rb +19 -2
  37. data/lib/rhc/helpers.rb +32 -194
  38. data/lib/rhc/highline_extensions.rb +412 -0
  39. data/lib/rhc/output_helpers.rb +31 -67
  40. data/lib/rhc/rest.rb +4 -2
  41. data/lib/rhc/rest/alias.rb +0 -2
  42. data/lib/rhc/rest/application.rb +9 -4
  43. data/lib/rhc/rest/authorization.rb +0 -2
  44. data/lib/rhc/rest/base.rb +1 -1
  45. data/lib/rhc/rest/client.rb +11 -9
  46. data/lib/rhc/rest/domain.rb +5 -1
  47. data/lib/rhc/rest/gear_group.rb +0 -2
  48. data/lib/rhc/rest/key.rb +0 -2
  49. data/lib/rhc/rest/mock.rb +32 -10
  50. data/lib/rhc/ssh_helpers.rb +2 -2
  51. data/lib/rhc/usage_templates/command_help.erb +20 -13
  52. data/lib/rhc/usage_templates/command_syntax_help.erb +1 -3
  53. data/lib/rhc/usage_templates/help.erb +15 -16
  54. data/lib/rhc/usage_templates/options_help.erb +7 -9
  55. data/lib/rhc/wizard.rb +193 -159
  56. data/spec/rest_spec_helper.rb +2 -2
  57. data/spec/rhc/cli_spec.rb +36 -5
  58. data/spec/rhc/command_spec.rb +94 -42
  59. data/spec/rhc/commands/account_spec.rb +1 -75
  60. data/spec/rhc/commands/alias_spec.rb +28 -28
  61. data/spec/rhc/commands/app_spec.rb +141 -33
  62. data/spec/rhc/commands/apps_spec.rb +4 -4
  63. data/spec/rhc/commands/authorization_spec.rb +8 -8
  64. data/spec/rhc/commands/cartridge_spec.rb +18 -9
  65. data/spec/rhc/commands/domain_spec.rb +16 -16
  66. data/spec/rhc/commands/git_clone_spec.rb +3 -3
  67. data/spec/rhc/commands/logout_spec.rb +86 -0
  68. data/spec/rhc/commands/port_forward_spec.rb +9 -9
  69. data/spec/rhc/commands/server_spec.rb +5 -5
  70. data/spec/rhc/commands/setup_spec.rb +19 -5
  71. data/spec/rhc/commands/snapshot_spec.rb +12 -12
  72. data/spec/rhc/commands/sshkey_spec.rb +11 -11
  73. data/spec/rhc/commands/tail_spec.rb +5 -5
  74. data/spec/rhc/commands/threaddump_spec.rb +3 -3
  75. data/spec/rhc/config_spec.rb +6 -6
  76. data/spec/rhc/helpers_spec.rb +72 -219
  77. data/spec/rhc/highline_extensions_spec.rb +269 -0
  78. data/spec/rhc/rest_application_spec.rb +28 -1
  79. data/spec/rhc/rest_client_spec.rb +20 -21
  80. data/spec/rhc/rest_spec.rb +10 -0
  81. data/spec/rhc/wizard_spec.rb +72 -32
  82. data/spec/spec_helper.rb +86 -56
  83. data/spec/wizard_spec_helper.rb +7 -4
  84. metadata +165 -160
  85. data/spec/spec.opts +0 -1
@@ -4,11 +4,23 @@ module RHC::Commands
4
4
  class Sshkey < Base
5
5
  include RHC::SSHHelpers
6
6
 
7
- summary 'Manage multiple keys for the registered rhcloud user.'
7
+ summary 'Add and remove keys for Git and SSH'
8
8
  syntax '<action>'
9
+ description <<-DESC
10
+ OpenShift uses public keys to securely access your application source
11
+ code and to control access to your application gears via SSH. Your
12
+ account may have one or more public SSH keys associated with it, and
13
+ any computer with the private SSH key will be able to download code
14
+ from Git or SSH to the application.
15
+
16
+ Depending on your operating system, you may have to ensure that both
17
+ Git and the local SSH installation have access to your keys. Running
18
+ the 'setup' command is any easy way to get your first key created and
19
+ uploaded.
20
+ DESC
9
21
  default_action :list
10
22
 
11
- summary 'Display all the SSH keys for the user account'
23
+ summary 'Display all the SSH keys for your account'
12
24
  syntax ''
13
25
  def list
14
26
  keys = rest_client.sshkeys.each{ |key| paragraph{ display_key(key) } }
@@ -18,7 +30,7 @@ module RHC::Commands
18
30
  0
19
31
  end
20
32
 
21
- summary 'List the SSH key with the given name'
33
+ summary 'Show the SSH key with the given name'
22
34
  syntax '<name>'
23
35
  argument :name, 'SSH key to display', []
24
36
  def show(name)
@@ -28,7 +40,7 @@ module RHC::Commands
28
40
  0
29
41
  end
30
42
 
31
- summary 'Add SSH key to the user account'
43
+ summary 'Add SSH key to your account'
32
44
  syntax '<name> <path to SSH key file>'
33
45
  argument :name, 'Name for this key', []
34
46
  argument :key, 'SSH public key filepath', []
@@ -54,13 +66,15 @@ module RHC::Commands
54
66
  0
55
67
  end
56
68
 
57
- summary 'Remove SSH key from the user account'
69
+ summary 'Remove SSH key from your account'
58
70
  syntax '<name>'
59
71
  alias_action :delete
60
- argument :name, 'SSH key to remove', []
72
+ argument :name, 'Name of SSH key to remove'
61
73
  def remove(name)
74
+ say "Removing the key '#{name} ... "
62
75
  rest_client.delete_key(name)
63
- results { say "SSH key '#{name}' has been removed" }
76
+
77
+ success "removed"
64
78
 
65
79
  0
66
80
  end
@@ -8,8 +8,8 @@ module RHC::Commands
8
8
 
9
9
  summary "Tail the logs of an application"
10
10
  syntax "<application>"
11
- argument :app, "Name of application you wish to view the logs of", ["-a", "--app app"]
12
- option ["-n", "--namespace namespace"], "Namespace of your application", :context => :namespace_context, :required => true
11
+ argument :app, "Name of application you wish to view the logs of", ["-a", "--app NAME"]
12
+ option ["-n", "--namespace NAME"], "Namespace of your application", :context => :namespace_context, :required => true
13
13
  option ["-o", "--opts options"], "Options to pass to the server-side (linux based) tail command (applicable to tail command only) (-f is implicit. See the linux tail man page full list of options.) (Ex: --opts '-n 100')"
14
14
  option ["-f", "--files files"], "File glob relative to app (default <application_name>/logs/*) (optional)"
15
15
  #option ["-c", "--cartridge name"], "Tail only a specific cartridge"
@@ -1,9 +1,9 @@
1
1
  require 'rhc/commands/base'
2
2
  module RHC::Commands
3
3
  class Threaddump < Base
4
- summary "Trigger a thread dump for JBoss and Ruby applications."
4
+ summary "Trigger a thread dump for JBoss and Ruby apps"
5
5
  syntax "<application>"
6
- option ["-n", "--namespace namespace"], "Namespace of your application", :context => :namespace_context, :required => true
6
+ option ["-n", "--namespace NAME"], "Namespace of your application", :context => :namespace_context, :required => true
7
7
  argument :app, "Name of the application on which to execute the thread dump", ["-a", "--app name"]
8
8
  def run(app)
9
9
  rest_app = rest_client.find_application(options.namespace, app)
@@ -12,10 +12,6 @@ module RHC
12
12
  ENV['LIBRA_SERVER'] || (!options.clean && config['libra_server']) || "openshift.redhat.com"
13
13
  end
14
14
 
15
- def token_context
16
- token_store.get(options.rhlogin, options.server) if options.rhlogin
17
- end
18
-
19
15
  def app_context
20
16
  debug "Getting app context"
21
17
 
@@ -1,7 +1,6 @@
1
1
  # From Rails core_ext/object.rb
2
2
  require 'rhc/json'
3
3
  require 'open-uri'
4
- require 'highline'
5
4
  require 'httpclient'
6
5
 
7
6
  class Object
@@ -24,6 +23,23 @@ class Object
24
23
  end
25
24
  end
26
25
 
26
+ class Array
27
+ # From rails
28
+ def split(value = nil)
29
+ using_block = block_given?
30
+
31
+ inject([[]]) do |results, element|
32
+ if (using_block && yield(element)) || (value == element)
33
+ results << []
34
+ else
35
+ results.last << element
36
+ end
37
+
38
+ results
39
+ end
40
+ end
41
+ end
42
+
27
43
  class File
28
44
  def chunk(chunk_size=1024)
29
45
  yield read(chunk_size) until eof?
@@ -37,6 +53,85 @@ class String
37
53
  def wrap(wrap_length=80, char="\n")
38
54
  scan(/.{#{wrap_length}}|.+/).join(char)
39
55
  end
56
+
57
+ def strip_heredoc
58
+ indent = scan(/^[ \t]*(?=\S)/).min.size || 0
59
+ gsub(/^[ \t]{#{indent}}/, '').
60
+ gsub(/(\b|\S)[^\S\n]*\n(\S)/m, '\1 \2').
61
+ gsub(/\n+\Z/, '').
62
+ gsub(/\n{3,}/, "\n\n")
63
+ end
64
+
65
+ ANSI_ESCAPE_SEQUENCE = /\e\[(\d{1,2}(?:;\d{1,2})*[@-~])/
66
+ ANSI_ESCAPE_MATCH = '\e\[\d+(?:;\d+)*[@-~]'
67
+ CHAR_SKIP_ANSI = "(?:(?:#{ANSI_ESCAPE_MATCH})+.?|.(?:#{ANSI_ESCAPE_MATCH})*)"
68
+
69
+ #
70
+ # Split the given string at limit, treating ANSI escape sequences as
71
+ # zero characters in length. Will insert an ANSI reset code (\e[0m)
72
+ # at the end of each line containing an ANSI code, assuming that a
73
+ # reset was not in the wrapped segment.
74
+ #
75
+ # All newlines are preserved.
76
+ #
77
+ # Lines longer than limit without natural breaks will be forcibly
78
+ # split at the exact limit boundary.
79
+ #
80
+ # Returns an Array
81
+ #
82
+ def textwrap_ansi(limit, breakword=true)
83
+ re = breakword ? /
84
+ (
85
+ # Match substrings that end in whitespace shorter than limit
86
+ #{CHAR_SKIP_ANSI}{1,#{limit}} # up to limit
87
+ (?:\s+|$) # require the limit to end on whitespace
88
+ |
89
+ # Match substrings equal to the limit
90
+ #{CHAR_SKIP_ANSI}{1,#{limit}}
91
+ )
92
+ /x :
93
+ /
94
+ (
95
+ # Match substrings that end in whitespace shorter than limit
96
+ #{CHAR_SKIP_ANSI}{1,#{limit}}
97
+ (?:\s|$) # require the limit to end on whitespace
98
+ |
99
+ # Match all continguous whitespace strings
100
+ #{CHAR_SKIP_ANSI}+?
101
+ (?:\s|$)
102
+ (?:\s+|$)?
103
+ )
104
+ /x
105
+ escapes = []
106
+
107
+ split("\n",-1).inject([]) do |a, line|
108
+ if line.length < limit
109
+ a << line
110
+ else
111
+ line.scan(re) do |segment, other|
112
+ if escapes.present?
113
+ a << escapes.map{ |s| "\e[#{s}"}.join
114
+ a[-1] << segment.rstrip
115
+ else
116
+ a << segment.rstrip
117
+ end
118
+
119
+ segment.scan(ANSI_ESCAPE_SEQUENCE).map{ |e| e.first }.each do |e|
120
+ case e
121
+ when '0m' then escapes.clear
122
+ else escapes << e
123
+ end
124
+ end
125
+ a[-1] << "\e[0m" if escapes.present?
126
+ end
127
+ end
128
+ a
129
+ end
130
+ end
131
+
132
+ def strip_ansi
133
+ gsub(ANSI_ESCAPE_SEQUENCE, '')
134
+ end
40
135
  end
41
136
 
42
137
  unless HTTP::Message.method_defined? :ok?
@@ -99,78 +194,3 @@ class Hash
99
194
  merge!( other_hash ){|key,left,right| left }
100
195
  end
101
196
  end
102
-
103
- # Some versions of highline get in an infinite loop when trying to wrap.
104
- # Fixes BZ 866530.
105
- class HighLine
106
-
107
- def wrap_line(line)
108
- wrapped_line = []
109
- i = chars_in_line = 0
110
- word = []
111
-
112
- while i < line.length
113
- # we have to give a length to the index because ruby 1.8 returns the
114
- # byte code when using a single fixednum index
115
- c = line[i, 1]
116
- color_code = nil
117
- # escape character probably means color code, let's check
118
- if c == "\e"
119
- color_code = line[i..i+6].match(/\e\[\d{1,2}m/)
120
- if color_code
121
- # first the existing word buffer then the color code
122
- wrapped_line << word.join.wrap(@wrap_at) << color_code[0]
123
- word.clear
124
-
125
- i += color_code[0].length
126
- end
127
- end
128
-
129
- # visible character
130
- if !color_code
131
- chars_in_line += 1
132
- word << c
133
-
134
- # time to wrap the line?
135
- if chars_in_line == @wrap_at
136
- if c == ' ' or line[i+1, 1] == ' ' or word.length == @wrap_at
137
- wrapped_line << word.join
138
- word.clear
139
- end
140
-
141
- wrapped_line[-1].rstrip!
142
- wrapped_line << "\n"
143
-
144
- # consume any spaces at the begining of the next line
145
- word = word.join.lstrip.split(//)
146
- chars_in_line = word.length
147
-
148
- if line[i+1, 1] == ' '
149
- i += 1 while line[i+1, 1] == ' '
150
- end
151
-
152
- else
153
- if c == ' '
154
- wrapped_line << word.join
155
- word.clear
156
- end
157
- end
158
-
159
- i += 1
160
- end
161
- end
162
-
163
- wrapped_line << word.join
164
- wrapped_line.join
165
- end
166
-
167
- def wrap(text)
168
- wrapped_text = []
169
- lines = text.split(/\r?\n/)
170
- lines.each_with_index do |line, i|
171
- wrapped_text << wrap_line(i == lines.length - 1 ? line : line.rstrip)
172
- end
173
-
174
- return wrapped_text.join("\n")
175
- end
176
- end
@@ -134,4 +134,10 @@ module RHC
134
134
  super message, 1
135
135
  end
136
136
  end
137
+
138
+ class ServerAPINotSupportedException < Exception
139
+ def initialize(min_version, current_version)
140
+ super "The server does not support this command (requires #{min_version}, found #{current_version})."
141
+ end
142
+ end
137
143
  end
@@ -5,20 +5,37 @@ module RHC
5
5
  def template(name)
6
6
  ERB.new(File.read(File.join(File.dirname(__FILE__), 'usage_templates', "#{name}.erb")), nil, '-')
7
7
  end
8
+ def render
9
+ template(:help).result RunnerHelpBindings.new(@runner).get_binding
10
+ end
8
11
  def render_command_syntax command
9
12
  template(:command_syntax_help).result command.get_binding
10
13
  end
11
14
  def render_options runner
12
- template(:options_help).result runner.get_binding
15
+ template(:options_help).result RunnerHelpBindings.new(runner).get_binding
16
+ end
17
+ end
18
+
19
+ class RunnerHelpBindings < SimpleDelegator
20
+ include RHC::Helpers
21
+
22
+ def commands
23
+ __getobj__.instance_variable_get(:@commands)
24
+ end
25
+
26
+ def get_binding
27
+ binding
13
28
  end
14
29
  end
15
30
 
16
31
  class CommandHelpBindings
32
+ include RHC::Helpers
33
+
17
34
  def initialize(command, instance_commands, runner)
18
35
  @command = command
19
36
  @actions = instance_commands.collect do |command_name, command_class|
20
37
  next if command_class.summary.nil?
21
- m = /^#{command.name} ([^ ]+)/.match(command_name)
38
+ m = /^#{command.name}[\-]([^ ]+)/.match(command_name)
22
39
  # if we have a match and it is not an alias then we can use it
23
40
  m and command_name == command_class.name ? {:name => m[1], :summary => command_class.summary || ""} : nil
24
41
  end
@@ -29,22 +29,15 @@ module RHC
29
29
  MAX_RETRIES = 7
30
30
  DEFAULT_DELAY_THROTTLE = 2.0
31
31
 
32
- def disable_deprecated?
33
- # 1) default for now is false
34
- # 2) when releasing a 1.0 beta flip this to true
35
- # 3) all deprecated aliases should be removed right before 1.0
36
- disable = false
37
-
38
- env_disable = ENV['DISABLE_DEPRECATED']
39
- disable = true if env_disable == '1'
40
-
41
- disable
42
- end
43
-
44
32
  def decode_json(s)
45
33
  RHC::Vendor::OkJson.decode(s)
46
34
  end
47
35
 
36
+ def system_path(path)
37
+ return path.gsub(File::SEPARATOR, File::ALT_SEPARATOR) if File.const_defined?('ALT_SEPARATOR') and File::ALT_SEPARATOR.present?
38
+ path
39
+ end
40
+
48
41
  def date(s)
49
42
  now = Date.today
50
43
  d = datetime_rfc3339(s).to_time
@@ -100,7 +93,7 @@ module RHC
100
93
 
101
94
  global_option '-l', '--rhlogin LOGIN', "OpenShift login"
102
95
  global_option '-p', '--password PASSWORD', "OpenShift password"
103
- global_option '--token TOKEN', "An authorization token for accessing your account.", :context => :token_context
96
+ global_option '--token TOKEN', "An authorization token for accessing your account."
104
97
 
105
98
  global_option '-d', '--debug', "Turn on debugging", :hide => true
106
99
 
@@ -124,7 +117,7 @@ module RHC
124
117
  global_option '--noprompt', "Suppress all interactive operations command", :hide => true do
125
118
  $terminal.page_at = nil
126
119
  end
127
- global_option '--config FILE', "Path of a different config file", :hide => true
120
+ global_option '--config FILE', "Path of a different config file (default: #{system_path("~/.openshift/express.conf")})", :hide => true
128
121
  global_option '--clean', "Ignore any saved configuration options", :hide => true
129
122
  global_option '--mock', "Run in mock mode", :hide => true do
130
123
  #:nocov:
@@ -154,6 +147,10 @@ module RHC
154
147
  uri.path = '/broker/rest/api' if uri.path.blank? || uri.path == '/'
155
148
  uri
156
149
  end
150
+
151
+ def token_for_user
152
+ options.token or (token_store.get(options.rhlogin, options.server) if options.rhlogin)
153
+ end
157
154
 
158
155
  def client_from_options(opts)
159
156
  RHC::Rest::Client.new({
@@ -183,6 +180,10 @@ module RHC
183
180
  # Output helpers
184
181
  #
185
182
 
183
+ def interactive?
184
+ $stdout.tty? and not options.noprompt
185
+ end
186
+
186
187
  def debug(msg)
187
188
  $stderr.puts "DEBUG: #{msg}" if debug?
188
189
  end
@@ -193,66 +194,23 @@ module RHC
193
194
  false
194
195
  end
195
196
 
196
- def deprecated_command(correct,short = false)
197
- deprecated("This command is deprecated. Please use '#{correct}' instead.",short)
197
+ def disable_deprecated?
198
+ ENV['DISABLE_DEPRECATED'] == '1'
198
199
  end
199
200
 
200
- def deprecated_option(deprecated,new)
201
- deprecated("The option '#{deprecated}' is deprecated. Please use '#{new}' instead")
201
+ def deprecated_command(correct, short=false)
202
+ deprecated("This command is deprecated. Please use '#{correct}' instead.", short)
202
203
  end
203
204
 
204
- def deprecated(msg,short = false)
205
- HighLine::use_color = false if windows? # handle deprecated commands that does not start through highline
206
-
207
- info = " For porting and testing purposes you may switch this %s to %s by setting the DISABLE_DEPRECATED environment variable to %d. It is not recommended to do so in a production environment as this option will be removed in a future release."
208
- msg << info unless short
205
+ def deprecated_option(deprecated, other)
206
+ deprecated("The option '#{deprecated}' is deprecated. Please use '#{other}' instead")
207
+ end
209
208
 
209
+ def deprecated(msg,short = false)
210
210
  raise DeprecatedError.new(msg % ['an error','a warning',0]) if disable_deprecated?
211
-
212
211
  warn "Warning: #{msg}\n" % ['a warning','an error',1]
213
212
  end
214
213
 
215
- @@indent = 0
216
- @@last_line_open = false
217
- def say(msg, *args)
218
- output = if Hash[*args][:stderr]
219
- $stderr
220
- else
221
- separate_blocks
222
- $terminal.instance_variable_get(:@output)
223
- end
224
-
225
- Array(msg).each do |statement|
226
- statement = statement.to_str
227
- next unless statement.present?
228
-
229
- template = ERB.new(statement, nil, "%")
230
- statement = template.result(binding)
231
-
232
- statement = $terminal.wrap(statement) unless $terminal.instance_variable_get(:@wrap_at).nil?
233
- statement = $terminal.send(:page_print, statement) unless $terminal.instance_variable_get(:@page_at).nil?
234
-
235
- output.print(' ' * @@indent * INDENT) unless @@last_line_open
236
-
237
- @@last_line_open =
238
- if statement[-1, 1] == " " or statement[-1, 1] == "\t"
239
- output.print(statement)
240
- output.flush
241
- else
242
- output.puts(statement)
243
- end
244
- end
245
-
246
- msg
247
- end
248
-
249
- [:ask, :agree].each do |sym|
250
- define_method(sym) do |*args, &block|
251
- separate_blocks
252
- super(*args, &block)
253
- end
254
- end
255
-
256
214
  def confirm_action(question)
257
215
  return if options.confirm
258
216
  return if !options.noprompt && paragraph{ agree("#{question} (yes|no): ") }
@@ -275,39 +233,19 @@ module RHC
275
233
  say color(msg, :red), *args
276
234
  end
277
235
 
278
- def color(s, color)
279
- $terminal.color(s, color)
236
+ # OVERRIDE: Replaces default commander behavior
237
+ def color(*args)
238
+ $terminal.color(*args)
280
239
  end
281
240
 
282
- def pluralize(count, s)
283
- count == 1 ? "#{count} #{s}" : "#{count} #{s}s"
241
+ [:pager, :indent, :paragraph, :section, :header, :table, :table_args].each do |sym|
242
+ define_method(sym) do |*args, &block|
243
+ $terminal.send(sym, *args, &block)
244
+ end
284
245
  end
285
246
 
286
- # given an array of arrays "items", construct an array of strings that can
287
- # be used to print in tabular form.
288
- def table(items, opts={}, &block)
289
- items = items.map &block if block_given?
290
- widths = []
291
- items.each do |item|
292
- item.each_with_index do |s, i|
293
- item[i] = s.to_s
294
- widths[i] = [widths[i] || 0, item[i].length].max
295
- end
296
- end
297
- align = opts[:align] || []
298
- join = opts[:join] || ' '
299
- if opts[:header]
300
- opts[:header].each_with_index do |s, i|
301
- widths[i] = [widths[i] || 0, s.length].max
302
- end
303
- sep = opts[:separator] || "="
304
- ary = Array.new(opts[:header].length)
305
- items.unshift ary.each_with_index {|obj, idx| ary[idx] = sep.to_s * (widths[idx] || 1)}
306
- items.unshift(opts[:header])
307
- end
308
- items.map do |item|
309
- item.each_with_index.map{ |s,i| s.send((align[i] == :right ? :rjust : :ljust), widths[i], ' ') }.join(join).rstrip
310
- end
247
+ def pluralize(count, s)
248
+ count == 1 ? "#{count} #{s}" : "#{count} #{s}s"
311
249
  end
312
250
 
313
251
  # This will format table headings for a consistent look and feel
@@ -360,92 +298,6 @@ module RHC
360
298
  end
361
299
  end
362
300
 
363
- #def tee(&block)
364
- # original = [$stdout, $stderr]
365
- # $stdout, $stderr = (tees = original.map{ |io| StringTee.new(io) })
366
- # yield
367
- #ensure
368
- # $stdout, $stderr = original
369
- # tees.each(&:close_write).map(&:string)
370
- #end
371
-
372
- def header(str,opts = {}, &block)
373
- str = underline(str)
374
- str = str.map{ |s| color(s, opts[:color]) } if opts[:color]
375
- say str
376
- if block_given?
377
- indent &block
378
- end
379
- end
380
-
381
- def underline(s)
382
- [s, "-"*s.length]
383
- end
384
-
385
- INDENT = 2
386
- def indent(&block)
387
- @@indent += 1
388
- begin
389
- yield
390
- ensure
391
- @@indent -= 1
392
- end
393
- end
394
-
395
- ##
396
- # section
397
- #
398
- # highline helper mixin which correctly formats block of say and ask
399
- # output to have correct margins. section remembers the last margin
400
- # used and calculates the relitive margin from the previous section.
401
- # For example:
402
- #
403
- # section(bottom=1) do
404
- # say "Hello"
405
- # end
406
- #
407
- # section(top=1) do
408
- # say "World"
409
- # end
410
- #
411
- # Will output:
412
- #
413
- # > Hello
414
- # >
415
- # > World
416
- #
417
- # with only one newline between the two. Biggest margin wins.
418
- #
419
- # params:
420
- # top - top margin specified in lines
421
- # bottom - bottom margin specified in line
422
- #
423
- @@margin = nil
424
- def section(params={}, &block)
425
- top = params[:top] || 0
426
- bottom = params[:bottom] || 0
427
-
428
- # the first section cannot take a newline
429
- top = 0 unless @@margin
430
- @@margin = [top, @@margin || 0].max
431
-
432
- value = block.call
433
-
434
- say "\n" if @@last_line_open
435
- @@margin = [bottom, @@margin].max
436
-
437
- value
438
- end
439
-
440
- ##
441
- # paragraph
442
- #
443
- # highline helper which creates a section with margins of 1, 1
444
- #
445
- def paragraph(&block)
446
- section(:top => 1, :bottom => 1, &block)
447
- end
448
-
449
301
  ##
450
302
  # results
451
303
  #
@@ -465,11 +317,6 @@ module RHC
465
317
  def unix? ; !jruby? && !windows? end
466
318
  def mac? ; RbConfig::CONFIG['host_os'] =~ /^darwin/ end
467
319
 
468
- def system_path(path)
469
- return path.gsub(File::SEPARATOR, File::ALT_SEPARATOR) if File.const_defined?('ALT_SEPARATOR') and File::ALT_SEPARATOR.present?
470
- path
471
- end
472
-
473
320
  #
474
321
  # Check if host exists
475
322
  #
@@ -529,14 +376,5 @@ module RHC
529
376
 
530
377
  [status, stdout, stderr]
531
378
  end
532
-
533
- private
534
-
535
- def separate_blocks
536
- if (@@margin ||= 0) > 0 && !@@last_line_open
537
- $terminal.instance_variable_get(:@output).print "\n" * @@margin
538
- @@margin = 0
539
- end
540
- end
541
379
  end
542
380
  end