cliutils 1.2.3 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.md +4 -0
- data/Rakefile +1 -1
- data/cliutils.gemspec +1 -1
- data/lib/cliutils/configuration.rb +1 -1
- data/lib/cliutils/configurator.rb +10 -7
- data/lib/cliutils/{version.rb → constants.rb} +2 -1
- data/lib/cliutils/ext/{Hash+Extensions.rb → hash_extensions.rb} +8 -9
- data/lib/cliutils/ext/{Logger+Extensions.rb → logger_extensions.rb} +6 -7
- data/lib/cliutils/ext/{String+Extensions.rb → string_extensions.rb} +22 -9
- data/lib/cliutils/{logger-delegator.rb → logger_delegator.rb} +3 -1
- data/lib/cliutils/messenging.rb +3 -3
- data/lib/cliutils/prefs/pref.rb +10 -19
- data/lib/cliutils/prefs/{pref-behavior.rb → pref_behavior.rb} +1 -1
- data/lib/cliutils/prefs/{pref-validation.rb → pref_validation.rb} +3 -3
- data/lib/cliutils/prefs.rb +14 -14
- data/lib/cliutils/{pretty-io.rb → pretty_io.rb} +17 -11
- data/lib/cliutils.rb +7 -8
- data/test/configurator_test.rb +7 -6
- data/test/hash_extensions_test.rb +12 -11
- data/test/logger_extensions_test.rb +4 -3
- data/test/messenging_test.rb +11 -10
- data/test/prefs_test.rb +27 -26
- data/test/string_extesions_test.rb +3 -2
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cca92462495e55bd03893b1ce6a19c1830288b56
|
4
|
+
data.tar.gz: dd8f5e2ed4434f381f0bca8a66d34fcab3cf6834
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 226d3b909c6a8f887818491f4611db68128e991c818c4aeb8268316f3f3d0415bf06a5a6967e961c6377f0cfbc3149b8dd94e3ad68dd1e4dcb18086cecdbc46a
|
7
|
+
data.tar.gz: 0404033a25e60197ec39c4e58cde3a72616d1a09c9d051a44d0c4e74a85e349d3c1b949c33516bc847f38ab77c959de3cf5a1c1109bdc5cbd43d8e9b57e33c82
|
data/HISTORY.md
CHANGED
data/Rakefile
CHANGED
data/cliutils.gemspec
CHANGED
@@ -8,7 +8,7 @@ module CLIUtils
|
|
8
8
|
# Stores the path to the configuration file.
|
9
9
|
# @return [String]
|
10
10
|
attr_reader :config_path
|
11
|
-
|
11
|
+
|
12
12
|
# Stores the configuration data itself.
|
13
13
|
# @return [Hash]
|
14
14
|
attr_reader :data
|
@@ -21,8 +21,8 @@ module CLIUtils
|
|
21
21
|
@config_path = _path
|
22
22
|
@data = {}
|
23
23
|
|
24
|
-
if File.
|
25
|
-
data = YAML
|
24
|
+
if File.exist?(_path)
|
25
|
+
data = YAML.load_file(_path)
|
26
26
|
@data.deep_merge!(data).deep_symbolize_keys!
|
27
27
|
end
|
28
28
|
end
|
@@ -55,10 +55,11 @@ module CLIUtils
|
|
55
55
|
# @param [Prefs] prefs The Prefs class to examine
|
56
56
|
# @return [void]
|
57
57
|
def ingest_prefs(prefs)
|
58
|
-
fail 'Invaid Prefs class'
|
58
|
+
fail 'Invaid Prefs class' unless prefs.kind_of?(Prefs)
|
59
59
|
prefs.prompts.each do |p|
|
60
|
-
|
61
|
-
@data
|
60
|
+
section_sym = p.config_section.to_sym
|
61
|
+
add_section(section_sym) unless @data.key?(section_sym)
|
62
|
+
@data[section_sym].merge!(p.config_key.to_sym => p.answer)
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
@@ -80,7 +81,9 @@ module CLIUtils
|
|
80
81
|
# stored flat file.
|
81
82
|
# @return [void]
|
82
83
|
def save
|
83
|
-
File.open(@config_path, 'w')
|
84
|
+
File.open(@config_path, 'w') do |f|
|
85
|
+
f.write(@data.deep_stringify_keys.to_yaml)
|
86
|
+
end
|
84
87
|
end
|
85
88
|
end
|
86
89
|
end
|
@@ -2,13 +2,12 @@
|
|
2
2
|
# Contains many convenient methods borrowed from Rails
|
3
3
|
# http://api.rubyonrails.org/classes/Hash.html
|
4
4
|
class Hash
|
5
|
-
|
6
5
|
# Deep merges a hash into the current one.
|
7
6
|
# @param [Hash] other_hash The hash to merge in
|
8
7
|
# @yield &block
|
9
8
|
# @return [Hash]
|
10
9
|
def deep_merge!(other_hash, &block)
|
11
|
-
other_hash.each_pair do |k,v|
|
10
|
+
other_hash.each_pair do |k, v|
|
12
11
|
tv = self[k]
|
13
12
|
if tv.is_a?(Hash) && v.is_a?(Hash)
|
14
13
|
self[k] = tv.deep_merge(v, &block)
|
@@ -23,28 +22,28 @@ class Hash
|
|
23
22
|
# returns the new Hash.
|
24
23
|
# @return [Hash]
|
25
24
|
def deep_stringify_keys
|
26
|
-
deep_transform_keys{ |key| key.to_s }
|
25
|
+
deep_transform_keys { |key| key.to_s }
|
27
26
|
end
|
28
27
|
|
29
28
|
# Same as deep_stringify_keys, but destructively
|
30
29
|
# alters the original Hash.
|
31
30
|
# @return [Hash]
|
32
31
|
def deep_stringify_keys!
|
33
|
-
deep_transform_keys!{ |key| key.to_s }
|
32
|
+
deep_transform_keys! { |key| key.to_s }
|
34
33
|
end
|
35
34
|
|
36
35
|
# Recursively turns all Hash keys into symbols and
|
37
36
|
# returns the new Hash.
|
38
37
|
# @return [Hash]
|
39
38
|
def deep_symbolize_keys
|
40
|
-
deep_transform_keys{ |key| key.to_sym rescue key }
|
39
|
+
deep_transform_keys { |key| key.to_sym rescue key }
|
41
40
|
end
|
42
41
|
|
43
42
|
# Same as deep_symbolize_keys, but destructively
|
44
43
|
# alters the original Hash.
|
45
44
|
# @return [Hash]
|
46
45
|
def deep_symbolize_keys!
|
47
|
-
deep_transform_keys!{ |key| key.to_sym rescue key }
|
46
|
+
deep_transform_keys! { |key| key.to_sym rescue key }
|
48
47
|
end
|
49
48
|
|
50
49
|
# Generic method to perform recursive operations on a
|
@@ -78,7 +77,7 @@ class Hash
|
|
78
77
|
result[yield(key)] = _deep_transform_keys_in_object(value, &block)
|
79
78
|
end
|
80
79
|
when Array
|
81
|
-
object.map {|e| _deep_transform_keys_in_object(e, &block) }
|
80
|
+
object.map { |e| _deep_transform_keys_in_object(e, &block) }
|
82
81
|
else
|
83
82
|
object
|
84
83
|
end
|
@@ -98,9 +97,9 @@ class Hash
|
|
98
97
|
end
|
99
98
|
object
|
100
99
|
when Array
|
101
|
-
object.map! {|e| _deep_transform_keys_in_object!(e, &block)}
|
100
|
+
object.map! { |e| _deep_transform_keys_in_object!(e, &block) }
|
102
101
|
else
|
103
102
|
object
|
104
103
|
end
|
105
104
|
end
|
106
|
-
end
|
105
|
+
end
|
@@ -2,21 +2,20 @@ require 'logger'
|
|
2
2
|
|
3
3
|
# Logger Class extensions
|
4
4
|
class Logger
|
5
|
-
|
6
5
|
# Creates a custom Logger level based on the passed
|
7
6
|
# tag.
|
8
7
|
# @param [String] tag The Logger level to create
|
9
8
|
# @return [void]
|
10
9
|
def self.custom_level(tag)
|
11
|
-
SEV_LABEL << tag
|
12
|
-
idx = SEV_LABEL.size - 1
|
10
|
+
SEV_LABEL << tag
|
11
|
+
idx = SEV_LABEL.size - 1
|
13
12
|
|
14
13
|
define_method(tag.downcase.gsub(/\W+/, '_').to_sym) do |progname, &block|
|
15
14
|
add(idx, nil, progname, &block)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
19
18
|
custom_level('PROMPT')
|
20
19
|
custom_level('SECTION')
|
21
20
|
custom_level('SUCCESS')
|
22
|
-
end
|
21
|
+
end
|
@@ -1,38 +1,51 @@
|
|
1
1
|
# String Class extensions
|
2
2
|
class String
|
3
|
-
|
4
3
|
# Outputs a string in a formatted color.
|
5
4
|
# @param [<Integer, String>] color_code The code to use
|
6
5
|
# @return [void]
|
7
6
|
def colorize(color_code)
|
8
7
|
"\033[#{ color_code }m#{ self }\033[0m"
|
9
8
|
end
|
10
|
-
|
9
|
+
|
11
10
|
# Makes the associated string blue.
|
12
11
|
# @return [void]
|
13
|
-
def blue
|
12
|
+
def blue
|
13
|
+
colorize(34)
|
14
|
+
end
|
14
15
|
|
15
16
|
# Makes the associated string cyan.
|
16
17
|
# @return [void]
|
17
|
-
def cyan
|
18
|
+
def cyan
|
19
|
+
colorize(36)
|
20
|
+
end
|
18
21
|
|
19
22
|
# Makes the associated string green.
|
20
23
|
# @return [void]
|
21
|
-
def green
|
24
|
+
def green
|
25
|
+
colorize(32)
|
26
|
+
end
|
22
27
|
|
23
28
|
# Makes the associated string purple.
|
24
29
|
# @return [void]
|
25
|
-
def purple
|
30
|
+
def purple
|
31
|
+
colorize(35)
|
32
|
+
end
|
26
33
|
|
27
34
|
# Makes the associated string red.
|
28
35
|
# @return [void]
|
29
|
-
def red
|
36
|
+
def red
|
37
|
+
colorize(31)
|
38
|
+
end
|
30
39
|
|
31
40
|
# Makes the associated string white.
|
32
41
|
# @return [void]
|
33
|
-
def white
|
42
|
+
def white
|
43
|
+
colorize(37)
|
44
|
+
end
|
34
45
|
|
35
46
|
# Makes the associated string yellow.
|
36
47
|
# @return [void]
|
37
|
-
def yellow
|
48
|
+
def yellow
|
49
|
+
colorize(33)
|
50
|
+
end
|
38
51
|
end
|
@@ -39,7 +39,9 @@ module CLIUtils
|
|
39
39
|
# @param [<String, Symbol>] target_name The target to remove
|
40
40
|
# @return [void]
|
41
41
|
def detach(target_name)
|
42
|
-
|
42
|
+
unless @targets.key?(target_name)
|
43
|
+
fail "Cannot delete invalid target: #{ target_name }"
|
44
|
+
end
|
43
45
|
@targets.delete(target_name)
|
44
46
|
LoggerDelegator.delegate
|
45
47
|
end
|
data/lib/cliutils/messenging.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'cliutils/
|
1
|
+
require 'cliutils/pretty_io'
|
2
2
|
|
3
3
|
module CLIUtils
|
4
4
|
# CLIMessenger Module
|
@@ -21,7 +21,7 @@ module CLIUtils
|
|
21
21
|
stdout_logger.formatter = proc do |severity, datetime, progname, msg|
|
22
22
|
send(severity.downcase, msg)
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
LoggerDelegator.new(STDOUT: stdout_logger)
|
26
26
|
end
|
27
27
|
|
@@ -32,4 +32,4 @@ module CLIUtils
|
|
32
32
|
@@messenger ||= default_instance
|
33
33
|
end
|
34
34
|
end
|
35
|
-
end
|
35
|
+
end
|
data/lib/cliutils/prefs/pref.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'cliutils/messenging'
|
2
|
-
require 'cliutils/prefs/
|
3
|
-
require 'cliutils/prefs/
|
2
|
+
require 'cliutils/prefs/pref_behavior'
|
3
|
+
require 'cliutils/prefs/pref_validation'
|
4
4
|
|
5
5
|
module CLIUtils
|
6
6
|
# Pref Class
|
@@ -43,7 +43,7 @@ module CLIUtils
|
|
43
43
|
# Stores the prompt text.
|
44
44
|
# @return [String]
|
45
45
|
attr_accessor :prompt
|
46
|
-
|
46
|
+
|
47
47
|
# Stores key/value combinations required to show this Pref.
|
48
48
|
# @return [Hash]
|
49
49
|
attr_accessor :validators
|
@@ -59,16 +59,9 @@ module CLIUtils
|
|
59
59
|
# @param [Pref] other
|
60
60
|
# @return [Boolean]
|
61
61
|
def ==(other)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
self.config_section == other.config_section &&
|
66
|
-
self.default == other.default &&
|
67
|
-
self.last_error_message == other.last_error_message &&
|
68
|
-
self.options == other.options &&
|
69
|
-
self.prereqs == other.prereqs &&
|
70
|
-
self.prompt == other.prompt &&
|
71
|
-
self.validators == other.validators
|
62
|
+
@config_key == other.config_key &&
|
63
|
+
@config_section == other.config_section &&
|
64
|
+
@prompt == other.prompt
|
72
65
|
end
|
73
66
|
|
74
67
|
# Runs the passed text through this Pref's behaviors.
|
@@ -84,7 +77,6 @@ module CLIUtils
|
|
84
77
|
messenger.warn("Skipping undefined Pref behavior: #{ b }")
|
85
78
|
end
|
86
79
|
end
|
87
|
-
|
88
80
|
modified_text
|
89
81
|
else
|
90
82
|
text
|
@@ -99,7 +91,7 @@ module CLIUtils
|
|
99
91
|
_confirm_options(text) &&
|
100
92
|
_confirm_validators(text)
|
101
93
|
end
|
102
|
-
|
94
|
+
|
103
95
|
private
|
104
96
|
|
105
97
|
# Validates a text against the options for this Pref
|
@@ -109,11 +101,11 @@ module CLIUtils
|
|
109
101
|
ret = true
|
110
102
|
if @options
|
111
103
|
unless @options.include?(text)
|
112
|
-
@last_error_message = "Invalid option chosen (\"#{ text }\");
|
104
|
+
@last_error_message = "Invalid option chosen (\"#{ text }\");"\
|
105
|
+
"valid options are: #{ options }"
|
113
106
|
ret = false
|
114
107
|
end
|
115
108
|
end
|
116
|
-
|
117
109
|
ret
|
118
110
|
end
|
119
111
|
|
@@ -135,8 +127,7 @@ module CLIUtils
|
|
135
127
|
end
|
136
128
|
end
|
137
129
|
end
|
138
|
-
|
139
130
|
ret
|
140
131
|
end
|
141
132
|
end
|
142
|
-
end
|
133
|
+
end
|
@@ -23,7 +23,7 @@ module CLIUtils
|
|
23
23
|
c = text.to_s =~ /\A[A-Za-z0-9\s]+\z/
|
24
24
|
Validator.new(c, m)
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# Validates that a value is a date.
|
28
28
|
# @param [String] text The text to inspect
|
29
29
|
# @return [Boolean]
|
@@ -38,7 +38,7 @@ module CLIUtils
|
|
38
38
|
# @param [String] text The text to inspect
|
39
39
|
# @return [Boolean]
|
40
40
|
def self.non_nil(text)
|
41
|
-
m =
|
41
|
+
m = 'Nil text not allowed'
|
42
42
|
c = !text.nil? && !text.empty?
|
43
43
|
Validator.new(c, m)
|
44
44
|
end
|
@@ -61,4 +61,4 @@ module CLIUtils
|
|
61
61
|
Validator.new(c, m)
|
62
62
|
end
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
data/lib/cliutils/prefs.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'cliutils/prefs/pref'
|
2
|
-
require 'cliutils/
|
2
|
+
require 'cliutils/pretty_io'
|
3
3
|
|
4
4
|
module CLIUtils
|
5
5
|
# Engine to derive preferences from a YAML file, deliver
|
@@ -13,14 +13,14 @@ module CLIUtils
|
|
13
13
|
# Stores a Configurator instance.
|
14
14
|
# @return [Configurator]
|
15
15
|
attr_reader :configurator
|
16
|
-
|
16
|
+
|
17
17
|
# Stores answers to prompt questions.
|
18
18
|
# @return [Array]
|
19
19
|
attr_reader :prompts
|
20
20
|
|
21
21
|
# Reads prompt data from and stores it.
|
22
22
|
# @param [<String, Hash, Array>] data Filepath to YAML, Hash, or Array
|
23
|
-
# @param [Configurator] configurator
|
23
|
+
# @param [Configurator] configurator Source of defailt values
|
24
24
|
# @return [void]
|
25
25
|
def initialize(data, configurator = nil)
|
26
26
|
@answers = []
|
@@ -29,21 +29,21 @@ module CLIUtils
|
|
29
29
|
|
30
30
|
case data
|
31
31
|
when String
|
32
|
-
if File.
|
32
|
+
if File.exist?(data)
|
33
33
|
@config_path = data
|
34
|
-
data = YAML
|
34
|
+
data = YAML.load_file(data).deep_symbolize_keys
|
35
35
|
@prompts = _generate_prefs(data)
|
36
36
|
else
|
37
|
-
fail "Invalid configuration file: #{ data }"
|
37
|
+
fail "Invalid configuration file: #{ data }"
|
38
38
|
end
|
39
39
|
when Hash
|
40
40
|
@config_path = nil
|
41
|
-
data = {:
|
41
|
+
data = { prompts: data } unless data.keys[0] == :prompts
|
42
42
|
data.deep_symbolize_keys!
|
43
43
|
@prompts = _generate_prefs(data)
|
44
44
|
when Array
|
45
45
|
@config_path = nil
|
46
|
-
data = {:
|
46
|
+
data = { prompts: data }.deep_symbolize_keys
|
47
47
|
@prompts = _generate_prefs(data)
|
48
48
|
else
|
49
49
|
fail 'Invalid configuration data'
|
@@ -59,8 +59,8 @@ module CLIUtils
|
|
59
59
|
@prompts.reject { |p| p.prereqs }.each do |p|
|
60
60
|
_deliver_prompt(p)
|
61
61
|
end
|
62
|
-
|
63
|
-
@prompts.
|
62
|
+
|
63
|
+
@prompts.select { |p| p.prereqs }.each do |p|
|
64
64
|
_deliver_prompt(p) if _prereqs_fulfilled?(p)
|
65
65
|
end
|
66
66
|
end
|
@@ -75,8 +75,9 @@ module CLIUtils
|
|
75
75
|
default = p.default
|
76
76
|
|
77
77
|
unless @configurator.nil?
|
78
|
-
|
79
|
-
|
78
|
+
section_sym = p.config_section.to_sym
|
79
|
+
unless @configurator.data[section_sym].nil?
|
80
|
+
config_val = @configurator.data[section_sym][p.config_key.to_sym]
|
80
81
|
default = config_val unless config_val.nil?
|
81
82
|
end
|
82
83
|
end
|
@@ -84,7 +85,6 @@ module CLIUtils
|
|
84
85
|
valid_option_chosen = false
|
85
86
|
until valid_option_chosen
|
86
87
|
response = prompt(p.prompt, default)
|
87
|
-
|
88
88
|
if p.validate(response)
|
89
89
|
valid_option_chosen = true
|
90
90
|
p.answer = p.evaluate_behaviors(response)
|
@@ -109,7 +109,7 @@ module CLIUtils
|
|
109
109
|
def _prereqs_fulfilled?(p)
|
110
110
|
ret = true
|
111
111
|
p.prereqs.each do |req|
|
112
|
-
a = @prompts.
|
112
|
+
a = @prompts.find do |answer|
|
113
113
|
answer.config_key == req[:config_key] &&
|
114
114
|
answer.answer == req[:config_value]
|
115
115
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
begin
|
2
|
-
|
2
|
+
unless (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM).nil?
|
3
|
+
require 'Win32/Console/ANSI'
|
4
|
+
end
|
3
5
|
rescue LoadError
|
4
|
-
|
6
|
+
raise 'You must run `gem install win32console` to use CLIMessage on Windows'
|
5
7
|
end
|
6
8
|
|
7
9
|
require 'readline'
|
@@ -19,7 +21,7 @@ module CLIUtils
|
|
19
21
|
# @return [Integer]
|
20
22
|
attr_accessor :wrap_char_limit
|
21
23
|
end
|
22
|
-
|
24
|
+
|
23
25
|
self.wrap = true
|
24
26
|
self.wrap_char_limit = 80
|
25
27
|
|
@@ -41,7 +43,7 @@ module CLIUtils
|
|
41
43
|
40.upto(47) do |bg|
|
42
44
|
print "\033[#{attr};#{fg};#{bg}m #{fg};#{bg} "
|
43
45
|
end
|
44
|
-
|
46
|
+
puts "\033[0m"
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
@@ -106,11 +108,11 @@ module CLIUtils
|
|
106
108
|
Readline.completion_append_character = nil
|
107
109
|
Readline.completion_proc = lambda do |prefix|
|
108
110
|
files = Dir["#{start_dir}#{prefix}*"]
|
109
|
-
files.
|
110
|
-
|
111
|
-
map { |f| File.directory?(f) ? f + "/" : f }
|
111
|
+
files.map { |f| File.expand_path(f) }
|
112
|
+
.map { |f| File.directory?(f) ? "#{ f }/" : f }
|
112
113
|
end
|
113
|
-
|
114
|
+
p = "# #{ prompt }#{ default.nil? ? ':' : " [default: #{ default }]:" } "
|
115
|
+
choice = Readline.readline(p.cyan)
|
114
116
|
if choice.empty?
|
115
117
|
default
|
116
118
|
else
|
@@ -165,13 +167,17 @@ module CLIUtils
|
|
165
167
|
# @param [String] text The text to wrap
|
166
168
|
# @param [String] prefix_str The prefix for each line
|
167
169
|
# @return [String]
|
168
|
-
def _word_wrap(text, prefix_str)
|
170
|
+
def _word_wrap(text, prefix_str)
|
169
171
|
if PrettyIO.wrap
|
170
172
|
return text if PrettyIO.wrap_char_limit <= 0
|
171
|
-
|
173
|
+
|
174
|
+
limit = PrettyIO.wrap_char_limit - prefix_str.length
|
175
|
+
text.gsub(/\n/, ' ')
|
176
|
+
.gsub(/(.{1,#{ limit }})(\s+|$)/, "#{ prefix_str }\\1\n")
|
177
|
+
.strip
|
172
178
|
else
|
173
179
|
text
|
174
180
|
end
|
175
181
|
end
|
176
182
|
end
|
177
|
-
end
|
183
|
+
end
|
data/lib/cliutils.rb
CHANGED
@@ -1,18 +1,17 @@
|
|
1
|
-
require 'cliutils/ext/
|
2
|
-
require 'cliutils/ext/
|
3
|
-
require 'cliutils/ext/
|
1
|
+
require 'cliutils/ext/hash_extensions'
|
2
|
+
require 'cliutils/ext/logger_extensions'
|
3
|
+
require 'cliutils/ext/string_extensions'
|
4
4
|
|
5
|
-
require 'cliutils/
|
5
|
+
require 'cliutils/constants'
|
6
|
+
require 'cliutils/pretty_io'
|
6
7
|
require 'cliutils/configurator'
|
7
8
|
require 'cliutils/configuration'
|
8
|
-
require 'cliutils/
|
9
|
+
require 'cliutils/logger_delegator'
|
9
10
|
require 'cliutils/messenging'
|
10
11
|
require 'cliutils/prefs'
|
11
12
|
require 'cliutils/prefs/pref'
|
12
|
-
require 'cliutils/version'
|
13
13
|
|
14
14
|
# The CLIUtils module, which wraps everything
|
15
15
|
# in this gem.
|
16
16
|
module CLIUtils
|
17
|
-
|
18
|
-
end
|
17
|
+
end
|
data/test/configurator_test.rb
CHANGED
@@ -3,6 +3,7 @@ require 'test/unit'
|
|
3
3
|
|
4
4
|
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/configurator')
|
5
5
|
|
6
|
+
# Tests for the Configurator class
|
6
7
|
class TestConfigurator < Test::Unit::TestCase
|
7
8
|
def setup
|
8
9
|
@config_path = '/tmp/test.config'
|
@@ -10,25 +11,25 @@ class TestConfigurator < Test::Unit::TestCase
|
|
10
11
|
end
|
11
12
|
|
12
13
|
def teardown
|
13
|
-
FileUtils.rm(@config_path) if File.
|
14
|
+
FileUtils.rm(@config_path) if File.exist?(@config_path)
|
14
15
|
end
|
15
16
|
|
16
17
|
def test_add_section
|
17
18
|
@config.add_section(:test)
|
18
|
-
assert_equal(@config.data,
|
19
|
+
assert_equal(@config.data, test: {})
|
19
20
|
end
|
20
21
|
|
21
22
|
def test_delete_section
|
22
23
|
@config.add_section(:test)
|
23
24
|
@config.add_section(:test2)
|
24
25
|
@config.delete_section(:test)
|
25
|
-
assert_equal(@config.data,
|
26
|
+
assert_equal(@config.data, test2: {})
|
26
27
|
end
|
27
28
|
|
28
29
|
def test_accessing
|
29
30
|
@config.add_section(:test)
|
30
31
|
@config.data[:test].merge!(name: 'Bob')
|
31
|
-
assert_equal(@config.test,
|
32
|
+
assert_equal(@config.test, name: 'Bob')
|
32
33
|
end
|
33
34
|
|
34
35
|
def test_reset
|
@@ -40,9 +41,9 @@ class TestConfigurator < Test::Unit::TestCase
|
|
40
41
|
|
41
42
|
def test_save
|
42
43
|
@config.add_section(:section1)
|
43
|
-
@config.section1.merge!(
|
44
|
+
@config.section1.merge!(a: 'test', b: 'test')
|
44
45
|
@config.save
|
45
|
-
|
46
|
+
|
46
47
|
File.open(@config_path, 'r') do |f|
|
47
48
|
assert_output("---\nsection1:\n a: test\n b: test\n") { puts f.read }
|
48
49
|
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
|
-
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/
|
3
|
+
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/hash_extensions')
|
4
4
|
|
5
|
+
# Tests for the Hash extension methods
|
5
6
|
class TestHashExtensions < Test::Unit::TestCase
|
6
7
|
def test_deep_merge!
|
7
|
-
h1 = {key: 'value', key2:
|
8
|
-
h2 = {
|
9
|
-
exp_result = {:
|
8
|
+
h1 = { key: 'value', key2: %w(value1, value2) }
|
9
|
+
h2 = { key: 'another_value' }
|
10
|
+
exp_result = { key: 'another_value', key2: %w(value1, value2) }
|
10
11
|
actual_result = h1.deep_merge!(h2)
|
11
12
|
|
12
13
|
assert_equal(exp_result, actual_result)
|
13
14
|
end
|
14
15
|
|
15
16
|
def test_deep_stringify_keys
|
16
|
-
h = {key: {subkey1: 'value1', subkey2: {subsubkey1: 'value'}}}
|
17
|
-
exp_result = {'key' => {'subkey1' => 'value1', 'subkey2' => {'subsubkey1' => 'value'}}}
|
17
|
+
h = { key: { subkey1: 'value1', subkey2: { subsubkey1: 'value' } } }
|
18
|
+
exp_result = { 'key' => { 'subkey1' => 'value1', 'subkey2' => { 'subsubkey1' => 'value' } } }
|
18
19
|
actual_result = h.deep_stringify_keys
|
19
20
|
|
20
21
|
assert_not_equal(h, actual_result)
|
@@ -23,7 +24,7 @@ class TestHashExtensions < Test::Unit::TestCase
|
|
23
24
|
|
24
25
|
def test_deep_stringify_keys!
|
25
26
|
h = {key: {subkey1: 'value1', subkey2: {subsubkey1: 'value'}}}
|
26
|
-
exp_result = {'key' => {'subkey1' => 'value1', 'subkey2' => {'subsubkey1' => 'value'}}}
|
27
|
+
exp_result = { 'key' => { 'subkey1' => 'value1', 'subkey2' => { 'subsubkey1' => 'value' } } }
|
27
28
|
actual_result = h.deep_stringify_keys!
|
28
29
|
|
29
30
|
assert_equal(h, actual_result)
|
@@ -31,8 +32,8 @@ class TestHashExtensions < Test::Unit::TestCase
|
|
31
32
|
end
|
32
33
|
|
33
34
|
def test_deep_symbolize_keys
|
34
|
-
h = {'key' => {'subkey1' => 'value1', 'subkey2' => {'subsubkey1' => 'value'}}}
|
35
|
-
exp_result = {key: {subkey1: 'value1', subkey2: {subsubkey1: 'value'}}}
|
35
|
+
h = { 'key' => { 'subkey1' => 'value1', 'subkey2' => { 'subsubkey1' => 'value'} } }
|
36
|
+
exp_result = { key: { subkey1: 'value1', subkey2: { subsubkey1: 'value'} } }
|
36
37
|
actual_result = h.deep_symbolize_keys
|
37
38
|
|
38
39
|
assert_not_equal(h, actual_result)
|
@@ -40,8 +41,8 @@ class TestHashExtensions < Test::Unit::TestCase
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def test_deep_symbolize_keys!
|
43
|
-
h = {'key' => {'subkey1' => 'value1', 'subkey2' => {'subsubkey1' => 'value'}}}
|
44
|
-
exp_result = {key: {subkey1: 'value1', subkey2: {subsubkey1: 'value'}}}
|
44
|
+
h = { 'key' => { 'subkey1' => 'value1', 'subkey2' => { 'subsubkey1' => 'value'} } }
|
45
|
+
exp_result = { key: { subkey1: 'value1', subkey2: { subsubkey1: 'value'} } }
|
45
46
|
actual_result = h.deep_symbolize_keys!
|
46
47
|
|
47
48
|
assert_equal(h, actual_result)
|
@@ -1,16 +1,17 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
|
-
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/
|
3
|
+
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/logger_extensions')
|
4
4
|
|
5
|
+
# Tests for the Logger extension methods
|
5
6
|
class TestLoggerExtensions < Test::Unit::TestCase
|
6
7
|
def test_custom_level
|
7
8
|
l = Logger.new(STDOUT)
|
8
9
|
l.formatter = proc do |severity, datetime, progname, msg|
|
9
10
|
puts "#{ severity }: #{ msg }"
|
10
11
|
end
|
11
|
-
|
12
|
+
|
12
13
|
assert_output("PROMPT: test\n") { l.prompt('test') }
|
13
14
|
assert_output("SECTION: test\n") { l.section('test') }
|
14
15
|
assert_output("SUCCESS: test\n") { l.success('test') }
|
15
16
|
end
|
16
|
-
end
|
17
|
+
end
|
data/test/messenging_test.rb
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
require 'logger'
|
2
2
|
require 'test/unit'
|
3
3
|
|
4
|
-
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/
|
5
|
-
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/
|
6
|
-
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/
|
4
|
+
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/string_extensions')
|
5
|
+
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/pretty_io')
|
6
|
+
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/logger_delegator')
|
7
7
|
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/messenging')
|
8
8
|
|
9
|
+
# Tests for the Hash extension methods
|
9
10
|
class TestMessenging < Test::Unit::TestCase
|
10
11
|
include CLIUtils::Messenging
|
11
|
-
|
12
|
+
|
12
13
|
def setup
|
13
14
|
@file1path = '/tmp/file1.txt'
|
14
15
|
end
|
15
16
|
|
16
17
|
def teardown
|
17
|
-
FileUtils.rm(@file1path) if File.
|
18
|
+
FileUtils.rm(@file1path) if File.exist?(@file1path)
|
18
19
|
end
|
19
|
-
|
20
|
+
|
20
21
|
def test_stdout_output
|
21
22
|
assert_output('# This is error'.red + "\n") { messenger.send(:error, 'This is error') }
|
22
23
|
assert_output('# This is info'.blue + "\n") { messenger.send(:info, 'This is info') }
|
@@ -24,10 +25,10 @@ class TestMessenging < Test::Unit::TestCase
|
|
24
25
|
assert_output('# This is success'.green + "\n") { messenger.send(:success, 'This is success') }
|
25
26
|
assert_output('# This is warn'.yellow + "\n") { messenger.send(:warn, 'This is warn') }
|
26
27
|
end
|
27
|
-
|
28
|
+
|
28
29
|
def test_wrapping
|
29
30
|
CLIUtils::PrettyIO.wrap_char_limit = 35
|
30
|
-
|
31
|
+
|
31
32
|
long_str = 'This is a really long string that should wrap itself at some point, okay?'
|
32
33
|
expected_str = long_str.gsub(/\n/, ' ').gsub(/(.{1,#{CLIUtils::PrettyIO.wrap_char_limit - 2}})(\s+|$)/, "# \\1\n").strip
|
33
34
|
assert_output(expected_str.blue + "\n") { messenger.send(:info, long_str) }
|
@@ -38,13 +39,13 @@ class TestMessenging < Test::Unit::TestCase
|
|
38
39
|
file_logger.formatter = proc do |severity, datetime, progname, msg|
|
39
40
|
"#{ severity }: #{ msg }\n"
|
40
41
|
end
|
41
|
-
|
42
|
+
|
42
43
|
messenger.attach(FILE: file_logger)
|
43
44
|
messenger.send(:info, 'Info test')
|
44
45
|
messenger.send(:error, 'Error test')
|
45
46
|
messenger.detach(:FILE)
|
46
47
|
messenger.send(:warn, 'Warn test')
|
47
|
-
|
48
|
+
|
48
49
|
File.open(@file1path, 'r') do |f|
|
49
50
|
assert_output("INFO: Info test\nERROR: Error test\n") { puts f.read.lines.to_a[1..-1].join }
|
50
51
|
end
|
data/test/prefs_test.rb
CHANGED
@@ -1,72 +1,73 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'yaml'
|
3
3
|
|
4
|
-
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/
|
4
|
+
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/hash_extensions')
|
5
5
|
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/prefs')
|
6
6
|
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/prefs/pref')
|
7
7
|
|
8
|
+
# Tests for the Prefs class
|
8
9
|
class TestPrefs < Test::Unit::TestCase
|
9
10
|
def setup
|
10
11
|
@prefs_arr = [
|
11
12
|
{
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
'prompt' => 'Batman or Superman?',
|
14
|
+
'default' => 'Batman',
|
15
|
+
'config_key' => 'superhero',
|
16
|
+
'config_section' => 'personal_info'
|
16
17
|
},
|
17
18
|
{
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
'prompt' => 'Do you feel smart for preferring Batman?',
|
20
|
+
'default' => 'Y',
|
21
|
+
'config_key' => 'batman_answer',
|
22
|
+
'config_section' => 'personal_info',
|
23
|
+
'prereqs' => [
|
23
24
|
{
|
24
|
-
|
25
|
-
|
25
|
+
'config_key' => 'superhero',
|
26
|
+
'config_value' => 'Batman'
|
26
27
|
}
|
27
28
|
]
|
28
29
|
},
|
29
30
|
{
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
'prompt' => 'Why do you prefer Superman?!',
|
32
|
+
'default' => 'No clue',
|
33
|
+
'config_key' => 'superman_answer',
|
34
|
+
'config_section' => 'personal_info',
|
35
|
+
'prereqs' => [
|
35
36
|
{
|
36
|
-
|
37
|
-
|
37
|
+
'config_key' => 'superhero',
|
38
|
+
'config_value' => 'Superman'
|
38
39
|
}
|
39
40
|
]
|
40
41
|
}
|
41
42
|
]
|
42
|
-
|
43
|
+
|
43
44
|
@prefs_hash = {:prompts=>@prefs_arr}
|
44
45
|
@prefs_filepath = '/tmp/prefstest.yaml'
|
45
46
|
FileUtils.cp(File.join(File.dirname(__FILE__), '..', 'test/test_files/prefstest.yaml'), @prefs_filepath)
|
46
47
|
end
|
47
48
|
|
48
49
|
def teardown
|
49
|
-
FileUtils.rm(@prefs_filepath) if File.
|
50
|
+
FileUtils.rm(@prefs_filepath) if File.exist?(@prefs_filepath)
|
50
51
|
end
|
51
52
|
|
52
53
|
def test_file_creation
|
53
54
|
p = CLIUtils::Prefs.new(@prefs_filepath)
|
54
55
|
prefs = YAML::load_file(@prefs_filepath).deep_symbolize_keys
|
55
56
|
|
56
|
-
assert_equal(prefs[:prompts].map { |p| CLIUtils::Pref.new(p) }, p.
|
57
|
+
assert_equal(prefs[:prompts].map { |p| CLIUtils::Pref.new(p) }, p.prompts)
|
57
58
|
end
|
58
59
|
|
59
60
|
def test_array_creation
|
60
61
|
p = CLIUtils::Prefs.new(@prefs_arr)
|
61
62
|
prefs = @prefs_hash.deep_symbolize_keys
|
62
|
-
|
63
|
-
assert_equal(prefs[:prompts].map { |p| CLIUtils::Pref.new(p) }, p.
|
63
|
+
|
64
|
+
assert_equal(prefs[:prompts].map { |p| CLIUtils::Pref.new(p) }, p.prompts)
|
64
65
|
end
|
65
66
|
|
66
67
|
def test_hash_creation
|
67
68
|
p = CLIUtils::Prefs.new(@prefs_hash)
|
68
69
|
prefs = @prefs_hash.deep_symbolize_keys
|
69
|
-
|
70
|
-
assert_equal(prefs[:prompts].map { |p| CLIUtils::Pref.new(p) }, p.
|
70
|
+
|
71
|
+
assert_equal(prefs[:prompts].map { |p| CLIUtils::Pref.new(p) }, p.prompts)
|
71
72
|
end
|
72
73
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
|
-
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/
|
3
|
+
require File.join(File.dirname(__FILE__), '..', 'lib/cliutils/ext/string_extensions')
|
4
4
|
|
5
|
+
# Tests for the String extension methods
|
5
6
|
class TestStringExtensions < Test::Unit::TestCase
|
6
7
|
def test_custom_colors
|
7
8
|
assert_output("\e[34mtest\e[0m\n") { puts 'test'.blue }
|
@@ -11,4 +12,4 @@ class TestStringExtensions < Test::Unit::TestCase
|
|
11
12
|
assert_output("\e[31mtest\e[0m\n") { puts 'test'.red }
|
12
13
|
assert_output("\e[33mtest\e[0m\n") { puts 'test'.yellow }
|
13
14
|
end
|
14
|
-
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cliutils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Bach
|
@@ -86,17 +86,17 @@ files:
|
|
86
86
|
- lib/cliutils.rb
|
87
87
|
- lib/cliutils/configuration.rb
|
88
88
|
- lib/cliutils/configurator.rb
|
89
|
-
- lib/cliutils/
|
90
|
-
- lib/cliutils/ext/
|
91
|
-
- lib/cliutils/ext/
|
92
|
-
- lib/cliutils/
|
89
|
+
- lib/cliutils/constants.rb
|
90
|
+
- lib/cliutils/ext/hash_extensions.rb
|
91
|
+
- lib/cliutils/ext/logger_extensions.rb
|
92
|
+
- lib/cliutils/ext/string_extensions.rb
|
93
|
+
- lib/cliutils/logger_delegator.rb
|
93
94
|
- lib/cliutils/messenging.rb
|
94
95
|
- lib/cliutils/prefs.rb
|
95
|
-
- lib/cliutils/prefs/pref-behavior.rb
|
96
|
-
- lib/cliutils/prefs/pref-validation.rb
|
97
96
|
- lib/cliutils/prefs/pref.rb
|
98
|
-
- lib/cliutils/
|
99
|
-
- lib/cliutils/
|
97
|
+
- lib/cliutils/prefs/pref_behavior.rb
|
98
|
+
- lib/cliutils/prefs/pref_validation.rb
|
99
|
+
- lib/cliutils/pretty_io.rb
|
100
100
|
- res/readme-images/messenger-types-1.png
|
101
101
|
- res/readme-images/messenger-warn.png
|
102
102
|
- res/readme-images/multi-logger.png
|