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.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +48 -0
- data/LICENSE.txt +22 -0
- data/README.md +288 -0
- data/README.rdoc +19 -0
- data/Rakefile +45 -0
- data/bin/cliutils +38 -0
- data/cliutils.gemspec +28 -0
- data/features/cli_manager.feature +13 -0
- data/features/step_definitions/cli_manager_steps.rb +1 -0
- data/features/support/env.rb +16 -0
- data/html/CLIUtils/Configuration.html +271 -0
- data/html/CLIUtils/Configurator.html +504 -0
- data/html/CLIUtils/LoggerDelegator.html +344 -0
- data/html/CLIUtils/Messenging.html +284 -0
- data/html/CLIUtils/Prefs.html +330 -0
- data/html/CLIUtils/PrettyIO.html +799 -0
- data/html/CLIUtils.html +112 -0
- data/html/Hash.html +453 -0
- data/html/Logger.html +183 -0
- data/html/Object.html +120 -0
- data/html/README_md.html +454 -0
- data/html/String.html +413 -0
- data/html/created.rid +13 -0
- data/html/fonts/Lato-Light.ttf +0 -0
- data/html/fonts/Lato-LightItalic.ttf +0 -0
- data/html/fonts/Lato-Regular.ttf +0 -0
- data/html/fonts/Lato-RegularItalic.ttf +0 -0
- data/html/fonts/SourceCodePro-Bold.ttf +0 -0
- data/html/fonts/SourceCodePro-Regular.ttf +0 -0
- data/html/fonts.css +167 -0
- data/html/images/add.png +0 -0
- data/html/images/arrow_up.png +0 -0
- data/html/images/brick.png +0 -0
- data/html/images/brick_link.png +0 -0
- data/html/images/bug.png +0 -0
- data/html/images/bullet_black.png +0 -0
- data/html/images/bullet_toggle_minus.png +0 -0
- data/html/images/bullet_toggle_plus.png +0 -0
- data/html/images/date.png +0 -0
- data/html/images/delete.png +0 -0
- data/html/images/find.png +0 -0
- data/html/images/loadingAnimation.gif +0 -0
- data/html/images/macFFBgHack.png +0 -0
- data/html/images/package.png +0 -0
- data/html/images/page_green.png +0 -0
- data/html/images/page_white_text.png +0 -0
- data/html/images/page_white_width.png +0 -0
- data/html/images/plugin.png +0 -0
- data/html/images/ruby.png +0 -0
- data/html/images/tag_blue.png +0 -0
- data/html/images/tag_green.png +0 -0
- data/html/images/transparent.png +0 -0
- data/html/images/wrench.png +0 -0
- data/html/images/wrench_orange.png +0 -0
- data/html/images/zoom.png +0 -0
- data/html/index.html +455 -0
- data/html/js/darkfish.js +140 -0
- data/html/js/jquery.js +18 -0
- data/html/js/navigation.js +142 -0
- data/html/js/search.js +109 -0
- data/html/js/search_index.js +1 -0
- data/html/js/searcher.js +228 -0
- data/html/rdoc.css +580 -0
- data/html/table_of_contents.html +399 -0
- data/lib/.DS_Store +0 -0
- data/lib/cliutils/configuration.rb +48 -0
- data/lib/cliutils/configurator.rb +119 -0
- data/lib/cliutils/ext/Hash+Extensions.rb +145 -0
- data/lib/cliutils/ext/Logger+Extensions.rb +27 -0
- data/lib/cliutils/ext/String+Extensions.rb +26 -0
- data/lib/cliutils/logger-delegator.rb +66 -0
- data/lib/cliutils/messenging.rb +51 -0
- data/lib/cliutils/prefs.rb +116 -0
- data/lib/cliutils/pretty-io.rb +255 -0
- data/lib/cliutils/version.rb +3 -0
- data/lib/cliutils.rb +15 -0
- data/res/readme-images/messenger-types-1.png +0 -0
- data/res/readme-images/messenger-warn.png +0 -0
- data/res/readme-images/multi-logger.png +0 -0
- data/res/readme-images/prettyio-color-chart.png +0 -0
- data/res/readme-images/prettyio-gnarly-text.png +0 -0
- data/res/readme-images/prettyio-red-text.png +0 -0
- data/res/readme-images/prompting.png +0 -0
- data/res/readme-images/wrapping.png +0 -0
- data/test/configurator_test.rb +50 -0
- data/test/hash_extensions_test.rb +50 -0
- data/test/logger_extensions_test.rb +16 -0
- data/test/messenging_test.rb +53 -0
- data/test/prefs_test.rb +29 -0
- data/test/string_extesions_test.rb +14 -0
- data/test/test_files/prefstest.yaml +33 -0
- 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
|
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
|