opennebula-cli 3.8.0.beta1
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/bin/oneacct +113 -0
- data/bin/oneacl +97 -0
- data/bin/onecluster +189 -0
- data/bin/onedatastore +165 -0
- data/bin/onegroup +137 -0
- data/bin/onehost +205 -0
- data/bin/oneimage +311 -0
- data/bin/onetemplate +277 -0
- data/bin/oneuser +404 -0
- data/bin/onevm +532 -0
- data/bin/onevnet +227 -0
- data/lib/cli_helper.rb +294 -0
- data/lib/command_parser.rb +719 -0
- data/lib/one_helper/oneacct_helper.rb +179 -0
- data/lib/one_helper/oneacl_helper.rb +130 -0
- data/lib/one_helper/onecluster_helper.rb +129 -0
- data/lib/one_helper/onedatastore_helper.rb +131 -0
- data/lib/one_helper/onegroup_helper.rb +134 -0
- data/lib/one_helper/onehost_helper.rb +196 -0
- data/lib/one_helper/oneimage_helper.rb +327 -0
- data/lib/one_helper/onequota_helper.rb +256 -0
- data/lib/one_helper/onetemplate_helper.rb +123 -0
- data/lib/one_helper/oneuser_helper.rb +242 -0
- data/lib/one_helper/onevm_helper.rb +266 -0
- data/lib/one_helper/onevnet_helper.rb +156 -0
- data/lib/one_helper.rb +609 -0
- metadata +93 -0
@@ -0,0 +1,719 @@
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
2
|
+
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
|
3
|
+
# #
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
|
+
# not use this file except in compliance with the License. You may obtain #
|
6
|
+
# a copy of the License at #
|
7
|
+
# #
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
9
|
+
# #
|
10
|
+
# Unless required by applicable law or agreed to in writing, software #
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
13
|
+
# See the License for the specific language governing permissions and #
|
14
|
+
# limitations under the License. #
|
15
|
+
#--------------------------------------------------------------------------- #
|
16
|
+
|
17
|
+
require 'optparse'
|
18
|
+
require 'pp'
|
19
|
+
|
20
|
+
class String
|
21
|
+
def unindent(spaces=nil)
|
22
|
+
unless spaces
|
23
|
+
m = self.match(/^(\s*)/)
|
24
|
+
spaces = m[1].size
|
25
|
+
end
|
26
|
+
|
27
|
+
self.gsub!(/^ {#{spaces}}/, '')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module CommandParser
|
32
|
+
OPTIONS = [
|
33
|
+
VERBOSE={
|
34
|
+
:name => "verbose",
|
35
|
+
:short => "-v",
|
36
|
+
:large => "--verbose",
|
37
|
+
:description => "Verbose mode"
|
38
|
+
},
|
39
|
+
HELP={
|
40
|
+
:name => "help",
|
41
|
+
:short => "-h",
|
42
|
+
:large => "--help",
|
43
|
+
:description => "Show this message"
|
44
|
+
},
|
45
|
+
VERSION={
|
46
|
+
:name => "version",
|
47
|
+
:short => "-V",
|
48
|
+
:large => "--version",
|
49
|
+
:description => "Show version and copyright information",
|
50
|
+
}
|
51
|
+
]
|
52
|
+
|
53
|
+
class CmdParser
|
54
|
+
attr_reader :options, :args
|
55
|
+
|
56
|
+
def initialize(args=[], &block)
|
57
|
+
@available_options = Array.new
|
58
|
+
@commands = Hash.new
|
59
|
+
@formats = Hash.new
|
60
|
+
|
61
|
+
@main = nil
|
62
|
+
|
63
|
+
@exit_code = nil
|
64
|
+
|
65
|
+
@args = args
|
66
|
+
@options = Hash.new
|
67
|
+
|
68
|
+
define_default_formats
|
69
|
+
|
70
|
+
instance_eval(&block)
|
71
|
+
|
72
|
+
self.run
|
73
|
+
end
|
74
|
+
|
75
|
+
# Defines the usage information of the command
|
76
|
+
# @param [String] str
|
77
|
+
def usage(str)
|
78
|
+
@usage = str
|
79
|
+
@name ||= @usage.split(' ').first
|
80
|
+
end
|
81
|
+
|
82
|
+
# Defines the version the command
|
83
|
+
# @param [String] str
|
84
|
+
def version(str)
|
85
|
+
@version = str
|
86
|
+
end
|
87
|
+
|
88
|
+
# Defines the additional information of the command
|
89
|
+
# @param [String] str
|
90
|
+
def description(str)
|
91
|
+
@description = str
|
92
|
+
end
|
93
|
+
|
94
|
+
# Defines the name of the command
|
95
|
+
# @param [String] str
|
96
|
+
def name(str)
|
97
|
+
@name = str
|
98
|
+
end
|
99
|
+
|
100
|
+
# Defines a block that will be used to parse the arguments
|
101
|
+
# of the command. Formats defined using this method con be used
|
102
|
+
# in the arguments section of the command method, when defining a new
|
103
|
+
# action
|
104
|
+
#
|
105
|
+
# @param [Symbol] format name of the format
|
106
|
+
# @param [String] description
|
107
|
+
#
|
108
|
+
# @yieldreturn [Array[Integer, String]] the block must return an Array
|
109
|
+
# containing the result (0:success, 1:failure) and the
|
110
|
+
# new value for the argument.
|
111
|
+
def format(format, description, &block)
|
112
|
+
@formats[format] = {
|
113
|
+
:desc => description,
|
114
|
+
:proc => block
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
# Defines a global option for the command that will be used for all the
|
119
|
+
# actions
|
120
|
+
# @param [Hash, Array<Hash>] options the option to be included. An
|
121
|
+
# array of options can be also provided
|
122
|
+
# @option options [String] :name
|
123
|
+
# @option options [String] :short
|
124
|
+
# @option options [String] :large
|
125
|
+
# @option options [String] :description
|
126
|
+
# @option options [Class] :format
|
127
|
+
# @option options [Block] :proc The block receives the value of the
|
128
|
+
# option and the hash of options. The block must return an Array
|
129
|
+
# containing the result (0:success, 1:failure) and the
|
130
|
+
# new value for the argument or nil. More than one option can be
|
131
|
+
# specified in the block using the options hash. This hash will be
|
132
|
+
# available inside the command block.
|
133
|
+
#
|
134
|
+
# @example
|
135
|
+
# This example will define the following options:
|
136
|
+
# options[:type] = type
|
137
|
+
#
|
138
|
+
# TYPE={
|
139
|
+
# :name => "type",
|
140
|
+
# :short => "-t type",
|
141
|
+
# :large => "--type type",
|
142
|
+
# :format => String,
|
143
|
+
# :description => "Type of the new Image"
|
144
|
+
# }
|
145
|
+
#
|
146
|
+
# This example will define the following options:
|
147
|
+
# options[:check] = true
|
148
|
+
# options[:datastore] = id
|
149
|
+
#
|
150
|
+
# DATASTORE = {
|
151
|
+
# :name => "datastore",
|
152
|
+
# :short => "-d id|name",
|
153
|
+
# :large => "--datastore id|name" ,
|
154
|
+
# :description => "Selects the datastore",
|
155
|
+
# :format => String,
|
156
|
+
# :proc => lambda { |o, options|
|
157
|
+
# options[:check] = true
|
158
|
+
# [0, OpenNebulaHelper.dname_to_id(o)]
|
159
|
+
# }
|
160
|
+
# }
|
161
|
+
#
|
162
|
+
def option(options)
|
163
|
+
if options.instance_of?(Array)
|
164
|
+
options.each { |o| @available_options << o }
|
165
|
+
elsif options.instance_of?(Hash)
|
166
|
+
@available_options << options
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Defines the exit code to be returned by the command
|
171
|
+
# @param [Integer] code
|
172
|
+
def exit_code(code)
|
173
|
+
@exit_code = code
|
174
|
+
end
|
175
|
+
|
176
|
+
def exit_with_code(code, output=nil)
|
177
|
+
puts output if output
|
178
|
+
exit code
|
179
|
+
end
|
180
|
+
|
181
|
+
# Defines a new action for the command, several actions can be defined
|
182
|
+
# for a command. For example: create, delete, list.
|
183
|
+
# The options and args variables can be used inside the block, and
|
184
|
+
# they contain the parsedarguments and options.
|
185
|
+
#
|
186
|
+
# @param [Symbol] name Name of the action (i.e: :create, :list)
|
187
|
+
# @param [String] desc Description of the action
|
188
|
+
# @param [Array<Symbol, Array<Symbol, nil>>, Hash] args_format arguments
|
189
|
+
# or specific options for this actiion
|
190
|
+
# Note that the first argument of the command is the
|
191
|
+
# action and should not be defined using this parameter. The rest of
|
192
|
+
# the argument must be defined using this parameter.
|
193
|
+
# This parameter can use formats previously defined with the format
|
194
|
+
# method
|
195
|
+
# Options are specified using a hash :options => ... containing
|
196
|
+
# the hashes representing the options. The option method doc contains
|
197
|
+
# the hash that has to be used to specify an option
|
198
|
+
# @yieldreturn [Integer, Array[Integer, String]] the block must
|
199
|
+
# return the exit_code and if a String is returned it will be printed
|
200
|
+
#
|
201
|
+
# @example
|
202
|
+
# Definining two arguments:
|
203
|
+
# $ onetest test a1 a2
|
204
|
+
#
|
205
|
+
# CommandParser::CmdParser.new(ARGV) do
|
206
|
+
# description "Test"
|
207
|
+
# usage "onetest <command> <args> [options]"
|
208
|
+
# version "1.0"
|
209
|
+
#
|
210
|
+
# options VERBOSE, HELP
|
211
|
+
#
|
212
|
+
# command :test, "Test", :test1, :test2, :options => XML do
|
213
|
+
# puts options[:xml]
|
214
|
+
# puts options[:verbose]
|
215
|
+
# puts args[0]
|
216
|
+
# puts args[1]
|
217
|
+
# [0, "It works"]
|
218
|
+
# end
|
219
|
+
# end
|
220
|
+
#
|
221
|
+
#
|
222
|
+
# Defining optional arguments: test1 is mandatory, test2 optional
|
223
|
+
# $ onetest test a1 | $ onetest test a1 a2
|
224
|
+
#
|
225
|
+
# CommandParser::CmdParser.new(ARGV) do
|
226
|
+
# description "Test"
|
227
|
+
# usage "onetest <command> <args> [options]"
|
228
|
+
# version "1.0"
|
229
|
+
#
|
230
|
+
# options VERBOSE, HELP
|
231
|
+
#
|
232
|
+
# command :test, "Test", :test1, [:test2, nil], :options => XML do
|
233
|
+
# puts options[:xml]
|
234
|
+
# puts options[:verbose]
|
235
|
+
# puts args[0]
|
236
|
+
# puts "It works"
|
237
|
+
# 0
|
238
|
+
# end
|
239
|
+
# end
|
240
|
+
#
|
241
|
+
#
|
242
|
+
# Defining an argument with different formats:
|
243
|
+
# $ onetest test a1 a2 | $ onetest test a1 123
|
244
|
+
#
|
245
|
+
# CommandParser::CmdParser.new(ARGV) do
|
246
|
+
# description "Test"
|
247
|
+
# usage "onetest <command> <args> [options]"
|
248
|
+
# version "1.0"
|
249
|
+
#
|
250
|
+
# options VERBOSE, HELP
|
251
|
+
#
|
252
|
+
# format :format1, "String to Integer" do
|
253
|
+
# [0, arg.to_i]
|
254
|
+
# end
|
255
|
+
#
|
256
|
+
# command :test, "Test", :test1, [:format1, format2], :options => XML do
|
257
|
+
# puts options[:xml]
|
258
|
+
# puts options[:verbose]
|
259
|
+
# puts args[0]
|
260
|
+
# 0
|
261
|
+
# end
|
262
|
+
# end
|
263
|
+
#
|
264
|
+
def command(name, desc, *args_format, &block)
|
265
|
+
cmd = Hash.new
|
266
|
+
cmd[:desc] = desc
|
267
|
+
cmd[:arity] = 0
|
268
|
+
cmd[:options] = []
|
269
|
+
cmd[:args_format] = Array.new
|
270
|
+
args_format.each {|args|
|
271
|
+
if args.instance_of?(Array)
|
272
|
+
cmd[:arity]+=1 unless args.include?(nil)
|
273
|
+
cmd[:args_format] << args
|
274
|
+
elsif args.instance_of?(Hash) && args[:options]
|
275
|
+
cmd[:options] << args[:options]
|
276
|
+
else
|
277
|
+
cmd[:arity]+=1
|
278
|
+
cmd[:args_format] << [args]
|
279
|
+
end
|
280
|
+
}
|
281
|
+
cmd[:proc] = block
|
282
|
+
@commands[name.to_sym] = cmd
|
283
|
+
end
|
284
|
+
|
285
|
+
# Defines a new action for the command, several actions can be defined
|
286
|
+
# for a command. For example: create, delete, list.
|
287
|
+
# The options and args variables can be used inside the block, and
|
288
|
+
# they contain the parsedarguments and options.
|
289
|
+
#
|
290
|
+
# @param [Array<Symbol, Array<Symbol, nil>>] args_format arguments
|
291
|
+
# or specific options for this actiion
|
292
|
+
# Note that the first argument of the command is the
|
293
|
+
# action and should not be defined using this parameter. The rest of
|
294
|
+
# the argument must be defined using this parameter.
|
295
|
+
# This parameter can use formats previously defined with the format
|
296
|
+
# method
|
297
|
+
# @yieldreturn [Integer, Array[Integer, String]] the block must
|
298
|
+
# return the exit_code and if a String is returned it will be printed
|
299
|
+
#
|
300
|
+
# @example
|
301
|
+
# Definining two arguments:
|
302
|
+
# $ onetest a1 a2
|
303
|
+
#
|
304
|
+
# CommandParser::CmdParser.new(ARGV) do
|
305
|
+
# description "Test"
|
306
|
+
# usage "onetest <args> [options]"
|
307
|
+
# version "1.0"
|
308
|
+
#
|
309
|
+
# options XML, VERBOSE, HELP
|
310
|
+
#
|
311
|
+
# main :test1, :test2 do
|
312
|
+
# puts options[:xml]
|
313
|
+
# puts options[:verbose]
|
314
|
+
# puts args[0]
|
315
|
+
# puts args[1]
|
316
|
+
# [0, "It works"]
|
317
|
+
# end
|
318
|
+
# end
|
319
|
+
#
|
320
|
+
#
|
321
|
+
# Defining optional arguments: test1 is mandatory, test2 optional
|
322
|
+
# $ onetest a1 | $ onetest a1 a2
|
323
|
+
#
|
324
|
+
# CommandParser::CmdParser.new(ARGV) do
|
325
|
+
# description "Test"
|
326
|
+
# usage "onetest <args> [<options>]"
|
327
|
+
# version "1.0"
|
328
|
+
#
|
329
|
+
# options XML, VERBOSE, HELP
|
330
|
+
#
|
331
|
+
# main :test1, [:test2, nil] do
|
332
|
+
# puts options[:xml]
|
333
|
+
# puts options[:verbose]
|
334
|
+
# puts args[0]
|
335
|
+
# puts "It works"
|
336
|
+
# 0
|
337
|
+
# end
|
338
|
+
# end
|
339
|
+
#
|
340
|
+
#
|
341
|
+
# Defining an argument with different formats:
|
342
|
+
# $ onetest a1 a2 | $ onetest a1 123
|
343
|
+
#
|
344
|
+
# CommandParser::CmdParser.new(ARGV) do
|
345
|
+
# description "Test"
|
346
|
+
# usage "onetest <args> [<options>]"
|
347
|
+
# version "1.0"
|
348
|
+
#
|
349
|
+
# options XML, VERBOSE, HELP
|
350
|
+
#
|
351
|
+
# format :format1, "String to Integer" do
|
352
|
+
# [0, arg.to_i]
|
353
|
+
# end
|
354
|
+
#
|
355
|
+
# main :test1, [:format1, :format2] do
|
356
|
+
# puts options[:xml]
|
357
|
+
# puts options[:verbose]
|
358
|
+
# puts args[0]
|
359
|
+
# puts args[1]
|
360
|
+
# 0
|
361
|
+
# end
|
362
|
+
# end
|
363
|
+
#
|
364
|
+
def main(*args_format, &block)
|
365
|
+
@main=Hash.new
|
366
|
+
@main[:arity] = 0
|
367
|
+
@main[:args_format] = Array.new
|
368
|
+
args_format.collect {|args|
|
369
|
+
if args.instance_of?(Array)
|
370
|
+
@main[:arity]+=1 unless args.include?(nil)
|
371
|
+
@main[:args_format] << args
|
372
|
+
elsif args.instance_of?(Hash) && args[:options]
|
373
|
+
@available_options << args[:options]
|
374
|
+
else
|
375
|
+
@main[:arity]+=1
|
376
|
+
@main[:args_format] << [args]
|
377
|
+
end
|
378
|
+
}
|
379
|
+
|
380
|
+
@main[:proc] = block
|
381
|
+
end
|
382
|
+
|
383
|
+
# DEPRECATED, use format and options instead
|
384
|
+
def set(e, *args, &block)
|
385
|
+
case e
|
386
|
+
when :option
|
387
|
+
option(args[0])
|
388
|
+
when :format
|
389
|
+
format(args[0], args[1], &block)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
|
394
|
+
def run
|
395
|
+
comm_name=""
|
396
|
+
|
397
|
+
if @main
|
398
|
+
comm_name = @name
|
399
|
+
comm = @main
|
400
|
+
elsif
|
401
|
+
if @args[0] && !@args[0].match(/^-/)
|
402
|
+
comm_name = @args.shift.to_sym
|
403
|
+
comm = @commands[comm_name]
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
if comm.nil?
|
408
|
+
print_help
|
409
|
+
exit -1
|
410
|
+
end
|
411
|
+
|
412
|
+
extra_options = comm[:options] if comm
|
413
|
+
parse(extra_options)
|
414
|
+
|
415
|
+
if comm
|
416
|
+
check_args!(comm_name, comm[:arity], comm[:args_format])
|
417
|
+
|
418
|
+
rc = comm[:proc].call
|
419
|
+
if rc.instance_of?(Array)
|
420
|
+
puts rc[1]
|
421
|
+
exit rc.first
|
422
|
+
else
|
423
|
+
exit(@exit_code || rc)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
private
|
429
|
+
|
430
|
+
def parse(extra_options)
|
431
|
+
@cmdparse=OptionParser.new do |opts|
|
432
|
+
merge = @available_options
|
433
|
+
merge = @available_options + extra_options if extra_options
|
434
|
+
merge.flatten.each do |e|
|
435
|
+
args = []
|
436
|
+
args << e[:short] if e[:short]
|
437
|
+
args << e[:large]
|
438
|
+
args << e[:format]
|
439
|
+
args << e[:description]
|
440
|
+
|
441
|
+
opts.on(*args) do |o|
|
442
|
+
if e[:proc]
|
443
|
+
rc = e[:proc].call(o, @options)
|
444
|
+
if rc.instance_of?(Array)
|
445
|
+
if rc[0] == 0
|
446
|
+
options[e[:name].to_sym] = rc[1]
|
447
|
+
else
|
448
|
+
puts rc[1]
|
449
|
+
puts "option #{e[:name]}: Parsing error"
|
450
|
+
exit -1
|
451
|
+
end
|
452
|
+
end
|
453
|
+
elsif e[:name]=="help"
|
454
|
+
print_help
|
455
|
+
exit
|
456
|
+
elsif e[:name]=="version"
|
457
|
+
puts @version
|
458
|
+
exit
|
459
|
+
else
|
460
|
+
@options[e[:name].to_sym]=o
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
begin
|
467
|
+
@cmdparse.parse!(@args)
|
468
|
+
rescue => e
|
469
|
+
puts e.message
|
470
|
+
exit -1
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
def check_args!(name, arity, args_format)
|
475
|
+
if @args.length < arity
|
476
|
+
print "Command #{name} requires "
|
477
|
+
if arity>1
|
478
|
+
puts "#{args_format.length} parameters to run."
|
479
|
+
else
|
480
|
+
puts "one parameter to run"
|
481
|
+
end
|
482
|
+
puts
|
483
|
+
puts "Usage:"
|
484
|
+
|
485
|
+
if @main
|
486
|
+
print " #{@usage}\n"
|
487
|
+
else
|
488
|
+
print " #{name} "
|
489
|
+
print_command(@commands[name])
|
490
|
+
end
|
491
|
+
exit -1
|
492
|
+
else
|
493
|
+
id=0
|
494
|
+
@args.collect!{|arg|
|
495
|
+
unless format=args_format[id]
|
496
|
+
args_str=args_format.collect{ |a|
|
497
|
+
if a.include?(nil)
|
498
|
+
"[#{a.compact.join("|")}]"
|
499
|
+
else
|
500
|
+
"<#{a.join("|")}>"
|
501
|
+
end
|
502
|
+
}.join(' ')
|
503
|
+
|
504
|
+
puts "Wrong number of arguments"
|
505
|
+
if args_str.empty?
|
506
|
+
puts "No argument is required"
|
507
|
+
else
|
508
|
+
puts "The arguments should be: #{args_str}"
|
509
|
+
end
|
510
|
+
exit -1
|
511
|
+
end
|
512
|
+
|
513
|
+
format = args_format[id]
|
514
|
+
argument = nil
|
515
|
+
error_msg = nil
|
516
|
+
format.each { |f|
|
517
|
+
if @formats[f]
|
518
|
+
format_hash = @formats[f]
|
519
|
+
elsif f.nil?
|
520
|
+
argument = nil
|
521
|
+
break
|
522
|
+
else
|
523
|
+
format_hash = @formats[:text]
|
524
|
+
end
|
525
|
+
|
526
|
+
rc = format_hash[:proc].call(arg)
|
527
|
+
if rc[0]==0
|
528
|
+
argument=rc[1]
|
529
|
+
break
|
530
|
+
else
|
531
|
+
error_msg=rc[1]
|
532
|
+
next
|
533
|
+
end
|
534
|
+
}
|
535
|
+
|
536
|
+
unless argument
|
537
|
+
puts error_msg if error_msg
|
538
|
+
puts "command #{name}: argument #{id} must be one of #{format.join(', ')}"
|
539
|
+
exit -1
|
540
|
+
end
|
541
|
+
|
542
|
+
id+=1
|
543
|
+
argument
|
544
|
+
}
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
########################################################################
|
549
|
+
# Printers
|
550
|
+
########################################################################
|
551
|
+
|
552
|
+
def print_help
|
553
|
+
if @usage
|
554
|
+
puts "## SYNOPSIS"
|
555
|
+
puts
|
556
|
+
puts @usage
|
557
|
+
puts
|
558
|
+
end
|
559
|
+
puts @description if @description
|
560
|
+
puts
|
561
|
+
print_options
|
562
|
+
puts
|
563
|
+
print_commands
|
564
|
+
puts
|
565
|
+
print_formatters
|
566
|
+
puts
|
567
|
+
if @version
|
568
|
+
puts "## LICENSE"
|
569
|
+
puts @version
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
|
574
|
+
def print_options
|
575
|
+
puts "## OPTIONS"
|
576
|
+
|
577
|
+
shown_opts = Array.new
|
578
|
+
opt_format = "#{' '*5}%-25s %s"
|
579
|
+
@commands.each{ |key,value|
|
580
|
+
value[:options].flatten.each { |o|
|
581
|
+
if shown_opts.include?(o[:name])
|
582
|
+
next
|
583
|
+
else
|
584
|
+
shown_opts << o[:name]
|
585
|
+
|
586
|
+
str = ""
|
587
|
+
str << o[:short].split(' ').first << ', ' if o[:short]
|
588
|
+
str << o[:large]
|
589
|
+
|
590
|
+
printf opt_format, str, o[:description]
|
591
|
+
puts
|
592
|
+
end
|
593
|
+
}
|
594
|
+
}
|
595
|
+
|
596
|
+
@available_options.each{ |o|
|
597
|
+
str = ""
|
598
|
+
str << o[:short].split(' ').first << ', ' if o[:short]
|
599
|
+
str << o[:large]
|
600
|
+
|
601
|
+
printf opt_format, str, o[:description]
|
602
|
+
puts
|
603
|
+
}
|
604
|
+
end
|
605
|
+
|
606
|
+
def print_commands
|
607
|
+
cmd_format5 = "#{' '*3}%s"
|
608
|
+
|
609
|
+
if @main
|
610
|
+
print_command(@main)
|
611
|
+
else
|
612
|
+
puts "## COMMANDS"
|
613
|
+
|
614
|
+
@commands.each{ |key,value|
|
615
|
+
printf cmd_format5, "* #{key} "
|
616
|
+
|
617
|
+
print_command(value)
|
618
|
+
}
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
def print_command(command)
|
623
|
+
cmd_format10 = "#{' '*8}%s"
|
624
|
+
|
625
|
+
args_str=command[:args_format].collect{ |a|
|
626
|
+
if a.include?(nil)
|
627
|
+
"[<#{a.compact.join("|")}>]"
|
628
|
+
else
|
629
|
+
"<#{a.join("|")}>"
|
630
|
+
end
|
631
|
+
}.join(' ')
|
632
|
+
printf "#{args_str}"
|
633
|
+
puts
|
634
|
+
|
635
|
+
command[:desc].split("\n").each { |l|
|
636
|
+
printf cmd_format10, l
|
637
|
+
puts
|
638
|
+
} if command[:desc]
|
639
|
+
|
640
|
+
if command[:options] && !command[:options].empty?
|
641
|
+
opts_str=command[:options].flatten.collect{|o|
|
642
|
+
o[:name]
|
643
|
+
}.join(', ')
|
644
|
+
printf cmd_format10, "valid options: #{opts_str}"
|
645
|
+
puts
|
646
|
+
end
|
647
|
+
puts
|
648
|
+
end
|
649
|
+
|
650
|
+
def print_formatters
|
651
|
+
puts "## ARGUMENT FORMATS"
|
652
|
+
|
653
|
+
cmd_format5 = "#{' '*3}%s"
|
654
|
+
cmd_format10 = "#{' '*8}%s"
|
655
|
+
@formats.each{ |key,value|
|
656
|
+
printf cmd_format5, "* #{key}"
|
657
|
+
puts
|
658
|
+
|
659
|
+
value[:desc].split("\n").each { |l|
|
660
|
+
printf cmd_format10, l
|
661
|
+
puts
|
662
|
+
}
|
663
|
+
|
664
|
+
puts
|
665
|
+
}
|
666
|
+
end
|
667
|
+
|
668
|
+
########################################################################
|
669
|
+
# Default Formatters for arguments
|
670
|
+
########################################################################
|
671
|
+
def format_text(arg)
|
672
|
+
arg.instance_of?(String) ? [0,arg] : [-1]
|
673
|
+
end
|
674
|
+
|
675
|
+
def format_int(arg)
|
676
|
+
arg.match(/^\d+$/) ? [0,arg] : [-1]
|
677
|
+
end
|
678
|
+
|
679
|
+
def format_file(arg)
|
680
|
+
File.file?(arg) ? [0,arg] : [-1]
|
681
|
+
end
|
682
|
+
|
683
|
+
REG_RANGE=/^(?:(?:\d+\.\.\d+|\d+),)*(?:\d+\.\.\d+|\d+)$/
|
684
|
+
|
685
|
+
def format_range(arg)
|
686
|
+
arg_s = arg.gsub(" ","").to_s
|
687
|
+
return [-1] unless arg_s.match(REG_RANGE)
|
688
|
+
|
689
|
+
ids = Array.new
|
690
|
+
arg_s.split(',').each { |e|
|
691
|
+
if e.match(/^\d+$/)
|
692
|
+
ids << e.to_i
|
693
|
+
elsif m = e.match(/^(\d+)\.\.(\d+)$/)
|
694
|
+
ids += (m[1].to_i..m[2].to_i).to_a
|
695
|
+
else
|
696
|
+
return [-1]
|
697
|
+
end
|
698
|
+
}
|
699
|
+
|
700
|
+
return 0,ids.uniq
|
701
|
+
end
|
702
|
+
|
703
|
+
def define_default_formats
|
704
|
+
format :file, "Path to a file" do |arg|
|
705
|
+
format_file(arg)
|
706
|
+
end
|
707
|
+
|
708
|
+
format :range, "List of id's in the form 1,8..15" do |arg|
|
709
|
+
format_range(arg)
|
710
|
+
end
|
711
|
+
|
712
|
+
format :text, "String" do |arg|
|
713
|
+
format_text(arg)
|
714
|
+
end
|
715
|
+
end
|
716
|
+
end
|
717
|
+
end
|
718
|
+
|
719
|
+
|