cmdlib 0.1.1 → 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 +4 -4
- data/lib/cmdlib.rb +2 -2
- data/lib/cmdlib/application.rb +369 -0
- data/lib/cmdlib/command.rb +32 -7
- data/lib/cmdlib/describe.rb +1 -45
- data/lib/cmdlib/option.rb +2 -1
- data/lib/cmdlib/version.rb +1 -1
- metadata +4 -5
- data/lib/cmdlib/handler.rb +0 -205
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b170999269670668c26d833c36d2158df2cdf373
|
4
|
+
data.tar.gz: 60b3ffb61f88cbf422833981e91edf923e292283
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f436c4bde1fbc0827656abc8711c25d77de4aed20c56cccb162b34ef1a3f14bdf041fa8f39c6f8898294760e586ef4bef390a1f289103a7e526d3438aa24bc64
|
7
|
+
data.tar.gz: d9755efdb11c202488ef87d9741d3bbc89de00160806b4e1f3c6936a03ddb253af94bf25d0a7dc7440b6238a1dae5a5d7ff3c24e62613d959c0a8bba4e7b500e
|
data/lib/cmdlib.rb
CHANGED
@@ -0,0 +1,369 @@
|
|
1
|
+
module Cmdlib
|
2
|
+
# Class edscribe CLI application (TOP class).
|
3
|
+
class App
|
4
|
+
OPTION_PREFIX_SHORT = '-'
|
5
|
+
OPTION_PREFIX_LONG = '--'
|
6
|
+
|
7
|
+
# This array contain information to use application.
|
8
|
+
attr_accessor :name, :about, :usage
|
9
|
+
|
10
|
+
# Version string (will be display to -v or --version).
|
11
|
+
attr_accessor :version, :options, :commands
|
12
|
+
|
13
|
+
def initialize ( appname )
|
14
|
+
@name = appname
|
15
|
+
@about = []
|
16
|
+
@usage = []
|
17
|
+
@commands = []
|
18
|
+
@options = {}
|
19
|
+
@default = nil
|
20
|
+
@version = '0.1.1'
|
21
|
+
|
22
|
+
addopt Option.new( 'V', 'version', 'Display application version.' )
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Add CLICommand object to CLIHandler.
|
27
|
+
def addcmd ( cmd )
|
28
|
+
raise TypeError, 'Incorrectly types for command object.' unless
|
29
|
+
cmd.is_a? Cmdlib::Command
|
30
|
+
|
31
|
+
@commands << cmd
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# Add CLICommand object to CLIHandler.
|
36
|
+
def addopt ( opt )
|
37
|
+
raise TypeError, 'Incorrectly types for option object.' unless
|
38
|
+
opt.instance_of? Cmdlib::Option
|
39
|
+
|
40
|
+
@options[opt.longname.to_sym] = opt
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# Default command for run without arguments.
|
45
|
+
def default ( cmd )
|
46
|
+
raise TypeError, 'Incorrectly types for command object.' unless
|
47
|
+
cmd.is_a? Cmdlib::Command
|
48
|
+
|
49
|
+
@default = cmd
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Display commands info
|
54
|
+
def display_commands( cmdlist )
|
55
|
+
maxlen = 0
|
56
|
+
cmdlist.each do |cmd|
|
57
|
+
maxlen = cmd.name.length if cmd.name.length > maxlen
|
58
|
+
end
|
59
|
+
cmdlist.each do |cmd|
|
60
|
+
print ' ' + cmd.name
|
61
|
+
print "#{' ' * (maxlen - cmd.name.length)} # "
|
62
|
+
puts cmd.brief
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# Display options info
|
68
|
+
def display_options( optlist )
|
69
|
+
maxlen = 0
|
70
|
+
listout = []
|
71
|
+
optlist.each_value do |opt|
|
72
|
+
optnames = ''
|
73
|
+
if opt.shortname.length == 0
|
74
|
+
optnames += ' '
|
75
|
+
else
|
76
|
+
optnames += OPTION_PREFIX_SHORT + opt.shortname
|
77
|
+
end
|
78
|
+
optnames += ','
|
79
|
+
optnames += OPTION_PREFIX_LONG + opt.longname if opt.longname.length != 0
|
80
|
+
optnames += '=[...]' if opt.param == true
|
81
|
+
listout << { :n => optnames, :b => opt.brief }
|
82
|
+
maxlen = optnames.length if optnames.length > maxlen
|
83
|
+
end
|
84
|
+
listout.each do |opt|
|
85
|
+
print ' ' + opt[:n]
|
86
|
+
print "#{' ' * (maxlen - opt[:n].length)} # "
|
87
|
+
puts opt[:b]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# Main method to run application.
|
93
|
+
def run
|
94
|
+
option_parser @options
|
95
|
+
|
96
|
+
# Check on include version request.
|
97
|
+
if @options[:version].value then
|
98
|
+
puts "#{@name}, version #{@version}"
|
99
|
+
exit
|
100
|
+
end
|
101
|
+
|
102
|
+
# Check on include help request.
|
103
|
+
if ARGV[0] == 'help' or ARGV[0] == '--help' or ARGV[0] == '-h' then
|
104
|
+
# Help arguments apsent, well then display information about application.
|
105
|
+
if ARGV.size == 1 then
|
106
|
+
puts
|
107
|
+
puts "*** #{@name} ***".center(80)
|
108
|
+
# Display about info.
|
109
|
+
if @about.size > 0 then
|
110
|
+
puts '** ABOUT:'
|
111
|
+
@about.each do |line|
|
112
|
+
puts " #{line}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
# Display usage info.
|
116
|
+
if @usage.size > 0 then
|
117
|
+
puts
|
118
|
+
puts '** USAGE:'
|
119
|
+
@usage.each do |line|
|
120
|
+
puts " #{line}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
# Display options info.
|
124
|
+
puts
|
125
|
+
puts '** OPTIONS:'
|
126
|
+
display_options @options
|
127
|
+
# Display commands info
|
128
|
+
if @commands.size > 0 then
|
129
|
+
@commands.each do |c| c.init end
|
130
|
+
puts
|
131
|
+
puts '** COMMANDS:'
|
132
|
+
display_commands @commands
|
133
|
+
puts
|
134
|
+
puts "For details, type: help [COMMAND]"
|
135
|
+
end
|
136
|
+
puts
|
137
|
+
# Help arguments exist, find command in application command list.
|
138
|
+
else
|
139
|
+
ARGV.delete_at( 0 )
|
140
|
+
cmd = command_select
|
141
|
+
if ARGV.size != 0 then
|
142
|
+
puts "fatal error: unknown command '#{ARGV[0]}'"
|
143
|
+
exit
|
144
|
+
end
|
145
|
+
# Display describe information on command.
|
146
|
+
puts
|
147
|
+
puts Cmdlib::Describe.outtitle( cmd.name )
|
148
|
+
puts " #{cmd.brief}"
|
149
|
+
if cmd.details.size > 0 then
|
150
|
+
puts
|
151
|
+
puts '** DETAILS:'
|
152
|
+
cmd.details.each do |e|
|
153
|
+
puts " #{e}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
if cmd.example.size > 0 then
|
157
|
+
puts
|
158
|
+
puts '** EXAMPLE:'
|
159
|
+
cmd.example.each do |e|
|
160
|
+
puts " #{e}"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
# Display options info.
|
164
|
+
if cmd.options.size > 0 then
|
165
|
+
puts
|
166
|
+
puts '** OPTIONS:'
|
167
|
+
display_options cmd.options
|
168
|
+
end
|
169
|
+
# Display commands info.
|
170
|
+
if cmd.subcmd.size > 0 then
|
171
|
+
cmd.subcmd.each do |c| c.init end
|
172
|
+
puts
|
173
|
+
puts '** SUBCOMMANDS:'
|
174
|
+
display_commands cmd.subcmd
|
175
|
+
puts
|
176
|
+
puts "For details, type: help #{cmd.name} [SUBCOMMAND]"
|
177
|
+
end
|
178
|
+
puts
|
179
|
+
end
|
180
|
+
exit
|
181
|
+
end
|
182
|
+
|
183
|
+
# Handling default command (if exist her).
|
184
|
+
if @default != nil then
|
185
|
+
option_excess
|
186
|
+
if ARGV.size < @default.argnum then
|
187
|
+
puts "fatal error: to few arguments for programm, use <help>."
|
188
|
+
else
|
189
|
+
@default.handler( @options, ARGV )
|
190
|
+
end
|
191
|
+
exit
|
192
|
+
end
|
193
|
+
|
194
|
+
# Handling commands.
|
195
|
+
cmd = command_select
|
196
|
+
if cmd == nil then
|
197
|
+
puts "fatal error: unknown command or command miss, use <help>."
|
198
|
+
exit
|
199
|
+
end
|
200
|
+
if ARGV.size < cmd.argnum then
|
201
|
+
puts "fatal error: to few arguments for command, use: <help> <command name>."
|
202
|
+
exit
|
203
|
+
end
|
204
|
+
# Scaning options fir this command
|
205
|
+
option_parser cmd.options
|
206
|
+
option_excess
|
207
|
+
#cmd.init
|
208
|
+
cmd.handler( @options, ARGV )
|
209
|
+
exit
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
# Search command in command list.
|
214
|
+
# Return command object if search success,
|
215
|
+
# else return nil.
|
216
|
+
# cmdlist -- array with command objects.
|
217
|
+
# cmd -- string with command name from ARGV.
|
218
|
+
def command_search( cmdlist, cmd )
|
219
|
+
cmdlist.each do |c|
|
220
|
+
c.init
|
221
|
+
return c if c.name == cmd
|
222
|
+
end
|
223
|
+
return nil
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
# Select and return command object in application.
|
228
|
+
def command_select
|
229
|
+
command = command_search( @commands, ARGV[0] )
|
230
|
+
if command != nil then
|
231
|
+
# remove command name from ARGV and search next.
|
232
|
+
ARGV.delete_at( 0 )
|
233
|
+
ARGV.each do |arg|
|
234
|
+
cmd = command_search( command.subcmd, arg )
|
235
|
+
break if cmd == nil
|
236
|
+
ARGV.delete_at( 0 )
|
237
|
+
command = cmd
|
238
|
+
end
|
239
|
+
end
|
240
|
+
return command
|
241
|
+
end
|
242
|
+
|
243
|
+
|
244
|
+
# Check input arguments on equal option syntax.
|
245
|
+
# if success return option { :n => <argument name>, :t => <option type> },
|
246
|
+
# else return '' in all fields.
|
247
|
+
def getopt ( opt )
|
248
|
+
result = { :n => '', :t => '', }
|
249
|
+
if opt.length > OPTION_PREFIX_LONG.length then
|
250
|
+
if opt[0, OPTION_PREFIX_LONG.length] == OPTION_PREFIX_LONG then
|
251
|
+
result[:n] = opt[OPTION_PREFIX_LONG.length, opt.length]
|
252
|
+
result[:t] = OPTION_PREFIX_LONG
|
253
|
+
return result
|
254
|
+
end
|
255
|
+
end
|
256
|
+
if opt.length > OPTION_PREFIX_SHORT.length then
|
257
|
+
if opt[0, OPTION_PREFIX_SHORT.length] == OPTION_PREFIX_SHORT then
|
258
|
+
result[:n] = opt[OPTION_PREFIX_SHORT.length, opt.length]
|
259
|
+
result[:t] = OPTION_PREFIX_SHORT
|
260
|
+
return result
|
261
|
+
end
|
262
|
+
end
|
263
|
+
return result
|
264
|
+
end
|
265
|
+
|
266
|
+
|
267
|
+
# Check ARGV to exess options.
|
268
|
+
def option_excess
|
269
|
+
ARGV.each do |opt|
|
270
|
+
o = getopt( opt )
|
271
|
+
if o[:n] != '' then
|
272
|
+
puts "fatal error: unknown option '#{o[:t]}#{o[:n]}'"
|
273
|
+
exit
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
|
279
|
+
# Compare parsing option (form by getopt) with application option.
|
280
|
+
# Return true if options is equal, else return false.
|
281
|
+
# opt_form -- object formed by getopt.
|
282
|
+
# opt_app -- application option object.
|
283
|
+
def option_compare ( opt_form, opt_app )
|
284
|
+
case opt_form[:t]
|
285
|
+
when OPTION_PREFIX_SHORT
|
286
|
+
return true if opt_form[:n][0, opt_app.shortname.length] == opt_app.shortname
|
287
|
+
when OPTION_PREFIX_LONG
|
288
|
+
return true if opt_form[:n].split('=')[0] == opt_app.longname
|
289
|
+
end
|
290
|
+
return false
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
# Search option in application options.
|
295
|
+
# Return option key-name if option found, else return nil.
|
296
|
+
# option -- object formed by getopt.
|
297
|
+
# options -- options object list.
|
298
|
+
def option_search( option, options )
|
299
|
+
# Search in global options list
|
300
|
+
options.each_value do |opt|
|
301
|
+
return opt.longname.to_sym if option_compare( option, opt )
|
302
|
+
end
|
303
|
+
return nil
|
304
|
+
end
|
305
|
+
|
306
|
+
|
307
|
+
# Set application option object.
|
308
|
+
# opt_form -- object formed by getopt.
|
309
|
+
# opt_app -- application option object.
|
310
|
+
# Return delete name in ARGV or ''.
|
311
|
+
def option_set ( opt_form, opt_app )
|
312
|
+
if opt_app.param then
|
313
|
+
# option parameter buit-in option name by '='
|
314
|
+
if opt_form[:n].include? '=' then
|
315
|
+
opt_app.value = opt_form[:n].split('=')[-1]
|
316
|
+
return ''
|
317
|
+
end
|
318
|
+
# option parameter buit-in option name
|
319
|
+
if opt_form[:t] == OPTION_PREFIX_SHORT and
|
320
|
+
opt_form[:n].length > opt_app.shortname.length then
|
321
|
+
opt_app.value = opt_form[:n][opt_app.shortname.length, opt_form[:n].length - opt_app.shortname.length]
|
322
|
+
return ''
|
323
|
+
end
|
324
|
+
# option parameter present in next ARGV.
|
325
|
+
if opt_form[:i].next >= ARGV.size then
|
326
|
+
puts "fatal error: unable to find argument for option '#{opt_form[:n]}'."
|
327
|
+
exit
|
328
|
+
end
|
329
|
+
# if next argument is a option.
|
330
|
+
arg = ARGV[opt_form[:i].next]
|
331
|
+
if getopt( arg )[:n] != '' then
|
332
|
+
puts "fatal error: miss argument for option '#{opt_form[:t]}#{opt_form[:n]}'."
|
333
|
+
exit
|
334
|
+
end
|
335
|
+
opt_app.value = arg
|
336
|
+
return arg
|
337
|
+
else
|
338
|
+
opt_app.value = true
|
339
|
+
end
|
340
|
+
return ''
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
# Parsing options in command line.
|
345
|
+
def option_parser( optlist )
|
346
|
+
return if optlist.size == 0
|
347
|
+
deletelist = []
|
348
|
+
# search option in argument list.
|
349
|
+
ARGV.each_with_index do |opt,i|
|
350
|
+
o = getopt( opt )
|
351
|
+
if o[:n] != '' and o[:n] != 'h' and o[:n] != 'help'
|
352
|
+
o[:i] = i
|
353
|
+
# Search in application list
|
354
|
+
result = option_search( o, optlist )
|
355
|
+
if result != nil then
|
356
|
+
deletelist << opt
|
357
|
+
result = option_set( o, optlist[result] )
|
358
|
+
deletelist << result if result != ''
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
# delete option from ARGV.
|
363
|
+
deletelist.each do |n|
|
364
|
+
ARGV.delete( n )
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
end # class App
|
369
|
+
end # module Cmdlib
|
data/lib/cmdlib/command.rb
CHANGED
@@ -3,19 +3,44 @@ module Cmdlib
|
|
3
3
|
class Command
|
4
4
|
|
5
5
|
# Contain object with describe text.
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :name, :brief, :details, :example
|
7
7
|
|
8
|
-
#
|
8
|
+
# List with options for command and subcommand.
|
9
|
+
attr_accessor :options, :subcmd
|
10
|
+
|
11
|
+
# Mandatory argument numbers for command.
|
9
12
|
attr_accessor :argnum
|
10
13
|
|
11
14
|
def initialize
|
12
|
-
@
|
13
|
-
@
|
15
|
+
@name = ''
|
16
|
+
@brief = ''
|
17
|
+
@details = []
|
18
|
+
@example = []
|
19
|
+
@options = {}
|
20
|
+
@subcmd = []
|
21
|
+
@argnum = 0
|
14
22
|
end
|
15
23
|
|
16
|
-
def
|
17
|
-
puts "fatal error: do not set handler for '#{@describe.oname}' command."
|
24
|
+
def init
|
18
25
|
end
|
19
|
-
|
26
|
+
|
27
|
+
def handler( global_options, args )
|
28
|
+
puts "error: handler do not set for this command."
|
29
|
+
end
|
30
|
+
|
31
|
+
def addopt ( opt )
|
32
|
+
raise TypeError, 'Incorrectly types for option object.' unless
|
33
|
+
opt.instance_of? Cmdlib::Option
|
34
|
+
|
35
|
+
@options[opt.longname.to_sym] = opt
|
36
|
+
end
|
37
|
+
|
38
|
+
def addcmd ( cmd )
|
39
|
+
raise TypeError, 'Incorrectly types for command object.' unless
|
40
|
+
cmd.is_a? Cmdlib::Command
|
20
41
|
|
42
|
+
@subcmd << cmd
|
43
|
+
end
|
44
|
+
|
45
|
+
end # class Command
|
21
46
|
end # module Cmdlib
|
data/lib/cmdlib/describe.rb
CHANGED
@@ -1,31 +1,6 @@
|
|
1
1
|
module Cmdlib
|
2
|
-
# Create class with describe information
|
3
|
-
# of any objects.
|
4
2
|
class Describe
|
5
3
|
|
6
|
-
# This string have should text with object name.
|
7
|
-
attr_accessor :oname
|
8
|
-
|
9
|
-
# This string have should text with brief information.
|
10
|
-
attr_accessor :brief
|
11
|
-
|
12
|
-
# This array string have should text with details information.
|
13
|
-
attr_accessor :details
|
14
|
-
|
15
|
-
# This array string have should text with examples information.
|
16
|
-
attr_accessor :example
|
17
|
-
|
18
|
-
# This array string have should text with tags information.
|
19
|
-
attr_accessor :options
|
20
|
-
|
21
|
-
def initialize
|
22
|
-
@oname = ''
|
23
|
-
@brief = ''
|
24
|
-
@details = []
|
25
|
-
@example = []
|
26
|
-
@options = []
|
27
|
-
end
|
28
|
-
|
29
4
|
# Display title in follow format: *** [title] ***.
|
30
5
|
def self.outtitle ( str )
|
31
6
|
if( str.length < (80-4) ) then
|
@@ -39,25 +14,6 @@ module Cmdlib
|
|
39
14
|
puts str
|
40
15
|
end
|
41
16
|
end
|
42
|
-
|
43
|
-
# Display all information about object.
|
44
|
-
def display
|
45
|
-
puts
|
46
|
-
Describe.outtitle( @oname )
|
47
|
-
puts
|
48
|
-
puts ' ' + @brief
|
49
|
-
puts
|
50
|
-
puts '** DESCRIBE:'
|
51
|
-
@details.each do |line|
|
52
|
-
puts ' ' + line
|
53
|
-
end
|
54
|
-
puts
|
55
|
-
puts '** EXAMPLE:'
|
56
|
-
@example.each do |line|
|
57
|
-
puts ' ' + line
|
58
|
-
end
|
59
|
-
puts
|
60
|
-
end
|
17
|
+
|
61
18
|
end # class Describe
|
62
|
-
|
63
19
|
end # module Cmdlib
|
data/lib/cmdlib/option.rb
CHANGED
@@ -22,7 +22,8 @@ module Cmdlib
|
|
22
22
|
raise TypeError, 'Incorrectly types for option constructor.' unless
|
23
23
|
sname.instance_of? String and
|
24
24
|
lname.instance_of? String and
|
25
|
-
brief.instance_of? String
|
25
|
+
brief.instance_of? String and
|
26
|
+
sname.length == 1 and lname.length > 1
|
26
27
|
|
27
28
|
@shortname = sname
|
28
29
|
@longname = lname
|
data/lib/cmdlib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cmdlib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton S. Gerasimov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -46,9 +46,9 @@ extensions: []
|
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
48
|
- lib/cmdlib.rb
|
49
|
+
- lib/cmdlib/application.rb
|
49
50
|
- lib/cmdlib/command.rb
|
50
51
|
- lib/cmdlib/describe.rb
|
51
|
-
- lib/cmdlib/handler.rb
|
52
52
|
- lib/cmdlib/option.rb
|
53
53
|
- lib/cmdlib/version.rb
|
54
54
|
homepage: https://github.com/gera-gas/cmdlib
|
@@ -71,9 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
71
|
version: '0'
|
72
72
|
requirements: []
|
73
73
|
rubyforge_project:
|
74
|
-
rubygems_version: 2.
|
74
|
+
rubygems_version: 2.6.4
|
75
75
|
signing_key:
|
76
76
|
specification_version: 4
|
77
77
|
summary: Simple constructor of CLI (Command Line Interface) handler.
|
78
78
|
test_files: []
|
79
|
-
has_rdoc:
|
data/lib/cmdlib/handler.rb
DELETED
@@ -1,205 +0,0 @@
|
|
1
|
-
module Cmdlib
|
2
|
-
# Class with methods for handled commands
|
3
|
-
# from CLI application.
|
4
|
-
class Handler
|
5
|
-
OPTION_PREFIX_SHORT = '-'
|
6
|
-
OPTION_PREFIX_LONG = '--'
|
7
|
-
|
8
|
-
# This array contain information to use application.
|
9
|
-
attr_accessor :usage
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@usage = []
|
13
|
-
@cmdlist = []
|
14
|
-
@optlist = []
|
15
|
-
end
|
16
|
-
|
17
|
-
# Add CLICommand object to CLIHandler.
|
18
|
-
def addcmd ( cmd )
|
19
|
-
raise TypeError, 'Incorrectly types for command object.' unless
|
20
|
-
cmd.respond_to? :describe and
|
21
|
-
cmd.respond_to? :handler and
|
22
|
-
cmd.describe.instance_of? Describe
|
23
|
-
|
24
|
-
@cmdlist << cmd
|
25
|
-
end
|
26
|
-
|
27
|
-
# Add CLICommand object to CLIHandler.
|
28
|
-
def addopt ( opt )
|
29
|
-
raise TypeError, 'Incorrectly types for option object.' unless
|
30
|
-
opt.respond_to? :brief and
|
31
|
-
opt.respond_to? :shortname and
|
32
|
-
opt.respond_to? :longname and
|
33
|
-
opt.respond_to? :value and
|
34
|
-
opt.respond_to? :param and
|
35
|
-
opt.brief.instance_of? String
|
36
|
-
|
37
|
-
@optlist << opt
|
38
|
-
end
|
39
|
-
|
40
|
-
# Main handler method, execute command handler.
|
41
|
-
def run
|
42
|
-
# parsing options.
|
43
|
-
optparser
|
44
|
-
|
45
|
-
# handled position arguments.
|
46
|
-
if ARGV.size > 0 then
|
47
|
-
if ARGV[0] == 'help' or ARGV[0] == '--help' or ARGV[0] == '-h' then
|
48
|
-
# display help specificly command.
|
49
|
-
if ARGV.size == 2 then
|
50
|
-
@cmdlist.each do |e|
|
51
|
-
if ARGV[1] == e.describe.oname then
|
52
|
-
e.describe.display
|
53
|
-
exit
|
54
|
-
end
|
55
|
-
end
|
56
|
-
puts "fatal error: unknown command with name - #{ARGV[1]}"
|
57
|
-
# display usage help.
|
58
|
-
else
|
59
|
-
puts
|
60
|
-
# dislpay usage information.
|
61
|
-
@usage.each do |e|
|
62
|
-
puts e
|
63
|
-
end
|
64
|
-
if @cmdlist.size > 0 then
|
65
|
-
puts
|
66
|
-
puts '** COMMANDS:'
|
67
|
-
maxlen = 0
|
68
|
-
# dislpay command list.
|
69
|
-
@cmdlist.each do |e|
|
70
|
-
maxlen = e.describe.oname.length if e.describe.oname.length > maxlen
|
71
|
-
end
|
72
|
-
@cmdlist.each do |e|
|
73
|
-
print ' ' + e.describe.oname
|
74
|
-
print "#{' ' * (maxlen - e.describe.oname.length)} -- "
|
75
|
-
puts e.describe.brief
|
76
|
-
end
|
77
|
-
puts
|
78
|
-
puts ' For details type: help <command>'
|
79
|
-
end
|
80
|
-
puts
|
81
|
-
# display options list.
|
82
|
-
if @optlist.size > 0 then
|
83
|
-
puts '** OPTIONS:'
|
84
|
-
maxlen = 0
|
85
|
-
# make shortname to string with option names.
|
86
|
-
listout = []
|
87
|
-
@optlist.each do |e|
|
88
|
-
optnames = ''
|
89
|
-
if e.shortname.length == 0
|
90
|
-
optnames += ' '
|
91
|
-
else
|
92
|
-
optnames += OPTION_PREFIX_SHORT + e.shortname
|
93
|
-
end
|
94
|
-
optnames += ','
|
95
|
-
if e.longname.length != 0
|
96
|
-
optnames += OPTION_PREFIX_LONG + e.longname
|
97
|
-
end
|
98
|
-
listout << optnames
|
99
|
-
maxlen = optnames.length if optnames.length > maxlen
|
100
|
-
end
|
101
|
-
# make longname to string with option names.
|
102
|
-
@optlist.each_with_index do |e,i|
|
103
|
-
print ' ' + listout[i]
|
104
|
-
print "#{' ' * (maxlen - listout[i].length)} -- "
|
105
|
-
puts e.brief
|
106
|
-
end
|
107
|
-
puts
|
108
|
-
end
|
109
|
-
end
|
110
|
-
else
|
111
|
-
# handling input command.
|
112
|
-
@cmdlist.each do |e|
|
113
|
-
if ARGV[0] == e.describe.oname then
|
114
|
-
# check arguments numbers.
|
115
|
-
if e.argnum != nil then
|
116
|
-
if (ARGV.size - 1) != e.argnum then
|
117
|
-
puts 'fatal error: wrong arguments for program.'
|
118
|
-
exit
|
119
|
-
end
|
120
|
-
end
|
121
|
-
# run handler of command.
|
122
|
-
e.handler
|
123
|
-
exit
|
124
|
-
end
|
125
|
-
end
|
126
|
-
puts "fatal error: unknown command with name - #{ARGV[0]}"
|
127
|
-
end
|
128
|
-
# exit, after handled all arguments.
|
129
|
-
exit
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# Check input arguments on equal option syntax.
|
134
|
-
# Return option name if success, else return ''.
|
135
|
-
def getopt ( opt )
|
136
|
-
if opt.length > OPTION_PREFIX_LONG.length then
|
137
|
-
return opt[OPTION_PREFIX_LONG.length, opt.length] if opt[0, OPTION_PREFIX_LONG.length] == OPTION_PREFIX_LONG
|
138
|
-
end
|
139
|
-
if opt.length > OPTION_PREFIX_SHORT.length then
|
140
|
-
return opt[OPTION_PREFIX_SHORT.length, opt.length] if opt[0, OPTION_PREFIX_SHORT.length] == OPTION_PREFIX_SHORT
|
141
|
-
end
|
142
|
-
return ''
|
143
|
-
end
|
144
|
-
|
145
|
-
# parse command line on the option exist.
|
146
|
-
def optparser
|
147
|
-
options = []
|
148
|
-
# search option in option list.
|
149
|
-
ARGV.each_with_index do |opt,i|
|
150
|
-
r = getopt( opt )
|
151
|
-
options << i if r != '' and r != 'h' and r != 'help'
|
152
|
-
end
|
153
|
-
# handling each option in list.
|
154
|
-
options.each do |oi|
|
155
|
-
# find option in CLIHandler list.
|
156
|
-
@optlist.each do |opt|
|
157
|
-
argval = getopt( ARGV[oi] )
|
158
|
-
# if option has a parameter.
|
159
|
-
if opt.param then
|
160
|
-
# if option-value set in next argument.
|
161
|
-
if argval == opt.longname or
|
162
|
-
argval == opt.shortname then
|
163
|
-
# argument is not set.
|
164
|
-
if oi.next >= ARGV.size then
|
165
|
-
puts "fatal error: unable to find argument for option '#{ARGV[oi]}'."
|
166
|
-
exit
|
167
|
-
end
|
168
|
-
# if next argument option.
|
169
|
-
if getopt( ARGV[oi.next] ) != '' then
|
170
|
-
puts "fatal error: miss argument for option '#{ARGV[oi]}'."
|
171
|
-
exit
|
172
|
-
end
|
173
|
-
opt.value = ARGV[oi.next]
|
174
|
-
options << oi.next
|
175
|
-
next
|
176
|
-
end
|
177
|
-
# if option-value built-in option.
|
178
|
-
oname = opt.shortname
|
179
|
-
oname = opt.longname if ARGV[oi][0, OPTION_PREFIX_LONG.length] == OPTION_PREFIX_LONG
|
180
|
-
if argval[0, oname.length] == oname then
|
181
|
-
opt.value = argval[oname.length, argval.length - oname.length]
|
182
|
-
# delete assign symbols.
|
183
|
-
opt.value = opt.value[1, opt.value.length - 1] if opt.value[0] == '='
|
184
|
-
end
|
185
|
-
# single (toggle) option.
|
186
|
-
else
|
187
|
-
if argval == opt.longname or
|
188
|
-
argval == opt.shortname then
|
189
|
-
opt.value = true
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
# delete option from ARGV.
|
195
|
-
onamelist = []
|
196
|
-
options.each do |oi|
|
197
|
-
onamelist << ARGV[oi]
|
198
|
-
end
|
199
|
-
onamelist.each do |oname|
|
200
|
-
ARGV.delete( oname )
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end # class Handler
|
204
|
-
|
205
|
-
end # module Cmdlib
|