cowtech-lib 1.9.0 → 1.9.1
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.
- data/cowtech-lib.gemspec +1 -9
- data/lib/cowtech-lib.rb +9 -5
- data/lib/cowtech-lib/console.rb +287 -245
- data/lib/cowtech-lib/option_parser.rb +52 -50
- data/lib/cowtech-lib/script.rb +26 -28
- data/lib/cowtech-lib/shell.rb +23 -18
- data/lib/cowtech-lib/version.rb +2 -2
- metadata +4 -33
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -17
data/cowtech-lib.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{cowtech-lib}
|
8
|
-
s.version = "1.9.
|
8
|
+
s.version = "1.9.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Shogun"]
|
@@ -18,8 +18,6 @@ Gem::Specification.new do |s|
|
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
|
-
"Gemfile",
|
22
|
-
"Gemfile.lock",
|
23
21
|
"LICENSE.txt",
|
24
22
|
"README.rdoc",
|
25
23
|
"Rakefile",
|
@@ -42,15 +40,9 @@ Gem::Specification.new do |s|
|
|
42
40
|
s.specification_version = 3
|
43
41
|
|
44
42
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
45
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
|
46
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
47
43
|
else
|
48
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
49
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
50
44
|
end
|
51
45
|
else
|
52
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
53
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
54
46
|
end
|
55
47
|
end
|
56
48
|
|
data/lib/cowtech-lib.rb
CHANGED
@@ -22,8 +22,12 @@
|
|
22
22
|
# A copy of the GNU General Public License is available at: http://www.gnu.org/licenses/gpl.txt
|
23
23
|
#
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
module Cowtech
|
26
|
+
module Lib
|
27
|
+
autoload :Version, 'cowtech-lib/version'
|
28
|
+
autoload :Console, 'cowtech-lib/console'
|
29
|
+
autoload :OptionParser, 'cowtech-lib/option_parser'
|
30
|
+
autoload :Shell, 'cowtech-lib/shell'
|
31
|
+
autoload :Script, 'cowtech-lib/script'
|
32
|
+
end
|
33
|
+
end
|
data/lib/cowtech-lib/console.rb
CHANGED
@@ -26,289 +26,331 @@
|
|
26
26
|
#
|
27
27
|
|
28
28
|
require "rexml/document"
|
29
|
-
require "open4"
|
30
|
-
require "find"
|
31
|
-
require "fileutils"
|
32
29
|
|
33
30
|
class String
|
34
31
|
def to_a
|
35
32
|
[self]
|
36
33
|
end
|
37
34
|
end
|
35
|
+
|
36
|
+
class Hash
|
37
|
+
def method_missing(method, *arg)
|
38
|
+
# PER ORA SUPPORTIAMO SOLO I GETTER
|
39
|
+
self[method.to_sym]
|
40
|
+
end
|
38
41
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
class Console
|
44
|
-
public
|
45
|
-
|
46
|
-
# Indentation level
|
47
|
-
attr :indent_level
|
48
|
-
|
49
|
-
# Whether show executed commands
|
50
|
-
attr :show_commands
|
51
|
-
|
52
|
-
# Whether show output of executed commands
|
53
|
-
attr :show_outputs
|
54
|
-
|
55
|
-
# Whether simply print commands rather than executing them
|
56
|
-
attr :skip_commands
|
57
|
-
|
58
|
-
# Exit status for commands
|
59
|
-
attr_reader :statuses
|
60
|
-
|
61
|
-
# Indentation string(s)
|
62
|
-
attr :indentator, true
|
63
|
-
|
64
|
-
# Sets indentation level.
|
65
|
-
# Arguments:
|
66
|
-
# * <em>indent</em>: The new indentation level
|
67
|
-
# * <em></em>: If the level is absolute or relative to the current level
|
68
|
-
def indent_set(level, absolute = false)
|
69
|
-
@indent_level = Math.max((!absolute ? @indent_level : 0) + level, 0)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Resets indentation level to 0.
|
73
|
-
def indent_reset
|
74
|
-
@indent_level = 0
|
75
|
-
end
|
42
|
+
def respond_to?(method)
|
43
|
+
self.has_key?(method.to_sym)
|
44
|
+
end
|
45
|
+
end
|
76
46
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# Returns: The indentated message
|
91
|
-
def indent(msg, level = nil)
|
92
|
-
(@@indentator * (level || @indent_level)) + msg
|
93
|
-
end
|
94
|
-
|
95
|
-
=begin rdoc
|
96
|
-
Substitute tag with color.
|
97
|
-
|
98
|
-
Arguments:
|
99
|
-
* <em>node</em>: The node which operate on
|
100
|
-
* <em>stack</em>: The stack of old styles. <b>Do not set this by yourself!</b>
|
101
|
-
|
102
|
-
Returns: The new text
|
103
|
-
=end
|
104
|
-
def subst_color(node, stack = [])
|
105
|
-
rv = ""
|
106
|
-
styles = (node.name == "text" and node.attributes["style"]) ? node.attributes["style"].split(" ") : nil
|
107
|
-
|
108
|
-
# Add style of current tag
|
109
|
-
if styles then
|
110
|
-
styles.each do |style|
|
111
|
-
rv += @@styles[style] || ""
|
112
|
-
end
|
47
|
+
module Cowtech
|
48
|
+
module Lib
|
49
|
+
# A class which provides some method to operate with files and to format pretty messages.
|
50
|
+
# @author Shogun
|
51
|
+
class Console
|
52
|
+
# Indentation level
|
53
|
+
attr_accessor :indent_level
|
54
|
+
|
55
|
+
# Whether show executed commands
|
56
|
+
attr_accessor :show_commands
|
57
|
+
|
58
|
+
# Whether show output of executed commands
|
59
|
+
attr_accessor :show_outputs
|
113
60
|
|
114
|
-
|
61
|
+
# Whether simply print commands rather than executing them
|
62
|
+
attr_accessor :skip_commands
|
63
|
+
|
64
|
+
# Exit status for commands
|
65
|
+
attr_reader :statuses
|
66
|
+
|
67
|
+
# Indentation string(s)
|
68
|
+
attr_accessor :indentator
|
69
|
+
|
70
|
+
# Sets indentation level.
|
71
|
+
# Arguments:
|
72
|
+
# * <em>indent</em>: The new indentation level
|
73
|
+
# * <em></em>: If the level is absolute or relative to the current level
|
74
|
+
def indent_set(level, absolute = false)
|
75
|
+
@indent_level = [(!absolute ? @indent_level : 0) + level, 0].max
|
115
76
|
end
|
116
77
|
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
78
|
+
# Resets indentation level to 0.
|
79
|
+
def indent_reset
|
80
|
+
@indent_level = 0
|
81
|
+
end
|
82
|
+
|
83
|
+
# Execute codes in an indented block
|
84
|
+
def indent_region(level, absolute = false)
|
85
|
+
old_level = @indent_level
|
86
|
+
self.indent_set(level, absolute)
|
87
|
+
yield
|
88
|
+
@indent_level = old_level
|
124
89
|
end
|
125
90
|
|
126
|
-
#
|
127
|
-
|
128
|
-
|
91
|
+
# Indents a message.
|
92
|
+
#
|
93
|
+
# Arguments:
|
94
|
+
# * <em>msg</em>: The message to indent
|
95
|
+
# * <em>add_additional</em>: Whether add extra space to align to initial message "*"
|
96
|
+
# Returns: The indentated message
|
97
|
+
def indent(msg, level = nil)
|
98
|
+
(@@indentator * (level || @indent_level)) + msg
|
99
|
+
end
|
100
|
+
|
101
|
+
# Substitute tag with color.
|
102
|
+
#
|
103
|
+
# Arguments:
|
104
|
+
# * <em>node</em>: The node which operate on
|
105
|
+
# * <em>stack</em>: The stack of old styles. <b>Do not set this by yourself!</b>
|
106
|
+
#
|
107
|
+
# Returns: The new text
|
108
|
+
def parse_message(node, stack = [])
|
109
|
+
rv = ""
|
110
|
+
styles = (node.name == "text" and node.attributes["style"]) ? node.attributes["style"].split(" ") : nil
|
111
|
+
|
112
|
+
# Add style of current tag
|
113
|
+
if styles then
|
114
|
+
styles.each do |style|
|
115
|
+
rv += @@styles[style] || ""
|
116
|
+
end
|
117
|
+
|
118
|
+
stack.push(styles)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Now parse subnodes
|
122
|
+
node.children.each do |child|
|
123
|
+
if child.node_type == :text then
|
124
|
+
rv += child.to_s
|
125
|
+
elsif child.name == "text" then
|
126
|
+
rv += self.parse_message(child, stack)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Remove style of current tag
|
131
|
+
if styles then
|
132
|
+
stack.pop()
|
129
133
|
|
130
|
-
|
131
|
-
|
132
|
-
|
134
|
+
# Restore previous style
|
135
|
+
(stack.pop || ["default"]).each do |style|
|
136
|
+
rv += @@styles[style]
|
137
|
+
end
|
133
138
|
end
|
139
|
+
|
140
|
+
rv
|
134
141
|
end
|
135
|
-
|
136
|
-
rv
|
137
|
-
end
|
138
142
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
143
|
+
# Prints a message.
|
144
|
+
# Arguments:
|
145
|
+
# * <em>msg</em>: The message to print
|
146
|
+
# * <em>dots</em>: Whether add "..." to the message
|
147
|
+
# * <em>newline</em>: Whether add a newline to the message
|
148
|
+
# * <em>plain</em>: Whether ignore tags
|
149
|
+
# * <em>must_indent</em>: Whether indent the message
|
150
|
+
# * <em>internal</em>: If the method is called by another method. <b>Do not set this by yourself!</b>
|
151
|
+
def write(args)
|
152
|
+
msg = args[:msg]
|
153
|
+
|
154
|
+
# Check some alternative syntax
|
155
|
+
[:begin, :warn, :error, :debug, :info, :right, :end].each do |t|
|
156
|
+
if args[t] then
|
157
|
+
msg = args[t]
|
158
|
+
args[:type] = t
|
159
|
+
args[t] = nil
|
160
|
+
end
|
161
|
+
end
|
162
|
+
args[:fatal] = true if args[:status] == :fail
|
163
|
+
|
164
|
+
# Check for specific msg type
|
165
|
+
if [:begin, :warn, :error, :debug, :info].include?(args[:type]) then
|
166
|
+
mc = {:begin => "bold green", :warn => "bold yellow", :error => "bold red", :debug => "magenta", :info => "bold cyan"}
|
167
|
+
color = args[:color] || mc[args[:type]]
|
168
|
+
msg = !args[:full_color] ? "<text style=\"#{color}\">*</text> #{self.indent(msg)}" : "<text style=\"#{color}\">* #{self.indent(msg)}</text>"
|
169
|
+
end
|
170
|
+
|
171
|
+
# Add dots and indentation if needed
|
172
|
+
msg = self.indent(msg + (args.fetch(:dots, true) ? "..." : ""), args[:indent] ? @indent_level : 0)
|
173
|
+
|
174
|
+
# Parse the message
|
175
|
+
unless args[:plain] then
|
176
|
+
begin
|
177
|
+
xml = "<text>#{msg}</text>"
|
178
|
+
msg = self.parse_message(REXML::Document.new(xml).root)
|
179
|
+
rescue Exception => e
|
180
|
+
print "[ERROR] Invalid message tagging, check XML syntax (or color requested) of the following message:\n\n\t#{xml}\n\n"
|
181
|
+
print "\tThe errors was: #{e.message} (#{e.class.to_s})\n\n"
|
182
|
+
exit(1)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# Add newline if needed
|
187
|
+
msg += "\n" if args.fetch(:newline, true)
|
188
|
+
|
189
|
+
if args[:internal] then
|
190
|
+
msg
|
191
|
+
else
|
192
|
+
if [:end, :right].include?(args[:type]) then
|
193
|
+
# Get screen width
|
194
|
+
@tty_width = `tput cols`.to_i if @tty_width < 0
|
195
|
+
|
196
|
+
# Get padding
|
197
|
+
pad = @tty_width - msg.inspect.gsub(/(\\e\[[0-9]+m)|(\")|(\\n)/, "").length
|
198
|
+
|
199
|
+
print "\033[A" if args[:up]
|
200
|
+
print "\033[0G\033[#{pad}C"
|
201
|
+
end
|
202
|
+
|
203
|
+
print(msg)
|
204
|
+
end
|
205
|
+
|
206
|
+
exit(args[:code] || 0) if args[:exit_after] || args[:fatal]
|
156
207
|
end
|
157
|
-
|
158
|
-
|
159
|
-
#
|
160
|
-
|
161
|
-
|
162
|
-
color = args[:color] || mc[args[:type]]
|
208
|
+
|
209
|
+
# Syntatic sugar
|
210
|
+
# Prints a warning message.
|
211
|
+
def warn(msg, args = nil)
|
212
|
+
args ||= {}
|
163
213
|
|
164
|
-
if
|
165
|
-
|
214
|
+
if msg.is_a?(Hash) then
|
215
|
+
args.merge!(msg)
|
166
216
|
else
|
167
|
-
msg =
|
217
|
+
args[:msg] = msg
|
168
218
|
end
|
219
|
+
|
220
|
+
args[:warn] = args[:msg]
|
221
|
+
|
222
|
+
self.write(args)
|
169
223
|
end
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
print "[ERROR] Invalid message tagging, check XML syntax (or color requested) of the following message:\n\n\t#{msg}\n\n"
|
180
|
-
exit(1)
|
224
|
+
|
225
|
+
# Prints an error message.
|
226
|
+
def error(msg, args = nil)
|
227
|
+
args ||= {}
|
228
|
+
|
229
|
+
if msg.is_a?(Hash) then
|
230
|
+
args.merge!(msg)
|
231
|
+
else
|
232
|
+
args[:msg] = msg
|
181
233
|
end
|
234
|
+
|
235
|
+
args[:error] = args[:msg]
|
236
|
+
|
237
|
+
self.write(args)
|
182
238
|
end
|
183
239
|
|
184
|
-
#
|
185
|
-
msg
|
186
|
-
|
187
|
-
|
188
|
-
msg
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
@tty_width = `tput cols`.to_i if @tty_width < 0
|
193
|
-
|
194
|
-
# Get padding
|
195
|
-
pad = @tty_width - msg.inspect.gsub(/(\\e\[[0-9]+m)|(\")|(\\n)/, "").length
|
196
|
-
|
197
|
-
print "\033[A" if args[:up]
|
198
|
-
print "\033[0G\033[#{pad}C"
|
240
|
+
# Prints and error message then abort.
|
241
|
+
def fatal(msg, args = nil)
|
242
|
+
args ||= {}
|
243
|
+
|
244
|
+
if msg.is_a?(Hash) then
|
245
|
+
args.merge!(msg)
|
246
|
+
else
|
247
|
+
args[:msg] = msg
|
199
248
|
end
|
200
|
-
|
201
|
-
|
249
|
+
|
250
|
+
args[:error] = args[:msg]
|
251
|
+
args[:exit_after] = true
|
252
|
+
args[:code] ||= 1
|
253
|
+
|
254
|
+
self.write(args)
|
202
255
|
end
|
203
|
-
|
204
|
-
exit(args[:code] || 0) if args[:exit_after] || args[:fatal]
|
205
|
-
end
|
206
256
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
args[:warn] = msg
|
211
|
-
self.write(*args)
|
212
|
-
end
|
257
|
+
# Prints an error status
|
258
|
+
def status(status, args = nil)
|
259
|
+
args ||= {}
|
213
260
|
|
214
|
-
|
215
|
-
|
216
|
-
args[:error] = msg
|
217
|
-
self.write(*args)
|
218
|
-
end
|
219
|
-
|
220
|
-
# Prints and error message then abort.
|
221
|
-
def fatal(msg, *args)
|
222
|
-
args[:error] = msg
|
223
|
-
args[:exit_after] = true
|
224
|
-
args[:code] ||= 1
|
225
|
-
self.write(*args)
|
226
|
-
end
|
227
|
-
|
228
|
-
# Prints an error status
|
229
|
-
def status(*args)
|
230
|
-
args[:end] = @@statuses[status] || @@statuses[:ok]
|
231
|
-
self.write(*args)
|
232
|
-
end
|
233
|
-
|
234
|
-
# Read input from the user.
|
235
|
-
#
|
236
|
-
# Arguments:
|
237
|
-
# * <em>msg</em>: The prompt to show
|
238
|
-
# * <em>valids</em>: A list of regexp to validate the input
|
239
|
-
# * <em>case_sensitive</em>: Wheter the validation is case_sensitive
|
240
|
-
#
|
241
|
-
# Returns: The read input
|
242
|
-
def read(*args)
|
243
|
-
# Adjust prompt
|
244
|
-
msg = args[:msg] + (msg !~ /([:?](\s*))$/) ? ":" : "")
|
245
|
-
msg += " " unless msg =~ / ^/
|
246
|
-
|
247
|
-
# Turn choices into regular expressions
|
248
|
-
regexps = (args[:valids] || []).to_a.collect do |valid|
|
249
|
-
unless valid.is_a?(Regexp) then
|
250
|
-
valid = Regexp.new((valid !~ /^\^/ ? "^" : "") + valid + (valid !~ /\$$/ ? "$" : ""), Regexp::EXTENDED + (args[:case_sensitive] ? Regexp::IGNORECASE : 0), "U")
|
261
|
+
if status.is_a?(Hash) then
|
262
|
+
args.merge!(status)
|
251
263
|
else
|
252
|
-
|
264
|
+
args[:status] = status
|
253
265
|
end
|
266
|
+
|
267
|
+
status = status.is_a?(Hash) ? status[:status] : status
|
268
|
+
args[:end] = @@statuses[status] || @@statuses[:ok]
|
269
|
+
args[:dots] = false
|
270
|
+
args[:up] = true if args[:up] == nil
|
271
|
+
self.write(args)
|
254
272
|
end
|
255
273
|
|
256
|
-
|
257
|
-
|
258
|
-
#
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
274
|
+
# Read input from the user.
|
275
|
+
#
|
276
|
+
# Arguments:
|
277
|
+
# * <em>msg</em>: The prompt to show
|
278
|
+
# * <em>valids</em>: A list of regexp to validate the input
|
279
|
+
# * <em>case_sensitive</em>: Wheter the validation is case_sensitive
|
280
|
+
#
|
281
|
+
# Returns: The read input
|
282
|
+
def read(args)
|
283
|
+
# Adjust prompt
|
284
|
+
msg = args[:msg] + ((msg !~ /([:?](\s*))$/) ? ":" : "")
|
285
|
+
msg += " " unless msg =~ / ^/
|
286
|
+
|
287
|
+
# Turn choices into regular expressions
|
288
|
+
regexps = (args[:valids] || []).to_a.collect do |valid|
|
289
|
+
unless valid.is_a?(Regexp) then
|
290
|
+
valid = Regexp.new((valid !~ /^\^/ ? "^" : "") + valid + (valid !~ /\$$/ ? "$" : ""), Regexp::EXTENDED + (args[:case_sensitive] ? Regexp::IGNORECASE : 0), "U")
|
291
|
+
else
|
292
|
+
valid
|
293
|
+
end
|
270
294
|
end
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
295
|
+
|
296
|
+
rv = nil
|
297
|
+
|
298
|
+
# Read input
|
299
|
+
while true do
|
300
|
+
# Show message
|
301
|
+
print(msg)
|
302
|
+
|
303
|
+
# Get reply
|
304
|
+
bufs = gets.chop()
|
305
|
+
|
306
|
+
# If we don't have any regexp
|
307
|
+
if regexps.length == 0 then
|
275
308
|
rv = bufs
|
276
309
|
break
|
277
310
|
end
|
311
|
+
|
312
|
+
# Validate inputs
|
313
|
+
regexps.each do |re|
|
314
|
+
if bufs =~ re then
|
315
|
+
rv = bufs
|
316
|
+
break
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
break if rv
|
321
|
+
self.write(:warn => "Sorry, your reply was not understood. Please try again")
|
278
322
|
end
|
279
|
-
|
280
|
-
|
281
|
-
|
323
|
+
|
324
|
+
rv
|
325
|
+
end
|
326
|
+
|
327
|
+
# Create a new Console.
|
328
|
+
def initialize
|
329
|
+
@indent_level = 0
|
330
|
+
@show_commands = false
|
331
|
+
@show_outputs = false
|
332
|
+
@skip_commands = false
|
333
|
+
@tty_width = -1
|
334
|
+
@@indentator= " "
|
335
|
+
|
336
|
+
@@styles = {
|
337
|
+
# Default color
|
338
|
+
"default" => "\33[0m",
|
339
|
+
# Text style
|
340
|
+
"bold" => "\33[1m", "underline" => "\33[4m", "blink" => "\33[5m", "reverse" => "\33[7m", "concealed" => "\33[8m",
|
341
|
+
# Foreground colors
|
342
|
+
"black" => "\33[30m", "red" => "\33[31m", "green" => "\33[32m", "yellow" => "\33[33m", "blue" => "\33[34m", "magenta" => "\33[35m", "cyan" => "\33[36m", "white" => "\33[37m",
|
343
|
+
# Background colors
|
344
|
+
"bg_black" => "\33[40m", "bg_red" => "\33[41m", "bg_green" => "\33[42m", "bg_yellow" => "\33[43m", "bg_blue" => "\33[44m", "bg_magenta" => "\33[45m", "bg_cyan" => "\33[46m", "bg_white" => "\33[47m"
|
345
|
+
}
|
346
|
+
|
347
|
+
@@statuses = {
|
348
|
+
:ok => '<text style="bold blue">[ <text style="bold green">OK</text> ]</text> ',
|
349
|
+
:pass => '<text style="bold blue">[<text style="bold cyan">PASS</text>]</text> ',
|
350
|
+
:fail => '<text style="bold blue">[<text style="bold red">FAIL</text>]</text> ',
|
351
|
+
:warn => '<text style="bold blue">[<text style="bold yellow">WARN</text>]</text> ',
|
352
|
+
}
|
282
353
|
end
|
283
|
-
end
|
284
|
-
|
285
|
-
# Create a new Console.
|
286
|
-
def initialize
|
287
|
-
@indent_level = 0
|
288
|
-
@show_commands = false
|
289
|
-
@show_outputs = false
|
290
|
-
@skip_commands = false
|
291
|
-
@tty_width = -1
|
292
|
-
@@indentator= " "
|
293
|
-
|
294
|
-
@@styles = {
|
295
|
-
# Default color
|
296
|
-
"default" => "\33[0m",
|
297
|
-
# Text style
|
298
|
-
"bold" => "\33[1m", "underline" => "\33[4m", "blink" => "\33[5m", "reverse" => "\33[7m", "concealed" => "\33[8m",
|
299
|
-
# Foreground colors
|
300
|
-
"black" => "\33[30m", "red" => "\33[31m", "green" => "\33[32m", "yellow" => "\33[33m", "blue" => "\33[34m", "magenta" => "\33[35m", "cyan" => "\33[36m", "white" => "\33[37m",
|
301
|
-
# Background colors
|
302
|
-
"bg_black" => "\33[40m", "bg_red" => "\33[41m", "bg_green" => "\33[42m", "bg_yellow" => "\33[43m", "bg_blue" => "\33[44m", "bg_magenta" => "\33[45m", "bg_cyan" => "\33[46m", "bg_white" => "\33[47m"
|
303
|
-
}
|
304
|
-
|
305
|
-
@@statuses = {
|
306
|
-
:ok => '<text style="bold blue">[ <text style="bold green">OK</text> ]</text> ',
|
307
|
-
:pass => '<text style="bold blue">[<text style="bold cyan">PASS</text>]</text> ',
|
308
|
-
:fail => '<text style="bold blue">[<text style="bold red">FAIL</text>]</text> ',
|
309
|
-
:warn => '<text style="bold blue">[<text style="bold yellow">WARN</text>]</text> ',
|
310
|
-
}
|
311
354
|
end
|
312
355
|
end
|
313
|
-
end
|
314
|
-
|
356
|
+
end
|
@@ -25,9 +25,7 @@
|
|
25
25
|
# THE SOFTWARE.
|
26
26
|
#
|
27
27
|
|
28
|
-
require "ostruct"
|
29
28
|
require "getoptlong"
|
30
|
-
require "CowtechLib/Console"
|
31
29
|
|
32
30
|
module Cowtech
|
33
31
|
module Lib
|
@@ -35,7 +33,7 @@ module Cowtech
|
|
35
33
|
# @author Shogun
|
36
34
|
class OptionParser
|
37
35
|
# The specified options
|
38
|
-
|
36
|
+
attr_accessor :options
|
39
37
|
|
40
38
|
# The full command line provided
|
41
39
|
attr_reader :cmdline
|
@@ -68,10 +66,10 @@ module Cowtech
|
|
68
66
|
# * <em>:required</em>: Whether the option is required
|
69
67
|
# * <em>:priority</em>: Priority for the option. Used only on the help message to sort (by increasing priority) the options.
|
70
68
|
def <<(options)
|
71
|
-
options = options.
|
69
|
+
options = [options] unless options.is_a?(Array)
|
72
70
|
|
73
71
|
options.each do |option|
|
74
|
-
@console.fatal(:msg => "Every attribute must be an Hash.") unless option.
|
72
|
+
@console.fatal(:msg => "Every attribute must be an Hash.", :dots => false) unless option.is_a?(Hash)
|
75
73
|
|
76
74
|
# Use symbols for names
|
77
75
|
option[:name] = option[:name].to_sym
|
@@ -80,7 +78,7 @@ module Cowtech
|
|
80
78
|
option[:type] ||= :string
|
81
79
|
|
82
80
|
# Check if type is valid
|
83
|
-
@console.fatal(:msg => "Invalid option type #{option[:type]} for option #{option[:name]}. Valid type are the following:\n\t#{@@valid_types.keys.join(", ")}.") unless
|
81
|
+
@console.fatal(:msg => "Invalid option type #{option[:type]} for option #{option[:name]}. Valid type are the following:\n\t#{@@valid_types.keys.join(", ")}.", :dots => false) unless @@valid_types.keys.include?(option[:type])
|
84
82
|
|
85
83
|
# Adjust the default value
|
86
84
|
case option[:type]
|
@@ -93,13 +91,13 @@ module Cowtech
|
|
93
91
|
end
|
94
92
|
|
95
93
|
# Adjust priority
|
96
|
-
option[:priority] = option[:priority].to_s.to_i unless option[:priority].is_a(Integer)
|
94
|
+
option[:priority] = option[:priority].to_s.to_i unless option[:priority].is_a?(Integer)
|
97
95
|
|
98
96
|
# Prepend dashes
|
99
|
-
option[:short] = "-" + option[:short] unless option[:short]
|
97
|
+
option[:short] = "-" + option[:short] unless option[:short] =~ /^-/
|
100
98
|
while not option[:long] =~ /^--/ do option[:long] = "-" + option[:long] end
|
101
|
-
@console.fatal(:msg
|
102
|
-
@console.fatal(:msg
|
99
|
+
@console.fatal(:msg => "Invalid short form \"#{option[:short]}\".", :dots => false) unless option[:short] =~ /^-[0-9a-z]$/i
|
100
|
+
@console.fatal(:msg => "Invalid long form \"#{option[:long]}\".", :dots => false) unless option[:long] =~ /^--([0-9a-z-]+)$/i
|
103
101
|
|
104
102
|
# Check for choices if the type is choices
|
105
103
|
if option[:type] == :choice then
|
@@ -111,16 +109,16 @@ module Cowtech
|
|
111
109
|
end
|
112
110
|
|
113
111
|
# Check that action is a block if the type is action
|
114
|
-
@console.fatal(
|
112
|
+
@console.fatal("Option \"#{option[:name]}\" of type action requires a action block.") if option[:type] == :action && (option[:action] == nil || !option[:action].is_a?(Proc.class))
|
115
113
|
|
116
114
|
# Check for uniqueness of option and its forms
|
117
|
-
@console.fatal(
|
118
|
-
@console.fatal(
|
119
|
-
@console.fatal(
|
115
|
+
@console.fatal("An option with name \"#{option[:name]}\" already exists.", :dots => false) if @inserted[:name].include?(option[:name])
|
116
|
+
@console.fatal("An option with short or long form \"#{option[:short]}\" already exists.", :dots => false) if @inserted[:short].include?(option[:short])
|
117
|
+
@console.fatal("An option with short or long form \"#{option[:long]}\" already exists.", :dots => false) if @inserted[:long].include?(option[:long])
|
120
118
|
|
121
119
|
# Save
|
122
120
|
@options[option[:name]] = option
|
123
|
-
@options_map[
|
121
|
+
@options_map[option[:long]] = option[:name]
|
124
122
|
@inserted[:name].push(option[:name])
|
125
123
|
@inserted[:short].push(option[:short])
|
126
124
|
@inserted[:long].push(option[:long])
|
@@ -132,7 +130,8 @@ module Cowtech
|
|
132
130
|
# Arguments:
|
133
131
|
# * <em>ignore_unknown</em>: Whether ignore unknown options
|
134
132
|
# * <em>ignore_unknown</em>: Whether ignore help options
|
135
|
-
def parse(
|
133
|
+
def parse(args = nil)
|
134
|
+
args ||= {}
|
136
135
|
# Create options
|
137
136
|
noat = [:bool, :action]
|
138
137
|
sopts = @options.each_value.collect do |option| [option[:long], option[:short], noat.include?(option[:type]) ? GetoptLong::NO_ARGUMENT : GetoptLong::REQUIRED_ARGUMENT] end
|
@@ -146,34 +145,34 @@ module Cowtech
|
|
146
145
|
optname = @options_map[given]
|
147
146
|
option = @options[optname]
|
148
147
|
value = nil
|
148
|
+
|
149
149
|
|
150
150
|
# VALIDATE ARGUMENT DUE TO CASE
|
151
151
|
case option[:type]
|
152
152
|
when :string then
|
153
153
|
value = arg
|
154
154
|
when :int then
|
155
|
-
if arg.strip =~ /^(-?)(\d+)$/ then value = arg.to_i(10) else @console.fatal(:msg => "Argument of option \"#{given}\" must be an integer.") end
|
155
|
+
if arg.strip =~ /^(-?)(\d+)$/ then value = arg.to_i(10) else @console.fatal(:msg => "Argument of option \"#{given}\" must be an integer.", :dots => false) end
|
156
156
|
when :float then
|
157
|
-
if arg.strip =~ /^(-?)(\d*)(\.(\d+))?$/ and arg.strip() != "." then value = arg.to_f else @console.fatal(:msg => "Argument of option \"#{given}\" must be a float.") end
|
157
|
+
if arg.strip =~ /^(-?)(\d*)(\.(\d+))?$/ and arg.strip() != "." then value = arg.to_f else @console.fatal(:msg => "Argument of option \"#{given}\" must be a float.", :dots => false) end
|
158
158
|
when :choice then
|
159
|
-
if @options[optname].choices.find_index { |choice| arg =~ choice } then value = arg else @console.fatal(:msg => "Invalid argument (invalid choice) for option \"#{given}\".")
|
159
|
+
if @options[optname].choices.find_index { |choice| arg =~ choice } then value = arg else @console.fatal(:msg => "Invalid argument (invalid choice) for option \"#{given}\".", :dots => false) end
|
160
160
|
when :list then
|
161
161
|
value = arg.split(",")
|
162
162
|
else
|
163
163
|
value = true
|
164
164
|
end
|
165
165
|
|
166
|
-
@options[optname] = value
|
166
|
+
@options[optname][:value] = value
|
167
167
|
end
|
168
168
|
rescue StandardError => exception
|
169
|
-
|
170
|
-
|
171
|
-
given = "-" * $1.length
|
169
|
+
if exception.message =~ /.+-- (.+)$/ then
|
170
|
+
given = $1
|
172
171
|
|
173
|
-
if exception.
|
174
|
-
@console.fatal(:msg => "Unknown option \"#{given}\".") unless args[:ignore_unknown]
|
175
|
-
elsif exception.
|
176
|
-
@console.fatal(:msg => "Option \"
|
172
|
+
if exception.is_a?(GetoptLong::InvalidOption) then
|
173
|
+
@console.fatal(:msg => "Unknown option \"#{given}\".", :dots => false) unless args[:ignore_unknown]
|
174
|
+
elsif exception.is_a?(GetoptLong::MissingArgument) then
|
175
|
+
@console.fatal(:msg => "Option \"-#{given}\" requires an argument.", :dots => false)
|
177
176
|
end
|
178
177
|
else
|
179
178
|
@console.fatal("Unexpected error: #{exc.message}.")
|
@@ -184,7 +183,7 @@ module Cowtech
|
|
184
183
|
@args = ARGV
|
185
184
|
|
186
185
|
# CHECK IF HELP WAS REQUESTED
|
187
|
-
if self.provided?("help") and args[:ignore_help]
|
186
|
+
if self.provided?("help") and !args[:ignore_help] then
|
188
187
|
self.print_help
|
189
188
|
exit(0)
|
190
189
|
end
|
@@ -192,10 +191,11 @@ module Cowtech
|
|
192
191
|
# NOW CHECK IF SOME REQUIRED OPTION WAS NOT SPECIFIED OR IF WE HAVE TO EXECUTE AN ACTION
|
193
192
|
@inserted[:name].each do |key|
|
194
193
|
option = @options[key]
|
194
|
+
|
195
195
|
if option[:required] == true and option[:value] == nil then
|
196
|
-
@console.fatal(:msg => "Required option \"#{opt.name}\" not specified.")
|
196
|
+
@console.fatal(:msg => "Required option \"#{opt.name}\" not specified.", :dots => false)
|
197
197
|
elsif option[:value] == true and option[:type] == :action then
|
198
|
-
|
198
|
+
option.action.call
|
199
199
|
end
|
200
200
|
end
|
201
201
|
end
|
@@ -205,6 +205,7 @@ module Cowtech
|
|
205
205
|
# * <em>name</em>: Option name
|
206
206
|
# Returns: <em>true</em> if options is defined, <em>false</em> otherwise.
|
207
207
|
def exists?(name)
|
208
|
+
name = name.to_sym
|
208
209
|
@options.keys.include?(name)
|
209
210
|
end
|
210
211
|
|
@@ -213,7 +214,8 @@ module Cowtech
|
|
213
214
|
# * <em>name</em>: Option name
|
214
215
|
# Returns: <em>true</em> if options was provided, <em>false</em> otherwise.
|
215
216
|
def provided?(name)
|
216
|
-
|
217
|
+
name = name.to_sym
|
218
|
+
(@options[name] || {})[:value] != nil
|
217
219
|
end
|
218
220
|
|
219
221
|
# Get a list of value for the requested options.
|
@@ -238,15 +240,15 @@ module Cowtech
|
|
238
240
|
# * <em>options</em>: Options list
|
239
241
|
# Returns: If a single argument is provided, only a value is returned, else an hash (name => value). If no argument is provided, return every option
|
240
242
|
def [](*options)
|
241
|
-
options = [options] unless options.
|
242
|
-
options = @options.keys if
|
243
|
+
options = [options] unless options.is_a?(Array)
|
244
|
+
options = @options.keys if options.length == 0
|
243
245
|
|
244
246
|
if options.length == 1 then
|
245
247
|
self.get(options[0])
|
246
248
|
else
|
247
249
|
rv = {}
|
248
250
|
options.each do |option|
|
249
|
-
rv[option] = self.get(option) if self.exists?(option)
|
251
|
+
rv[option.to_s] = self.get(option) if self.exists?(option)
|
250
252
|
end
|
251
253
|
rv
|
252
254
|
end
|
@@ -263,21 +265,21 @@ module Cowtech
|
|
263
265
|
if @app_name then
|
264
266
|
print "#{@app_name}"
|
265
267
|
if @app_version > 0 then print " #{@app_version}" end
|
266
|
-
if @
|
268
|
+
if @description then print " - #{@description}" end
|
267
269
|
print "\n"
|
268
270
|
end
|
269
271
|
|
270
272
|
# Print usage
|
271
273
|
if @messages["pre_usage"] then print "#{@messages["pre_usage"]}\n" end
|
272
|
-
print "#{if @usage then @usage else "Usage: #{
|
274
|
+
print "#{if @usage then @usage else "Usage: #{ARGV[0]} [OPTIONS]" end}\n"
|
273
275
|
|
274
276
|
# Print pre_options
|
275
277
|
if @messages["pre_options"] then print "#{@messages["pre_options"]}\n" end
|
276
278
|
print "\nValid options are:\n"
|
277
279
|
|
278
280
|
# Order options for printing
|
279
|
-
@sorted_opts = @inserted[
|
280
|
-
@options[first]
|
281
|
+
@sorted_opts = @inserted[:name].sort do |first, second|
|
282
|
+
@options[first][:priority] != @options[second][:priority] ? @options[first][:priority] <=> @options[second][:priority] : @inserted[:name].index(first) <=> @inserted[:name].index(second)
|
281
283
|
end
|
282
284
|
|
283
285
|
# Add options, saving max length
|
@@ -286,9 +288,8 @@ module Cowtech
|
|
286
288
|
@sorted_opts.each do |key|
|
287
289
|
opt = @options[key]
|
288
290
|
|
289
|
-
popt = "#{[opt
|
290
|
-
popt += ("=" + (if opt
|
291
|
-
|
291
|
+
popt = "#{[opt[:short], opt[:long]].join(", ")}"
|
292
|
+
popt += ("=" + (if opt[:meta] then opt[:meta] else "ARG" end)) unless [:bool, :action].include?(opt[:type])
|
292
293
|
popts[key] = popt
|
293
294
|
maxlen = popt.length if popt.length > maxlen
|
294
295
|
end
|
@@ -296,7 +297,7 @@ module Cowtech
|
|
296
297
|
# Print options
|
297
298
|
@sorted_opts.each do |key|
|
298
299
|
val = popts[key]
|
299
|
-
print "\t#{val}#{" " * (5 + (maxlen - val.length))}#{@options[key]
|
300
|
+
print "\t#{val}#{" " * (5 + (maxlen - val.length))}#{@options[key][:help]}\n"
|
300
301
|
end
|
301
302
|
|
302
303
|
# Print post_options
|
@@ -314,22 +315,23 @@ module Cowtech
|
|
314
315
|
# * <em>:pre_usage</em>: Message to print before the usage string
|
315
316
|
# * <em>:pre_options</em>: Message to print before the options list
|
316
317
|
# * <em>:post_options</em>: Message to print after the options list
|
317
|
-
def initialize(
|
318
|
-
msgs = if msgs.length > 0 then msgs[0] else {} end
|
319
|
-
|
318
|
+
def initialize(args)
|
320
319
|
# Initialize types
|
321
320
|
@@valid_types = {:bool => [], :string => [String, ""], :int => [Integer, 0], :float => [Float, 0.0], :choice => [String, ""], :list => [Array, []], :action => []}
|
322
321
|
|
323
322
|
# Copy arguments
|
324
323
|
@app_name = args[:name]
|
325
|
-
@
|
326
|
-
@
|
324
|
+
@app_version = args[:version]
|
325
|
+
@description = args[:description]
|
327
326
|
@usage = args[:usage]
|
328
|
-
|
327
|
+
|
328
|
+
# Copy messages
|
329
|
+
messages = args[:messages] || {}
|
330
|
+
if messages.is_a?(Hash) then @messages = messages else @console.fatal(:msg => "CowtechLib::OptionParser::initialize msgs argument must be an hash.") end
|
329
331
|
|
330
332
|
# Initialize variables
|
331
|
-
@console =
|
332
|
-
@inserted = {:name => [], :short => [], :long => []
|
333
|
+
@console = Console.new
|
334
|
+
@inserted = {:name => [], :short => [], :long => []}
|
333
335
|
@options = {}
|
334
336
|
@options_map = {}
|
335
337
|
@args = []
|
data/lib/cowtech-lib/script.rb
CHANGED
@@ -25,18 +25,11 @@
|
|
25
25
|
# THE SOFTWARE.
|
26
26
|
#
|
27
27
|
|
28
|
-
require "pp"
|
29
|
-
require "rexml/document"
|
30
|
-
require "rubygems"
|
31
|
-
require "open4"
|
32
|
-
require "find"
|
33
|
-
require "CowtechLib/Console"
|
34
|
-
require "CowtechLib/OptionParser"
|
35
|
-
|
36
28
|
module Cowtech
|
37
29
|
module Lib
|
38
30
|
# Class which implements a script to execute general tasks.
|
39
31
|
# @author Shogun
|
32
|
+
|
40
33
|
class Script
|
41
34
|
# Console object
|
42
35
|
attr_reader :console
|
@@ -58,25 +51,25 @@ module Cowtech
|
|
58
51
|
# * <em>pre_usage</em>: Message to print before the usage string
|
59
52
|
# * <em>pre_options</em>: Message to print before the options list
|
60
53
|
# * <em>post_options</em>: Message to print after the options list
|
61
|
-
def initialize(
|
54
|
+
def initialize(args)
|
62
55
|
@console = Console.new
|
63
|
-
@shell =
|
64
|
-
@options_parser = OptionParser.new(
|
56
|
+
@shell = Shell.new(@console)
|
57
|
+
@options_parser = OptionParser.new(args)
|
65
58
|
|
66
59
|
self.add_options()
|
67
60
|
@options_parser << [
|
68
|
-
{:name => "command-echo", :short => "-z", :long => "--command-echo", :type => :bool, :help => "Show executed commands."}
|
69
|
-
{:name => "command-show", :short => "-V", :long => "--command-show", :type => :bool, :help => "Show executed commands' output."}
|
61
|
+
{:name => "command-echo", :short => "-z", :long => "--command-echo", :type => :bool, :help => "Show executed commands."},
|
62
|
+
{:name => "command-show", :short => "-V", :long => "--command-show", :type => :bool, :help => "Show executed commands' output."},
|
70
63
|
{:name => "command-skip", :short => "-Z", :long => "--command-skip", :type => :bool, :help => "Don't really execut commands, only print them."}
|
71
64
|
]
|
72
65
|
|
73
|
-
@options_parser.parse
|
66
|
+
@options_parser.parse
|
74
67
|
|
75
68
|
@console.show_commands = @options_parser["command-echo"]
|
76
69
|
@console.show_outputs = @options_parser["command-show"]
|
77
70
|
@console.skip_commands = @options_parser["command-skip"]
|
78
71
|
|
79
|
-
self.run
|
72
|
+
self.run
|
80
73
|
end
|
81
74
|
|
82
75
|
# Execute a task, showing a message.
|
@@ -87,36 +80,41 @@ module Cowtech
|
|
87
80
|
# * <em>show_end</em>: If show message exit status
|
88
81
|
# * <em>go_up</em>: If go up one line to show exit status
|
89
82
|
# * <em>dots</em>: If show dots after message
|
90
|
-
def task(
|
91
|
-
if args
|
92
|
-
@console.
|
93
|
-
@console.
|
83
|
+
def task(args)
|
84
|
+
if args.fetch(:show_msg, true) then
|
85
|
+
@console.write(:begin => args[:msg], :dots => args[:dots]) if args.fetch(:show_msg, true)
|
86
|
+
@console.indent_set(3)
|
94
87
|
end
|
95
88
|
|
96
89
|
# Run the block
|
97
|
-
rv = yield
|
90
|
+
rv = yield
|
91
|
+
rv = :ok unless rv.is_a?(Symbol)
|
92
|
+
rv = [rv, true] unless rv.is_a?(Array)
|
98
93
|
|
99
94
|
# Show the result
|
100
|
-
|
101
|
-
|
95
|
+
if args.fetch(:show_result, true) then
|
96
|
+
@console.status(:status => rv[0], :fatal => false) if args.fetch(:show_result, true)
|
97
|
+
@console.indent_set(-3)
|
98
|
+
end
|
99
|
+
|
100
|
+
exit(1) if rv[0] != :ok && rv[1]
|
102
101
|
end
|
103
102
|
|
104
103
|
# Run the script.
|
105
104
|
#<b> MUST BY OVERRIDEN BY SUBCLASSES!</b>
|
106
105
|
def run
|
107
|
-
self.console.fatal("Script
|
106
|
+
self.console.fatal("Cowtech::Lib::Script#run must be overidden by subclasses.")
|
108
107
|
end
|
109
108
|
|
110
109
|
# Adds the command line options.
|
111
110
|
# <b>MUST BE OVERRIDEN BY SUBCLASSES!</b>
|
112
111
|
def add_options
|
113
|
-
self.console.fatal("Cowtech::Lib::Script
|
112
|
+
self.console.fatal("Cowtech::Lib::Script#add_options must be overidden by subclasses.")
|
114
113
|
end
|
115
114
|
|
116
|
-
|
117
|
-
|
118
|
-
self.new.run
|
115
|
+
def get_binding
|
116
|
+
binding
|
119
117
|
end
|
120
118
|
end
|
121
119
|
end
|
122
|
-
end
|
120
|
+
end
|
data/lib/cowtech-lib/shell.rb
CHANGED
@@ -25,12 +25,11 @@
|
|
25
25
|
# THE SOFTWARE.
|
26
26
|
#
|
27
27
|
|
28
|
-
require "rexml/document"
|
29
28
|
require "open4"
|
30
29
|
require "find"
|
31
30
|
require "fileutils"
|
32
31
|
|
33
|
-
module
|
32
|
+
module Cowtech
|
34
33
|
module Lib
|
35
34
|
# A class which provides some useful method for interaction with files and processes.
|
36
35
|
# @author Shogun
|
@@ -45,11 +44,11 @@ module CowtechLib
|
|
45
44
|
# * <em>fatal</em>: If abort on failure
|
46
45
|
#
|
47
46
|
# Returns: An object which the status attribute is the exit status of the process, and the output attribute is the output of the command
|
48
|
-
def run(
|
47
|
+
def run(args)
|
49
48
|
rv = {:status => 0, :output => []}
|
50
49
|
command = args[:command]
|
51
50
|
|
52
|
-
@console.write(:begin => args[:msg]) if args[:
|
51
|
+
@console.write(:begin => args[:msg]) if args[:show_msg]
|
53
52
|
|
54
53
|
if @console.show_commands then
|
55
54
|
@console.warn("Will run command: \"#{command}\"", :dots => false)
|
@@ -66,7 +65,8 @@ module CowtechLib
|
|
66
65
|
end
|
67
66
|
rv[:output] = rv[:output].join("\n")
|
68
67
|
|
69
|
-
self.status(rv[:status] == 0 ? :ok : :fail) if args[:show_exit]
|
68
|
+
self.status(:status => rv[:status] == 0 ? :ok : :fail, :fatal => false) if args[:show_exit]
|
69
|
+
exit(1) if args[:fatal] and rv[:status] != 0
|
70
70
|
rv
|
71
71
|
end
|
72
72
|
|
@@ -78,9 +78,9 @@ module CowtechLib
|
|
78
78
|
# * <em>codec</em>: The encoding used to open the file. <b>UNUSED FOR NOW!</b>
|
79
79
|
#
|
80
80
|
# Returns: A new <em>File</em> object
|
81
|
-
def open_file(
|
81
|
+
def open_file(args)
|
82
82
|
begin
|
83
|
-
File.new(args[:name], args[:mode] || "r" + (args[:codec]
|
83
|
+
File.new(args[:name], (args[:mode] || "r") + (args[:codec] ? ":#{args[:codec]}" : ""))
|
84
84
|
rescue Exception => e
|
85
85
|
@console.write(:error => "Unable to open file #{name}: #{e}")
|
86
86
|
nil
|
@@ -103,9 +103,9 @@ module CowtechLib
|
|
103
103
|
# * <em>:fc_symlink</em>: Check if the file is symbolic link
|
104
104
|
#
|
105
105
|
# Returns: <em>true</em> if any of tests had success, <em>false</em> otherwise
|
106
|
-
def file_check?(
|
106
|
+
def file_check?(args)
|
107
107
|
rv = false
|
108
|
-
tests = args[:tests].to_a
|
108
|
+
tests = (args[:tests] || [:exists]).to_a
|
109
109
|
|
110
110
|
if args[:file] then
|
111
111
|
rv = true
|
@@ -125,7 +125,7 @@ module CowtechLib
|
|
125
125
|
# * <em>show_error</em>: Whether show errors occurred
|
126
126
|
#
|
127
127
|
# Returns: <em>true</em> if operation had success, <em>false</em> otherwise.
|
128
|
-
def delete_files!(
|
128
|
+
def delete_files!(args)
|
129
129
|
rv = true
|
130
130
|
files = args[:files].to_a
|
131
131
|
|
@@ -135,7 +135,7 @@ module CowtechLib
|
|
135
135
|
if args[:show_errors] == true then
|
136
136
|
if e.message =~ /^Permission denied - (.+)/ then
|
137
137
|
@console.error("Cannot remove following non writable entry: #{$1}", :dots => false, :fatal => args[:fatal])
|
138
|
-
elsif e.message =~ /^No such file or directory - (.+)/
|
138
|
+
elsif e.message =~ /^No such file or directory - (.+)/ then
|
139
139
|
@console.error("Cannot remove following non existent entry: #{$1}", :dots => false, :fatal => args[:fatal])
|
140
140
|
end
|
141
141
|
end
|
@@ -167,7 +167,7 @@ module CowtechLib
|
|
167
167
|
# * <em>show_error</em>: Whether show errors occurred
|
168
168
|
#
|
169
169
|
# Returns: <em>true</em> if operation had success, <em>false</em> otherwise.
|
170
|
-
def create_directories(
|
170
|
+
def create_directories(args)
|
171
171
|
rv = true
|
172
172
|
files = args[:files].to_a
|
173
173
|
|
@@ -223,7 +223,7 @@ module CowtechLib
|
|
223
223
|
# * <em>show_error</em>: Whether show errors occurred
|
224
224
|
#
|
225
225
|
# Returns: <em>true</em> if operation had success, <em>false</em> otherwise.
|
226
|
-
def copy(
|
226
|
+
def copy(args)
|
227
227
|
rv = true
|
228
228
|
move = args[:move]
|
229
229
|
|
@@ -248,7 +248,6 @@ module CowtechLib
|
|
248
248
|
rv = false
|
249
249
|
rescue Exception => e
|
250
250
|
if args[:show_errors] then
|
251
|
-
self.error(, false)
|
252
251
|
@console.error("Cannot #{if move then "move" else "copy" end} following entries to <text style=\"bold white\">#{dest}</text>:", :dots => false)
|
253
252
|
@console.indent_region(3) do
|
254
253
|
files.each do |afile|
|
@@ -302,7 +301,7 @@ module CowtechLib
|
|
302
301
|
# * <em>show_error</em>: Whether show errors occurred
|
303
302
|
#
|
304
303
|
# Returns: <em>true</em> if operation had success, <em>false</em> otherwise.
|
305
|
-
def rename(
|
304
|
+
def rename(args)
|
306
305
|
rv = true
|
307
306
|
|
308
307
|
if src.is_a?(String) and dst.is_a?(String) then
|
@@ -322,7 +321,7 @@ module CowtechLib
|
|
322
321
|
# * <em>patterns</em>: List of requested patterns
|
323
322
|
#
|
324
323
|
# Returns: List of found files.
|
325
|
-
def find_by_pattern(
|
324
|
+
def find_by_pattern(args)
|
326
325
|
# TODO: E se patterns è vuoto?
|
327
326
|
rv = []
|
328
327
|
|
@@ -362,12 +361,18 @@ module CowtechLib
|
|
362
361
|
# * <em>extensions</em>: List of requested extensions
|
363
362
|
#
|
364
363
|
# Returns: List of found files.
|
365
|
-
def find_by_extension(
|
364
|
+
def find_by_extension(args)
|
366
365
|
args[:patterns] = (args[:extensions] || "").to_a.collect do |extension|
|
367
366
|
Regexp.new(extension + "$", Regexp::IGNORECASE)
|
368
367
|
end
|
369
368
|
|
370
|
-
self.find_by_pattern(
|
369
|
+
self.find_by_pattern(args)
|
370
|
+
end
|
371
|
+
|
372
|
+
# Creates a new shell
|
373
|
+
def initialize(console = nil)
|
374
|
+
console ||= Console.new
|
375
|
+
@console = console
|
371
376
|
end
|
372
377
|
end
|
373
378
|
end
|
data/lib/cowtech-lib/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 9
|
8
|
-
-
|
9
|
-
version: 1.9.
|
8
|
+
- 1
|
9
|
+
version: 1.9.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Shogun
|
@@ -16,35 +16,8 @@ cert_chain: []
|
|
16
16
|
|
17
17
|
date: 2011-02-21 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
|
-
dependencies:
|
20
|
-
|
21
|
-
name: jeweler
|
22
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
-
none: false
|
24
|
-
requirements:
|
25
|
-
- - ~>
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
segments:
|
28
|
-
- 1
|
29
|
-
- 5
|
30
|
-
- 1
|
31
|
-
version: 1.5.1
|
32
|
-
type: :development
|
33
|
-
prerelease: false
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: rcov
|
37
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
-
none: false
|
39
|
-
requirements:
|
40
|
-
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
segments:
|
43
|
-
- 0
|
44
|
-
version: "0"
|
45
|
-
type: :development
|
46
|
-
prerelease: false
|
47
|
-
version_requirements: *id002
|
19
|
+
dependencies: []
|
20
|
+
|
48
21
|
description: A general purpose utility library.
|
49
22
|
email: shogun_panda@me.com
|
50
23
|
executables: []
|
@@ -56,8 +29,6 @@ extra_rdoc_files:
|
|
56
29
|
- README.rdoc
|
57
30
|
files:
|
58
31
|
- .document
|
59
|
-
- Gemfile
|
60
|
-
- Gemfile.lock
|
61
32
|
- LICENSE.txt
|
62
33
|
- README.rdoc
|
63
34
|
- Rakefile
|
data/Gemfile
DELETED
data/Gemfile.lock
DELETED