cli-ui 1.3.0 → 1.4.0

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.
@@ -15,8 +15,13 @@ module CLI
15
15
  @options[option] = handler
16
16
  end
17
17
 
18
- def call(option)
19
- @options[option].call(option)
18
+ def call(options)
19
+ case options
20
+ when Array
21
+ options.map { |option| @options[option].call(options) }
22
+ else
23
+ @options[options].call(options)
24
+ end
20
25
  end
21
26
  end
22
27
  end
@@ -10,13 +10,11 @@ module CLI
10
10
  PERIOD = 0.1 # seconds
11
11
  TASK_FAILED = :task_failed
12
12
 
13
- RUNES = %w(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏).freeze
13
+ RUNES = CLI::UI::OS.current.supports_emoji? ? %w(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏).freeze : %w(\\ | / - \\ | / -).freeze
14
14
 
15
- begin
16
- colors = [CLI::UI::Color::CYAN.code] * 5 + [CLI::UI::Color::MAGENTA.code] * 5
17
- raise unless RUNES.size == colors.size
18
- GLYPHS = colors.zip(RUNES).map(&:join)
19
- end
15
+ colors = [CLI::UI::Color::CYAN.code] * (RUNES.size / 2).ceil +
16
+ [CLI::UI::Color::MAGENTA.code] * (RUNES.size / 2).to_i
17
+ GLYPHS = colors.zip(RUNES).map(&:join)
20
18
 
21
19
  class << self
22
20
  attr_accessor(:index)
@@ -25,6 +25,7 @@ module CLI
25
25
  @consumed_lines = 0
26
26
  @tasks = []
27
27
  @auto_debrief = auto_debrief
28
+ @start = Time.new
28
29
  end
29
30
 
30
31
  class Task
@@ -51,8 +52,9 @@ module CLI
51
52
  end
52
53
  end
53
54
 
55
+ @m = Mutex.new
54
56
  @force_full_render = false
55
- @done = false
57
+ @done = false
56
58
  @exception = nil
57
59
  @success = false
58
60
  end
@@ -95,13 +97,15 @@ module CLI
95
97
  # * +width+ - current terminal width to format for
96
98
  #
97
99
  def render(index, force = true, width: CLI::UI::Terminal.width)
98
- if force || @always_full_render || @force_full_render
99
- full_render(index, width)
100
- else
101
- partial_render(index)
100
+ @m.synchronize do
101
+ if force || @always_full_render || @force_full_render
102
+ full_render(index, width)
103
+ else
104
+ partial_render(index)
105
+ end
106
+ ensure
107
+ @force_full_render = false
102
108
  end
103
- ensure
104
- @force_full_render = false
105
109
  end
106
110
 
107
111
  # Update the spinner title
@@ -111,9 +115,11 @@ module CLI
111
115
  # * +title+ - title to change the spinner to
112
116
  #
113
117
  def update_title(new_title)
114
- @always_full_render = new_title =~ Formatter::SCAN_WIDGET
115
- @title = new_title
116
- @force_full_render = true
118
+ @m.synchronize do
119
+ @always_full_render = new_title =~ Formatter::SCAN_WIDGET
120
+ @title = new_title
121
+ @force_full_render = true
122
+ end
117
123
  end
118
124
 
119
125
  private
@@ -197,7 +203,7 @@ module CLI
197
203
  @consumed_lines += 1
198
204
  else
199
205
  offset = @consumed_lines - int_index
200
- move_to = CLI::UI::ANSI.cursor_up(offset) + "\r"
206
+ move_to = CLI::UI::ANSI.cursor_up(offset) + "\r"
201
207
  move_from = "\r" + CLI::UI::ANSI.cursor_down(offset)
202
208
 
203
209
  print(move_to + task.render(idx, idx.zero?, width: width) + move_from)
@@ -233,7 +239,7 @@ module CLI
233
239
  out = task.stdout
234
240
  err = task.stderr
235
241
 
236
- CLI::UI::Frame.open('Task Failed: ' + task.title, color: :red) do
242
+ CLI::UI::Frame.open('Task Failed: ' + task.title, color: :red, timing: Time.new - @start) do
237
243
  if e
238
244
  puts "#{e.class}: #{e.message}"
239
245
  puts "\tfrom #{e.backtrace.join("\n\tfrom ")}"
@@ -26,13 +26,14 @@ module CLI
26
26
  end
27
27
  end
28
28
 
29
- hook = Thread.current[:cliui_output_hook]
30
29
  # hook return of false suppresses output.
31
- if !hook || hook.call(args.first, @name) != false
32
- @stream.write_without_cli_ui(*prepend_id(@stream, args))
33
- if dup = StdoutRouter.duplicate_output_to
34
- dup.write(*prepend_id(dup, args))
35
- end
30
+ if (hook = Thread.current[:cliui_output_hook])
31
+ return if hook.call(args.map(&:to_s).join, @name) == false
32
+ end
33
+
34
+ @stream.write_without_cli_ui(*prepend_id(@stream, args))
35
+ if (dup = StdoutRouter.duplicate_output_to)
36
+ dup.write(*prepend_id(dup, args))
36
37
  end
37
38
  end
38
39
 
@@ -117,6 +118,10 @@ module CLI
117
118
  prev_frame_inset = Thread.current[:no_cliui_frame_inset]
118
119
  prev_hook = Thread.current[:cliui_output_hook]
119
120
 
121
+ if Thread.current.respond_to?(:report_on_exception)
122
+ Thread.current.report_on_exception = false
123
+ end
124
+
120
125
  self.class.with_stdin_masked do
121
126
  Thread.current[:no_cliui_frame_inset] = !@with_frame_inset
122
127
  Thread.current[:cliui_output_hook] = ->(data, stream) do
@@ -159,7 +164,7 @@ module CLI
159
164
  id = format("%05d", rand(10**5))
160
165
  Thread.current[:cliui_output_id] = {
161
166
  id: id,
162
- streams: on_streams
167
+ streams: on_streams,
163
168
  }
164
169
  yield(id)
165
170
  ensure
@@ -8,28 +8,38 @@ module CLI
8
8
  DEFAULT_HEIGHT = 24
9
9
 
10
10
  # Returns the width of the terminal, if possible
11
- # Otherwise will return 80
11
+ # Otherwise will return DEFAULT_WIDTH
12
12
  #
13
13
  def self.width
14
- if console = IO.respond_to?(:console) && IO.console
15
- width = console.winsize[1]
16
- width.zero? ? DEFAULT_WIDTH : width
17
- else
18
- DEFAULT_WIDTH
19
- end
20
- rescue Errno::EIO
21
- DEFAULT_WIDTH
14
+ winsize[1]
22
15
  end
23
16
 
17
+ # Returns the width of the terminal, if possible
18
+ # Otherwise, will return DEFAULT_HEIGHT
19
+ #
24
20
  def self.height
25
- if console = IO.respond_to?(:console) && IO.console
26
- height = console.winsize[0]
27
- height.zero? ? DEFAULT_HEIGHT : height
28
- else
29
- DEFAULT_HEIGHT
21
+ winsize[0]
22
+ end
23
+
24
+ def self.winsize
25
+ @winsize ||= begin
26
+ winsize = IO.console.winsize
27
+ setup_winsize_trap
28
+
29
+ if winsize.any?(&:zero?)
30
+ [DEFAULT_HEIGHT, DEFAULT_WIDTH]
31
+ else
32
+ winsize
33
+ end
34
+ rescue
35
+ [DEFAULT_HEIGHT, DEFAULT_WIDTH]
36
+ end
37
+ end
38
+
39
+ def self.setup_winsize_trap
40
+ @winsize_trap ||= Signal.trap('WINCH') do
41
+ @winsize = nil
30
42
  end
31
- rescue Errno::EIO
32
- DEFAULT_HEIGHT
33
43
  end
34
44
  end
35
45
  end
@@ -52,11 +52,11 @@ module CLI
52
52
  end
53
53
  end
54
54
  when PARSE_ESC
55
- case cp
55
+ mode = case cp
56
56
  when LEFT_SQUARE_BRACKET
57
- mode = PARSE_ANSI
57
+ PARSE_ANSI
58
58
  else
59
- mode = PARSE_ROOT
59
+ PARSE_ROOT
60
60
  end
61
61
  when PARSE_ANSI
62
62
  # ANSI escape codes preeeetty much have the format of:
@@ -1,5 +1,5 @@
1
1
  module CLI
2
2
  module UI
3
- VERSION = "1.3.0"
3
+ VERSION = "1.4.0"
4
4
  end
5
5
  end
@@ -49,6 +49,7 @@ module CLI
49
49
 
50
50
  class InvalidWidgetHandle < ArgumentError
51
51
  def initialize(handle)
52
+ super
52
53
  @handle = handle
53
54
  end
54
55
 
@@ -61,6 +62,7 @@ module CLI
61
62
 
62
63
  class InvalidWidgetArguments < ArgumentError
63
64
  def initialize(argstring, pattern)
65
+ super
64
66
  @argstring = argstring
65
67
  @pattern = pattern
66
68
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cli-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
8
  - Julian Nadeau
9
9
  - Lisa Ugray
10
- autorequire:
10
+ autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2019-08-14 00:00:00.000000000 Z
13
+ date: 2020-11-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -18,14 +18,14 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '10.0'
21
+ version: '13.0'
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '10.0'
28
+ version: '13.0'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: minitest
31
31
  requirement: !ruby/object:Gem::Requirement
@@ -49,12 +49,14 @@ executables: []
49
49
  extensions: []
50
50
  extra_rdoc_files: []
51
51
  files:
52
+ - ".dependabot/config.yml"
52
53
  - ".github/CODEOWNERS"
53
54
  - ".github/probots.yml"
54
55
  - ".gitignore"
55
56
  - ".rubocop.yml"
56
57
  - ".travis.yml"
57
58
  - Gemfile
59
+ - Gemfile.lock
58
60
  - LICENSE.txt
59
61
  - README.md
60
62
  - Rakefile
@@ -63,11 +65,16 @@ files:
63
65
  - dev.yml
64
66
  - lib/cli/ui.rb
65
67
  - lib/cli/ui/ansi.rb
66
- - lib/cli/ui/box.rb
67
68
  - lib/cli/ui/color.rb
68
69
  - lib/cli/ui/formatter.rb
69
70
  - lib/cli/ui/frame.rb
71
+ - lib/cli/ui/frame/frame_stack.rb
72
+ - lib/cli/ui/frame/frame_style.rb
73
+ - lib/cli/ui/frame/frame_style/box.rb
74
+ - lib/cli/ui/frame/frame_style/bracket.rb
70
75
  - lib/cli/ui/glyph.rb
76
+ - lib/cli/ui/os.rb
77
+ - lib/cli/ui/printer.rb
71
78
  - lib/cli/ui/progress.rb
72
79
  - lib/cli/ui/prompt.rb
73
80
  - lib/cli/ui/prompt/interactive_options.rb
@@ -86,7 +93,7 @@ homepage: https://github.com/shopify/cli-ui
86
93
  licenses:
87
94
  - MIT
88
95
  metadata: {}
89
- post_install_message:
96
+ post_install_message:
90
97
  rdoc_options: []
91
98
  require_paths:
92
99
  - lib
@@ -101,8 +108,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
108
  - !ruby/object:Gem::Version
102
109
  version: '0'
103
110
  requirements: []
104
- rubygems_version: 3.0.3
105
- signing_key:
111
+ rubygems_version: 3.0.2
112
+ signing_key:
106
113
  specification_version: 4
107
114
  summary: Terminal UI framework
108
115
  test_files: []
@@ -1,15 +0,0 @@
1
- require 'cli/ui'
2
-
3
- module CLI
4
- module UI
5
- module Box
6
- module Heavy
7
- VERT = '┃'
8
- HORZ = '━'
9
- DIV = "┣"
10
- TL = '┏'
11
- BL = '┗'
12
- end
13
- end
14
- end
15
- end