cli-ui 1.2.1 → 1.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37c3f9d8f4c1cd9dcf6d86319d35b947d2b99ae0dc0f1b975397d77f555f1f57
4
- data.tar.gz: d7b3eee8bba21a191746ecf244c428f8c702e1c2fbfb41242740d38a9d317dab
3
+ metadata.gz: 8de8c1fd6c855f812125e71e85dbfc12163dfd504215fab462d56ad5f4d2cc7e
4
+ data.tar.gz: 404f164084fd9cf85aa382a5d5f93b77b08ea4bc529840ebfe230e1b5ea7c620
5
5
  SHA512:
6
- metadata.gz: e35d9d93f31d2bacbd1623d63937f99deecc928e7ef97ebe0b5c4f6199b37952d9d7dad97cfe004ce7cc03296776f7767ccf08336dcbc261eb63f097450211cc
7
- data.tar.gz: a184a3dc46bfe4074bbfb8571253e00bc016ac40734ea2ab13baeabe526cfa3194855d3ca69424fd1b069157c7ec4ee7fc76debbdca71ecaa48fc145446039a8
6
+ metadata.gz: 9f737c534e372589165a3263854d3a90f024181f632f6ae918fcb7aafea69abad27f50246d35c2957c238447a74871f4705add26d1bf272ad58f4fcc52d31ae6
7
+ data.tar.gz: 56c449900c817637b97d0e99b05ac01375bbde1458db3f2d5e7122027cdd525e0b8aaf9b9d5290cc2f1fa8cae314efb1365ac46ab277629f5cebf5d113e39b0d
@@ -0,0 +1,8 @@
1
+ version: 1
2
+ update_configs:
3
+ - package_manager: "ruby:bundler"
4
+ directory: "/"
5
+ update_schedule: "weekly"
6
+ automerged_updates:
7
+ - match:
8
+ update_type: "semver:minor"
@@ -0,0 +1 @@
1
+ * @Shopify/dev-infra
@@ -0,0 +1,2 @@
1
+ enabled:
2
+ - cla
data/.gitignore CHANGED
@@ -1,4 +1,3 @@
1
- Gemfile.lock
2
1
  *.gem
3
2
  build
4
3
  .vagrant
data/.rubocop.yml CHANGED
@@ -1,11 +1,20 @@
1
- inherit_from:
2
- - http://shopify.github.io/ruby-style-guide/rubocop.yml
1
+ inherit_gem:
2
+ rubocop-shopify: rubocop-cli.yml
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 2.1
5
+ Exclude:
6
+ - vendor/**/*
7
+ TargetRubyVersion: 2.5
8
+
9
+ Style/FrozenStringLiteralComment:
10
+ Enabled: false
11
+
12
+ # This doesn't understand that <<~ doesn't exist in 2.0
13
+ Layout/HeredocIndentation:
14
+ Enabled: false
6
15
 
7
16
  # This doesn't take into account retrying from an exception
8
- Lint/HandleExceptions:
17
+ Lint/SuppressedException:
9
18
  Enabled: false
10
19
 
11
20
  # allow String.new to create mutable strings
@@ -15,3 +24,18 @@ Style/EmptyLiteral:
15
24
  # allow the use of globals which makes sense in a CLI app like this
16
25
  Style/GlobalVars:
17
26
  Enabled: false
27
+
28
+ # allow using %r{} for regexes
29
+ Style/RegexpLiteral:
30
+ Enabled: false
31
+
32
+ # allow readable Dev::Util.begin formatting
33
+ Style/MultilineBlockChain:
34
+ Enabled: false
35
+
36
+ # we prefer rescue to align with the beginning of the line containing begin, not begin itself
37
+ Layout/RescueEnsureAlignment:
38
+ Enabled: false
39
+
40
+ Style/StringLiterals:
41
+ EnforcedStyle: single_quotes
data/.travis.yml CHANGED
@@ -1,5 +1,7 @@
1
- sudo: false
2
1
  language: ruby
3
2
  rvm:
4
- - 2.3.3
5
- before_install: gem install bundler -v 1.15.0
3
+ - 2.5.8
4
+ - 2.6.6
5
+ - 2.7.1
6
+ - jruby-9.2.14.0
7
+ before_install: gem update --system
data/Gemfile CHANGED
@@ -1,11 +1,12 @@
1
1
  # NOTE: These are development-only dependencies
2
- source "https://rubygems.org"
2
+ source 'https://rubygems.org'
3
3
 
4
4
  gemspec
5
5
 
6
6
  group :development, :test do
7
7
  gem 'rubocop'
8
- gem 'byebug'
8
+ gem 'rubocop-shopify'
9
+ gem 'byebug', platforms: [:mri]
9
10
  gem 'method_source'
10
11
  end
11
12
 
data/Gemfile.lock ADDED
@@ -0,0 +1,60 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cli-ui (1.5.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ansi (1.5.0)
10
+ ast (2.4.2)
11
+ builder (3.2.4)
12
+ byebug (11.1.3)
13
+ method_source (1.0.0)
14
+ minitest (5.14.4)
15
+ minitest-reporters (1.4.3)
16
+ ansi
17
+ builder
18
+ minitest (>= 5.0)
19
+ ruby-progressbar
20
+ mocha (1.12.0)
21
+ parallel (1.20.1)
22
+ parser (3.0.0.0)
23
+ ast (~> 2.4.1)
24
+ rainbow (3.0.0)
25
+ rake (13.0.3)
26
+ regexp_parser (2.1.1)
27
+ rexml (3.2.5)
28
+ rubocop (1.12.1)
29
+ parallel (~> 1.10)
30
+ parser (>= 3.0.0.0)
31
+ rainbow (>= 2.2.2, < 4.0)
32
+ regexp_parser (>= 1.8, < 3.0)
33
+ rexml
34
+ rubocop-ast (>= 1.2.0, < 2.0)
35
+ ruby-progressbar (~> 1.7)
36
+ unicode-display_width (>= 1.4.0, < 3.0)
37
+ rubocop-ast (1.4.1)
38
+ parser (>= 2.7.1.5)
39
+ rubocop-shopify (2.0.1)
40
+ rubocop (~> 1.11)
41
+ ruby-progressbar (1.11.0)
42
+ unicode-display_width (2.0.0)
43
+
44
+ PLATFORMS
45
+ java
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ byebug
50
+ cli-ui!
51
+ method_source
52
+ minitest (>= 5.0.0)
53
+ minitest-reporters
54
+ mocha
55
+ rake (~> 13.0)
56
+ rubocop
57
+ rubocop-shopify
58
+
59
+ BUNDLED WITH
60
+ 2.1.0
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))
@@ -105,13 +108,26 @@ puts CLI::UI.fmt "{{red:Red}} {{green:Green}}"
105
108
  e.g. `{{*}}` => a yellow ⭑
106
109
 
107
110
  ```ruby
108
- puts CLI::UI.fmt "{{*}} {{x}} {{?}} {{v}}"
111
+ puts CLI::UI.fmt "{{*}} {{v}} {{?}} {{x}}"
109
112
  ```
110
113
 
111
114
  ![Symbol Formatting](https://user-images.githubusercontent.com/3074765/33799847-9ec03fd0-dd01-11e7-93f7-5f5cc540e61e.png)
112
115
 
113
116
  ---
114
117
 
118
+ ### Status Widget
119
+
120
+ ```ruby
121
+ CLI::UI::Spinner.spin("building packages: {{@widget/status:1:2:3:4}}") do |spinner|
122
+ # spinner.update_title(...)
123
+ sleep(3)
124
+ end
125
+ ```
126
+
127
+ ![Status Widget](https://user-images.githubusercontent.com/1284/61405142-11042580-a8a7-11e9-9885-46ba44c46358.gif)
128
+
129
+ ---
130
+
115
131
  ### Progress Bar
116
132
 
117
133
  Show progress of a process or operation.
@@ -128,6 +144,37 @@ end
128
144
 
129
145
  ---
130
146
 
147
+ ### Frame Styles
148
+
149
+ Modify the appearance of CLI::UI both globally and on an individual frame level.
150
+
151
+ To set the default style:
152
+
153
+ ```ruby
154
+ CLI::UI.frame_style = :box
155
+ ```
156
+
157
+ To style an individual frame:
158
+
159
+ ```ruby
160
+ CLI::UI.frame('New Style!', frame_style: :bracket) { puts 'It's pretty cool!' }
161
+ ```
162
+
163
+ The default style - `:box` - is what has been used up until now. The other style - `:bracket` - looks like this:
164
+
165
+ ```ruby
166
+ CLI::UI.frame_style = :bracket
167
+ CLI::UI::StdoutRouter.enable
168
+ CLI::UI::Frame.open('Frame 1') do
169
+ CLI::UI::Frame.open('Frame 2') { puts "inside frame 2" }
170
+ puts "inside frame 1"
171
+ end
172
+ ```
173
+
174
+ ![Frame Style](https://user-images.githubusercontent.com/315948/65287373-9a82de80-db08-11e9-94fb-20f4b7561c07.png)
175
+
176
+ ---
177
+
131
178
  ## Example Usage
132
179
 
133
180
  The following code makes use of nested-framing, multi-threaded spinners, formatted text, and more.
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require 'bundler/gem_tasks'
7
7
  TEST_ROOT = File.expand_path('../test', __FILE__)
8
8
 
9
9
  Rake::TestTask.new do |t|
10
- t.libs += ["test"]
10
+ t.libs += ['test']
11
11
  t.test_files = FileList[File.join(TEST_ROOT, '**', '*_test.rb')]
12
12
  t.verbose = false
13
13
  t.warning = false
@@ -17,4 +17,4 @@ RuboCop::RakeTask.new(:style) do |t|
17
17
  t.options = ['--display-cop-names']
18
18
  end
19
19
 
20
- task default: [:test]
20
+ task(default: [:test, :style])
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "cli/ui"
3
+ require 'bundler/setup'
4
+ require 'cli/ui'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "cli/ui"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start(__FILE__)
data/cli-ui.gemspec CHANGED
@@ -1,27 +1,27 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
2
+ lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "cli/ui/version"
4
+ require 'cli/ui/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "cli-ui"
7
+ spec.name = 'cli-ui'
8
8
  spec.version = CLI::UI::VERSION
9
- spec.authors = ["Burke Libbey", "Julian Nadeau", "Lisa Ugray"]
10
- spec.email = ["burke.libbey@shopify.com", "julian.nadeau@shopify.com", "lisa.ugray@shopify.com"]
9
+ spec.authors = ['Burke Libbey', 'Julian Nadeau', 'Lisa Ugray']
10
+ spec.email = ['burke.libbey@shopify.com', 'julian.nadeau@shopify.com', 'lisa.ugray@shopify.com']
11
11
 
12
12
  spec.summary = 'Terminal UI framework'
13
13
  spec.description = 'Terminal UI framework'
14
- spec.homepage = "https://github.com/shopify/cli-ui"
15
- spec.license = "MIT"
14
+ spec.homepage = 'https://github.com/shopify/cli-ui'
15
+ spec.license = 'MIT'
16
16
 
17
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ spec.files = %x(git ls-files -z).split("\x0").reject do |f|
18
18
  f.match(%r{^(test|spec|features)/})
19
19
  end
20
- spec.bindir = "exe"
20
+ spec.bindir = 'exe'
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
- spec.require_paths = ["lib"]
22
+ spec.require_paths = ['lib']
23
23
 
24
- spec.add_development_dependency "bundler", "~> 1.15"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "minitest", "~> 5.0"
24
+ # spec.add_development_dependency "bundler", "~> 2.0"
25
+ spec.add_development_dependency('rake', '~> 13.0')
26
+ spec.add_development_dependency('minitest', '~> 5.0')
27
27
  end
data/dev.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  up:
2
- - ruby: 2.3.3
2
+ - ruby: 2.5.1
3
3
  - bundler
4
4
 
5
5
  commands:
data/lib/cli/ui.rb CHANGED
@@ -1,16 +1,19 @@
1
1
  module CLI
2
2
  module UI
3
- autoload :ANSI, 'cli/ui/ansi'
4
- autoload :Glyph, 'cli/ui/glyph'
5
- autoload :Color, 'cli/ui/color'
6
- autoload :Box, 'cli/ui/box'
7
- autoload :Frame, 'cli/ui/frame'
8
- autoload :Progress, 'cli/ui/progress'
9
- autoload :Prompt, 'cli/ui/prompt'
10
- autoload :Terminal, 'cli/ui/terminal'
11
- autoload :Truncater, 'cli/ui/truncater'
12
- autoload :Formatter, 'cli/ui/formatter'
13
- autoload :Spinner, 'cli/ui/spinner'
3
+ autoload :ANSI, 'cli/ui/ansi'
4
+ autoload :Glyph, 'cli/ui/glyph'
5
+ autoload :Color, 'cli/ui/color'
6
+ autoload :Frame, 'cli/ui/frame'
7
+ autoload :OS, 'cli/ui/os'
8
+ autoload :Printer, 'cli/ui/printer'
9
+ autoload :Progress, 'cli/ui/progress'
10
+ autoload :Prompt, 'cli/ui/prompt'
11
+ autoload :Terminal, 'cli/ui/terminal'
12
+ autoload :Truncater, 'cli/ui/truncater'
13
+ autoload :Formatter, 'cli/ui/formatter'
14
+ autoload :Spinner, 'cli/ui/spinner'
15
+ autoload :Widgets, 'cli/ui/widgets'
16
+ autoload :Wrap, 'cli/ui/wrap'
14
17
 
15
18
  # Convenience accessor to +CLI::UI::Spinner::SpinGroup+
16
19
  SpinGroup = Spinner::SpinGroup
@@ -27,7 +30,7 @@ module CLI
27
30
  end
28
31
 
29
32
  # Color resolution using +CLI::UI::Color.lookup+
30
- # Will lookup using +Color.lookup+ if a symbol, otherwise we assume it is a valid color and return it
33
+ # Will lookup using +Color.lookup+ unless it's already a CLI::UI::Color (or nil)
31
34
  #
32
35
  # ==== Attributes
33
36
  #
@@ -35,35 +38,50 @@ module CLI
35
38
  #
36
39
  def self.resolve_color(input)
37
40
  case input
38
- when Symbol
39
- CLI::UI::Color.lookup(input)
41
+ when CLI::UI::Color, nil
42
+ input
40
43
  else
44
+ CLI::UI::Color.lookup(input)
45
+ end
46
+ end
47
+
48
+ # Frame style resolution using +CLI::UI::Frame::FrameStyle.lookup+.
49
+ # Will lookup using +FrameStyle.lookup+ unless it's already a CLI::UI::Frame::FrameStyle(or nil)
50
+ #
51
+ # ==== Attributes
52
+ #
53
+ # * +input+ - frame style to resolve
54
+ def self.resolve_style(input)
55
+ case input
56
+ when CLI::UI::Frame::FrameStyle, nil
41
57
  input
58
+ else
59
+ CLI::UI::Frame::FrameStyle.lookup(input)
42
60
  end
43
61
  end
44
62
 
45
- # Conviencence Method for +CLI::UI::Prompt.confirm+
63
+ # Convenience Method for +CLI::UI::Prompt.confirm+
46
64
  #
47
65
  # ==== Attributes
48
66
  #
49
67
  # * +question+ - question to confirm
50
68
  #
51
- def self.confirm(question)
52
- CLI::UI::Prompt.confirm(question)
69
+ def self.confirm(question, **kwargs)
70
+ CLI::UI::Prompt.confirm(question, **kwargs)
53
71
  end
54
72
 
55
- # Conviencence Method for +CLI::UI::Prompt.ask+
73
+ # Convenience Method for +CLI::UI::Prompt.ask+
56
74
  #
57
75
  # ==== Attributes
58
76
  #
59
77
  # * +question+ - question to ask
60
- # * +kwargs+ - arugments for +Prompt.ask+
78
+ # * +kwargs+ - arguments for +Prompt.ask+
61
79
  #
62
80
  def self.ask(question, **kwargs)
63
81
  CLI::UI::Prompt.ask(question, **kwargs)
64
82
  end
65
83
 
66
- # Conviencence Method to resolve text using +CLI::UI::Formatter.format+
84
+ # Convenience Method to resolve text using +CLI::UI::Formatter.format+
67
85
  # Check +CLI::UI::Formatter::SGR_MAP+ for available formatting options
68
86
  #
69
87
  # ==== Attributes
@@ -75,10 +93,10 @@ module CLI
75
93
  return input if input.nil?
76
94
  formatted = CLI::UI::Formatter.new(input).format
77
95
  return formatted unless truncate_to
78
- return CLI::UI::Truncater.call(formatted, truncate_to)
96
+ CLI::UI::Truncater.call(formatted, truncate_to)
79
97
  end
80
98
 
81
- # Conviencence Method to format text using +CLI::UI::Formatter.format+
99
+ # Convenience Method to format text using +CLI::UI::Formatter.format+
82
100
  # Check +CLI::UI::Formatter::SGR_MAP+ for available formatting options
83
101
  #
84
102
  # https://user-images.githubusercontent.com/3074765/33799827-6d0721a2-dd01-11e7-9ab5-c3d455264afe.png
@@ -96,29 +114,44 @@ module CLI
96
114
  CLI::UI::Formatter.new(input).format(enable_color: enable_color)
97
115
  end
98
116
 
99
- # Conviencence Method for +CLI::UI::Frame.open+
117
+ def self.wrap(input)
118
+ CLI::UI::Wrap.new(input).wrap
119
+ end
120
+
121
+ # Convenience Method for +CLI::UI::Printer.puts+
122
+ #
123
+ # ==== Attributes
124
+ #
125
+ # * +msg+ - Message to print
126
+ # * +kwargs+ - keyword arguments for +Printer.puts+
127
+ #
128
+ def self.puts(msg, **kwargs)
129
+ CLI::UI::Printer.puts(msg, **kwargs)
130
+ end
131
+
132
+ # Convenience Method for +CLI::UI::Frame.open+
100
133
  #
101
134
  # ==== Attributes
102
135
  #
103
136
  # * +args+ - arguments for +Frame.open+
104
137
  # * +block+ - block for +Frame.open+
105
138
  #
106
- def self.frame(*args, &block)
107
- CLI::UI::Frame.open(*args, &block)
139
+ def self.frame(*args, **kwargs, &block)
140
+ CLI::UI::Frame.open(*args, **kwargs, &block)
108
141
  end
109
142
 
110
- # Conviencence Method for +CLI::UI::Spinner.spin+
143
+ # Convenience Method for +CLI::UI::Spinner.spin+
111
144
  #
112
145
  # ==== Attributes
113
146
  #
114
147
  # * +args+ - arguments for +Spinner.open+
115
148
  # * +block+ - block for +Spinner.open+
116
149
  #
117
- def self.spinner(*args, &block)
118
- CLI::UI::Spinner.spin(*args, &block)
150
+ def self.spinner(*args, **kwargs, &block)
151
+ CLI::UI::Spinner.spin(*args, **kwargs, &block)
119
152
  end
120
153
 
121
- # Conviencence Method to override frame color using +CLI::UI::Frame.with_frame_color+
154
+ # Convenience Method to override frame color using +CLI::UI::Frame.with_frame_color+
122
155
  #
123
156
  # ==== Attributes
124
157
  #
@@ -137,12 +170,12 @@ module CLI
137
170
  #
138
171
  def self.log_output_to(path)
139
172
  if CLI::UI::StdoutRouter.duplicate_output_to
140
- raise "multiple logs not allowed"
173
+ raise 'multiple logs not allowed'
141
174
  end
142
175
  CLI::UI::StdoutRouter.duplicate_output_to = File.open(path, 'w')
143
176
  yield
144
177
  ensure
145
- if file_descriptor = CLI::UI::StdoutRouter.duplicate_output_to
178
+ if (file_descriptor = CLI::UI::StdoutRouter.duplicate_output_to)
146
179
  file_descriptor.close
147
180
  CLI::UI::StdoutRouter.duplicate_output_to = nil
148
181
  end
@@ -181,6 +214,19 @@ module CLI
181
214
  end
182
215
 
183
216
  self.enable_color = $stdout.tty?
217
+
218
+ # Set the default frame style.
219
+ # Convenience method for setting the default frame style with +CLI::UI::Frame.frame_style=+
220
+ #
221
+ # Raises ArgumentError if +frame_style+ is not valid
222
+ #
223
+ # ==== Attributes
224
+ #
225
+ # * +symbol+ - the default frame style to use for frames
226
+ #
227
+ def self.frame_style=(frame_style)
228
+ Frame.frame_style = frame_style.to_sym
229
+ end
184
230
  end
185
231
  end
186
232