cli-ui 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dec73837349569f0f2d2555575e7fea915e3dc5d
4
+ data.tar.gz: b7386d60f9bdb31b1889e62356925cce2030cfbf
5
+ SHA512:
6
+ metadata.gz: 19b01cb99b895ba3be3033576adcbf408bf0ce64859d7824c93ad26e1f3a04f5d23d06ce19338834191c5f9f6ea29c9f469334794d71898c273707019d31f7cc
7
+ data.tar.gz: 26c8932e7e8fe55808eabdecc03b5ff6bc2bb671c3f6339d1c145a2dd0ccc93439be8e03c6b622c07115ca5b6cd310fc6c38e74f8ba396a8f19e631ad3c98184
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ *.gem
2
+ build
3
+ .vagrant
4
+ .DS_Store
5
+ .bundle
6
+
7
+ .starscope.db
8
+ cscope.out
9
+ tags
10
+
11
+ .byebug_history
12
+
13
+ .rubocop-*
14
+ doc
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ inherit_from:
2
+ - http://shopify.github.io/ruby-style-guide/rubocop.yml
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.1
6
+
7
+ # This doesn't take into account retrying from an exception
8
+ Lint/HandleExceptions:
9
+ Enabled: false
10
+
11
+ # allow String.new to create mutable strings
12
+ Style/EmptyLiteral:
13
+ Enabled: false
14
+
15
+ # allow the use of globals which makes sense in a CLI app like this
16
+ Style/GlobalVars:
17
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.3
5
+ before_install: gem install bundler -v 1.15.0
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ # NOTE: These are development-only dependencies
2
+ source "https://rubygems.org"
3
+
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'rubocop'
8
+ gem 'byebug'
9
+ gem 'method_source'
10
+ end
11
+
12
+ group :test do
13
+ gem 'mocha', require: false
14
+ gem 'minitest', '>= 5.0.0', require: false
15
+ gem 'minitest-reporters', require: false
16
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,54 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cli-ui (0.1.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ansi (1.5.0)
10
+ ast (2.3.0)
11
+ builder (3.2.3)
12
+ byebug (9.0.6)
13
+ metaclass (0.0.4)
14
+ method_source (0.8.2)
15
+ minitest (5.10.2)
16
+ minitest-reporters (1.1.14)
17
+ ansi
18
+ builder
19
+ minitest (>= 5.0)
20
+ ruby-progressbar
21
+ mocha (1.2.1)
22
+ metaclass (~> 0.0.1)
23
+ parallel (1.12.0)
24
+ parser (2.4.0.2)
25
+ ast (~> 2.3)
26
+ powerpack (0.1.1)
27
+ rainbow (3.0.0)
28
+ rake (10.5.0)
29
+ rubocop (0.52.0)
30
+ parallel (~> 1.10)
31
+ parser (>= 2.4.0.2, < 3.0)
32
+ powerpack (~> 0.1)
33
+ rainbow (>= 2.2.2, < 4.0)
34
+ ruby-progressbar (~> 1.7)
35
+ unicode-display_width (~> 1.0, >= 1.0.1)
36
+ ruby-progressbar (1.9.0)
37
+ unicode-display_width (1.3.0)
38
+
39
+ PLATFORMS
40
+ ruby
41
+
42
+ DEPENDENCIES
43
+ bundler (~> 1.15)
44
+ byebug
45
+ cli-ui!
46
+ method_source
47
+ minitest (>= 5.0.0)
48
+ minitest-reporters
49
+ mocha
50
+ rake (~> 10.0)
51
+ rubocop
52
+
53
+ BUNDLED WITH
54
+ 1.16.0
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Burke Libbey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,164 @@
1
+ CLI UI
2
+ ---
3
+
4
+ CLI UI is a small framework for generating nice command-line user interfaces
5
+
6
+ - [Master Documentation](http://www.rubydoc.info/github/Shopify/cli-ui/master/CLI/UI)
7
+ - [Documentation of the Rubygems version](http://www.rubydoc.info/gems/cli-ui/)
8
+ - [Rubygems](https://rubygems.org/gems/cli-ui)
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ gem install cli-ui
14
+ ```
15
+
16
+ or add the following to your Gemfile:
17
+
18
+ ```ruby
19
+ gem 'cli-ui'
20
+ ```
21
+
22
+ In your code, simply add a `require 'cli/ui'`. Most options assume `CLI::UI::StdoutRouter.enable` has been called.
23
+
24
+ ## Features
25
+
26
+ This may not be an exhaustive list. Please check our [documentation](http://www.rubydoc.info/github/Shopify/cli-ui/master/CLI/UI) for more information.
27
+
28
+ ---
29
+
30
+ ### Nested framing
31
+ To handle content flow (see example below)
32
+
33
+ ```ruby
34
+ CLI::UI::StdoutRouter.enable
35
+ CLI::UI::Frame.open('Frame 1') do
36
+ CLI::UI::Frame.open('Frame 2') { puts "inside frame 2" }
37
+ puts "inside frame 1"
38
+ end
39
+ ```
40
+
41
+ ![Nested Framing](https://user-images.githubusercontent.com/3074765/33799861-cb5dcb5c-dd01-11e7-977e-6fad38cee08c.png)
42
+
43
+ ---
44
+
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)
47
+
48
+ ```ruby
49
+ CLI::UI.ask('What language/framework do you use?', options: %w(rails go ruby python))
50
+ ```
51
+
52
+ ![Interactive Prompt](https://user-images.githubusercontent.com/3074765/33797984-0ebb5e64-dcdf-11e7-9e7e-7204f279cece.gif)
53
+
54
+ ---
55
+
56
+ ### Free form text prompts
57
+
58
+ ```ruby
59
+ CLI::UI.ask('Is CLI UI Awesome?', default: 'It is great!')
60
+ ```
61
+
62
+ ![Free form text prompt](https://user-images.githubusercontent.com/3074765/33799822-47f23302-dd01-11e7-82f3-9072a5a5f611.png)
63
+
64
+ ---
65
+
66
+ ### Spinner groups
67
+ Handle many multi-threaded processes while suppressing output unless there is an issue. Can update title to show state.
68
+
69
+ ```ruby
70
+ spin_group = CLI::UI::SpinGroup.new
71
+ spin_group.add('Title') { |spinner| sleep 3.0 }
72
+ spin_group.add('Title 2') { |spinner| sleep 3.0; spinner.update_title('New Title'); sleep 3.0 }
73
+ spin_group.wait
74
+ ```
75
+
76
+ ![Spinner Group](https://user-images.githubusercontent.com/3074765/33798295-d94fd822-dce3-11e7-819b-43e5502d490e.gif)
77
+
78
+ ---
79
+
80
+ ### Text Color formatting
81
+ e.g. `{{red:Red}} {{green:Green}}`
82
+
83
+ ```ruby
84
+ puts CLI::UI.fmt "{{red:Red}} {{green:Green}}"
85
+ ```
86
+
87
+ ![Text Format](https://user-images.githubusercontent.com/3074765/33799827-6d0721a2-dd01-11e7-9ab5-c3d455264afe.png)
88
+
89
+ ---
90
+
91
+ ### Symbol/Glyph Formatting
92
+ e.g. `{{*}}` => a yellow ⭑
93
+
94
+ ```ruby
95
+ puts CLI::UI.fmt "{{*}} {{x}} {{?}} {{v}}"
96
+ ```
97
+
98
+ ![Symbol Formatting](https://user-images.githubusercontent.com/3074765/33799847-9ec03fd0-dd01-11e7-93f7-5f5cc540e61e.png)
99
+
100
+ ---
101
+
102
+ ### Progress Bar
103
+
104
+ Show progress of a process or operation.
105
+
106
+ ```ruby
107
+ CLI::UI::Progress.progress do |bar|
108
+ 100.times do
109
+ bar.tick
110
+ end
111
+ end
112
+ ```
113
+
114
+ ![Progress Bar](https://user-images.githubusercontent.com/3074765/33799794-cc4c940e-dd00-11e7-9bdc-90f77ec9167c.gif)
115
+
116
+ ---
117
+
118
+ ## Example Usage
119
+
120
+ The following code makes use of nested-framing, multi-threaded spinners, formatted text, and more.
121
+
122
+ ```ruby
123
+ require 'cli/ui'
124
+
125
+ CLI::UI::StdoutRouter.enable
126
+
127
+ CLI::UI::Frame.open('{{*}} {{bold:a}}', color: :green) do
128
+ CLI::UI::Frame.open('{{i}} b', color: :magenta) do
129
+ CLI::UI::Frame.open('{{?}} c', color: :cyan) do
130
+ sg = CLI::UI::SpinGroup.new
131
+ sg.add('wow') do |spinner|
132
+ sleep(2.5)
133
+ spinner.update_title('second round!')
134
+ sleep (1.0)
135
+ end
136
+ sg.add('such spin') { sleep(1.6) }
137
+ sg.add('many glyph') { sleep(2.0) }
138
+ sg.wait
139
+ end
140
+ end
141
+ CLI::UI::Frame.divider('{{v}} lol')
142
+ puts CLI::UI.fmt '{{info:words}} {{red:oh no!}} {{green:success!}}'
143
+ sg = CLI::UI::SpinGroup.new
144
+ sg.add('more spins') { sleep(0.5) ; raise 'oh no' }
145
+ sg.wait
146
+ end
147
+ ```
148
+
149
+ Output:
150
+
151
+ ![Example Output](https://user-images.githubusercontent.com/3074765/33797758-7a54c7cc-dcdb-11e7-918e-a47c9689f068.gif)
152
+
153
+ ## Development
154
+
155
+ - Run tests using `bundle exec rake test`. All code should be tested.
156
+ - No code, outside of development and tests needs, should use dependencies. This is a self contained library
157
+
158
+ ## Contributing
159
+
160
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/cli-ui.
161
+
162
+ ## License
163
+
164
+ The code is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
2
+ require 'cli/ui'
3
+ require 'rake/testtask'
4
+ require 'rubocop/rake_task'
5
+ require 'bundler/gem_tasks'
6
+
7
+ TEST_ROOT = File.expand_path('../test', __FILE__)
8
+
9
+ Rake::TestTask.new do |t|
10
+ t.libs += ["test"]
11
+ t.test_files = FileList[File.join(TEST_ROOT, '**', '*_test.rb')]
12
+ t.verbose = false
13
+ t.warning = false
14
+ end
15
+
16
+ RuboCop::RakeTask.new(:style) do |t|
17
+ t.options = ['--display-cop-names']
18
+ end
19
+
20
+ task default: [:test]
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "cli/ui"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/cli-ui.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "cli/ui/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cli-ui"
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"]
11
+
12
+ spec.summary = 'Terminal UI framework'
13
+ spec.description = 'Terminal UI framework'
14
+ spec.homepage = "https://github.com/shopify/cli-ui"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
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"
27
+ end
data/dev.yml ADDED
@@ -0,0 +1,14 @@
1
+ up:
2
+ - ruby: 2.3.3
3
+ - bundler
4
+
5
+ commands:
6
+ test:
7
+ run: |
8
+ if [ "$#" -eq 1 ] && [[ -f $1 ]];
9
+ then
10
+ rake test TEST=$1
11
+ else
12
+ rake test $@
13
+ fi
14
+ style: "bundle exec rubocop -D"
data/lib/cli/ui.rb ADDED
@@ -0,0 +1,163 @@
1
+ module CLI
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 :Formatter, 'cli/ui/formatter'
12
+ autoload :Spinner, 'cli/ui/spinner'
13
+
14
+ # Convenience accessor to +CLI::UI::Spinner::SpinGroup+
15
+ SpinGroup = Spinner::SpinGroup
16
+
17
+ # Glyph resolution using +CLI::UI::Glyph.lookup+
18
+ # Look at the method signature for +Glyph.lookup+ for more details
19
+ #
20
+ # ==== Attributes
21
+ #
22
+ # * +handle+ - handle of the glyph to resolve
23
+ #
24
+ def self.glyph(handle)
25
+ CLI::UI::Glyph.lookup(handle)
26
+ end
27
+
28
+ # Color resolution using +CLI::UI::Color.lookup+
29
+ # Will lookup using +Color.lookup+ if a symbol, otherwise we assume it is a valid color and return it
30
+ #
31
+ # ==== Attributes
32
+ #
33
+ # * +input+ - color to resolve
34
+ #
35
+ def self.resolve_color(input)
36
+ case input
37
+ when Symbol
38
+ CLI::UI::Color.lookup(input)
39
+ else
40
+ input
41
+ end
42
+ end
43
+
44
+ # Conviencence Method for +CLI::UI::Prompt.confirm+
45
+ #
46
+ # ==== Attributes
47
+ #
48
+ # * +question+ - question to confirm
49
+ #
50
+ def self.confirm(question)
51
+ CLI::UI::Prompt.confirm(question)
52
+ end
53
+
54
+ # Conviencence Method for +CLI::UI::Prompt.ask+
55
+ #
56
+ # ==== Attributes
57
+ #
58
+ # * +question+ - question to ask
59
+ # * +kwargs+ - arugments for +Prompt.ask+
60
+ #
61
+ def self.ask(question, **kwargs)
62
+ CLI::UI::Prompt.ask(question, **kwargs)
63
+ end
64
+
65
+ # Conviencence Method to resolve text using +CLI::UI::Formatter.format+
66
+ # Check +CLI::UI::Formatter::SGR_MAP+ for available formatting options
67
+ #
68
+ # ==== Attributes
69
+ #
70
+ # * +input+ - input to format
71
+ #
72
+ def self.resolve_text(input)
73
+ return input if input.nil?
74
+ CLI::UI::Formatter.new(input).format
75
+ end
76
+
77
+ # Conviencence Method to format text using +CLI::UI::Formatter.format+
78
+ # Check +CLI::UI::Formatter::SGR_MAP+ for available formatting options
79
+ #
80
+ # https://user-images.githubusercontent.com/3074765/33799827-6d0721a2-dd01-11e7-9ab5-c3d455264afe.png
81
+ # https://user-images.githubusercontent.com/3074765/33799847-9ec03fd0-dd01-11e7-93f7-5f5cc540e61e.png
82
+ #
83
+ # ==== Attributes
84
+ #
85
+ # * +input+ - input to format
86
+ #
87
+ # ==== Options
88
+ #
89
+ # * +enable_color+ - should color be used? default to true
90
+ #
91
+ def self.fmt(input, enable_color: true)
92
+ CLI::UI::Formatter.new(input).format(enable_color: enable_color)
93
+ end
94
+
95
+ # Conviencence Method for +CLI::UI::Frame.open+
96
+ #
97
+ # ==== Attributes
98
+ #
99
+ # * +args+ - arguments for +Frame.open+
100
+ # * +block+ - block for +Frame.open+
101
+ #
102
+ def self.frame(*args, &block)
103
+ CLI::UI::Frame.open(*args, &block)
104
+ end
105
+
106
+ # Conviencence Method for +CLI::UI::Spinner.spin+
107
+ #
108
+ # ==== Attributes
109
+ #
110
+ # * +args+ - arguments for +Spinner.open+
111
+ # * +block+ - block for +Spinner.open+
112
+ #
113
+ def self.spinner(*args, &block)
114
+ CLI::UI::Spinner.spin(*args, &block)
115
+ end
116
+
117
+ # Conviencence Method to override frame color using +CLI::UI::Frame.with_frame_color+
118
+ #
119
+ # ==== Attributes
120
+ #
121
+ # * +color+ - color to override to
122
+ # * +block+ - block for +Frame.with_frame_color_override+
123
+ #
124
+ def self.with_frame_color(color, &block)
125
+ CLI::UI::Frame.with_frame_color_override(color, &block)
126
+ end
127
+
128
+ # Duplicate output to a file path
129
+ #
130
+ # ==== Attributes
131
+ #
132
+ # * +path+ - path to duplicate output to
133
+ #
134
+ def self.log_output_to(path)
135
+ if CLI::UI::StdoutRouter.duplicate_output_to
136
+ raise "multiple logs not allowed"
137
+ end
138
+ CLI::UI::StdoutRouter.duplicate_output_to = File.open(path, 'w')
139
+ yield
140
+ ensure
141
+ if file_descriptor = CLI::UI::StdoutRouter.duplicate_output_to
142
+ file_descriptor.close
143
+ CLI::UI::StdoutRouter.duplicate_output_to = nil
144
+ end
145
+ end
146
+
147
+ # Disable all framing within a block
148
+ #
149
+ # ==== Attributes
150
+ #
151
+ # * +block+ - block in which to disable frames
152
+ #
153
+ def self.raw
154
+ prev = Thread.current[:no_cliui_frame_inset]
155
+ Thread.current[:no_cliui_frame_inset] = true
156
+ yield
157
+ ensure
158
+ Thread.current[:no_cliui_frame_inset] = prev
159
+ end
160
+ end
161
+ end
162
+
163
+ require 'cli/ui/stdout_router'