cli-ui 1.2.1 → 1.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37c3f9d8f4c1cd9dcf6d86319d35b947d2b99ae0dc0f1b975397d77f555f1f57
4
- data.tar.gz: d7b3eee8bba21a191746ecf244c428f8c702e1c2fbfb41242740d38a9d317dab
3
+ metadata.gz: 7c658a2195a92d5e4ccf05fc1359eef09d25b5a01e0110c6ab84190d4a10c922
4
+ data.tar.gz: 4745f15513a91abef5cce3e3523d26de38d60336dbdf723601402fe8bd4b2635
5
5
  SHA512:
6
- metadata.gz: e35d9d93f31d2bacbd1623d63937f99deecc928e7ef97ebe0b5c4f6199b37952d9d7dad97cfe004ce7cc03296776f7767ccf08336dcbc261eb63f097450211cc
7
- data.tar.gz: a184a3dc46bfe4074bbfb8571253e00bc016ac40734ea2ab13baeabe526cfa3194855d3ca69424fd1b069157c7ec4ee7fc76debbdca71ecaa48fc145446039a8
6
+ metadata.gz: 609b7cab1cde15280659813f6b283c419c76b744a9089dcded708c3cf08113b7118150fd5e6642f8e41709f8b481ad0a51927d48ac294432ce108209faefccce
7
+ data.tar.gz: feb06db36c85af0d83c2407bf6ebb06ee1c65ea8ec38b7b80b09bbeaac0a25220a7fe2707993bee950916cd203e31d219b6db6adf132b08e9027be8e00df846a
data/README.md CHANGED
@@ -34,7 +34,7 @@ To handle content flow (see example below)
34
34
  CLI::UI::StdoutRouter.enable
35
35
  CLI::UI::Frame.open('Frame 1') do
36
36
  CLI::UI::Frame.open('Frame 2') { puts "inside frame 2" }
37
- puts "inside frame 1"
37
+ puts "inside frame 1"
38
38
  end
39
39
  ```
40
40
 
@@ -43,7 +43,10 @@ end
43
43
  ---
44
44
 
45
45
  ### Interactive Prompts
46
- Prompt user with options and ask them to choose. Can answer using arrow keys, numbers, or vim bindings (or y/n for yes/no questions)
46
+ Prompt user with options and ask them to choose. Can answer using arrow keys, vim bindings (`j`/`k`), or numbers (or y/n for yes/no questions).
47
+
48
+ For large numbers of options, using `e`, `:`, or `G` will toggle "line select" mode which allows numbers greater than 9 to be typed and
49
+ `f` or `/` will allow the user to filter options using a free-form text input.
47
50
 
48
51
  ```ruby
49
52
  CLI::UI.ask('What language/framework do you use?', options: %w(rails go ruby python))
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.add_development_dependency "bundler", "~> 1.15"
24
+ # spec.add_development_dependency "bundler", "~> 2.0"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "minitest", "~> 5.0"
27
27
  end
@@ -48,8 +48,8 @@ module CLI
48
48
  #
49
49
  # * +question+ - question to confirm
50
50
  #
51
- def self.confirm(question)
52
- CLI::UI::Prompt.confirm(question)
51
+ def self.confirm(question, **kwargs)
52
+ CLI::UI::Prompt.confirm(question, **kwargs)
53
53
  end
54
54
 
55
55
  # Conviencence Method for +CLI::UI::Prompt.ask+
@@ -72,7 +72,7 @@ module CLI
72
72
  # Format the progress bar to be printed to terminal
73
73
  #
74
74
  def to_s
75
- suffix = " #{(@percent_done * 100).round(2)}%"
75
+ suffix = " #{(@percent_done * 100).floor}%".ljust(5)
76
76
  workable_width = @max_width - Frame.prefix_width - suffix.size
77
77
  filled = [(@percent_done * workable_width.to_f).ceil, 0].max
78
78
  unfilled = [workable_width - filled, 0].max
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'cli/ui'
2
3
  require 'readline'
3
4
 
@@ -30,11 +31,15 @@ module CLI
30
31
  # * +:default+ - The default answer to the question (e.g. they just press enter and don't input anything)
31
32
  # * +:is_file+ - Tells the input to use file auto-completion (tab completion)
32
33
  # * +:allow_empty+ - Allows the answer to be empty
34
+ # * +:multiple+ - Allow multiple options to be selected
35
+ # * +:filter_ui+ - Enable option filtering (default: true)
36
+ # * +:select_ui+ - Enable long-form option selection (default: true)
33
37
  #
34
38
  # Note:
35
39
  # * +:options+ or providing a +Block+ conflicts with +:default+ and +:is_file+, you cannot set options with either of these keywords
36
40
  # * +:default+ conflicts with +:allow_empty:, you cannot set these together
37
41
  # * +:options+ conflicts with providing a +Block+ , you may only set one
42
+ # * +:multiple+ can only be used with +:options+ or a +Block+; it is ignored, otherwise.
38
43
  #
39
44
  # ==== Block (optional)
40
45
  #
@@ -71,13 +76,13 @@ module CLI
71
76
  # handler.option('python') { |selection| selection }
72
77
  # end
73
78
  #
74
- def ask(question, options: nil, default: nil, is_file: nil, allow_empty: true, multiple: false, &options_proc)
79
+ def ask(question, options: nil, default: nil, is_file: nil, allow_empty: true, multiple: false, filter_ui: true, select_ui: true, &options_proc)
75
80
  if ((options || block_given?) && (default || is_file))
76
81
  raise(ArgumentError, 'conflicting arguments: options provided with default or is_file')
77
82
  end
78
83
 
79
84
  if options || block_given?
80
- ask_interactive(question, options, multiple: multiple, &options_proc)
85
+ ask_interactive(question, options, multiple: multiple, filter_ui: filter_ui, select_ui: select_ui, &options_proc)
81
86
  else
82
87
  ask_free_form(question, default, is_file, allow_empty)
83
88
  end
@@ -91,8 +96,10 @@ module CLI
91
96
  # Confirmation question
92
97
  # CLI::UI::Prompt.confirm('Is the sky blue?')
93
98
  #
94
- def confirm(question)
95
- ask_interactive(question, %w(yes no)) == 'yes'
99
+ # CLI::UI::Prompt.confirm('Do a dangerous thing?', default: false)
100
+ #
101
+ def confirm(question, default: true)
102
+ ask_interactive(question, default ? %w(yes no) : %w(no yes), filter_ui: false) == 'yes'
96
103
  end
97
104
 
98
105
  private
@@ -121,7 +128,7 @@ module CLI
121
128
  end
122
129
  end
123
130
 
124
- def ask_interactive(question, options = nil, multiple: false)
131
+ def ask_interactive(question, options = nil, multiple: false, filter_ui: true, select_ui: true)
125
132
  raise(ArgumentError, 'conflicting arguments: options and block given') if options && block_given?
126
133
 
127
134
  options ||= if block_given?
@@ -132,6 +139,8 @@ module CLI
132
139
 
133
140
  raise(ArgumentError, 'insufficient options') if options.nil? || options.size < 2
134
141
  instructions = (multiple ? "Toggle options. " : "") + "Choose with ↑ ↓ ⏎"
142
+ instructions += ", filter with 'f'" if filter_ui
143
+ instructions += ", enter option with 'e'" if select_ui and options.size > 9
135
144
  puts_question("#{question} {{yellow:(#{instructions})}}")
136
145
  resp = interactive_prompt(options, multiple: multiple)
137
146
 
@@ -195,10 +204,11 @@ module CLI
195
204
  # thread to manage output, but the current strategy feels like a
196
205
  # better tradeoff.
197
206
  prefix = CLI::UI.with_frame_color(:blue) { CLI::UI::Frame.prefix }
198
- prompt = prefix + CLI::UI.fmt('{{blue:> }}{{yellow:')
207
+ prompt = prefix + CLI::UI.fmt('{{blue:> }}') + CLI::UI::Color::YELLOW.code
199
208
 
200
209
  begin
201
210
  line = Readline.readline(prompt, true)
211
+ print CLI::UI::Color::RESET.code
202
212
  line.to_s.chomp
203
213
  rescue Interrupt
204
214
  CLI::UI.raw { STDERR.puts('^C' + CLI::UI::Color::RESET.code) }
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'io/console'
2
3
 
3
4
  module CLI
@@ -10,6 +11,9 @@ module CLI
10
11
  # Prompts the user with options
11
12
  # Uses an interactive session to allow the user to pick an answer
12
13
  # Can use arrows, y/n, numbers (1/2), and vim bindings to control
14
+ # For more than 9 options, hitting 'e', ':', or 'G' will enter select
15
+ # mode allowing the user to type in longer numbers
16
+ # Pressing 'f' or '/' will allow the user to filter the results
13
17
  #
14
18
  # https://user-images.githubusercontent.com/3074765/33797984-0ebb5e64-dcdf-11e7-9e7e-7204f279cece.gif
15
19
  #
@@ -42,16 +46,22 @@ module CLI
42
46
  @answer = nil
43
47
  @state = :root
44
48
  @multiple = multiple
49
+ # Indicate that an extra line (the "metadata" line) is present and
50
+ # the terminal output should be drawn over when processing user input
51
+ @displaying_metadata = false
52
+ @filter = ''
45
53
  # 0-indexed array representing if selected
46
54
  # @options[0] is selected if @chosen[0]
47
55
  @chosen = Array.new(@options.size) { false } if multiple
48
56
  @redraw = true
57
+ @presented_options = []
49
58
  end
50
59
 
51
60
  # Calls the +InteractiveOptions+ and asks the question
52
61
  # Usually used from +self.call+
53
62
  #
54
63
  def call
64
+ calculate_option_line_lengths
55
65
  CLI::UI.raw { print(ANSI.hide_cursor) }
56
66
  while @answer.nil?
57
67
  render_options
@@ -59,6 +69,7 @@ module CLI
59
69
  reset_position
60
70
  end
61
71
  clear_output
72
+
62
73
  @answer
63
74
  ensure
64
75
  CLI::UI.raw do
@@ -68,46 +79,96 @@ module CLI
68
79
 
69
80
  private
70
81
 
71
- def reset_position
82
+ def calculate_option_line_lengths
83
+ @terminal_width_at_calculation_time = CLI::UI::Terminal.width
84
+ # options will be an array of questions but each option can be multi-line
85
+ # so to get the # of lines, you need to join then split
86
+
87
+ # since lines may be longer than the terminal is wide, we need to
88
+ # determine how many extra lines would be taken up by them
89
+ max_width = (@terminal_width_at_calculation_time -
90
+ @options.count.to_s.size - # Width of the displayed number
91
+ 5 - # Extra characters added during rendering
92
+ (@multiple ? 1 : 0) # Space for the checkbox, if rendered
93
+ ).to_f
94
+
95
+ @option_lengths = @options.map do |text|
96
+ width = 1 if text.empty?
97
+ width ||= text
98
+ .split("\n")
99
+ .reject(&:empty?)
100
+ .map { |l| (l.length / max_width).ceil }
101
+ .reduce(&:+)
102
+
103
+ width
104
+ end
105
+ end
106
+
107
+ def reset_position(number_of_lines=num_lines)
72
108
  # This will put us back at the beginning of the options
73
109
  # When we redraw the options, they will be overwritten
74
110
  CLI::UI.raw do
75
- num_lines.times { print(ANSI.previous_line) }
111
+ number_of_lines.times { print(ANSI.previous_line) }
76
112
  end
77
113
  end
78
114
 
79
- def clear_output
115
+ def clear_output(number_of_lines=num_lines)
80
116
  CLI::UI.raw do
81
117
  # Write over all lines with whitespace
82
- num_lines.times { puts(' ' * CLI::UI::Terminal.width) }
118
+ number_of_lines.times { puts(' ' * CLI::UI::Terminal.width) }
83
119
  end
84
- reset_position
120
+ reset_position number_of_lines
121
+
122
+ # Update if metadata is being displayed
123
+ # This must be done _after_ the output is cleared or it won't draw over
124
+ # the entire output
125
+ @displaying_metadata = display_metadata?
126
+ end
127
+
128
+ # Don't use this in place of +@displaying_metadata+, this updates too
129
+ # quickly to be useful when drawing to the screen.
130
+ def display_metadata?
131
+ filtering? or selecting? or has_filter?
85
132
  end
86
133
 
87
134
  def num_lines
88
- options = presented_options.map(&:first)
89
- # @options will be an array of questions but each option can be multi-line
90
- # so to get the # of lines, you need to join then split
135
+ calculate_option_line_lengths if terminal_width_changed?
91
136
 
92
- # empty_option_count is needed since empty option titles are omitted
93
- # from the line count when reject(&:empty?) is called
137
+ option_length = presented_options.reduce(0) do |total_length, (_, option_number)|
138
+ # Handle continuation markers and "Done" option when multiple is true
139
+ next total_length + 1 if option_number.nil? or option_number.zero?
140
+ total_length + @option_lengths[option_number - 1]
141
+ end
142
+
143
+ option_length + (@displaying_metadata ? 1 : 0)
144
+ end
94
145
 
95
- empty_option_count = options.count(&:empty?)
96
- joined_options = options.join("\n")
97
- joined_options.split("\n").reject(&:empty?).size + empty_option_count
146
+ def terminal_width_changed?
147
+ @terminal_width_at_calculation_time != CLI::UI::Terminal.width
98
148
  end
99
149
 
100
150
  ESC = "\e"
151
+ BACKSPACE = "\u007F"
152
+ CTRL_C = "\u0003"
153
+ CTRL_D = "\u0004"
101
154
 
102
155
  def up
103
- min_pos = @multiple ? 0 : 1
104
- @active = @active - 1 >= min_pos ? @active - 1 : @options.length
156
+ active_index = @filtered_options.index { |_,num| num == @active } || 0
157
+
158
+ previous_visible = @filtered_options[active_index - 1]
159
+ previous_visible ||= @filtered_options.last
160
+
161
+ @active = previous_visible ? previous_visible.last : -1
105
162
  @redraw = true
106
163
  end
107
164
 
108
165
  def down
109
- min_pos = @multiple ? 0 : 1
110
- @active = @active + 1 <= @options.length ? @active + 1 : min_pos
166
+ active_index = @filtered_options.index { |_,num| num == @active } || 0
167
+
168
+ next_visible = @filtered_options[active_index + 1]
169
+ next_visible ||= @filtered_options.first
170
+
171
+ @active = next_visible ? next_visible.last : -1
111
172
  @redraw = true
112
173
  end
113
174
 
@@ -141,7 +202,36 @@ module CLI
141
202
  @redraw = true
142
203
  end
143
204
 
205
+ def build_selection(char)
206
+ @active = (@active.to_s + char).to_i
207
+ @redraw = true
208
+ end
209
+
210
+ def chop_selection
211
+ @active = @active.to_s.chop.to_i
212
+ @redraw = true
213
+ end
214
+
215
+ def update_search(char)
216
+ @redraw = true
217
+
218
+ # Control+D or Backspace on empty search closes search
219
+ if char == CTRL_D or (@filter.empty? and char == BACKSPACE)
220
+ @filter = ''
221
+ @state = :root
222
+ return
223
+ end
224
+
225
+ if char == BACKSPACE
226
+ @filter.chop!
227
+ else
228
+ @filter += char
229
+ end
230
+ end
231
+
144
232
  def select_current
233
+ # Prevent selection of invisible options
234
+ return unless presented_options.any? { |_,num| num == @active }
145
235
  select_n(@active)
146
236
  end
147
237
 
@@ -153,29 +243,49 @@ module CLI
153
243
  # rubocop:disable Style/WhenThen,Layout/SpaceBeforeSemicolon
154
244
  def wait_for_user_input
155
245
  char = read_char
246
+ @last_char = char
247
+
248
+ case char
249
+ when :timeout ; raise Interrupt # Timeout, use interrupt to simulate
250
+ when CTRL_C ; raise Interrupt
251
+ end
252
+
156
253
  case @state
157
254
  when :root
158
255
  case char
159
- when :timeout ; raise Interrupt # Timeout, use interrupt to simulate
160
256
  when ESC ; @state = :esc
161
257
  when 'k' ; up
162
258
  when 'j' ; down
163
- when '0' ; select_n(char.to_i)
164
- when ('1'..@options.size.to_s) ; select_n(char.to_i)
259
+ when 'e', ':', 'G' ; start_line_select
260
+ when 'f', '/' ; start_filter
261
+ when ('0'..@options.size.to_s) ; select_n(char.to_i)
165
262
  when 'y', 'n' ; select_bool(char)
166
263
  when " ", "\r", "\n" ; select_current # <enter>
167
- when "\u0003" ; raise Interrupt # Ctrl-c
264
+ end
265
+ when :filter
266
+ case char
267
+ when ESC ; @state = :esc
268
+ when "\r", "\n" ; select_current
269
+ else ; update_search(char)
270
+ end
271
+ when :line_select
272
+ case char
273
+ when ESC ; @state = :esc
274
+ when 'k' ; up ; @state = :root
275
+ when 'j' ; down ; @state = :root
276
+ when 'e',':','G','q' ; stop_line_select
277
+ when '0'..'9' ; build_selection(char)
278
+ when BACKSPACE ; chop_selection # Pop last input on backspace
279
+ when ' ', "\r", "\n" ; select_current
168
280
  end
169
281
  when :esc
170
282
  case char
171
- when :timeout ; raise Interrupt # Timeout, use interrupt to simulate
172
283
  when '[' ; @state = :esc_bracket
173
284
  else ; raise Interrupt # unhandled escape sequence.
174
285
  end
175
286
  when :esc_bracket
176
- @state = :root
287
+ @state = has_filter? ? :filter : :root
177
288
  case char
178
- when :timeout ; raise Interrupt # Timeout, use interrupt to simulate
179
289
  when 'A' ; up
180
290
  when 'B' ; down
181
291
  else ; raise Interrupt # unhandled escape sequence.
@@ -184,6 +294,35 @@ module CLI
184
294
  end
185
295
  # rubocop:enable Style/WhenThen,Layout/SpaceBeforeSemicolon
186
296
 
297
+ def selecting?
298
+ @state == :line_select
299
+ end
300
+
301
+ def filtering?
302
+ @state == :filter
303
+ end
304
+
305
+ def has_filter?
306
+ !@filter.empty?
307
+ end
308
+
309
+ def start_filter
310
+ @state = :filter
311
+ @redraw = true
312
+ end
313
+
314
+ def start_line_select
315
+ @state = :line_select
316
+ @active = 0
317
+ @redraw = true
318
+ end
319
+
320
+ def stop_line_select
321
+ @state = :root
322
+ @active = 1 if @active.zero?
323
+ @redraw = true
324
+ end
325
+
187
326
  def read_char
188
327
  raw_tty! do
189
328
  getc = $stdin.getc
@@ -205,9 +344,18 @@ module CLI
205
344
  return @presented_options unless recalculate
206
345
 
207
346
  @presented_options = @options.zip(1..Float::INFINITY)
347
+ if has_filter?
348
+ @presented_options.select! { |option,_| option.downcase.include?(@filter.downcase) }
349
+ end
350
+
351
+ # Used for selection purposes
352
+ @filtered_options = @presented_options.dup
353
+
208
354
  @presented_options.unshift([DONE, 0]) if @multiple
209
355
 
210
- while num_lines > max_options
356
+ ensure_visible_is_active if has_filter?
357
+
358
+ while num_lines > max_lines
211
359
  # try to keep the selection centered in the window:
212
360
  if distance_from_selection_to_end > distance_from_start_to_selection
213
361
  # selection is closer to top than bottom, so trim a row from the bottom
@@ -223,14 +371,22 @@ module CLI
223
371
  @presented_options
224
372
  end
225
373
 
374
+ def ensure_visible_is_active
375
+ unless presented_options.any? { |_, num| num == @active }
376
+ @active = presented_options.first&.last.to_i
377
+ end
378
+ end
379
+
226
380
  def distance_from_selection_to_end
227
- last_visible_option_number = @presented_options[-1].last || @presented_options[-2].last
228
- last_visible_option_number - @active
381
+ @presented_options.count - index_of_active_option
229
382
  end
230
383
 
231
384
  def distance_from_start_to_selection
232
- first_visible_option_number = @presented_options[0].last || @presented_options[1].last
233
- @active - first_visible_option_number
385
+ index_of_active_option
386
+ end
387
+
388
+ def index_of_active_option
389
+ @presented_options.index { |_,num| num == @active }.to_i
234
390
  end
235
391
 
236
392
  def ensure_last_item_is_continuation_marker
@@ -241,14 +397,38 @@ module CLI
241
397
  @presented_options.unshift(["...", nil]) if @presented_options.first.last
242
398
  end
243
399
 
244
- def max_options
245
- @max_options ||= CLI::UI::Terminal.height - 2 # Keeps a one line question visible
400
+ def max_lines
401
+ CLI::UI::Terminal.height - (@displaying_metadata ? 3 : 2) # Keeps a one line question visible
246
402
  end
247
403
 
248
404
  def render_options
405
+ previously_displayed_lines = num_lines
406
+
407
+ @displaying_metadata = display_metadata?
408
+
409
+ options = presented_options(recalculate: true)
410
+
411
+ clear_output(previously_displayed_lines) if previously_displayed_lines > num_lines
412
+
249
413
  max_num_length = (@options.size + 1).to_s.length
250
414
 
251
- presented_options(recalculate: true).each do |choice, num|
415
+ metadata_text = if selecting?
416
+ select_text = @active
417
+ select_text = '{{info:e, q, or up/down anytime to exit}}' if @active == 0
418
+ "Select: #{select_text}"
419
+ elsif filtering? or has_filter?
420
+ filter_text = @filter
421
+ filter_text = '{{info:Ctrl-D anytime or Backspace now to exit}}' if @filter.empty?
422
+ "Filter: #{filter_text}"
423
+ end
424
+
425
+ if metadata_text
426
+ CLI::UI.with_frame_color(:blue) do
427
+ puts CLI::UI.fmt(" {{green:#{metadata_text}}}#{ANSI.clear_to_end_of_line}")
428
+ end
429
+ end
430
+
431
+ options.each do |choice, num|
252
432
  is_chosen = @multiple && num && @chosen[num - 1]
253
433
 
254
434
  padding = ' ' * (max_num_length - num.to_s.length)
@@ -261,19 +441,29 @@ module CLI
261
441
  format = " #{format}"
262
442
 
263
443
  message += sprintf(format, CHECKBOX_ICON[is_chosen]) if @multiple && num && num > 0
264
- message += choice.split("\n").map { |l| sprintf(format, l) }.join("\n")
444
+ message += format_choice(format, choice)
265
445
 
266
446
  if num == @active
267
- message = message.split("\n").map.with_index do |l, idx|
268
- idx == 0 ? "{{blue:> #{l.strip}}}" : "{{blue:>#{l.strip}}}"
269
- end.join("\n")
447
+
448
+ color = (filtering? or selecting?) ? 'green' : 'blue'
449
+ message = message.split("\n").map { |l| "{{#{color}:> #{l.strip}}}" }.join("\n")
270
450
  end
271
451
 
272
452
  CLI::UI.with_frame_color(:blue) do
273
- puts CLI::UI.fmt(message) + CLI::UI::ANSI.clear_to_end_of_line
453
+ puts CLI::UI.fmt(message)
274
454
  end
275
455
  end
276
456
  end
457
+
458
+ def format_choice(format, choice)
459
+ eol = CLI::UI::ANSI.clear_to_end_of_line
460
+ lines = choice.split("\n")
461
+
462
+ return eol if lines.empty? # Handle blank options
463
+
464
+ lines.map! { |l| sprintf(format, l) + eol }
465
+ lines.join("\n")
466
+ end
277
467
  end
278
468
  end
279
469
  end
@@ -197,7 +197,13 @@ module CLI
197
197
  sleep(PERIOD)
198
198
  end
199
199
 
200
- debrief if @auto_debrief
200
+ if @auto_debrief
201
+ debrief
202
+ else
203
+ @m.synchronize do
204
+ @tasks.all?(&:success)
205
+ end
206
+ end
201
207
  end
202
208
 
203
209
  # Debriefs failed tasks is +auto_debrief+ is true
@@ -1,5 +1,5 @@
1
1
  module CLI
2
2
  module UI
3
- VERSION = "1.2.1"
3
+ VERSION = "1.2.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cli-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
@@ -10,22 +10,8 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2018-11-06 00:00:00.000000000 Z
13
+ date: 2019-02-27 00:00:00.000000000 Z
14
14
  dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: bundler
17
- requirement: !ruby/object:Gem::Requirement
18
- requirements:
19
- - - "~>"
20
- - !ruby/object:Gem::Version
21
- version: '1.15'
22
- type: :development
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - "~>"
27
- - !ruby/object:Gem::Version
28
- version: '1.15'
29
15
  - !ruby/object:Gem::Dependency
30
16
  name: rake
31
17
  requirement: !ruby/object:Gem::Requirement
@@ -110,8 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
96
  - !ruby/object:Gem::Version
111
97
  version: '0'
112
98
  requirements: []
113
- rubyforge_project:
114
- rubygems_version: 2.7.6
99
+ rubygems_version: 3.0.2
115
100
  signing_key:
116
101
  specification_version: 4
117
102
  summary: Terminal UI framework