cliutils 1.0.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.
Files changed (96) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +1 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +48 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +288 -0
  8. data/README.rdoc +19 -0
  9. data/Rakefile +45 -0
  10. data/bin/cliutils +38 -0
  11. data/cliutils.gemspec +28 -0
  12. data/features/cli_manager.feature +13 -0
  13. data/features/step_definitions/cli_manager_steps.rb +1 -0
  14. data/features/support/env.rb +16 -0
  15. data/html/CLIUtils/Configuration.html +271 -0
  16. data/html/CLIUtils/Configurator.html +504 -0
  17. data/html/CLIUtils/LoggerDelegator.html +344 -0
  18. data/html/CLIUtils/Messenging.html +284 -0
  19. data/html/CLIUtils/Prefs.html +330 -0
  20. data/html/CLIUtils/PrettyIO.html +799 -0
  21. data/html/CLIUtils.html +112 -0
  22. data/html/Hash.html +453 -0
  23. data/html/Logger.html +183 -0
  24. data/html/Object.html +120 -0
  25. data/html/README_md.html +454 -0
  26. data/html/String.html +413 -0
  27. data/html/created.rid +13 -0
  28. data/html/fonts/Lato-Light.ttf +0 -0
  29. data/html/fonts/Lato-LightItalic.ttf +0 -0
  30. data/html/fonts/Lato-Regular.ttf +0 -0
  31. data/html/fonts/Lato-RegularItalic.ttf +0 -0
  32. data/html/fonts/SourceCodePro-Bold.ttf +0 -0
  33. data/html/fonts/SourceCodePro-Regular.ttf +0 -0
  34. data/html/fonts.css +167 -0
  35. data/html/images/add.png +0 -0
  36. data/html/images/arrow_up.png +0 -0
  37. data/html/images/brick.png +0 -0
  38. data/html/images/brick_link.png +0 -0
  39. data/html/images/bug.png +0 -0
  40. data/html/images/bullet_black.png +0 -0
  41. data/html/images/bullet_toggle_minus.png +0 -0
  42. data/html/images/bullet_toggle_plus.png +0 -0
  43. data/html/images/date.png +0 -0
  44. data/html/images/delete.png +0 -0
  45. data/html/images/find.png +0 -0
  46. data/html/images/loadingAnimation.gif +0 -0
  47. data/html/images/macFFBgHack.png +0 -0
  48. data/html/images/package.png +0 -0
  49. data/html/images/page_green.png +0 -0
  50. data/html/images/page_white_text.png +0 -0
  51. data/html/images/page_white_width.png +0 -0
  52. data/html/images/plugin.png +0 -0
  53. data/html/images/ruby.png +0 -0
  54. data/html/images/tag_blue.png +0 -0
  55. data/html/images/tag_green.png +0 -0
  56. data/html/images/transparent.png +0 -0
  57. data/html/images/wrench.png +0 -0
  58. data/html/images/wrench_orange.png +0 -0
  59. data/html/images/zoom.png +0 -0
  60. data/html/index.html +455 -0
  61. data/html/js/darkfish.js +140 -0
  62. data/html/js/jquery.js +18 -0
  63. data/html/js/navigation.js +142 -0
  64. data/html/js/search.js +109 -0
  65. data/html/js/search_index.js +1 -0
  66. data/html/js/searcher.js +228 -0
  67. data/html/rdoc.css +580 -0
  68. data/html/table_of_contents.html +399 -0
  69. data/lib/.DS_Store +0 -0
  70. data/lib/cliutils/configuration.rb +48 -0
  71. data/lib/cliutils/configurator.rb +119 -0
  72. data/lib/cliutils/ext/Hash+Extensions.rb +145 -0
  73. data/lib/cliutils/ext/Logger+Extensions.rb +27 -0
  74. data/lib/cliutils/ext/String+Extensions.rb +26 -0
  75. data/lib/cliutils/logger-delegator.rb +66 -0
  76. data/lib/cliutils/messenging.rb +51 -0
  77. data/lib/cliutils/prefs.rb +116 -0
  78. data/lib/cliutils/pretty-io.rb +255 -0
  79. data/lib/cliutils/version.rb +3 -0
  80. data/lib/cliutils.rb +15 -0
  81. data/res/readme-images/messenger-types-1.png +0 -0
  82. data/res/readme-images/messenger-warn.png +0 -0
  83. data/res/readme-images/multi-logger.png +0 -0
  84. data/res/readme-images/prettyio-color-chart.png +0 -0
  85. data/res/readme-images/prettyio-gnarly-text.png +0 -0
  86. data/res/readme-images/prettyio-red-text.png +0 -0
  87. data/res/readme-images/prompting.png +0 -0
  88. data/res/readme-images/wrapping.png +0 -0
  89. data/test/configurator_test.rb +50 -0
  90. data/test/hash_extensions_test.rb +50 -0
  91. data/test/logger_extensions_test.rb +16 -0
  92. data/test/messenging_test.rb +53 -0
  93. data/test/prefs_test.rb +29 -0
  94. data/test/string_extesions_test.rb +14 -0
  95. data/test/test_files/prefstest.yaml +33 -0
  96. metadata +199 -0
@@ -0,0 +1,145 @@
1
+ # ======================================================
2
+ # Hash Class
3
+ #
4
+ # Contains many convenient methods borrowed from Rails
5
+ # http://api.rubyonrails.org/classes/Hash.html
6
+ # ======================================================
7
+ class Hash
8
+ # ====================================================
9
+ # Methods
10
+ # ====================================================
11
+ # ----------------------------------------------------
12
+ # deep_merge! method
13
+ #
14
+ # Deep merges a hash into the current one.
15
+ # @param other_hash The hash to merge in
16
+ # @param &block
17
+ # @return Hash
18
+ # ----------------------------------------------------
19
+ def deep_merge!(other_hash, &block)
20
+ other_hash.each_pair do |k,v|
21
+ tv = self[k]
22
+ if tv.is_a?(Hash) && v.is_a?(Hash)
23
+ self[k] = tv.deep_merge(v, &block)
24
+ else
25
+ self[k] = block && tv ? block.call(k, tv, v) : v
26
+ end
27
+ end
28
+ self
29
+ end
30
+
31
+ # ----------------------------------------------------
32
+ # deep_stringify_keys method
33
+ #
34
+ # Recursively turns all Hash keys into strings and
35
+ # returns the new Hash.
36
+ # @return Hash
37
+ # ----------------------------------------------------
38
+ def deep_stringify_keys
39
+ deep_transform_keys{ |key| key.to_s }
40
+ end
41
+
42
+ # ----------------------------------------------------
43
+ # deep_symbolize_keys! method
44
+ #
45
+ # Same as deep_stringify_keys, but destructively
46
+ # alters the original Hash.
47
+ # @return Hash
48
+ # ----------------------------------------------------
49
+ def deep_stringify_keys!
50
+ deep_transform_keys!{ |key| key.to_s }
51
+ end
52
+
53
+ # ----------------------------------------------------
54
+ # deep_symbolize_keys method
55
+ #
56
+ # Recursively turns all Hash keys into symbols and
57
+ # returns the new Hash.
58
+ # @return Hash
59
+ # ----------------------------------------------------
60
+ def deep_symbolize_keys
61
+ deep_transform_keys{ |key| key.to_sym rescue key }
62
+ end
63
+
64
+ # ----------------------------------------------------
65
+ # deep_symbolize_keys! method
66
+ #
67
+ # Same as deep_symbolize_keys, but destructively
68
+ # alters the original Hash.
69
+ # @return Hash
70
+ # ----------------------------------------------------
71
+ def deep_symbolize_keys!
72
+ deep_transform_keys!{ |key| key.to_sym rescue key }
73
+ end
74
+
75
+ # ----------------------------------------------------
76
+ # deep_transform_keys method
77
+ #
78
+ # Generic method to perform recursive operations on a
79
+ # Hash.
80
+ # @return Hash
81
+ # ----------------------------------------------------
82
+ def deep_transform_keys(&block)
83
+ _deep_transform_keys_in_object(self, &block)
84
+ end
85
+
86
+ # ----------------------------------------------------
87
+ # deep_transform_keys! method
88
+ #
89
+ # Same as deep_transform_keys, but destructively
90
+ # alters the original Hash.
91
+ # @return Hash
92
+ # ----------------------------------------------------
93
+ def deep_transform_keys!(&block)
94
+ _deep_transform_keys_in_object!(self, &block)
95
+ end
96
+
97
+ private
98
+
99
+ # ----------------------------------------------------
100
+ # _deep_transform_keys_in_object method
101
+ #
102
+ # Modification to deep_transform_keys that allows for
103
+ # the existence of arrays.
104
+ # https://github.com/rails/rails/pull/9720/files?short_path=4be3c90
105
+ # @param object The object to examine
106
+ # @param &block A block to execute on the opject
107
+ # @return Object
108
+ # ----------------------------------------------------
109
+ def _deep_transform_keys_in_object(object, &block)
110
+ case object
111
+ when Hash
112
+ object.each_with_object({}) do |(key, value), result|
113
+ result[yield(key)] = _deep_transform_keys_in_object(value, &block)
114
+ end
115
+ when Array
116
+ object.map {|e| _deep_transform_keys_in_object(e, &block) }
117
+ else
118
+ object
119
+ end
120
+ end
121
+
122
+ # ----------------------------------------------------
123
+ # _deep_transform_keys_in_object! method
124
+ #
125
+ # Same as _deep_transform_keys_in_object, but
126
+ # destructively alters the original Object.
127
+ # @param object The object to examine
128
+ # @param &block A block to execute on the opject
129
+ # @return Object
130
+ # ----------------------------------------------------
131
+ def _deep_transform_keys_in_object!(object, &block)
132
+ case object
133
+ when Hash
134
+ object.keys.each do |key|
135
+ value = object.delete(key)
136
+ object[yield(key)] = _deep_transform_keys_in_object!(value, &block)
137
+ end
138
+ object
139
+ when Array
140
+ object.map! {|e| _deep_transform_keys_in_object!(e, &block)}
141
+ else
142
+ object
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,27 @@
1
+ require 'logger'
2
+
3
+ # ======================================================
4
+ # Logger Class
5
+ # ======================================================
6
+ class Logger
7
+ # ----------------------------------------------------
8
+ # custom_level method
9
+ #
10
+ # Creates a custom Logger level based on the passed
11
+ # tag.
12
+ # @param tag The Logger level to create
13
+ # @return Void
14
+ # ----------------------------------------------------
15
+ def self.custom_level(tag)
16
+ SEV_LABEL << tag
17
+ idx = SEV_LABEL.size - 1
18
+
19
+ define_method(tag.downcase.gsub(/\W+/, '_').to_sym) do |progname, &block|
20
+ add(idx, nil, progname, &block)
21
+ end
22
+ end
23
+
24
+ custom_level('PROMPT')
25
+ custom_level('SECTION')
26
+ custom_level('SUCCESS')
27
+ end
@@ -0,0 +1,26 @@
1
+ # ======================================================
2
+ # String Class
3
+ # ======================================================
4
+ class String
5
+ # ====================================================
6
+ # Color String Methods
7
+ # ====================================================
8
+ # ----------------------------------------------------
9
+ # colorize method
10
+ #
11
+ # Outputs a string in a formatted color.
12
+ # @param color_code The code to use
13
+ # @return Void
14
+ # ----------------------------------------------------
15
+ def colorize(color_code)
16
+ "\033[#{ color_code }m#{ self }\033[0m"
17
+ end
18
+
19
+ def blue; colorize(34) end
20
+ def cyan; colorize(36) end
21
+ def green; colorize(32) end
22
+ def purple; colorize(35) end
23
+ def red; colorize(31) end
24
+ def white; colorize(37) end
25
+ def yellow; colorize(33) end
26
+ end
@@ -0,0 +1,66 @@
1
+ module CLIUtils
2
+ # ======================================================
3
+ # LoggerDelegator Class
4
+ #
5
+ # Manages any configuration values and the flat YAML file
6
+ # into which they get stored.
7
+ # ======================================================
8
+ class LoggerDelegator
9
+ # ====================================================
10
+ # Attributes
11
+ # ====================================================
12
+ attr_reader :devices
13
+
14
+ # ====================================================
15
+ # Methods
16
+ # ====================================================
17
+ # ----------------------------------------------------
18
+ # initialize method
19
+ #
20
+ # Initializer
21
+ # @param *targets The endpoints to delegate to
22
+ # @return void
23
+ # ----------------------------------------------------
24
+ def initialize(*targets)
25
+ @targets = targets
26
+ LoggerDelegator.delegate
27
+ end
28
+
29
+ # ----------------------------------------------------
30
+ # attach method
31
+ #
32
+ # Attaches a new target to delegate to.
33
+ # @return void
34
+ # ----------------------------------------------------
35
+ def attach(target)
36
+ @targets << target
37
+ LoggerDelegator.delegate
38
+ end
39
+
40
+ # ----------------------------------------------------
41
+ # delegate_all method
42
+ #
43
+ # Creates delegator methods for all of the methods
44
+ # on IO.
45
+ # @return void
46
+ # ----------------------------------------------------
47
+ def self.delegate
48
+ %w(log debug info warn error section success).each do |m|
49
+ define_method(m) do |*args|
50
+ @targets.map { |t| t.send(m, *args) }
51
+ end
52
+ end
53
+ end
54
+
55
+ # ----------------------------------------------------
56
+ # detach method
57
+ #
58
+ # Detaches a delegation target.
59
+ # @return void
60
+ # ----------------------------------------------------
61
+ def detach(target)
62
+ @targets.delete(target)
63
+ LoggerDelegator.delegate
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,51 @@
1
+ module CLIUtils
2
+ # ======================================================
3
+ # CLIMessenger Module
4
+ # Outputs color-coordinated messages to a CLI
5
+ # ======================================================
6
+ module Messenging
7
+ include CLIUtils::PrettyIO
8
+
9
+ # ====================================================
10
+ # Methods
11
+ # ====================================================
12
+ # ----------------------------------------------------
13
+ # included method
14
+ #
15
+ # Hook called when this module gets mixed in; extends
16
+ # the includer with the methods defined here.
17
+ # @param k The includer
18
+ # @return Void
19
+ # ----------------------------------------------------
20
+ def self.included(k)
21
+ k.extend(self)
22
+ end
23
+
24
+ # ----------------------------------------------------
25
+ # default_instance method
26
+ #
27
+ # Returns a default instance of LoggerDelegator that
28
+ # delegates to STDOUT only.
29
+ # @return LoggerDelegator
30
+ # ----------------------------------------------------
31
+ def default_instance
32
+ stdout_logger = Logger.new(STDOUT)
33
+ stdout_logger.formatter = proc do |severity, datetime, progname, msg|
34
+ send(severity.downcase, msg)
35
+ end
36
+
37
+ LoggerDelegator.new(stdout_logger)
38
+ end
39
+
40
+ # ----------------------------------------------------
41
+ # messenger method
42
+ #
43
+ # Singleton method to return (or initialize, if needed)
44
+ # a LoggerDelegator.
45
+ # @return LoggerDelegator
46
+ # ----------------------------------------------------
47
+ def messenger
48
+ @messenger ||= default_instance
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,116 @@
1
+ module CLIUtils
2
+ # ======================================================
3
+ # PrefManager Class
4
+ #
5
+ # Engine to derive preferences from a YAML file, deliver
6
+ # those to a user via a prompt, and collect the results.
7
+ # ======================================================
8
+ class Prefs
9
+ include PrettyIO
10
+ # ====================================================
11
+ # Attributes
12
+ # ====================================================
13
+ attr_reader :answers, :config_path, :prompts
14
+
15
+ # ====================================================
16
+ # Methods
17
+ # ====================================================
18
+ # ----------------------------------------------------
19
+ # initialize method
20
+ #
21
+ # Reads prompt data from YAML file.
22
+ # @return Void
23
+ # ----------------------------------------------------
24
+ def initialize(data)
25
+ @answers = []
26
+ @prompts = {}
27
+
28
+ case data
29
+ when String
30
+ if File.exists?(data)
31
+ @config_path = data
32
+
33
+ prompts = YAML::load_file(data)
34
+ @prompts.deep_merge!(prompts).deep_symbolize_keys!
35
+ else
36
+ fail "Invalid configuration file: #{ yaml_path }"
37
+ end
38
+ when Array
39
+ @config_path = nil
40
+
41
+ prompts = {:prompts => data}
42
+ @prompts.deep_merge!(prompts).deep_symbolize_keys!
43
+ else
44
+ fail 'Invalid configuration data'
45
+ end
46
+ end
47
+
48
+ # ----------------------------------------------------
49
+ # ask method
50
+ #
51
+ # Runs through all of the prompt questions and collects
52
+ # answers from the user. Note that all questions w/o
53
+ # requirements are examined first; once those are
54
+ # complete, questions w/ requirements are examined.
55
+ # @return Void
56
+ # ----------------------------------------------------
57
+ def ask
58
+ @prompts[:prompts].reject { |p| p[:requirements] }.each do |p|
59
+ _deliver_prompt(p)
60
+ end
61
+
62
+ @prompts[:prompts].find_all { |p| p[:requirements] }.each do |p|
63
+ _deliver_prompt(p) if _requirements_fulfilled?(p)
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ # ----------------------------------------------------
70
+ # _deliver_prompt method
71
+ #
72
+ # Utility method for prompting the user to answer the
73
+ # question (taking into account any options).
74
+ # @param p The prompt
75
+ # @return Void
76
+ # ----------------------------------------------------
77
+ def _deliver_prompt(p)
78
+ if p[:options].nil?
79
+ pref = prompt(p[:prompt], p[:default])
80
+ else
81
+ valid_option_chosen = false
82
+ until valid_option_chosen
83
+ pref = prompt(p[:prompt], p[:default])
84
+ if p[:options].include?(pref)
85
+ valid_option_chosen = true
86
+ else
87
+ error("Invalid option chosen: #{ pref }")
88
+ end
89
+ end
90
+ end
91
+
92
+ p[:answer] = pref
93
+ @answers << p
94
+ end
95
+
96
+ # ----------------------------------------------------
97
+ # _requirements_fulfilled? method
98
+ #
99
+ # Utility method for determining whether a prompt's
100
+ # requirements have already been fulfilled.
101
+ # @param p The prompt
102
+ # @return Void
103
+ # ----------------------------------------------------
104
+ def _requirements_fulfilled?(p)
105
+ ret = true
106
+ p[:requirements].each do |req|
107
+ a = @answers.detect do |answer|
108
+ answer[:key] == req[:key] &&
109
+ answer[:answer] == req[:value]
110
+ end
111
+ ret = false if a.nil?
112
+ end
113
+ ret
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,255 @@
1
+ begin
2
+ require 'Win32/Console/ANSI' if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
3
+ rescue LoadError
4
+ raise 'You must run `gem install win32console` to use CLIMessage on Windows'
5
+ end
6
+
7
+ require 'readline'
8
+
9
+ module CLIUtils
10
+ # ======================================================
11
+ # CLIMessenger Module
12
+ # Outputs color-coordinated messages to a CLI
13
+ # ======================================================
14
+ module PrettyIO
15
+ @@wrap = true
16
+ @@wrap_char_limit = 40
17
+
18
+ # ====================================================
19
+ # Methods
20
+ # ====================================================
21
+ # ----------------------------------------------------
22
+ # included method
23
+ #
24
+ # Hook called when this module gets mixed in; extends
25
+ # the includer with the methods defined here.
26
+ # @param k The includer
27
+ # @return Void
28
+ # ----------------------------------------------------
29
+ def self.included(k)
30
+ k.extend(self)
31
+ end
32
+
33
+ # ----------------------------------------------------
34
+ # color_chart method
35
+ #
36
+ # Displays a chart of all the possible ANSI foreground
37
+ # and background color combinations.
38
+ # @return Void
39
+ # ----------------------------------------------------
40
+ def color_chart
41
+ [0, 1, 4, 5, 7].each do |attr|
42
+ puts '----------------------------------------------------------------'
43
+ puts "ESC[#{attr};Foreground;Background"
44
+ 30.upto(37) do |fg|
45
+ 40.upto(47) do |bg|
46
+ print "\033[#{attr};#{fg};#{bg}m #{fg};#{bg} "
47
+ end
48
+ puts "\033[0m"
49
+ end
50
+ end
51
+ end
52
+
53
+ # ----------------------------------------------------
54
+ # debug method
55
+ #
56
+ # Empty method so that Messenging doesn't freak
57
+ # out when passed a debug message.
58
+ # @return Void
59
+ # ----------------------------------------------------
60
+ def debug(m); end
61
+
62
+ # ----------------------------------------------------
63
+ # error method
64
+ #
65
+ # Outputs a formatted-red error message.
66
+ # @param m The message to output
67
+ # @return Void
68
+ # ----------------------------------------------------
69
+ def error(m)
70
+ puts _word_wrap(m, '# ').red
71
+ end
72
+
73
+ # ----------------------------------------------------
74
+ # info method
75
+ #
76
+ # Outputs a formatted-blue informational message.
77
+ # @param m The message to output
78
+ # @return Void
79
+ # ----------------------------------------------------
80
+ def info(m)
81
+ puts _word_wrap(m, '# ').blue
82
+ end
83
+
84
+ # ----------------------------------------------------
85
+ # info_block method
86
+ #
87
+ # Wraps a block in an opening and closing info message.
88
+ # @param m1 The opening message to output
89
+ # @param m2 The closing message to output
90
+ # @param multiline Whether the message should be multiline
91
+ # @return Void
92
+ # ----------------------------------------------------
93
+ def info_block(m1, m2 = 'Done.', multiline = false)
94
+ if block_given?
95
+ if multiline
96
+ info(m1)
97
+ else
98
+ print _word_wrap(m1, '# ').blue
99
+ end
100
+
101
+ yield
102
+
103
+ if multiline
104
+ info(m2)
105
+ else
106
+ puts _word_wrap(m2, '# ').blue
107
+ end
108
+ else
109
+ fail 'Did not specify a valid block'
110
+ end
111
+ end
112
+
113
+ # ----------------------------------------------------
114
+ # log method
115
+ #
116
+ # Empty method so that Messenging doesn't freak
117
+ # out when passed a debug message.
118
+ # @return Void
119
+ # ----------------------------------------------------
120
+ def log(m); end
121
+
122
+ # ----------------------------------------------------
123
+ # prompt method
124
+ #
125
+ # Outputs a prompt, collects the user's response, and
126
+ # returns it.
127
+ # @param prompt The prompt to output
128
+ # @param default The default option
129
+ # @return String
130
+ # ----------------------------------------------------
131
+ def prompt(prompt, default = nil, start_dir = '')
132
+ Readline.completion_append_character = nil
133
+ Readline.completion_proc = lambda do |prefix|
134
+ files = Dir["#{start_dir}#{prefix}*"]
135
+ files.
136
+ map { |f| File.expand_path(f) }.
137
+ map { |f| File.directory?(f) ? f + "/" : f }
138
+ end
139
+ choice = Readline.readline("# #{ prompt }#{ default.nil? ? ':' : " [default: #{ default }]:" } ".cyan)
140
+ if choice.empty?
141
+ default
142
+ else
143
+ choice
144
+ end
145
+ end
146
+
147
+ # ----------------------------------------------------
148
+ # section method
149
+ #
150
+ # Outputs a formatted-purple section message.
151
+ # @param m The message to output
152
+ # @return Void
153
+ # ----------------------------------------------------
154
+ def section(m)
155
+ puts _word_wrap(m, '---> ').purple
156
+ end
157
+
158
+ # ----------------------------------------------------
159
+ # section_block method
160
+ #
161
+ # Wraps a block in an opening and closing section
162
+ # message.
163
+ # @param m1 The opening message to output
164
+ # @param m2 The closing message to output
165
+ # @param multiline A multiline message or not
166
+ # @return Void
167
+ # ----------------------------------------------------
168
+ def section_block(m, multiline = true)
169
+ if block_given?
170
+ if multiline
171
+ section(m)
172
+ else
173
+ print _word_wrap(m, '---> ').purple
174
+ end
175
+
176
+ yield
177
+ else
178
+ fail 'Did not specify a valid block'
179
+ end
180
+ end
181
+
182
+ # ----------------------------------------------------
183
+ # success method
184
+ #
185
+ # Outputs a formatted-green success message.
186
+ # @param m The message to output
187
+ # @return Void
188
+ # ----------------------------------------------------
189
+ def success(m)
190
+ puts _word_wrap(m, '# ').green
191
+ end
192
+
193
+ # ----------------------------------------------------
194
+ # warning method
195
+ #
196
+ # Outputs a formatted-yellow warning message.
197
+ # @param m The message to output
198
+ # @return Void
199
+ # ----------------------------------------------------
200
+ def warn(m)
201
+ puts _word_wrap(m, '# ').yellow
202
+ end
203
+
204
+ # ----------------------------------------------------
205
+ # wrap method
206
+ #
207
+ # Toggles wrapping on or off
208
+ # @return Integer
209
+ # ----------------------------------------------------
210
+ def self.wrap(on)
211
+ @@wrap = on
212
+ end
213
+
214
+ # ----------------------------------------------------
215
+ # wrap_limit method
216
+ #
217
+ # Returns the current character wrap amount
218
+ # @return Integer
219
+ # ----------------------------------------------------
220
+ def self.wrap_limit
221
+ @@wrap_char_limit
222
+ end
223
+
224
+ # ----------------------------------------------------
225
+ # wrap_at method
226
+ #
227
+ # Sets the number of characters at which to wrap
228
+ # @return Integer
229
+ # ----------------------------------------------------
230
+ def self.wrap_at(chars)
231
+ @@wrap_char_limit = chars
232
+ end
233
+
234
+ private
235
+
236
+ # ----------------------------------------------------
237
+ # _word_wrap method
238
+ #
239
+ # Outputs a wrapped string (where each line is limited
240
+ # to a certain number of characters).
241
+ # @param text The text to wrap
242
+ # @param prefix_str The prefix for each line
243
+ # @param line_width The number of characters per line
244
+ # @return String
245
+ # ----------------------------------------------------
246
+ def _word_wrap(text, prefix_str)
247
+ if @@wrap
248
+ return text if @@wrap_char_limit <= 0
249
+ text.gsub(/\n/, ' ').gsub(/(.{1,#{@@wrap_char_limit - prefix_str.length}})(\s+|$)/, "#{ prefix_str }\\1\n").strip
250
+ else
251
+ text
252
+ end
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,3 @@
1
+ module CLIUtils
2
+ VERSION = "1.0.0"
3
+ end
data/lib/cliutils.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'cliutils/ext/Hash+Extensions'
2
+ require 'cliutils/ext/Logger+Extensions'
3
+ require 'cliutils/ext/String+Extensions'
4
+
5
+ require 'cliutils/pretty-io'
6
+ require 'cliutils/configurator'
7
+ require 'cliutils/configuration'
8
+ require 'cliutils/logger-delegator'
9
+ require 'cliutils/messenging'
10
+ require 'cliutils/prefs'
11
+ require 'cliutils/version'
12
+
13
+ module CLIUtils
14
+
15
+ end