cli-ui 1.3.0 → 1.4.0

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