startapp 0.1.6
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.
- checksums.yaml +7 -0
- data/COPYRIGHT +1 -0
- data/LICENSE +11 -0
- data/README.md +95 -0
- data/Rakefile +6 -0
- data/autocomplete/rhc_bash +1672 -0
- data/bin/app +37 -0
- data/conf/express.conf +8 -0
- data/features/assets/deploy.tar.gz +0 -0
- data/features/core_feature.rb +191 -0
- data/features/deployments_feature.rb +129 -0
- data/features/domains_feature.rb +58 -0
- data/features/keys_feature.rb +37 -0
- data/features/members_feature.rb +166 -0
- data/lib/rhc/auth/basic.rb +64 -0
- data/lib/rhc/auth/token.rb +102 -0
- data/lib/rhc/auth/token_store.rb +53 -0
- data/lib/rhc/auth.rb +5 -0
- data/lib/rhc/autocomplete.rb +66 -0
- data/lib/rhc/autocomplete_templates/bash.erb +39 -0
- data/lib/rhc/cartridge_helpers.rb +118 -0
- data/lib/rhc/cli.rb +40 -0
- data/lib/rhc/command_runner.rb +185 -0
- data/lib/rhc/commands/account.rb +25 -0
- data/lib/rhc/commands/alias.rb +124 -0
- data/lib/rhc/commands/app.rb +726 -0
- data/lib/rhc/commands/apps.rb +20 -0
- data/lib/rhc/commands/authorization.rb +115 -0
- data/lib/rhc/commands/base.rb +174 -0
- data/lib/rhc/commands/cartridge.rb +329 -0
- data/lib/rhc/commands/clone.rb +66 -0
- data/lib/rhc/commands/configure.rb +20 -0
- data/lib/rhc/commands/create.rb +100 -0
- data/lib/rhc/commands/delete.rb +19 -0
- data/lib/rhc/commands/deploy.rb +32 -0
- data/lib/rhc/commands/deployment.rb +82 -0
- data/lib/rhc/commands/domain.rb +172 -0
- data/lib/rhc/commands/env.rb +142 -0
- data/lib/rhc/commands/force_stop.rb +17 -0
- data/lib/rhc/commands/git_clone.rb +34 -0
- data/lib/rhc/commands/logout.rb +51 -0
- data/lib/rhc/commands/logs.rb +21 -0
- data/lib/rhc/commands/member.rb +148 -0
- data/lib/rhc/commands/port_forward.rb +197 -0
- data/lib/rhc/commands/reload.rb +17 -0
- data/lib/rhc/commands/restart.rb +17 -0
- data/lib/rhc/commands/scp.rb +54 -0
- data/lib/rhc/commands/server.rb +40 -0
- data/lib/rhc/commands/setup.rb +60 -0
- data/lib/rhc/commands/show.rb +43 -0
- data/lib/rhc/commands/snapshot.rb +137 -0
- data/lib/rhc/commands/ssh.rb +51 -0
- data/lib/rhc/commands/sshkey.rb +97 -0
- data/lib/rhc/commands/start.rb +17 -0
- data/lib/rhc/commands/stop.rb +17 -0
- data/lib/rhc/commands/tail.rb +47 -0
- data/lib/rhc/commands/threaddump.rb +14 -0
- data/lib/rhc/commands/tidy.rb +17 -0
- data/lib/rhc/commands.rb +396 -0
- data/lib/rhc/config.rb +321 -0
- data/lib/rhc/context_helper.rb +121 -0
- data/lib/rhc/core_ext.rb +202 -0
- data/lib/rhc/coverage_helper.rb +33 -0
- data/lib/rhc/deployment_helpers.rb +111 -0
- data/lib/rhc/exceptions.rb +256 -0
- data/lib/rhc/git_helpers.rb +106 -0
- data/lib/rhc/help_formatter.rb +55 -0
- data/lib/rhc/helpers.rb +481 -0
- data/lib/rhc/highline_extensions.rb +479 -0
- data/lib/rhc/json.rb +51 -0
- data/lib/rhc/output_helpers.rb +260 -0
- data/lib/rhc/rest/activation.rb +11 -0
- data/lib/rhc/rest/alias.rb +42 -0
- data/lib/rhc/rest/api.rb +87 -0
- data/lib/rhc/rest/application.rb +348 -0
- data/lib/rhc/rest/attributes.rb +36 -0
- data/lib/rhc/rest/authorization.rb +8 -0
- data/lib/rhc/rest/base.rb +79 -0
- data/lib/rhc/rest/cartridge.rb +162 -0
- data/lib/rhc/rest/client.rb +650 -0
- data/lib/rhc/rest/deployment.rb +18 -0
- data/lib/rhc/rest/domain.rb +98 -0
- data/lib/rhc/rest/environment_variable.rb +15 -0
- data/lib/rhc/rest/gear_group.rb +16 -0
- data/lib/rhc/rest/httpclient.rb +145 -0
- data/lib/rhc/rest/key.rb +44 -0
- data/lib/rhc/rest/membership.rb +105 -0
- data/lib/rhc/rest/mock.rb +1042 -0
- data/lib/rhc/rest/user.rb +32 -0
- data/lib/rhc/rest.rb +148 -0
- data/lib/rhc/scp_helpers.rb +27 -0
- data/lib/rhc/ssh_helpers.rb +380 -0
- data/lib/rhc/tar_gz.rb +51 -0
- data/lib/rhc/usage_templates/command_help.erb +51 -0
- data/lib/rhc/usage_templates/command_syntax_help.erb +11 -0
- data/lib/rhc/usage_templates/help.erb +61 -0
- data/lib/rhc/usage_templates/missing_help.erb +1 -0
- data/lib/rhc/usage_templates/options_help.erb +12 -0
- data/lib/rhc/vendor/okjson.rb +600 -0
- data/lib/rhc/vendor/parseconfig.rb +178 -0
- data/lib/rhc/vendor/sshkey.rb +253 -0
- data/lib/rhc/vendor/zliby.rb +628 -0
- data/lib/rhc/version.rb +5 -0
- data/lib/rhc/wizard.rb +637 -0
- data/lib/rhc.rb +34 -0
- data/spec/coverage_helper.rb +82 -0
- data/spec/direct_execution_helper.rb +339 -0
- data/spec/keys/example.pem +23 -0
- data/spec/keys/example_private.pem +27 -0
- data/spec/keys/server.pem +19 -0
- data/spec/rest_spec_helper.rb +31 -0
- data/spec/rhc/assets/cert.crt +22 -0
- data/spec/rhc/assets/cert_key_rsa +27 -0
- data/spec/rhc/assets/empty.txt +0 -0
- data/spec/rhc/assets/env_vars.txt +7 -0
- data/spec/rhc/assets/env_vars_2.txt +1 -0
- data/spec/rhc/assets/foo.txt +1 -0
- data/spec/rhc/assets/targz_corrupted.tar.gz +1 -0
- data/spec/rhc/assets/targz_sample.tar.gz +0 -0
- data/spec/rhc/auth_spec.rb +442 -0
- data/spec/rhc/cli_spec.rb +186 -0
- data/spec/rhc/command_spec.rb +435 -0
- data/spec/rhc/commands/account_spec.rb +42 -0
- data/spec/rhc/commands/alias_spec.rb +333 -0
- data/spec/rhc/commands/app_spec.rb +777 -0
- data/spec/rhc/commands/apps_spec.rb +39 -0
- data/spec/rhc/commands/authorization_spec.rb +157 -0
- data/spec/rhc/commands/cartridge_spec.rb +665 -0
- data/spec/rhc/commands/clone_spec.rb +41 -0
- data/spec/rhc/commands/deployment_spec.rb +327 -0
- data/spec/rhc/commands/domain_spec.rb +401 -0
- data/spec/rhc/commands/env_spec.rb +493 -0
- data/spec/rhc/commands/git_clone_spec.rb +102 -0
- data/spec/rhc/commands/logout_spec.rb +86 -0
- data/spec/rhc/commands/member_spec.rb +247 -0
- data/spec/rhc/commands/port_forward_spec.rb +217 -0
- data/spec/rhc/commands/scp_spec.rb +77 -0
- data/spec/rhc/commands/server_spec.rb +69 -0
- data/spec/rhc/commands/setup_spec.rb +118 -0
- data/spec/rhc/commands/snapshot_spec.rb +179 -0
- data/spec/rhc/commands/ssh_spec.rb +163 -0
- data/spec/rhc/commands/sshkey_spec.rb +188 -0
- data/spec/rhc/commands/tail_spec.rb +81 -0
- data/spec/rhc/commands/threaddump_spec.rb +84 -0
- data/spec/rhc/config_spec.rb +407 -0
- data/spec/rhc/helpers_spec.rb +531 -0
- data/spec/rhc/highline_extensions_spec.rb +314 -0
- data/spec/rhc/json_spec.rb +30 -0
- data/spec/rhc/rest_application_spec.rb +258 -0
- data/spec/rhc/rest_client_spec.rb +752 -0
- data/spec/rhc/rest_spec.rb +740 -0
- data/spec/rhc/targz_spec.rb +55 -0
- data/spec/rhc/wizard_spec.rb +756 -0
- data/spec/spec_helper.rb +575 -0
- data/spec/wizard_spec_helper.rb +330 -0
- metadata +469 -0
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
require 'delegate'
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Add specific improved functionality
|
|
5
|
+
#
|
|
6
|
+
class HighLineExtension < HighLine
|
|
7
|
+
attr_writer :debug
|
|
8
|
+
|
|
9
|
+
[:ask, :agree].each do |sym|
|
|
10
|
+
define_method(sym) do |*args, &block|
|
|
11
|
+
separate_blocks
|
|
12
|
+
r = super(*args, &block)
|
|
13
|
+
@last_line_open = false
|
|
14
|
+
r
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if HighLine::CHARACTER_MODE == 'stty'
|
|
19
|
+
def raw_no_echo_mode
|
|
20
|
+
@state = `stty -g 2>/dev/null`
|
|
21
|
+
`stty raw -echo -icanon isig 2>&1`
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def restore_mode
|
|
25
|
+
`stty #{@state} 2>&1`
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def debug(msg)
|
|
30
|
+
$stderr.puts "DEBUG: #{msg}" if debug?
|
|
31
|
+
end
|
|
32
|
+
def debug_error(e)
|
|
33
|
+
debug "#{e.message} (#{e.class})\n #{e.backtrace.join("\n ")}"
|
|
34
|
+
end
|
|
35
|
+
def debug?
|
|
36
|
+
@debug
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# OVERRIDE
|
|
40
|
+
def say(msg)
|
|
41
|
+
if msg.respond_to? :to_str
|
|
42
|
+
separate_blocks
|
|
43
|
+
|
|
44
|
+
statement = msg.to_str
|
|
45
|
+
return statement unless statement.present?
|
|
46
|
+
|
|
47
|
+
template = ERB.new(statement, nil, "%")
|
|
48
|
+
statement = template.result(binding)
|
|
49
|
+
|
|
50
|
+
if @wrap_at
|
|
51
|
+
statement = statement.chomp.textwrap_ansi(@wrap_at, false)
|
|
52
|
+
if @last_line_open && statement.length > 1
|
|
53
|
+
@last_line_open = false
|
|
54
|
+
@output.puts
|
|
55
|
+
end
|
|
56
|
+
statement = statement.join("#{indentation}\n")
|
|
57
|
+
end
|
|
58
|
+
statement = send(:page_print, statement) unless @page_at.nil?
|
|
59
|
+
|
|
60
|
+
@output.print(indentation) unless @last_line_open
|
|
61
|
+
|
|
62
|
+
@last_line_open =
|
|
63
|
+
if statement[-1, 1] == " " or statement[-1, 1] == "\t"
|
|
64
|
+
@output.print(statement)
|
|
65
|
+
@output.flush
|
|
66
|
+
#statement.strip_ansi.length + (@last_line_open || 0)
|
|
67
|
+
true
|
|
68
|
+
else
|
|
69
|
+
@output.puts(statement)
|
|
70
|
+
false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
elsif msg.respond_to? :each
|
|
74
|
+
separate_blocks
|
|
75
|
+
|
|
76
|
+
@output.print if @last_line_open
|
|
77
|
+
@last_line_open = false
|
|
78
|
+
|
|
79
|
+
color = msg.color if msg.respond_to? :color
|
|
80
|
+
@output.print HighLine::Style(color).code if color
|
|
81
|
+
|
|
82
|
+
msg.each do |s|
|
|
83
|
+
@output.print indentation
|
|
84
|
+
@output.puts s
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
@output.print HighLine::CLEAR if color
|
|
88
|
+
@output.flush
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
msg
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# given an array of arrays "items", construct an array of strings that can
|
|
95
|
+
# be used to print in tabular form.
|
|
96
|
+
def table(items, opts={}, &block)
|
|
97
|
+
items = items.map(&block) if block_given?
|
|
98
|
+
opts[:width] ||= default_max_width
|
|
99
|
+
Table.new(items, opts)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def table_args(indent=nil, *args)
|
|
103
|
+
opts = {}
|
|
104
|
+
opts[:indent] = indent
|
|
105
|
+
opts[:width] = [default_max_width, *args]
|
|
106
|
+
opts
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def default_max_width
|
|
110
|
+
@wrap_at ? @wrap_at - indentation.length : nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def header(str,opts = {}, &block)
|
|
114
|
+
say Header.new(str, default_max_width, ' ')
|
|
115
|
+
if block_given?
|
|
116
|
+
indent &block
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
#:nocov:
|
|
121
|
+
# Backport from Highline 1.6.16
|
|
122
|
+
unless HighLine.method_defined? :indent
|
|
123
|
+
#
|
|
124
|
+
# Outputs indentation with current settings
|
|
125
|
+
#
|
|
126
|
+
def indentation
|
|
127
|
+
@indent_size ||= 2
|
|
128
|
+
@indent_level ||= 0
|
|
129
|
+
return ' '*@indent_size*@indent_level
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
#
|
|
133
|
+
# Executes block or outputs statement with indentation
|
|
134
|
+
#
|
|
135
|
+
def indent(increase=1, statement=nil, multiline=nil)
|
|
136
|
+
@indent_size ||= 2
|
|
137
|
+
@indent_level ||= 0
|
|
138
|
+
@indent_level += increase
|
|
139
|
+
multi = @multi_indent
|
|
140
|
+
@multi_indent = multiline unless multiline.nil?
|
|
141
|
+
if block_given?
|
|
142
|
+
yield self
|
|
143
|
+
else
|
|
144
|
+
say(statement)
|
|
145
|
+
end
|
|
146
|
+
ensure
|
|
147
|
+
@multi_indent = multi
|
|
148
|
+
@indent_level -= increase
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
#:nocov:
|
|
152
|
+
|
|
153
|
+
##
|
|
154
|
+
# section
|
|
155
|
+
#
|
|
156
|
+
# highline helper mixin which correctly formats block of say and ask
|
|
157
|
+
# output to have correct margins. section remembers the last margin
|
|
158
|
+
# used and calculates the relitive margin from the previous section.
|
|
159
|
+
# For example:
|
|
160
|
+
#
|
|
161
|
+
# section(bottom=1) do
|
|
162
|
+
# say "Hello"
|
|
163
|
+
# end
|
|
164
|
+
#
|
|
165
|
+
# section(top=1) do
|
|
166
|
+
# say "World"
|
|
167
|
+
# end
|
|
168
|
+
#
|
|
169
|
+
# Will output:
|
|
170
|
+
#
|
|
171
|
+
# > Hello
|
|
172
|
+
# >
|
|
173
|
+
# > World
|
|
174
|
+
#
|
|
175
|
+
# with only one newline between the two. Biggest margin wins.
|
|
176
|
+
#
|
|
177
|
+
# params:
|
|
178
|
+
# top - top margin specified in lines
|
|
179
|
+
# bottom - bottom margin specified in line
|
|
180
|
+
#
|
|
181
|
+
def section(params={}, &block)
|
|
182
|
+
top = params[:top] || 0
|
|
183
|
+
bottom = params[:bottom] || 0
|
|
184
|
+
|
|
185
|
+
# the first section cannot take a newline
|
|
186
|
+
top = 0 unless @margin
|
|
187
|
+
@margin = [top, @margin || 0].max
|
|
188
|
+
|
|
189
|
+
separate_blocks if params[:now]
|
|
190
|
+
value = block.call
|
|
191
|
+
|
|
192
|
+
say "\n" if @last_line_open
|
|
193
|
+
@margin = [bottom, @margin].max
|
|
194
|
+
|
|
195
|
+
value
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
##
|
|
199
|
+
# paragraph
|
|
200
|
+
#
|
|
201
|
+
# highline helper which creates a section with margins of 1, 1
|
|
202
|
+
#
|
|
203
|
+
def paragraph(&block)
|
|
204
|
+
section(:top => 1, :bottom => 1, &block)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def pager
|
|
208
|
+
#:nocov:
|
|
209
|
+
return if RHC::Helpers.windows?
|
|
210
|
+
return unless @output.tty?
|
|
211
|
+
|
|
212
|
+
read, write = IO.pipe
|
|
213
|
+
|
|
214
|
+
unless Kernel.fork
|
|
215
|
+
# Child process
|
|
216
|
+
STDOUT.reopen(write)
|
|
217
|
+
STDERR.reopen(write) if STDERR.tty?
|
|
218
|
+
read.close
|
|
219
|
+
write.close
|
|
220
|
+
return
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Parent process, become pager
|
|
224
|
+
STDIN.reopen(read)
|
|
225
|
+
read.close
|
|
226
|
+
write.close
|
|
227
|
+
|
|
228
|
+
ENV['LESS'] = 'FSRX' # Don't page if the input is short enough
|
|
229
|
+
|
|
230
|
+
Kernel.select [STDIN] # Wait until we have input before we start the pager
|
|
231
|
+
pager = ENV['PAGER'] || 'less'
|
|
232
|
+
exec pager rescue exec "/bin/sh", "-c", pager
|
|
233
|
+
#:nocov:
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
private
|
|
237
|
+
def separate_blocks
|
|
238
|
+
if (@margin ||= 0) > 0 && !@last_line_open
|
|
239
|
+
@output.print "\n" * @margin
|
|
240
|
+
@margin = 0
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
#
|
|
246
|
+
# An element capable of being split into multiple logical rows
|
|
247
|
+
#
|
|
248
|
+
module RowBased
|
|
249
|
+
extend Forwardable
|
|
250
|
+
def_delegators :rows, :each, :to_a, :join
|
|
251
|
+
alias_method :each_line, :each
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
class HighLine::Header < Struct.new(:text, :width, :indent, :color)
|
|
255
|
+
include RowBased
|
|
256
|
+
|
|
257
|
+
protected
|
|
258
|
+
def rows
|
|
259
|
+
@rows ||= begin
|
|
260
|
+
if !width || width == 0
|
|
261
|
+
[text.is_a?(Array) ? text.compact.join(' ') : text]
|
|
262
|
+
|
|
263
|
+
elsif text.is_a? Array
|
|
264
|
+
text.compact!
|
|
265
|
+
widths = text.map{ |s| s.strip_ansi.length }
|
|
266
|
+
chars, join, indented = 0, 1, (indent || '').length
|
|
267
|
+
narrow = width - indented
|
|
268
|
+
text.zip(widths).inject([]) do |rows, (section, w)|
|
|
269
|
+
if rows.empty?
|
|
270
|
+
if w > width
|
|
271
|
+
rows.concat(section.textwrap_ansi(width))
|
|
272
|
+
else
|
|
273
|
+
rows << section.dup
|
|
274
|
+
chars += w
|
|
275
|
+
end
|
|
276
|
+
else
|
|
277
|
+
if w + chars + join > narrow
|
|
278
|
+
rows.concat(section.textwrap_ansi(narrow).map{ |s| "#{indent}#{s}" })
|
|
279
|
+
chars = 0
|
|
280
|
+
elsif chars == 0
|
|
281
|
+
rows << "#{indent}#{section}"
|
|
282
|
+
chars += w + indented
|
|
283
|
+
else
|
|
284
|
+
rows[-1] << " #{section}"
|
|
285
|
+
chars += w + join
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
rows
|
|
289
|
+
end
|
|
290
|
+
else
|
|
291
|
+
text.textwrap_ansi(width)
|
|
292
|
+
end
|
|
293
|
+
end.tap do |rows|
|
|
294
|
+
rows << '-' * (rows.map{ |s| s.strip_ansi.length }.max || 0)
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
#
|
|
300
|
+
# Represent a columnar layout of items with wrapping and flexible layout.
|
|
301
|
+
#
|
|
302
|
+
class HighLine::Table
|
|
303
|
+
include RowBased
|
|
304
|
+
|
|
305
|
+
def initialize(items=nil,options={},&mapper)
|
|
306
|
+
@items, @options, @mapper = items, options, mapper
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def color
|
|
310
|
+
opts[:color]
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
protected
|
|
314
|
+
attr_reader :items
|
|
315
|
+
|
|
316
|
+
def opts
|
|
317
|
+
@options
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def align
|
|
321
|
+
opts[:align] || []
|
|
322
|
+
end
|
|
323
|
+
def joiner
|
|
324
|
+
opts[:join] || ' '
|
|
325
|
+
end
|
|
326
|
+
def indent
|
|
327
|
+
opts[:indent] || ''
|
|
328
|
+
end
|
|
329
|
+
def heading
|
|
330
|
+
@heading ||= opts[:heading] ? HighLine::Header.new(opts[:heading], max_width, indent) : nil
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def source_rows
|
|
334
|
+
@source_rows ||= begin
|
|
335
|
+
(@mapper ? (items.map &@mapper) : items).each do |row|
|
|
336
|
+
row.map! do |col|
|
|
337
|
+
case col
|
|
338
|
+
when Array then col.join("\n")
|
|
339
|
+
when String then col
|
|
340
|
+
else col.to_s
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
def headers
|
|
348
|
+
@headers ||= opts[:header] ? [Array(opts[:header])] : []
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def columns
|
|
352
|
+
@columns ||= source_rows.map(&:length).max || 0
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def column_widths
|
|
356
|
+
@column_widths ||= begin
|
|
357
|
+
widths = Array.new(columns){ Width.new(0,0,0) }
|
|
358
|
+
(source_rows + headers).each do |row|
|
|
359
|
+
row.each_with_index do |col, i|
|
|
360
|
+
w = widths[i]
|
|
361
|
+
s = col.strip_ansi
|
|
362
|
+
word_length = s.scan(/\b\S+/).inject(0){ |l, word| l = word.length if l <= word.length; l }
|
|
363
|
+
w.min = word_length unless w.min > word_length
|
|
364
|
+
w.max = s.length unless w.max > s.length
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
widths
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
Width = Struct.new(:min, :max, :set)
|
|
372
|
+
|
|
373
|
+
def allocate_widths_for(available)
|
|
374
|
+
available -= (columns-1) * joiner.length + indent.length
|
|
375
|
+
return column_widths.map{ |w| w.max } if available >= column_widths.inject(0){ |sum, w| sum + w.max } || column_widths.inject(0){ |sum, w| sum + w.min } > available
|
|
376
|
+
|
|
377
|
+
fair = available / columns
|
|
378
|
+
column_widths.each do |w|
|
|
379
|
+
if w.set > 0
|
|
380
|
+
available -= w.set
|
|
381
|
+
next
|
|
382
|
+
end
|
|
383
|
+
w.set = if w.max <= fair
|
|
384
|
+
available -= w.max
|
|
385
|
+
w.max
|
|
386
|
+
else
|
|
387
|
+
0
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
remaining = column_widths.inject(0) do |sum, w|
|
|
392
|
+
if w.set == 0
|
|
393
|
+
sum += w.max
|
|
394
|
+
available -= w.min
|
|
395
|
+
end
|
|
396
|
+
sum
|
|
397
|
+
end
|
|
398
|
+
fair = available.to_f / remaining.to_f
|
|
399
|
+
|
|
400
|
+
column_widths.
|
|
401
|
+
each do |w|
|
|
402
|
+
if w.set == 0
|
|
403
|
+
alloc = (w.max * fair).to_i
|
|
404
|
+
overflow = alloc + w.min - w.max
|
|
405
|
+
if overflow > 0
|
|
406
|
+
alloc -= overflow
|
|
407
|
+
end
|
|
408
|
+
available -= alloc
|
|
409
|
+
w.set = alloc + w.min
|
|
410
|
+
end
|
|
411
|
+
end.
|
|
412
|
+
each do |w|
|
|
413
|
+
next unless available > 0
|
|
414
|
+
gap = w.max - w.set
|
|
415
|
+
if gap > 0
|
|
416
|
+
left = [gap,available].min
|
|
417
|
+
available -= left
|
|
418
|
+
w.set += left
|
|
419
|
+
end
|
|
420
|
+
end.map(&:set)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def widths
|
|
424
|
+
@widths ||= begin
|
|
425
|
+
case w = opts[:width]
|
|
426
|
+
when Array
|
|
427
|
+
column_widths.zip(w[1..-1]).each do |width, col|
|
|
428
|
+
width.set = col || 0
|
|
429
|
+
width.max = width.set if width.set > width.max
|
|
430
|
+
end
|
|
431
|
+
allocate_widths_for(w.first || 0)
|
|
432
|
+
when Integer
|
|
433
|
+
allocate_widths_for(w)
|
|
434
|
+
else
|
|
435
|
+
column_widths.map{ |w| w.max }
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def max_width
|
|
441
|
+
@max_width ||= opts[:width].is_a?(Array) ? opts[:width].first : (opts[:width] ? opts[:width] : 0)
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def header_rows
|
|
445
|
+
@header_rows ||= begin
|
|
446
|
+
headers << widths.map{ |w| '-' * w } if headers.present?
|
|
447
|
+
headers
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def rows
|
|
452
|
+
@rows ||= begin
|
|
453
|
+
body = (header_rows + source_rows).inject([]) do |a,row|
|
|
454
|
+
row = row.zip(widths).map{ |column,w| w && w > 0 ? column.textwrap_ansi(w, false) : [column] }
|
|
455
|
+
(row.map(&:length).max || 0).times do |i|
|
|
456
|
+
s = []
|
|
457
|
+
row.each_with_index do |lines, j|
|
|
458
|
+
cell = lines[i]
|
|
459
|
+
l = cell ? cell.strip_ansi.length : 0
|
|
460
|
+
s <<
|
|
461
|
+
if align[j] == :right
|
|
462
|
+
"#{' '*(widths[j]-l) if l < widths[j]}#{cell}"
|
|
463
|
+
else
|
|
464
|
+
"#{cell}#{' '*(widths[j]-l) if l < widths[j]}"
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
a << "#{indent}#{s.join(joiner).rstrip}"
|
|
468
|
+
end
|
|
469
|
+
a
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
body = heading.to_a.concat(body) if heading
|
|
473
|
+
body
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
$terminal = HighLineExtension.new
|
|
479
|
+
$terminal.indent_size = 2 if $terminal.respond_to? :indent_size
|
data/lib/rhc/json.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'rhc/vendor/okjson'
|
|
2
|
+
|
|
3
|
+
module RHC
|
|
4
|
+
|
|
5
|
+
module Json
|
|
6
|
+
|
|
7
|
+
def self.decode(string, options={})
|
|
8
|
+
string = string.read if string.respond_to?(:read)
|
|
9
|
+
result = RHC::Vendor::OkJson.decode(string)
|
|
10
|
+
options[:symbolize_keys] ? symbolize_keys(result) : result
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.encode(object, options={})
|
|
14
|
+
RHC::Vendor::OkJson.valenc(stringify_keys(object))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.symbolize_keys(object)
|
|
18
|
+
modify_keys(object) do |key|
|
|
19
|
+
key.is_a?(String) ? key.to_sym : key
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.stringify_keys(object)
|
|
24
|
+
modify_keys(object) do |key|
|
|
25
|
+
key.is_a?(Symbol) ? key.to_s : key
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.modify_keys(object, &modifier)
|
|
30
|
+
case object
|
|
31
|
+
when Array
|
|
32
|
+
object.map do |value|
|
|
33
|
+
modify_keys(value, &modifier)
|
|
34
|
+
end
|
|
35
|
+
when Hash
|
|
36
|
+
object.inject({}) do |result, (key, value)|
|
|
37
|
+
new_key = modifier.call(key)
|
|
38
|
+
new_value = modify_keys(value, &modifier)
|
|
39
|
+
result.merge! new_key => new_value
|
|
40
|
+
end
|
|
41
|
+
else
|
|
42
|
+
object
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class JsonError < ::StandardError; end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
|