cli_miami 0.0.9 → 1.0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -3
- data/i18n/en.yml +34 -0
- data/lib/cli_miami/ask.rb +174 -34
- data/lib/cli_miami/core.rb +84 -0
- data/lib/cli_miami/error.rb +108 -0
- data/lib/cli_miami/say.rb +62 -52
- data/lib/cli_miami/validation.rb +189 -0
- data/lib/cli_miami.rb +1 -1
- data/lib/namespaced.rb +71 -21
- data/spec/fixtures/i18n.yml +36 -0
- data/spec/lib/cli_miami/ask_spec.rb +134 -0
- data/spec/lib/cli_miami/error_spec.rb +75 -0
- data/spec/lib/cli_miami/say_spec.rb +87 -0
- data/spec/lib/cli_miami/validation_spec.rb +52 -0
- data/spec/lib/cli_miami_spec.rb +81 -0
- data/spec/spec_helper.rb +83 -0
- metadata +122 -28
- data/.gitignore +0 -2
- data/.rspec +0 -3
- data/.travis.yml +0 -6
- data/Gemfile +0 -11
- data/Gemfile.lock +0 -100
- data/Guardfile +0 -5
- data/yuyi_menu +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4027d96f33ad46d4e0859f84b1c9399ce569a8d3
|
4
|
+
data.tar.gz: b1442d5a721d9cedfd612ac86d73057617b2b808
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f7b627d647f53c1f8cfd48cc3adbc5a02dbecdbf61a3581eeb3b24879d3b60cbecdee265b2461c6f08f7576082c2f9c23b1e8a032413a891fee5dc5f4e5fbeb
|
7
|
+
data.tar.gz: 2be499f83f714ac02761f01baa93e5fe0f2a133f78022700bd665490ca72044183504d59dfacd13534e3e46a23fed18076b90b54e2785bb11d8e78be4e89ef21
|
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
[![
|
2
|
-
[![
|
3
|
-
[![
|
1
|
+
[![gem version](https://badge.fury.io/rb/CLI-Miami.svg)](https://rubygems.org/gems/CLI-Miami)
|
2
|
+
[![dependencies](https://gemnasium.com/brewster1134/CLI-Miami.svg)](https://gemnasium.com/brewster1134/CLI-Miami)
|
3
|
+
[![docs](http://inch-ci.org/github/brewster1134/CLI-Miami.svg?branch=master)](http://inch-ci.org/github/brewster1134/CLI-Miami)
|
4
|
+
[![build](https://travis-ci.org/brewster1134/CLI-Miami.svg?branch=master)](https://travis-ci.org/brewster1134/CLI-Miami)
|
5
|
+
[![coverage](https://coveralls.io/repos/brewster1134/CLI-Miami/badge.svg?branch=master)](https://coveralls.io/r/brewster1134/CLI-Miami?branch=master)
|
6
|
+
[![code climate](https://codeclimate.com/github/brewster1134/CLI-Miami/badges/gpa.svg)](https://codeclimate.com/github/brewster1134/CLI-Miami)
|
7
|
+
[![omniref](https://www.omniref.com/github/brewster1134/CLI-Miami.png)](https://www.omniref.com/github/brewster1134/CLI-Miami)
|
4
8
|
|
5
9
|
# CLI Miami
|
6
10
|
A feature rich alternative for `gets` and `puts` for your cli interface
|
@@ -85,3 +89,5 @@ yuyi -m https://raw.githubusercontent.com/brewster1134/CLI-Miami/master/yuyi_men
|
|
85
89
|
bundle install
|
86
90
|
bundle exec guard
|
87
91
|
```
|
92
|
+
|
93
|
+
[![WTFPL](http://www.wtfpl.net/wp-content/uploads/2012/12/wtfpl-badge-4.png)](http://www.wtfpl.net)
|
data/i18n/en.yml
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
en:
|
2
|
+
cli_miami:
|
3
|
+
# CliMiami core library strings
|
4
|
+
core:
|
5
|
+
empty: '[EMPTY]'
|
6
|
+
enter_end_value: 'Enter end value'
|
7
|
+
enter_start_value: 'Enter starting value'
|
8
|
+
enter_value_for: 'Enter a value for %{key}'
|
9
|
+
no_description: No description provided
|
10
|
+
|
11
|
+
errors:
|
12
|
+
# generic error type messages
|
13
|
+
convert: "`%{value}` cannot be converted to `%{type}`. Allowed values are: `%{allowed_values}` (%{description})"
|
14
|
+
length: "`%{value}` has a length of %{value_length}, but must be between %{min} and %{max} . Allowed values are: `%{allowed_values}` (%{description})"
|
15
|
+
regexp: "`%{value}` does not match the required format. Allowed values are: `%{allowed_values}` (%{description})"
|
16
|
+
type: "Unknown type %{type}"
|
17
|
+
|
18
|
+
# specific value type messages
|
19
|
+
# these messages will take precedence over the general messages above
|
20
|
+
array:
|
21
|
+
length: "Your array (%{value}) has %{value_length} items, but needs between %{allowed_values} (%{description})"
|
22
|
+
boolean:
|
23
|
+
file:
|
24
|
+
validate: "`%{value}` is not a valid path. Allowed values are: `%{allowed_values}` (%{description})"
|
25
|
+
fixnum:
|
26
|
+
length: "`%{value}` must be between %{min} and %{max} . Allowed values are: `%{allowed_values}` (%{description})"
|
27
|
+
float:
|
28
|
+
length: "`%{value}` must be between %{min} and %{max} . Allowed values are: `%{allowed_values}` (%{description})"
|
29
|
+
hash:
|
30
|
+
length: "Your object (%{value}) has %{value_length} items, but needs between %{allowed_values} (%{description})"
|
31
|
+
keys: "The object has `%{value}` set, but is missing `%{keys}`. Allowed values are: `%{allowed_values}` (%{description})"
|
32
|
+
range:
|
33
|
+
string:
|
34
|
+
symbol:
|
data/lib/cli_miami/ask.rb
CHANGED
@@ -1,54 +1,194 @@
|
|
1
1
|
#
|
2
|
-
# class CliMiami::
|
2
|
+
# class CliMiami::A
|
3
3
|
#
|
4
|
-
|
5
|
-
require 'readline'
|
6
|
-
|
7
4
|
class CliMiami::A
|
8
|
-
|
5
|
+
attr_reader :value
|
9
6
|
|
7
|
+
# A.sk API method
|
8
|
+
#
|
10
9
|
# See documentation for CliMiami::S.ay
|
11
|
-
# The same options are accepted
|
10
|
+
# The same options are accepted, with the addition of
|
11
|
+
# :readline - uses Readline instead of standard `gets`
|
12
|
+
# :type - symbol specifying what type of data is requested from the user
|
13
|
+
# :validate - hash of validation options
|
12
14
|
#
|
13
15
|
def self.sk question, options = {}, &block
|
14
|
-
|
15
|
-
|
16
|
-
:readline => false
|
17
|
-
}
|
18
|
-
|
19
|
-
# merge preset options
|
20
|
-
if options.is_a? Symbol
|
21
|
-
@options.merge! CliMiami.presets[options]
|
22
|
-
elsif preset = options.delete(:preset)
|
23
|
-
@options.merge! CliMiami.presets[preset]
|
24
|
-
end
|
16
|
+
new question, options, &block
|
17
|
+
end
|
25
18
|
|
26
|
-
|
27
|
-
if options.is_a? Hash
|
28
|
-
@options.merge! options
|
29
|
-
end
|
19
|
+
private
|
30
20
|
|
31
|
-
|
21
|
+
def initialize question, options
|
22
|
+
options = CliMiami.get_options options
|
32
23
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
24
|
+
# add description to question
|
25
|
+
question << ' (' << options[:description] << ')'
|
26
|
+
|
27
|
+
# display question
|
28
|
+
CliMiami::S.ay question, options
|
29
|
+
|
30
|
+
# request given type to user
|
31
|
+
@value = request_type options
|
39
32
|
|
40
33
|
# return response if no block is passed
|
34
|
+
# rubocop:disable Style/GuardClause
|
41
35
|
if block_given?
|
42
|
-
yield
|
36
|
+
yield @value
|
43
37
|
else
|
44
|
-
return
|
38
|
+
return @value
|
45
39
|
end
|
40
|
+
# rubocop:enable Style/GuardClause
|
46
41
|
end
|
47
42
|
|
48
|
-
|
43
|
+
# determine the expecting type, and request input form user
|
44
|
+
#
|
45
|
+
def request_type options
|
46
|
+
send("request_#{options[:type]}", options)
|
47
|
+
rescue
|
48
|
+
CliMiami::S.ay I18n.t('cli_miami.errors.type', options)
|
49
|
+
end
|
50
|
+
|
51
|
+
# for most types, a simple validation check is all that is needed
|
52
|
+
# if validation fails, we request the user to try again
|
53
|
+
#
|
54
|
+
# rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
|
55
|
+
def request_until_valid options, allow_empty_string = false
|
56
|
+
response = nil
|
57
|
+
|
58
|
+
while response.nil?
|
59
|
+
# get user input based on given file type
|
60
|
+
response = if options[:type] == :file
|
61
|
+
Readline.readline.chomp '/'
|
62
|
+
else
|
63
|
+
$stdin.gets.chomp
|
64
|
+
end
|
65
|
+
|
66
|
+
# for multiple entry type objects, we allow the user to justs press enter to finish adding entries
|
67
|
+
break if allow_empty_string && response == ''
|
68
|
+
|
69
|
+
# otherwise validate the user's input
|
70
|
+
validation = CliMiami::Validation.new response, options
|
71
|
+
if validation.valid?
|
72
|
+
response = validation.value
|
73
|
+
else
|
74
|
+
response = nil
|
75
|
+
CliMiami::S.ay validation.error, :cli_miami_fail
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
response
|
80
|
+
end
|
81
|
+
# rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity
|
82
|
+
alias_method :request_boolean, :request_until_valid
|
83
|
+
alias_method :request_file, :request_until_valid
|
84
|
+
alias_method :request_float, :request_until_valid
|
85
|
+
alias_method :request_fixnum, :request_until_valid
|
86
|
+
alias_method :request_string, :request_until_valid
|
87
|
+
alias_method :request_symbol, :request_until_valid
|
88
|
+
|
89
|
+
# rubocop:disable Metrics/MethodLength
|
90
|
+
def request_array options
|
91
|
+
array = []
|
92
|
+
value_options = CliMiami.get_options(options[:value_options] || {})
|
93
|
+
|
94
|
+
# build the array by prompting the user
|
95
|
+
# until the array length is an acceptable length, keep prompting user for values
|
96
|
+
while array.length < options[:max]
|
97
|
+
response = request_until_valid value_options, true
|
98
|
+
|
99
|
+
if response.empty?
|
100
|
+
break if CliMiami::Validation.new(array, options).valid?
|
101
|
+
redo
|
102
|
+
else
|
103
|
+
array << response
|
104
|
+
end
|
49
105
|
|
50
|
-
|
51
|
-
|
52
|
-
|
106
|
+
# update user
|
107
|
+
CliMiami::S.ay array.to_sentence, :cli_miami_success
|
108
|
+
end
|
109
|
+
|
110
|
+
array
|
111
|
+
end
|
112
|
+
|
113
|
+
# rubocop:disable Metrics/AbcSize, Metrics/BlockNesting, Metrics/PerceivedComplexity
|
114
|
+
def request_hash options
|
115
|
+
hash = {}
|
116
|
+
options[:keys] ||= []
|
117
|
+
value_options = CliMiami.get_options(options[:value_options] || {})
|
118
|
+
required_keys_set = false
|
119
|
+
|
120
|
+
# build the hash by prompting the user
|
121
|
+
# until the hash length of keys is an acceptable length, keep prompting user for values
|
122
|
+
while hash.keys.length < options[:max]
|
123
|
+
# if keys options is set, prompt for those values first
|
124
|
+
if required_keys_set == false
|
125
|
+
options[:keys].each do |key|
|
126
|
+
hash[key.to_sym] = request_until_valid value_options
|
127
|
+
|
128
|
+
# update user
|
129
|
+
CliMiami::S.ay hash.to_s, :cli_miami_success
|
130
|
+
end
|
131
|
+
|
132
|
+
# set boolean so we know all required keys are set
|
133
|
+
required_keys_set = true
|
134
|
+
|
135
|
+
# end this loop to re-check the while condition to make sure the max wasn't reached from required keys
|
136
|
+
# e.g. setting { max: 2, keys: [:foo, :bar] }
|
137
|
+
# this prevents users from entering user-defined keys since the max will already be met
|
138
|
+
next
|
139
|
+
|
140
|
+
# then start prompting for keys and values
|
141
|
+
else
|
142
|
+
# request key
|
143
|
+
user_key = request_until_valid value_options.merge(type: :symbol), true
|
144
|
+
|
145
|
+
if user_key.empty?
|
146
|
+
break if CliMiami::Validation.new(hash, options).valid?
|
147
|
+
redo
|
148
|
+
else
|
149
|
+
# request value
|
150
|
+
CliMiami::S.ay I18n.t('cli_miami.core.enter_value_for', key: user_key), :cli_miami_success
|
151
|
+
hash[user_key] = request_until_valid value_options, true
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
CliMiami::S.ay hash.to_s, :cli_miami_success
|
156
|
+
end
|
157
|
+
|
158
|
+
hash
|
159
|
+
end
|
160
|
+
# rubocop:enable Metrics/AbcSize, Metrics/BlockNesting, Metrics/PerceivedComplexity
|
161
|
+
|
162
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
163
|
+
def request_range options
|
164
|
+
start_value = nil
|
165
|
+
end_value = nil
|
166
|
+
range_value_options = CliMiami.get_options type: :float
|
167
|
+
|
168
|
+
# get start value
|
169
|
+
until (Float(start_value) rescue nil)
|
170
|
+
CliMiami::S.ay I18n.t('cli_miami.core.enter_start_value'), preset: :cli_miami_success, newline: false
|
171
|
+
start_value = request_until_valid range_value_options
|
172
|
+
end
|
173
|
+
|
174
|
+
# get end value
|
175
|
+
until (Float(end_value) rescue nil)
|
176
|
+
CliMiami::S.ay I18n.t('cli_miami.core.enter_end_value'), preset: :cli_miami_success, newline: false
|
177
|
+
end_value = request_until_valid range_value_options
|
178
|
+
end
|
179
|
+
|
180
|
+
# swap values if entered in reverse
|
181
|
+
start_value, end_value = end_value, start_value if start_value > end_value
|
182
|
+
|
183
|
+
# build range object
|
184
|
+
range = Range.new start_value, end_value
|
185
|
+
|
186
|
+
# if range is invalid, start over and request it again
|
187
|
+
if CliMiami::Validation.new(range, options).valid?
|
188
|
+
range
|
189
|
+
else
|
190
|
+
request_range options
|
191
|
+
end
|
53
192
|
end
|
193
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
54
194
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#
|
2
|
+
# 3rd party libraries & configuration
|
3
|
+
#
|
4
|
+
require 'active_support/core_ext/hash/conversions'
|
5
|
+
require 'active_support/core_ext/hash/keys'
|
6
|
+
require 'active_support/core_ext/string/inflections'
|
7
|
+
require 'i18n'
|
8
|
+
require 'readline'
|
9
|
+
|
10
|
+
# core object overrides
|
11
|
+
#
|
12
|
+
class Hash
|
13
|
+
def to_s
|
14
|
+
map do |k, v|
|
15
|
+
"#{k}: #{v}"
|
16
|
+
end.to_sentence
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# i18n
|
21
|
+
#
|
22
|
+
# load yml locales included in the cli miami gem
|
23
|
+
# [PATH TO GEMS]/cli_miami/i18n/en.yml
|
24
|
+
I18n.load_path += Dir["#{File.dirname(__FILE__)}/../i18n/*.yml"]
|
25
|
+
# load locale in current directory named `i18n.yml`
|
26
|
+
# ./i18n.yml
|
27
|
+
I18n.load_path += Dir['./i18n.yml']
|
28
|
+
# load locales in the folder `i18n` in the current directory
|
29
|
+
# ./i18n/en.yml
|
30
|
+
I18n.load_path += Dir['./i18n/*.yml']
|
31
|
+
|
32
|
+
# readline
|
33
|
+
#
|
34
|
+
Readline.completion_append_character = '/'
|
35
|
+
|
36
|
+
# creates Boolean type that true/false inherit
|
37
|
+
# this allows true/false to respond to a single Boolean class to check for
|
38
|
+
#
|
39
|
+
# rubocop:disable Style/Documentation
|
40
|
+
module Boolean; end
|
41
|
+
class TrueClass; include Boolean; end
|
42
|
+
class FalseClass; include Boolean; end
|
43
|
+
# rubocop:enable Style/Documentation
|
44
|
+
|
45
|
+
# global configuration and setup
|
46
|
+
#
|
47
|
+
module CliMiami::Core
|
48
|
+
BOOLEAN_TRUE_VALUES = %w(true t yes y).freeze
|
49
|
+
BOOLEAN_FALSE_VALUES = %w(false f no n).freeze
|
50
|
+
|
51
|
+
# keys: type values allowed through the API
|
52
|
+
# values: type used to validate internally in the Validation class
|
53
|
+
TYPE_MAP = {
|
54
|
+
array: :array,
|
55
|
+
boolean: :boolean,
|
56
|
+
dir: :file,
|
57
|
+
directory: :file,
|
58
|
+
file: :file,
|
59
|
+
fixnum: :fixnum,
|
60
|
+
float: :float,
|
61
|
+
folder: :file,
|
62
|
+
hash: :hash,
|
63
|
+
integer: :fixnum,
|
64
|
+
list: :array,
|
65
|
+
number: :fixnum,
|
66
|
+
object: :hash,
|
67
|
+
path: :file,
|
68
|
+
range: :range,
|
69
|
+
string: :string,
|
70
|
+
symbol: :symbol
|
71
|
+
}.freeze
|
72
|
+
|
73
|
+
# default presets
|
74
|
+
# rubocop:disable Style/ClassVars
|
75
|
+
@@presets = {
|
76
|
+
cli_miami_fail: {
|
77
|
+
color: :red
|
78
|
+
},
|
79
|
+
cli_miami_success: {
|
80
|
+
color: :green
|
81
|
+
}
|
82
|
+
}
|
83
|
+
# rubocop:enable Style/ClassVars
|
84
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#
|
2
|
+
# Build custom i18n error messages
|
3
|
+
#
|
4
|
+
class CliMiami::Error
|
5
|
+
attr_reader :message
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def initialize value, options, *error_keys
|
10
|
+
options[:value] = convert_type_to_string value
|
11
|
+
options[:allowed_values] = allowed_values options
|
12
|
+
|
13
|
+
@message = i18n_lookup_keys(options, *error_keys) || 'Unknown Error'
|
14
|
+
end
|
15
|
+
|
16
|
+
# convert value from it's type, to a user friendly string
|
17
|
+
# with core ruby objects, we create a `.to_string` method instead of changes the default `.to_s` method
|
18
|
+
#
|
19
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
20
|
+
def convert_type_to_string value
|
21
|
+
case value
|
22
|
+
|
23
|
+
when Array
|
24
|
+
value.map do |e|
|
25
|
+
if e.nil? || e == ''
|
26
|
+
I18n.t 'cli_miami.core.empty'
|
27
|
+
else
|
28
|
+
convert_type_to_string e
|
29
|
+
end
|
30
|
+
end.to_sentence
|
31
|
+
|
32
|
+
when Hash
|
33
|
+
value.map do |k, v|
|
34
|
+
v = if v.nil? || v == ''
|
35
|
+
I18n.t 'cli_miami.core.empty'
|
36
|
+
else
|
37
|
+
convert_type_to_string v
|
38
|
+
end
|
39
|
+
|
40
|
+
"#{k}: #{v}"
|
41
|
+
end.to_sentence
|
42
|
+
|
43
|
+
when Range
|
44
|
+
"#{value.min}-#{value.max}"
|
45
|
+
|
46
|
+
when File
|
47
|
+
File.expand_path value
|
48
|
+
|
49
|
+
else
|
50
|
+
value.to_s
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
55
|
+
|
56
|
+
# get allowed values based on validation details
|
57
|
+
#
|
58
|
+
# rubocop:disable Metrics/MethodLength
|
59
|
+
def allowed_values options
|
60
|
+
case options[:type]
|
61
|
+
when :array, :hash
|
62
|
+
if options[:value_options]
|
63
|
+
allowed_values options[:value_options]
|
64
|
+
else
|
65
|
+
"#{options[:min]}-#{options[:max]}"
|
66
|
+
end
|
67
|
+
|
68
|
+
when :boolean
|
69
|
+
all_boolean_values = CliMiami::BOOLEAN_TRUE_VALUES + CliMiami::BOOLEAN_FALSE_VALUES
|
70
|
+
all_boolean_values.to_sentence
|
71
|
+
|
72
|
+
when :fixnum, :float, :range, :string, :symbol
|
73
|
+
"#{options[:min]}-#{options[:max]}"
|
74
|
+
|
75
|
+
when :regexp
|
76
|
+
options[:regexp].inspect
|
77
|
+
|
78
|
+
else
|
79
|
+
'?'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
# rubocop:enable Metrics/MethodLength
|
83
|
+
|
84
|
+
# build an i18n dot notation string to use for lookup in the language yaml
|
85
|
+
#
|
86
|
+
# rubocop:disable Style/ClosingParenthesisIndentation
|
87
|
+
def i18n_lookup_keys options, *error_keys
|
88
|
+
# check for type specific error first, then look for generic errors
|
89
|
+
i18n_lookup(options,
|
90
|
+
'cli_miami',
|
91
|
+
'errors',
|
92
|
+
options[:type].to_s,
|
93
|
+
*error_keys
|
94
|
+
) || i18n_lookup(options,
|
95
|
+
'cli_miami',
|
96
|
+
'errors',
|
97
|
+
*error_keys
|
98
|
+
)
|
99
|
+
end
|
100
|
+
# rubocop:enable Style/ClosingParenthesisIndentation
|
101
|
+
|
102
|
+
# use i18n dot notation keys to lookup string
|
103
|
+
#
|
104
|
+
def i18n_lookup options, *keys
|
105
|
+
i18n_string = keys.flatten.compact.each(&:to_s).join('.')
|
106
|
+
I18n.t i18n_string, options if I18n.exists? i18n_string
|
107
|
+
end
|
108
|
+
end
|
data/lib/cli_miami/say.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
#
|
2
|
-
# class CliMiami::Say
|
3
|
-
#
|
4
1
|
require 'term/ansicolor'
|
5
2
|
|
3
|
+
# Reopen String class for ANSI color support
|
6
4
|
class String
|
7
5
|
include Term::ANSIColor
|
8
6
|
end
|
9
7
|
|
8
|
+
#
|
9
|
+
# class CliMiami::S.ay
|
10
|
+
#
|
10
11
|
class CliMiami::S
|
12
|
+
# S.ay API method
|
11
13
|
#
|
12
14
|
# @param options [Symbol or Hash] options can be preset symbol, or a hash of options.
|
13
15
|
#
|
@@ -18,7 +20,7 @@ class CliMiami::S
|
|
18
20
|
# color: => [symbol] See README for ansi color codes
|
19
21
|
# bgcolor: => [symbol] See README for ansi color codes
|
20
22
|
# style: => [symbol] See README for ansi style codes
|
21
|
-
# justify: => [center|
|
23
|
+
# justify: => [center|left|right] The type of justification to use
|
22
24
|
# padding: => [integer] The maximum string size to justify text in
|
23
25
|
# indent: => [integer] The number of characters to indent
|
24
26
|
# newline: => [boolean] True if you want a newline after the output
|
@@ -27,75 +29,83 @@ class CliMiami::S
|
|
27
29
|
# @return
|
28
30
|
#
|
29
31
|
def self.ay text = '', options = {}
|
30
|
-
# backup text and convert it to a string
|
31
|
-
original_text = text = text.to_s
|
32
|
-
|
33
32
|
# set default options
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
}
|
33
|
+
options = CliMiami.get_options options
|
34
|
+
new text, options
|
35
|
+
end
|
38
36
|
|
39
|
-
|
40
|
-
if options.is_a? Symbol
|
41
|
-
@options.merge! CliMiami.presets[options]
|
42
|
-
elsif preset = options.delete(:preset)
|
43
|
-
@options.merge! CliMiami.presets[preset]
|
44
|
-
end
|
37
|
+
private
|
45
38
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
39
|
+
def initialize text, options
|
40
|
+
@text = text
|
41
|
+
@options = options
|
50
42
|
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
43
|
+
# formatter methods
|
44
|
+
modify_justification!
|
45
|
+
modify_text_color!
|
46
|
+
modify_background_color!
|
47
|
+
modify_styles!
|
48
|
+
modify_indentation!
|
49
|
+
modify_overwrite!
|
55
50
|
|
56
|
-
#
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
# render formatted text to user
|
52
|
+
print_output
|
53
|
+
end
|
54
|
+
|
55
|
+
# Justify/Padding options
|
56
|
+
# must convert option to support String class method
|
57
|
+
def modify_justification!
|
58
|
+
justify =
|
59
|
+
case @options[:justify]
|
60
|
+
when :center then :center
|
61
|
+
when :right then :rjust
|
62
|
+
else :ljust
|
63
|
+
end
|
64
|
+
|
65
|
+
@text = @text.send justify, @options[:padding]
|
66
|
+
end
|
60
67
|
|
61
|
-
|
68
|
+
# Set foreground color
|
69
|
+
def modify_text_color!
|
62
70
|
if @options[:color]
|
63
71
|
# if bright style is passed, use the bright color variation
|
64
|
-
text = if @options[:style].delete :bright
|
65
|
-
text.send
|
72
|
+
@text = if @options[:style].delete :bright
|
73
|
+
@text.send "bright_#{@options[:color]}"
|
66
74
|
else
|
67
|
-
text.send
|
75
|
+
@text.send @options[:color]
|
68
76
|
end
|
69
77
|
end
|
78
|
+
end
|
70
79
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
80
|
+
# Set background color
|
81
|
+
def modify_background_color!
|
82
|
+
@text = @text.send("on_#{@options[:bgcolor]}") if @options[:bgcolor]
|
83
|
+
end
|
75
84
|
|
76
|
-
|
85
|
+
# Apply all styles
|
86
|
+
def modify_styles!
|
77
87
|
@options[:style].each do |style|
|
78
|
-
text = text.send(style)
|
88
|
+
@text = @text.send(style)
|
79
89
|
end
|
90
|
+
end
|
80
91
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
92
|
+
# Indent
|
93
|
+
def modify_indentation!
|
94
|
+
@text = (' ' * @options[:indent]) + @text if @options[:indent]
|
95
|
+
end
|
85
96
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
97
|
+
# Flag text to be overwritten by next text written
|
98
|
+
def modify_overwrite!
|
99
|
+
@text = "#{@text}\r" if @options[:overwrite]
|
100
|
+
end
|
90
101
|
|
102
|
+
# finally render the formatted text to the screen
|
103
|
+
def print_output
|
91
104
|
# Determine if a newline should be used
|
92
105
|
if !@options[:newline] || @options[:overwrite]
|
93
|
-
$stdout.print text
|
106
|
+
$stdout.print @text + ' '
|
94
107
|
else
|
95
|
-
$stdout.puts text
|
108
|
+
$stdout.puts @text
|
96
109
|
end
|
97
|
-
|
98
|
-
# return original text
|
99
|
-
return original_text
|
100
110
|
end
|
101
111
|
end
|