startapp 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|