shellopts 2.0.16 → 2.0.19
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 +4 -4
- data/PROBLEMS +52 -0
- data/lib/ext/follow.rb +26 -0
- data/lib/shellopts/grammar.rb +3 -3
- data/lib/shellopts/parser.rb +10 -15
- data/lib/shellopts/program.rb +48 -31
- data/lib/shellopts/version.rb +1 -1
- data/lib/shellopts.rb +136 -45
- data/main +15 -1185
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35b9e7b5699cc1a5637d4c00dd95c74047074f1227b0d05f9a9c8b04e1e2cc8b
|
4
|
+
data.tar.gz: c8deed23c8e6f0b26d080e15d2830edb5e65d1b5f2f821ccd83db7db27d7aefd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d3e96ec825ca58c0e653613ab84e2ede3e661737f5699571c81aaf9b2cb1252ea802581e5b981a1757d8a5a750ba998c43730c6d2da7d8228b721b06a45640e
|
7
|
+
data.tar.gz: e64eeac4c3bf784f8ef3a5e3a61c596e262bd23c4ee05857f76138f82ff2180afb72ccd5c2b7ffedc4e6aa2887b10c76e3a80c33e24ceadd20e71513549b5bf0
|
data/PROBLEMS
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
# Subcommand options are not recognized unless there exists an option on the
|
3
|
+
# program level (try to remove -a below)
|
4
|
+
|
5
|
+
SPEC = %(
|
6
|
+
Foreign data wrapper maintenance tool
|
7
|
+
|
8
|
+
-a,an-option
|
9
|
+
Gryf
|
10
|
+
|
11
|
+
list.servers! -- DATABASE
|
12
|
+
List foreign servers
|
13
|
+
|
14
|
+
create.server! -- DATABASE FDW-SERVER MSSQL-DATABASE [MSSQL-HOST [MSSQL-PORT]]
|
15
|
+
Create a new FDW server
|
16
|
+
|
17
|
+
-c,credentials=EFILE
|
18
|
+
Credentials file. The credentials file is a YAML formatted file that can
|
19
|
+
define the fields 'user', 'password', 'host', and 'port'
|
20
|
+
|
21
|
+
drop.server! -- DATABASE FDW-SERVER
|
22
|
+
Drop a FDW server. This cascades to FDW users too
|
23
|
+
|
24
|
+
list.users! -- DATABASE
|
25
|
+
List FDW users. 'users' in this context is postgres users that have an
|
26
|
+
associated FDW user mapping
|
27
|
+
|
28
|
+
--servers @ Also list the user's FDW servers
|
29
|
+
|
30
|
+
create.user! -- DATABASE FDW-SERVER [FDW-USER [FDW-PASSWORD]]
|
31
|
+
Create a FDW user. The user has to exist beforehand, this command only adds
|
32
|
+
a user mapping to the user and grants the usage privilege
|
33
|
+
|
34
|
+
-c,credentials=EFILE
|
35
|
+
Credentials file
|
36
|
+
|
37
|
+
drop.user! -- DATABASE FDW-USER
|
38
|
+
Drops a FDW user. The postgres user is not dropped but the user's user
|
39
|
+
mapping and grants are
|
40
|
+
)
|
41
|
+
|
42
|
+
###########################
|
43
|
+
|
44
|
+
# If option is only defined on a subcommand, it doesn't flow before the subcommand. This should be legal:
|
45
|
+
|
46
|
+
cmd -c sub
|
47
|
+
|
48
|
+
# Only this is legal today
|
49
|
+
|
50
|
+
cmd sub -c
|
51
|
+
|
52
|
+
|
data/lib/ext/follow.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
module Algorithm
|
3
|
+
class FollowEnumerator < Enumerator
|
4
|
+
def initialize(object, method = nil, &block)
|
5
|
+
closure = method ? lambda { |object| object.__send__(method) } : block
|
6
|
+
super() { |yielder|
|
7
|
+
while object
|
8
|
+
yielder << object
|
9
|
+
object = closure.call(object)
|
10
|
+
end
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def follow(object, method = nil, &block)
|
16
|
+
!method.nil? || block_given? or raise ArgumentError, "Needs either a method or a block"
|
17
|
+
method.nil? == block_given? or raise ArgumentError, "Can't use both method and block"
|
18
|
+
FollowEnumerator.new(object, method, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
module_function :follow
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
data/lib/shellopts/grammar.rb
CHANGED
@@ -30,7 +30,7 @@ module ShellOpts
|
|
30
30
|
def ancestors() parents.reverse end
|
31
31
|
|
32
32
|
def inspect
|
33
|
-
|
33
|
+
self.class.to_s
|
34
34
|
end
|
35
35
|
|
36
36
|
protected
|
@@ -72,7 +72,7 @@ module ShellOpts
|
|
72
72
|
# Note that the analyzer fails with an an error if both --with-separator
|
73
73
|
# and --with_separator are used because they would both map to
|
74
74
|
# :with_separator
|
75
|
-
|
75
|
+
attr_accessor :ident
|
76
76
|
|
77
77
|
# Canonical name (String) of the object
|
78
78
|
#
|
@@ -241,7 +241,7 @@ module ShellOpts
|
|
241
241
|
def [](key)
|
242
242
|
case key
|
243
243
|
when String; lookup(key.split("."))
|
244
|
-
when Symbol; lookup(key.to_s.
|
244
|
+
when Symbol; lookup(key.to_s.gsub(".", "!.").split(".").map(&:to_sym))
|
245
245
|
when Array; lookup(key)
|
246
246
|
else
|
247
247
|
nil
|
data/lib/shellopts/parser.rb
CHANGED
@@ -23,7 +23,7 @@ module ShellOpts
|
|
23
23
|
end
|
24
24
|
|
25
25
|
class Option
|
26
|
-
SHORT_NAME_RE = /[a-zA-Z0-9]/
|
26
|
+
SHORT_NAME_RE = /[a-zA-Z0-9?]/
|
27
27
|
LONG_NAME_RE = /[a-zA-Z0-9][a-zA-Z0-9_-]*/
|
28
28
|
NAME_RE = /(?:#{SHORT_NAME_RE}|#{LONG_NAME_RE})(?:,#{LONG_NAME_RE})*/
|
29
29
|
|
@@ -124,23 +124,18 @@ module ShellOpts
|
|
124
124
|
super(nil, token)
|
125
125
|
end
|
126
126
|
|
127
|
-
def
|
128
|
-
option_token = Token.new(:option, 1, 1,
|
129
|
-
brief_token = Token.new(:brief, 1, 1,
|
127
|
+
def inject_option(decl, brief, paragraph = nil, &block)
|
128
|
+
option_token = Token.new(:option, 1, 1, decl)
|
129
|
+
brief_token = Token.new(:brief, 1, 1, brief)
|
130
130
|
group = OptionGroup.new(self, option_token)
|
131
131
|
option = Option.parse(group, option_token)
|
132
132
|
brief = Brief.parse(group, brief_token)
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
"-h prints a brief help text, --help prints a longer man-style description of the command")
|
140
|
-
group = OptionGroup.new(self, option_token)
|
141
|
-
option = Option.parse(group, option_token)
|
142
|
-
brief = Brief.parse(group, brief_token)
|
143
|
-
paragraph = Paragraph.parse(group, paragraph_token)
|
133
|
+
paragraph ||= yield(option) if block_given?
|
134
|
+
if paragraph
|
135
|
+
paragraph_token = Token.new(:text, 1, 1, paragraph)
|
136
|
+
paragraph = Paragraph.parse(group, paragraph_token)
|
137
|
+
end
|
138
|
+
option
|
144
139
|
end
|
145
140
|
end
|
146
141
|
|
data/lib/shellopts/program.rb
CHANGED
@@ -52,7 +52,7 @@ module ShellOpts
|
|
52
52
|
# These methods can be overridden by an option or a command (this constant
|
53
53
|
# is not used - it is just for informational purposes)
|
54
54
|
OVERRIDEABLE_METHOD_NAMES = %w(
|
55
|
-
subcommand subcommand! supercommand!
|
55
|
+
subcommand subcommand! subcommands subcommands! supercommand!
|
56
56
|
)
|
57
57
|
|
58
58
|
# Redefine ::new to call #__initialize__
|
@@ -62,40 +62,28 @@ module ShellOpts
|
|
62
62
|
object
|
63
63
|
end
|
64
64
|
|
65
|
-
#
|
66
|
-
# possibly empty array of option objects if the
|
65
|
+
# Returns the command or option object identified by the UID if present and
|
66
|
+
# otherwise nil. Returns a possibly empty array of option objects if the
|
67
|
+
# option is repeatable. Raise an ArgumentError if the key doesn't exists
|
67
68
|
#
|
68
|
-
# The key is the
|
69
|
-
#
|
70
|
-
# and :cmd! or 'cmd' as command keys
|
69
|
+
# The +key+ is the symbolic UID of the object. Eg. :command.option or
|
70
|
+
# :command.subcommand!
|
71
71
|
#
|
72
|
-
def [](
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
72
|
+
def [](uid)
|
73
|
+
__grammar__.key?(uid) or ::Kernel.raise ::ArgumentError, "'#{uid}' is not a valid UID"
|
74
|
+
idents = uid.to_s.gsub(/\./, "!.").split(/\./).map(&:to_sym)
|
75
|
+
idents.inject(self) { |cmd, ident|
|
76
|
+
case ident.to_s
|
77
|
+
when /!$/
|
78
|
+
return nil if cmd.__subcommand__ != ident
|
79
|
+
cmd = cmd.__subcommand__!
|
79
80
|
else
|
80
|
-
__option_hash__[
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
81
|
+
opt = cmd.__option_hash__[ident]
|
82
|
+
opt.nil? && cmd.__grammar__[ident].repeatable? ? [] : opt
|
83
|
+
end
|
84
|
+
}
|
85
85
|
end
|
86
86
|
|
87
|
-
# Return true if the given command or option is present
|
88
|
-
def key?(key)
|
89
|
-
case object = __grammar__[key]
|
90
|
-
when ::ShellOpts::Grammar::Command
|
91
|
-
object.ident == __subcommand__
|
92
|
-
when ::ShellOpts::Grammar::Option
|
93
|
-
__option_hash__.key?(object.ident)
|
94
|
-
else
|
95
|
-
::Kernel.raise ::ArgumentError, "Unknown command or option: '#{key}'"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
87
|
# Returns a hash of the given options if defined. Returns all options if no
|
100
88
|
# options are given
|
101
89
|
def to_h(*keys)
|
@@ -133,6 +121,13 @@ module ShellOpts
|
|
133
121
|
#
|
134
122
|
def subcommand!() __subcommand__! end
|
135
123
|
|
124
|
+
# Returns the concatenated identifier of subcommands (eg. :cmd.subcmd!)
|
125
|
+
def subcommands() __subcommands__ end
|
126
|
+
|
127
|
+
# Returns the subcommands in an array. This doesn't include the top-level
|
128
|
+
# program object
|
129
|
+
def subcommands!() __subcommands__! end
|
130
|
+
|
136
131
|
# The parent command or nil. Initialized by #add_command
|
137
132
|
#
|
138
133
|
# Note: Can be overridden by a subcommand declaration (but not an
|
@@ -141,7 +136,7 @@ module ShellOpts
|
|
141
136
|
#
|
142
137
|
def supercommand!() __supercommand__ end
|
143
138
|
|
144
|
-
# UID of command/program
|
139
|
+
# UID of command/program (String)
|
145
140
|
def __uid__() @__grammar__.uid end
|
146
141
|
|
147
142
|
# Identfier including the exclamation mark (Symbol)
|
@@ -180,6 +175,16 @@ module ShellOpts
|
|
180
175
|
# The actual subcommand object or nil if not present
|
181
176
|
def __subcommand__!() @__subcommand__ end
|
182
177
|
|
178
|
+
# Implementation of the #subcommands method
|
179
|
+
def __subcommands__()
|
180
|
+
__subcommands__!.last&.__uid__&.to_sym
|
181
|
+
end
|
182
|
+
|
183
|
+
# Implementation of the #subcommands! method
|
184
|
+
def __subcommands__!()
|
185
|
+
::Algorithm.follow(self.__subcommand__!, :__subcommand__!).to_a
|
186
|
+
end
|
187
|
+
|
183
188
|
private
|
184
189
|
def __initialize__(grammar)
|
185
190
|
@__grammar__ = grammar
|
@@ -292,6 +297,18 @@ module ShellOpts
|
|
292
297
|
|
293
298
|
# The top-level command
|
294
299
|
class Program < Command
|
300
|
+
# Accessors for standard options values that are not affected if the option
|
301
|
+
# is renamed
|
302
|
+
attr_accessor :__quiet__
|
303
|
+
attr_accessor :__verbose__
|
304
|
+
attr_accessor :__debug__
|
305
|
+
|
306
|
+
def initialize
|
307
|
+
super
|
308
|
+
@__quiet__ = false
|
309
|
+
@__verbose__ = 0
|
310
|
+
@__debug__ = false
|
311
|
+
end
|
295
312
|
end
|
296
313
|
|
297
314
|
# Option models an option as given by the user on the subcommand line.
|
data/lib/shellopts/version.rb
CHANGED
data/lib/shellopts.rb
CHANGED
@@ -5,6 +5,7 @@ require 'constrain'
|
|
5
5
|
include Constrain
|
6
6
|
|
7
7
|
require 'ext/array.rb'
|
8
|
+
require 'ext/follow.rb'
|
8
9
|
require 'ext/forward_to.rb'
|
9
10
|
require 'ext/lcs.rb'
|
10
11
|
include ForwardTo
|
@@ -95,17 +96,20 @@ module ShellOpts
|
|
95
96
|
# Automatically add a -h and a --help option if true
|
96
97
|
attr_reader :help
|
97
98
|
|
98
|
-
# Version of client program. If not nil a --version option is added to the program
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
@version = IO.read(file).sub(/^.*VERSION\s*=\s*"(.*?)".*$/m, '\1') or
|
104
|
-
raise ArgumentError, "ShellOpts needs an explicit version"
|
105
|
-
end
|
99
|
+
# Version of client program. If not nil, a --version option is added to the program
|
100
|
+
attr_reader :version
|
101
|
+
|
102
|
+
# Automatically add a -q and a --quiet option if true
|
103
|
+
attr_reader :quiet
|
106
104
|
|
107
|
-
#
|
108
|
-
|
105
|
+
# Automatically add a -v and a --verbose option if true
|
106
|
+
attr_reader :verbose
|
107
|
+
|
108
|
+
# Automatically add a --debug option if true
|
109
|
+
attr_reader :debug
|
110
|
+
|
111
|
+
# Version number (this is usually detected dynamically)
|
112
|
+
attr_reader :version_number
|
109
113
|
|
110
114
|
# Floating options
|
111
115
|
attr_accessor :float
|
@@ -121,12 +125,33 @@ module ShellOpts
|
|
121
125
|
attr_reader :tokens
|
122
126
|
alias_method :ast, :grammar
|
123
127
|
|
124
|
-
def initialize(name: nil,
|
128
|
+
def initialize(name: nil,
|
129
|
+
# Options
|
130
|
+
help: true,
|
131
|
+
version: true,
|
132
|
+
quiet: nil,
|
133
|
+
verbose: nil,
|
134
|
+
debug: nil,
|
135
|
+
|
136
|
+
# Version number (usually detected)
|
137
|
+
version_number: nil,
|
138
|
+
|
139
|
+
# Floating options
|
140
|
+
float: true,
|
141
|
+
|
142
|
+
# Let exceptions through
|
143
|
+
exceptions: false
|
144
|
+
)
|
145
|
+
|
125
146
|
@name = name || File.basename($PROGRAM_NAME)
|
126
147
|
@help = help
|
127
|
-
@
|
128
|
-
@
|
129
|
-
@
|
148
|
+
@version = version || (version.nil? && !version_number.nil?)
|
149
|
+
@quiet = quiet
|
150
|
+
@verbose = verbose
|
151
|
+
@debug = debug
|
152
|
+
@version_number = version_number || find_version_number
|
153
|
+
@float = float
|
154
|
+
@exception = exception
|
130
155
|
end
|
131
156
|
|
132
157
|
# Compile source and return grammar object. Also sets #spec and #grammar.
|
@@ -138,8 +163,31 @@ module ShellOpts
|
|
138
163
|
@file = find_caller_file
|
139
164
|
@tokens = Lexer.lex(name, @spec, @oneline)
|
140
165
|
ast = Parser.parse(tokens)
|
141
|
-
|
142
|
-
|
166
|
+
|
167
|
+
help_spec = (@help == true ? "-h,help" : @help)
|
168
|
+
version_spec = (@version == true ? "--version" : @version)
|
169
|
+
quiet_spec = (@quiet == true ? "-q,quiet" : @quiet)
|
170
|
+
verbose_spec = (@verbose == true ? "+v,verbose" : @verbose)
|
171
|
+
debug_spec = (@debug == true ? "--debug" : @debug)
|
172
|
+
|
173
|
+
@quiet_option =
|
174
|
+
ast.inject_option(quiet_spec, "Quiet", "Do not write anything to standard output") if @quiet
|
175
|
+
@verbose_option =
|
176
|
+
ast.inject_option(verbose_spec, "Increase verbosity", "Write verbose output") if @verbose
|
177
|
+
@debug_option =
|
178
|
+
ast.inject_option(debug_spec, "Write debug information") if @debug
|
179
|
+
@help_option =
|
180
|
+
ast.inject_option(help_spec, "Write short or long help") { |option|
|
181
|
+
short_option = option.short_names.first
|
182
|
+
long_option = option.long_names.first
|
183
|
+
[
|
184
|
+
short_option && "#{short_option} prints a brief help text",
|
185
|
+
long_option && "#{long_option} prints a longer man-style description of the command"
|
186
|
+
].compact.join(", ")
|
187
|
+
} if @help
|
188
|
+
@version_option =
|
189
|
+
ast.inject_option(version_spec, "Write version number and exit") if @version
|
190
|
+
|
143
191
|
@grammar = Analyzer.analyze(ast)
|
144
192
|
}
|
145
193
|
self
|
@@ -152,16 +200,22 @@ module ShellOpts
|
|
152
200
|
handle_exceptions {
|
153
201
|
@argv = argv.dup
|
154
202
|
@program, @args = Interpreter.interpret(grammar, argv, float: float, exception: exception)
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
if @program[:help].name == "-h"
|
160
|
-
ShellOpts.brief
|
161
|
-
else
|
203
|
+
|
204
|
+
# Process standard options (that may have been renamed)
|
205
|
+
if @program.__send__(:"#{@help_option.ident}?")
|
206
|
+
if @program[:help].name =~ /^--/
|
162
207
|
ShellOpts.help
|
208
|
+
else
|
209
|
+
ShellOpts.brief
|
163
210
|
end
|
164
211
|
exit
|
212
|
+
elsif @program.__send__(:"#{@version_option.ident}?")
|
213
|
+
puts version_number
|
214
|
+
exit
|
215
|
+
else
|
216
|
+
@program.__quiet__ = @program.__send__(:"#{@quiet_option.ident}?") if @quiet
|
217
|
+
@program.__verbose__ = @program.__send__(:"#{@verbose_option.ident}") if @verbose
|
218
|
+
@program.__debug__ = @program.__send__(:"#{@debug_option.ident}?") if @debug
|
165
219
|
end
|
166
220
|
}
|
167
221
|
self
|
@@ -234,6 +288,13 @@ module ShellOpts
|
|
234
288
|
def self.help(subject = nil) ::ShellOpts.instance.help(subject) end
|
235
289
|
|
236
290
|
private
|
291
|
+
def find_version_number
|
292
|
+
exe = caller.find { |line| line =~ /`<top \(required\)>'$/ }&.sub(/:.*/, "") or return nil
|
293
|
+
file = Dir.glob(File.dirname(exe) + "/../lib/*/version.rb").first or return nil
|
294
|
+
IO.read(file).sub(/^.*VERSION\s*=\s*"(.*?)".*$/m, '\1') or
|
295
|
+
raise ArgumentError, "ShellOpts needs an explicit version"
|
296
|
+
end
|
297
|
+
|
237
298
|
def handle_exceptions(&block)
|
238
299
|
return yield if exception
|
239
300
|
begin
|
@@ -321,9 +382,13 @@ module ShellOpts
|
|
321
382
|
end
|
322
383
|
end
|
323
384
|
|
324
|
-
|
325
|
-
|
326
|
-
|
385
|
+
|
386
|
+
def self.process(spec, argv, quiet: nil, verbose: nil, debug: nil, **opts)
|
387
|
+
constrain quiet, String, true, false, nil
|
388
|
+
quiet = quiet.nil? ? Message.is_included? || Verbose.is_included? : quiet
|
389
|
+
verbose = verbose.nil? ? ::ShellOpts::Verbose.is_included? : verbose
|
390
|
+
debug = debug.nil? ? Debug.is_included? : debug
|
391
|
+
ShellOpts.process(spec, argv, quiet: quiet, verbose: verbose, debug: debug, **opts)
|
327
392
|
end
|
328
393
|
|
329
394
|
@instance = nil
|
@@ -344,31 +409,57 @@ module ShellOpts
|
|
344
409
|
exit 1
|
345
410
|
end
|
346
411
|
|
347
|
-
|
348
|
-
|
349
|
-
|
412
|
+
def self.notice(message)
|
413
|
+
$stderr.puts "#{instance.program.__grammar__.name}: #{message}" \
|
414
|
+
if !instance.quiet || !instance.program.quiet?
|
415
|
+
end
|
416
|
+
|
417
|
+
def self.mesg(message)
|
418
|
+
$stdout.puts message if !instance.quiet || !instance.program.__quiet__
|
419
|
+
end
|
420
|
+
|
421
|
+
def self.verb(level = 1, message)
|
422
|
+
$stdout.puts message if instance.verbose && level <= instance.program.__verbose__
|
423
|
+
end
|
424
|
+
|
425
|
+
def self.debug(message)
|
426
|
+
$stdout.puts message if instance.debug && instance.program.__debug__
|
427
|
+
end
|
428
|
+
|
429
|
+
def self.quiet_flag
|
430
|
+
end
|
431
|
+
|
432
|
+
def self.verbose_flag
|
433
|
+
end
|
434
|
+
|
435
|
+
def self.debug_flag
|
436
|
+
end
|
437
|
+
|
438
|
+
module Message
|
350
439
|
@is_included = false
|
351
440
|
def self.is_included?() @is_included end
|
352
|
-
def self.
|
353
|
-
@is_included = true
|
354
|
-
super
|
355
|
-
end
|
441
|
+
def self.included(...) @is_included = true; super end
|
356
442
|
|
357
|
-
def notice(message)
|
358
|
-
|
359
|
-
|
443
|
+
def notice(message) ::ShellOpts.notice(message) end
|
444
|
+
def mesg(message) ::ShellOpts.mesg(message) end
|
445
|
+
end
|
360
446
|
|
361
|
-
|
362
|
-
|
363
|
-
end
|
447
|
+
module Verbose
|
448
|
+
@is_included = false
|
449
|
+
def self.is_included?() @is_included end
|
450
|
+
def self.included(...) @is_included = true; super end
|
364
451
|
|
365
|
-
def
|
366
|
-
|
367
|
-
end
|
452
|
+
def notice(message) ::ShellOpts.notice(message) end
|
453
|
+
def mesg(message) ::ShellOpts.mesg(message) end
|
454
|
+
def verb(level = 1, message) ::ShellOpts.verb(level, message) end
|
455
|
+
end
|
368
456
|
|
369
|
-
|
370
|
-
|
371
|
-
end
|
457
|
+
module Debug
|
458
|
+
@is_included = false
|
459
|
+
def self.is_included?() @is_included end
|
460
|
+
def self.included(...) @is_included = true; super end
|
461
|
+
|
462
|
+
def debug(message) ::ShellOpts.debug(message) end
|
372
463
|
end
|
373
464
|
|
374
465
|
module ErrorHandling
|