cliutils 1.4.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/HISTORY.md +9 -0
- data/README.md +15 -639
- data/lib/cliutils/constants.rb +1 -1
- data/lib/cliutils/messaging.rb +112 -0
- data/lib/cliutils/prefs/pref.rb +113 -66
- data/lib/cliutils/prefs/pref_actions/open_url_action.rb +6 -2
- data/lib/cliutils/prefs/pref_actions/pref_action.rb +18 -9
- data/lib/cliutils/prefs/pref_behaviors/capitalize_behavior.rb +11 -0
- data/lib/cliutils/prefs/pref_behaviors/expand_filepath_behavior.rb +12 -0
- data/lib/cliutils/prefs/pref_behaviors/lowercase_behavior.rb +11 -0
- data/lib/cliutils/prefs/pref_behaviors/pref_behavior.rb +26 -0
- data/lib/cliutils/prefs/pref_behaviors/prefix_behavior.rb +11 -0
- data/lib/cliutils/prefs/pref_behaviors/suffix_behavior.rb +11 -0
- data/lib/cliutils/prefs/pref_behaviors/titlecase_behavior.rb +11 -0
- data/lib/cliutils/prefs/pref_behaviors/uppercase_behavior.rb +11 -0
- data/lib/cliutils/prefs/pref_validators/alphabetic_validator.rb +13 -0
- data/lib/cliutils/prefs/pref_validators/alphanumeric_validator.rb +14 -0
- data/lib/cliutils/prefs/pref_validators/date_validator.rb +13 -0
- data/lib/cliutils/prefs/pref_validators/datetime_validator.rb +13 -0
- data/lib/cliutils/prefs/pref_validators/filepath_exists_validator.rb +13 -0
- data/lib/cliutils/prefs/pref_validators/non_nil_validator.rb +13 -0
- data/lib/cliutils/prefs/pref_validators/number_validator.rb +13 -0
- data/lib/cliutils/prefs/pref_validators/pref_validator.rb +31 -0
- data/lib/cliutils/prefs/pref_validators/time_validator.rb +13 -0
- data/lib/cliutils/prefs/pref_validators/url_validator.rb +15 -0
- data/lib/cliutils/pretty_io.rb +0 -112
- data/lib/cliutils.rb +1 -0
- data/test/configurator_test.rb +1 -1
- data/test/hash_extensions_test.rb +1 -1
- data/test/logger_extensions_test.rb +1 -1
- data/test/messenging_test.rb +1 -1
- data/test/prefs_test.rb +1 -1
- data/test/string_extesions_test.rb +1 -1
- data/test/test_files/prefstest.yaml +29 -9
- data/test/test_helper.rb +6 -0
- metadata +22 -4
- data/lib/cliutils/prefs/pref_behavior.rb +0 -58
- data/lib/cliutils/prefs/pref_validation.rb +0 -96
@@ -0,0 +1,31 @@
|
|
1
|
+
module CLIUtils
|
2
|
+
# The generic base class for a Pref
|
3
|
+
# Validator.
|
4
|
+
class PrefValidator
|
5
|
+
include Messaging
|
6
|
+
|
7
|
+
# Holds whether the validator returned
|
8
|
+
# successful or not.
|
9
|
+
# @return [Boolean]
|
10
|
+
attr_accessor :is_valid
|
11
|
+
|
12
|
+
# Holds the message to display to the
|
13
|
+
# user when the Validator fails.
|
14
|
+
# @return [String]
|
15
|
+
attr_accessor :message
|
16
|
+
|
17
|
+
# Holds a reference to the Pref that is
|
18
|
+
# applying this Validator.
|
19
|
+
# @return [Pref]
|
20
|
+
attr_accessor :pref
|
21
|
+
|
22
|
+
# Validate the Validator!
|
23
|
+
# @parameter [String] text
|
24
|
+
# @raise [StandardError] if the subclass
|
25
|
+
# doesn't implement this method.
|
26
|
+
# @return [void]
|
27
|
+
def validate(text = nil)
|
28
|
+
fail "`validate` method not implemented on caller: #{ self.class }"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module CLIUtils
|
2
|
+
# A Validator to verify whether a Pref answer
|
3
|
+
# is a valid time.
|
4
|
+
class TimeValidator < PrefValidator
|
5
|
+
# Runs the Validator against the answer.
|
6
|
+
# @param [Object] text The "text" to evaluate
|
7
|
+
# @return [String]
|
8
|
+
def validate(text)
|
9
|
+
@is_valid = !(Time.parse(text) rescue nil).nil?
|
10
|
+
@message = "Response is not a time: #{ text }"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module CLIUtils
|
4
|
+
# A Validator to verify whether a Pref answer
|
5
|
+
# is a valid URL.
|
6
|
+
class UrlValidator < PrefValidator
|
7
|
+
# Runs the Validator against the answer.
|
8
|
+
# @param [Object] text The "text" to evaluate
|
9
|
+
# @return [String]
|
10
|
+
def validate(text)
|
11
|
+
@is_valid = text.to_s =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
|
12
|
+
@message = "Response is not a url: #{ text }"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/cliutils/pretty_io.rb
CHANGED
@@ -48,118 +48,6 @@ module CLIUtils
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
# Empty method so that Messaging doesn't freak
|
52
|
-
# out when passed a debug message.
|
53
|
-
# @return [void]
|
54
|
-
def debug(m); end
|
55
|
-
|
56
|
-
# Outputs a formatted-red error message.
|
57
|
-
# @param [String] m The message to output
|
58
|
-
# @return [void]
|
59
|
-
def error(m)
|
60
|
-
puts _word_wrap(m, '# ').red
|
61
|
-
end
|
62
|
-
|
63
|
-
# Outputs a formatted-blue informational message.
|
64
|
-
# @param [String] m The message to output
|
65
|
-
# @return [void]
|
66
|
-
def info(m)
|
67
|
-
puts _word_wrap(m, '# ').blue
|
68
|
-
end
|
69
|
-
|
70
|
-
# Wraps a block in an opening and closing info message.
|
71
|
-
# @param [String] m1 The opening message to output
|
72
|
-
# @param [String] m2 The closing message to output
|
73
|
-
# @param [<True, False>] multiline Whether the message should be multiline
|
74
|
-
# @yield
|
75
|
-
# @return [void]
|
76
|
-
def info_block(m1, m2 = 'Done.', multiline = false)
|
77
|
-
if block_given?
|
78
|
-
if multiline
|
79
|
-
info(m1)
|
80
|
-
else
|
81
|
-
print _word_wrap(m1, '# ').blue
|
82
|
-
end
|
83
|
-
|
84
|
-
yield
|
85
|
-
|
86
|
-
if multiline
|
87
|
-
info(m2)
|
88
|
-
else
|
89
|
-
puts _word_wrap(m2, '# ').blue
|
90
|
-
end
|
91
|
-
else
|
92
|
-
fail 'Did not specify a valid block'
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Empty method so that Messaging doesn't freak
|
97
|
-
# out when passed a log message.
|
98
|
-
# @return [void]
|
99
|
-
def log(m); end
|
100
|
-
|
101
|
-
# Outputs a prompt, collects the user's response, and
|
102
|
-
# returns it.
|
103
|
-
# @param [String] prompt The prompt to output
|
104
|
-
# @param [String] default The default option
|
105
|
-
# @param [String] start_dir The directory to start from for autocompletion
|
106
|
-
# @return [String]
|
107
|
-
def prompt(prompt, default = nil, start_dir = '')
|
108
|
-
Readline.completion_append_character = nil
|
109
|
-
Readline.completion_proc = lambda do |prefix|
|
110
|
-
files = Dir["#{start_dir}#{prefix}*"]
|
111
|
-
files.map { |f| File.expand_path(f) }
|
112
|
-
.map { |f| File.directory?(f) ? "#{ f }/" : f }
|
113
|
-
end
|
114
|
-
p = "# #{ prompt }#{ default.nil? ? ':' : " [default: #{ default }]:" } "
|
115
|
-
choice = Readline.readline(p.cyan)
|
116
|
-
if choice.empty?
|
117
|
-
default
|
118
|
-
else
|
119
|
-
choice
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# Outputs a formatted-purple section message.
|
124
|
-
# @param [String] m The message to output
|
125
|
-
# @return [void]
|
126
|
-
def section(m)
|
127
|
-
puts _word_wrap(m, '---> ').purple
|
128
|
-
end
|
129
|
-
|
130
|
-
# Wraps a block in an opening and closing section message.
|
131
|
-
# @param [String] m The opening message to output
|
132
|
-
# @param [<True, False>] multiline Whether the message should be multiline
|
133
|
-
# @yield
|
134
|
-
# @return [void]
|
135
|
-
def section_block(m, multiline = true)
|
136
|
-
if block_given?
|
137
|
-
if multiline
|
138
|
-
section(m)
|
139
|
-
else
|
140
|
-
print _word_wrap(m, '---> ').purple
|
141
|
-
end
|
142
|
-
|
143
|
-
yield
|
144
|
-
else
|
145
|
-
fail 'Did not specify a valid block'
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
# Outputs a formatted-green success message.
|
150
|
-
# @param [String] m The message to output
|
151
|
-
# @return [void]
|
152
|
-
def success(m)
|
153
|
-
puts _word_wrap(m, '# ').green
|
154
|
-
end
|
155
|
-
|
156
|
-
# Outputs a formatted-yellow warning message.
|
157
|
-
# @param [String] m The message to output
|
158
|
-
# @return [void]
|
159
|
-
def warn(m)
|
160
|
-
puts _word_wrap(m, '# ').yellow
|
161
|
-
end
|
162
|
-
|
163
51
|
private
|
164
52
|
|
165
53
|
# Outputs a wrapped string (where each line is limited
|
data/lib/cliutils.rb
CHANGED
@@ -11,6 +11,7 @@ require 'cliutils/messaging'
|
|
11
11
|
require 'cliutils/prefs'
|
12
12
|
require 'cliutils/prefs/pref'
|
13
13
|
require 'cliutils/prefs/pref_actions/pref_action'
|
14
|
+
require 'cliutils/prefs/pref_behaviors/pref_behavior'
|
14
15
|
require 'cliutils/prefs/pref_validators/pref_validator'
|
15
16
|
|
16
17
|
# The CLIUtils module, which wraps everything
|
data/test/configurator_test.rb
CHANGED
data/test/messenging_test.rb
CHANGED
data/test/prefs_test.rb
CHANGED
@@ -2,13 +2,33 @@ prompts:
|
|
2
2
|
- prompt_text: What is the top story on espn.com?
|
3
3
|
config_key: top_story
|
4
4
|
config_section: app_data
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
pre:
|
6
|
+
message: 'I will now open espn.com in your default browser.'
|
7
|
+
action:
|
8
|
+
name: open_url
|
9
|
+
parameters:
|
10
|
+
url: http://www.espn.com
|
11
|
+
post:
|
12
|
+
message: 'Thanks for inputting!'
|
12
13
|
validators:
|
13
|
-
-
|
14
|
-
-
|
14
|
+
# - alphabetic
|
15
|
+
# - alphanumeric
|
16
|
+
# - date
|
17
|
+
# - datetime
|
18
|
+
# - filepath_exists
|
19
|
+
# - non_nil
|
20
|
+
# - number
|
21
|
+
# - time
|
22
|
+
# - url
|
23
|
+
behaviors:
|
24
|
+
# - name: capitalize
|
25
|
+
# - name: expand_filepath
|
26
|
+
# - name: lowercase
|
27
|
+
# - name: prefix
|
28
|
+
# parameters:
|
29
|
+
# prefix: 'back'
|
30
|
+
# - name: suffix
|
31
|
+
# parameters:
|
32
|
+
# suffix: 'test'
|
33
|
+
# - name: titlecase
|
34
|
+
# - name: uppercase
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cliutils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Bach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -95,8 +95,24 @@ files:
|
|
95
95
|
- lib/cliutils/prefs/pref.rb
|
96
96
|
- lib/cliutils/prefs/pref_actions/open_url_action.rb
|
97
97
|
- lib/cliutils/prefs/pref_actions/pref_action.rb
|
98
|
-
- lib/cliutils/prefs/
|
99
|
-
- lib/cliutils/prefs/
|
98
|
+
- lib/cliutils/prefs/pref_behaviors/capitalize_behavior.rb
|
99
|
+
- lib/cliutils/prefs/pref_behaviors/expand_filepath_behavior.rb
|
100
|
+
- lib/cliutils/prefs/pref_behaviors/lowercase_behavior.rb
|
101
|
+
- lib/cliutils/prefs/pref_behaviors/pref_behavior.rb
|
102
|
+
- lib/cliutils/prefs/pref_behaviors/prefix_behavior.rb
|
103
|
+
- lib/cliutils/prefs/pref_behaviors/suffix_behavior.rb
|
104
|
+
- lib/cliutils/prefs/pref_behaviors/titlecase_behavior.rb
|
105
|
+
- lib/cliutils/prefs/pref_behaviors/uppercase_behavior.rb
|
106
|
+
- lib/cliutils/prefs/pref_validators/alphabetic_validator.rb
|
107
|
+
- lib/cliutils/prefs/pref_validators/alphanumeric_validator.rb
|
108
|
+
- lib/cliutils/prefs/pref_validators/date_validator.rb
|
109
|
+
- lib/cliutils/prefs/pref_validators/datetime_validator.rb
|
110
|
+
- lib/cliutils/prefs/pref_validators/filepath_exists_validator.rb
|
111
|
+
- lib/cliutils/prefs/pref_validators/non_nil_validator.rb
|
112
|
+
- lib/cliutils/prefs/pref_validators/number_validator.rb
|
113
|
+
- lib/cliutils/prefs/pref_validators/pref_validator.rb
|
114
|
+
- lib/cliutils/prefs/pref_validators/time_validator.rb
|
115
|
+
- lib/cliutils/prefs/pref_validators/url_validator.rb
|
100
116
|
- lib/cliutils/pretty_io.rb
|
101
117
|
- res/readme-images/actions-1.png
|
102
118
|
- res/readme-images/actions-2.png
|
@@ -121,6 +137,7 @@ files:
|
|
121
137
|
- test/prefs_test.rb
|
122
138
|
- test/string_extesions_test.rb
|
123
139
|
- test/test_files/prefstest.yaml
|
140
|
+
- test/test_helper.rb
|
124
141
|
homepage: http://www.bachyaproductions.com/cliutils-ruby-library-cli-apps/
|
125
142
|
licenses:
|
126
143
|
- MIT
|
@@ -153,4 +170,5 @@ test_files:
|
|
153
170
|
- test/prefs_test.rb
|
154
171
|
- test/string_extesions_test.rb
|
155
172
|
- test/test_files/prefstest.yaml
|
173
|
+
- test/test_helper.rb
|
156
174
|
has_rdoc:
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module CLIUtils
|
2
|
-
# PrefBehavior Module
|
3
|
-
# Behaviors that should be applied to a Pref's
|
4
|
-
# final value
|
5
|
-
module PrefBehavior
|
6
|
-
# Capitalizes the first word of the passed text.
|
7
|
-
# @param [String] args[0] The text to evaluate
|
8
|
-
# @return [String]
|
9
|
-
def self.capitalize(*args)
|
10
|
-
args[0].capitalize
|
11
|
-
end
|
12
|
-
|
13
|
-
# Expands the passed text (assumes it
|
14
|
-
# is a filepath).
|
15
|
-
# @param [String] args[0] The text to evaluate
|
16
|
-
# @return [String]
|
17
|
-
def self.expand_filepath(*args)
|
18
|
-
File.expand_path(args[0])
|
19
|
-
end
|
20
|
-
|
21
|
-
# Lowercases all characters in the passed text.
|
22
|
-
# @param [String] args[0] The text to evaluate
|
23
|
-
# @return [String]
|
24
|
-
def self.lowercase(*args)
|
25
|
-
args[0].downcase
|
26
|
-
end
|
27
|
-
|
28
|
-
# Adds a prefix to the passed text.
|
29
|
-
# @param [String] args[0] The text to evaluate
|
30
|
-
# @param [String] args[1] The prefix to add
|
31
|
-
# @return [String]
|
32
|
-
def self.prefix(*args)
|
33
|
-
args[1] + args[0]
|
34
|
-
end
|
35
|
-
|
36
|
-
# Adds a suffix to the passed text.
|
37
|
-
# @param [String] args[0] The text to evaluate
|
38
|
-
# @param [String] args[1] The suffix to add
|
39
|
-
# @return [String]
|
40
|
-
def self.suffix(*args)
|
41
|
-
args[0] + args[1]
|
42
|
-
end
|
43
|
-
|
44
|
-
# Capitalizes each word in the passed text.
|
45
|
-
# @param [String] args[0] The text to evaluate
|
46
|
-
# @return [String]
|
47
|
-
def self.titlecase(*args)
|
48
|
-
args[0].split.map(&:capitalize).join(' ')
|
49
|
-
end
|
50
|
-
|
51
|
-
# Uppercases all characters in the passed text.
|
52
|
-
# @param [String] args[0] The text to evaluate
|
53
|
-
# @return [String]
|
54
|
-
def self.uppercase(*args)
|
55
|
-
args[0].upcase
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
require 'uri'
|
2
|
-
|
3
|
-
module CLIUtils
|
4
|
-
# PrefValidation Module
|
5
|
-
# Validation rules that can be applied to a Pref.
|
6
|
-
module PrefValidation
|
7
|
-
# Struct to contain a validation result
|
8
|
-
# and a result message.
|
9
|
-
Validator = Struct.new(:code, :message)
|
10
|
-
|
11
|
-
# Validates that a value is only letters
|
12
|
-
# and spaces.
|
13
|
-
# @param [String] text The text to inspect
|
14
|
-
# @return [Boolean]
|
15
|
-
def self.alphabetic(text)
|
16
|
-
m = "Response is not alphabetic: #{ text }"
|
17
|
-
c = text.to_s =~ /\A[A-Za-z\s]+\z/
|
18
|
-
Validator.new(c, m)
|
19
|
-
end
|
20
|
-
|
21
|
-
# Validates that a value is only letters, numbers
|
22
|
-
# and spaces.
|
23
|
-
# @param [String] text The text to inspect
|
24
|
-
# @return [Boolean]
|
25
|
-
def self.alphanumeric(text)
|
26
|
-
m = "Response is not alphanumeric: #{ text }"
|
27
|
-
c = text.to_s =~ /\A[A-Za-z0-9\s]+\z/
|
28
|
-
Validator.new(c, m)
|
29
|
-
end
|
30
|
-
|
31
|
-
# Validates that a value is a date.
|
32
|
-
# @param [String] text The text to inspect
|
33
|
-
# @return [Boolean]
|
34
|
-
def self.date(text)
|
35
|
-
m = "Response is not a date: #{ text }"
|
36
|
-
c = !(Date.parse(text) rescue nil).nil?
|
37
|
-
Validator.new(c, m)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Validates that a value is a datetime.
|
41
|
-
# @param [String] text The text to inspect
|
42
|
-
# @return [Boolean]
|
43
|
-
def self.datetime(text)
|
44
|
-
m = "Response is not a datetime: #{ text }"
|
45
|
-
c = !(DateTime.parse(text) rescue nil).nil?
|
46
|
-
Validator.new(c, m)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Validates that a value is passed and is not
|
50
|
-
# empty.
|
51
|
-
# @param [String] text The text to inspect
|
52
|
-
# @return [Boolean]
|
53
|
-
def self.non_nil(text)
|
54
|
-
m = 'Nil text not allowed'
|
55
|
-
c = !text.nil? && !text.empty?
|
56
|
-
Validator.new(c, m)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Validates that a value is some sort of number.
|
60
|
-
# @param [String] text The text to inspect
|
61
|
-
# @return [Boolean]
|
62
|
-
def self.number(text)
|
63
|
-
m = "Response is not a number: #{ text }"
|
64
|
-
c = text.to_s =~ /\A[-+]?\d*\.?\d+\z/
|
65
|
-
Validator.new(c, m)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Validates that a filepath exists on the
|
69
|
-
# local filesystem.
|
70
|
-
# @param [String] text The text to inspect
|
71
|
-
# @return [Boolean]
|
72
|
-
def self.filepath_exists(text)
|
73
|
-
m = "Path does not exist locally: #{ text }"
|
74
|
-
c = Pathname.new(text).exist?
|
75
|
-
Validator.new(c, m)
|
76
|
-
end
|
77
|
-
|
78
|
-
# Validates that a value is a time.
|
79
|
-
# @param [String] text The text to inspect
|
80
|
-
# @return [Boolean]
|
81
|
-
def self.time(text)
|
82
|
-
m = "Response is not a time: #{ text }"
|
83
|
-
c = !(Time.parse(text) rescue nil).nil?
|
84
|
-
Validator.new(c, m)
|
85
|
-
end
|
86
|
-
|
87
|
-
# Validates that passed value is a URL.
|
88
|
-
# @param [String] text The text to inspect
|
89
|
-
# @return [Boolean]
|
90
|
-
def self.url(text)
|
91
|
-
m = "Response is not a url: #{ text }"
|
92
|
-
c = text.to_s =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
|
93
|
-
Validator.new(c, m)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|