cli-ui 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ad712abce399f06334f0af18135d831f788ab217
4
- data.tar.gz: dd3befbb4a7cf345965bdc10ebbaaa208a93a8db
2
+ SHA256:
3
+ metadata.gz: e8c6abe82a837c62e28cded106185a5ce2d09413637b94fb5bdb6524552648ac
4
+ data.tar.gz: 780168b9d23cd55acd5e95e6abcb7b5b0732c694db2feb0f73d5b04ce71dcd63
5
5
  SHA512:
6
- metadata.gz: 843c4c640d52da02bded3f3ac79bc3b4a7d8e56227f3914a1b3289887bceb89b54d26b11d8cc55e2cf2ad871e04f408e9f5cc631a79ebc3bba4d89ec1fd15afd
7
- data.tar.gz: 133dada99d103ea7449e6138f39d58929b09552895869317a3fba69844057a92eab3a3a0ecb920667a1c3357813c25bfd72af1b9d8ac6feccdb99697a26b928b
6
+ metadata.gz: cea8f4f738765f77a8474221a9449da3f7bb1cae7610fb5d21dc2ee02f7c03996fc26b661db4eefb1af924ab2b7af0469539040763804c7154353037100fdd0f
7
+ data.tar.gz: bfe35b8ded93b0fe857d55836fd0b1aef67b6c5cb036550a152db464e3657607c0fde84621ccfd2541bb477d262b16e3adef0b320a1b037b3664f2141df99404
@@ -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
@@ -2,10 +2,19 @@ inherit_from:
2
2
  - http://shopify.github.io/ruby-style-guide/rubocop.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,15 @@ 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
@@ -1,5 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.3.3
5
- before_install: gem install bundler -v 1.15.0
4
+ - 2.5.8
5
+ - 2.6.6
6
+ - 2.7.1
7
+ before_install: gem update --system
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cli-ui (1.4.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ansi (1.5.0)
10
+ ast (2.4.1)
11
+ builder (3.2.4)
12
+ byebug (11.1.3)
13
+ method_source (1.0.0)
14
+ minitest (5.14.2)
15
+ minitest-reporters (1.4.2)
16
+ ansi
17
+ builder
18
+ minitest (>= 5.0)
19
+ ruby-progressbar
20
+ mocha (1.11.2)
21
+ parallel (1.19.2)
22
+ parser (2.7.2.0)
23
+ ast (~> 2.4.1)
24
+ rainbow (3.0.0)
25
+ rake (13.0.1)
26
+ regexp_parser (1.8.2)
27
+ rexml (3.2.4)
28
+ rubocop (1.1.0)
29
+ parallel (~> 1.10)
30
+ parser (>= 2.7.1.5)
31
+ rainbow (>= 2.2.2, < 4.0)
32
+ regexp_parser (>= 1.8)
33
+ rexml
34
+ rubocop-ast (>= 1.0.1)
35
+ ruby-progressbar (~> 1.7)
36
+ unicode-display_width (>= 1.4.0, < 2.0)
37
+ rubocop-ast (1.1.0)
38
+ parser (>= 2.7.1.5)
39
+ ruby-progressbar (1.10.1)
40
+ unicode-display_width (1.7.0)
41
+
42
+ PLATFORMS
43
+ ruby
44
+
45
+ DEPENDENCIES
46
+ byebug
47
+ cli-ui!
48
+ method_source
49
+ minitest (>= 5.0.0)
50
+ minitest-reporters
51
+ mocha
52
+ rake (~> 13.0)
53
+ rubocop
54
+
55
+ BUNDLED WITH
56
+ 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
@@ -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])
@@ -14,14 +14,14 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "https://github.com/shopify/cli-ui"
15
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
20
  spec.bindir = "exe"
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"
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:
@@ -3,14 +3,16 @@ module CLI
3
3
  autoload :ANSI, 'cli/ui/ansi'
4
4
  autoload :Glyph, 'cli/ui/glyph'
5
5
  autoload :Color, 'cli/ui/color'
6
- autoload :Box, 'cli/ui/box'
7
6
  autoload :Frame, 'cli/ui/frame'
7
+ autoload :OS, 'cli/ui/os'
8
+ autoload :Printer, 'cli/ui/printer'
8
9
  autoload :Progress, 'cli/ui/progress'
9
10
  autoload :Prompt, 'cli/ui/prompt'
10
11
  autoload :Terminal, 'cli/ui/terminal'
11
12
  autoload :Truncater, 'cli/ui/truncater'
12
13
  autoload :Formatter, 'cli/ui/formatter'
13
14
  autoload :Spinner, 'cli/ui/spinner'
15
+ autoload :Widgets, 'cli/ui/widgets'
14
16
 
15
17
  # Convenience accessor to +CLI::UI::Spinner::SpinGroup+
16
18
  SpinGroup = Spinner::SpinGroup
@@ -27,7 +29,7 @@ module CLI
27
29
  end
28
30
 
29
31
  # 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
32
+ # Will lookup using +Color.lookup+ unless it's already a CLI::UI::Color (or nil)
31
33
  #
32
34
  # ==== Attributes
33
35
  #
@@ -35,35 +37,50 @@ module CLI
35
37
  #
36
38
  def self.resolve_color(input)
37
39
  case input
38
- when Symbol
39
- CLI::UI::Color.lookup(input)
40
+ when CLI::UI::Color, nil
41
+ input
40
42
  else
43
+ CLI::UI::Color.lookup(input)
44
+ end
45
+ end
46
+
47
+ # Frame style resolution using +CLI::UI::Frame::FrameStyle.lookup+.
48
+ # Will lookup using +FrameStyle.lookup+ unless it's already a CLI::UI::Frame::FrameStyle(or nil)
49
+ #
50
+ # ==== Attributes
51
+ #
52
+ # * +input+ - frame style to resolve
53
+ def self.resolve_style(input)
54
+ case input
55
+ when CLI::UI::Frame::FrameStyle, nil
41
56
  input
57
+ else
58
+ CLI::UI::Frame::FrameStyle.lookup(input)
42
59
  end
43
60
  end
44
61
 
45
- # Conviencence Method for +CLI::UI::Prompt.confirm+
62
+ # Convenience Method for +CLI::UI::Prompt.confirm+
46
63
  #
47
64
  # ==== Attributes
48
65
  #
49
66
  # * +question+ - question to confirm
50
67
  #
51
- def self.confirm(question)
52
- CLI::UI::Prompt.confirm(question)
68
+ def self.confirm(question, **kwargs)
69
+ CLI::UI::Prompt.confirm(question, **kwargs)
53
70
  end
54
71
 
55
- # Conviencence Method for +CLI::UI::Prompt.ask+
72
+ # Convenience Method for +CLI::UI::Prompt.ask+
56
73
  #
57
74
  # ==== Attributes
58
75
  #
59
76
  # * +question+ - question to ask
60
- # * +kwargs+ - arugments for +Prompt.ask+
77
+ # * +kwargs+ - arguments for +Prompt.ask+
61
78
  #
62
79
  def self.ask(question, **kwargs)
63
80
  CLI::UI::Prompt.ask(question, **kwargs)
64
81
  end
65
82
 
66
- # Conviencence Method to resolve text using +CLI::UI::Formatter.format+
83
+ # Convenience Method to resolve text using +CLI::UI::Formatter.format+
67
84
  # Check +CLI::UI::Formatter::SGR_MAP+ for available formatting options
68
85
  #
69
86
  # ==== Attributes
@@ -75,10 +92,10 @@ module CLI
75
92
  return input if input.nil?
76
93
  formatted = CLI::UI::Formatter.new(input).format
77
94
  return formatted unless truncate_to
78
- return CLI::UI::Truncater.call(formatted, truncate_to)
95
+ CLI::UI::Truncater.call(formatted, truncate_to)
79
96
  end
80
97
 
81
- # Conviencence Method to format text using +CLI::UI::Formatter.format+
98
+ # Convenience Method to format text using +CLI::UI::Formatter.format+
82
99
  # Check +CLI::UI::Formatter::SGR_MAP+ for available formatting options
83
100
  #
84
101
  # https://user-images.githubusercontent.com/3074765/33799827-6d0721a2-dd01-11e7-9ab5-c3d455264afe.png
@@ -96,29 +113,40 @@ module CLI
96
113
  CLI::UI::Formatter.new(input).format(enable_color: enable_color)
97
114
  end
98
115
 
99
- # Conviencence Method for +CLI::UI::Frame.open+
116
+ # Convenience Method for +CLI::UI::Printer.puts+
117
+ #
118
+ # ==== Attributes
119
+ #
120
+ # * +msg+ - Message to print
121
+ # * +kwargs+ - keyword arguments for +Printer.puts+
122
+ #
123
+ def self.puts(msg, **kwargs)
124
+ CLI::UI::Printer.puts(msg, **kwargs)
125
+ end
126
+
127
+ # Convenience Method for +CLI::UI::Frame.open+
100
128
  #
101
129
  # ==== Attributes
102
130
  #
103
131
  # * +args+ - arguments for +Frame.open+
104
132
  # * +block+ - block for +Frame.open+
105
133
  #
106
- def self.frame(*args, &block)
107
- CLI::UI::Frame.open(*args, &block)
134
+ def self.frame(*args, **kwargs, &block)
135
+ CLI::UI::Frame.open(*args, **kwargs, &block)
108
136
  end
109
137
 
110
- # Conviencence Method for +CLI::UI::Spinner.spin+
138
+ # Convenience Method for +CLI::UI::Spinner.spin+
111
139
  #
112
140
  # ==== Attributes
113
141
  #
114
142
  # * +args+ - arguments for +Spinner.open+
115
143
  # * +block+ - block for +Spinner.open+
116
144
  #
117
- def self.spinner(*args, &block)
118
- CLI::UI::Spinner.spin(*args, &block)
145
+ def self.spinner(*args, **kwargs, &block)
146
+ CLI::UI::Spinner.spin(*args, **kwargs, &block)
119
147
  end
120
148
 
121
- # Conviencence Method to override frame color using +CLI::UI::Frame.with_frame_color+
149
+ # Convenience Method to override frame color using +CLI::UI::Frame.with_frame_color+
122
150
  #
123
151
  # ==== Attributes
124
152
  #
@@ -142,7 +170,7 @@ module CLI
142
170
  CLI::UI::StdoutRouter.duplicate_output_to = File.open(path, 'w')
143
171
  yield
144
172
  ensure
145
- if file_descriptor = CLI::UI::StdoutRouter.duplicate_output_to
173
+ if (file_descriptor = CLI::UI::StdoutRouter.duplicate_output_to)
146
174
  file_descriptor.close
147
175
  CLI::UI::StdoutRouter.duplicate_output_to = nil
148
176
  end
@@ -181,6 +209,19 @@ module CLI
181
209
  end
182
210
 
183
211
  self.enable_color = $stdout.tty?
212
+
213
+ # Set the default frame style.
214
+ # Convenience method for setting the default frame style with +CLI::UI::Frame.frame_style=+
215
+ #
216
+ # Raises ArgumentError if +frame_style+ is not valid
217
+ #
218
+ # ==== Attributes
219
+ #
220
+ # * +symbol+ - the default frame style to use for frames
221
+ #
222
+ def self.frame_style=(frame_style)
223
+ Frame.frame_style = frame_style.to_sym
224
+ end
184
225
  end
185
226
  end
186
227
 
@@ -106,7 +106,9 @@ module CLI
106
106
  # * +n+ - The column to move to
107
107
  #
108
108
  def self.cursor_horizontal_absolute(n = 1)
109
- control(n.to_s, 'G')
109
+ cmd = control(n.to_s, 'G')
110
+ cmd += control('1', 'D') if CLI::UI::OS.current.shift_cursor_on_line_reset?
111
+ cmd
110
112
  end
111
113
 
112
114
  # Show the cursor
@@ -136,13 +138,17 @@ module CLI
136
138
  # Move to the next line
137
139
  #
138
140
  def self.next_line
139
- cursor_down + control('1', 'G')
141
+ cmd = cursor_down + control('1', 'G')
142
+ cmd += control('1', 'D') if CLI::UI::OS.current.shift_cursor_on_line_reset?
143
+ cmd
140
144
  end
141
145
 
142
146
  # Move to the previous line
143
147
  #
144
148
  def self.previous_line
145
- cursor_up + control('1', 'G')
149
+ cmd = cursor_up + control('1', 'G')
150
+ cmd += control('1', 'D') if CLI::UI::OS.current.shift_cursor_on_line_reset?
151
+ cmd
146
152
  end
147
153
 
148
154
  def self.clear_to_end_of_line