diff --git a/src/cli/command_parser.rb b/src/cli/command_parser.rb index 7c844738f1..75d297f3f1 100644 --- a/src/cli/command_parser.rb +++ b/src/cli/command_parser.rb @@ -54,25 +54,18 @@ module CommandParser attr_reader :options, :args def initialize(args=[], &block) - @opts = Array.new + @available_options = Array.new @commands = Hash.new @formats = Hash.new - @script = nil + + @main = nil + + @exit_code = nil @args = args @options = Hash.new - set :format, :file, "Path to a file" do |arg| - format_file(arg) - end - - set :format, :range, "List of id's in the form 1,8..15" do |arg| - format_range(arg) - end - - set :format, :text, "String" do |arg| - format_text(arg) - end + define_default_formats instance_eval(&block) @@ -80,11 +73,7 @@ module CommandParser end def usage(str) - @usage=< description, + :proc => block + } + end + + def option(options) + if options.instance_of?(Array) + options.each { |o| @available_options << o } + elsif options.instance_of?(Hash) + @available_options << options end end + # Define the exit code to be returned by the command + # @param [Integer] code + def exit_code(code) + @exit_code = code + end + def exit_with_code(code, output=nil) puts output if output exit code @@ -130,28 +131,40 @@ EOT @commands[name.to_sym] = cmd end - def script(*args_format, &block) - @script=Hash.new - @script[:args_format] = Array.new + def main(*args_format, &block) + @main=Hash.new + @main[:arity] = 0 + @main[:args_format] = Array.new args_format.collect {|args| if args.instance_of?(Array) - @script[:arity]+=1 unless args.include?(nil) - @script[:args_format] << args + @main[:arity]+=1 unless args.include?(nil) + @main[:args_format] << args elsif args.instance_of?(Hash) && args[:options] - @opts << args[:options] + @available_options << args[:options] else - @script[:arity]+=1 - @script[:args_format] << [args] + @main[:arity]+=1 + @main[:args_format] << [args] end } - @script[:proc] = block + @main[:proc] = block end + # DEPRECATED, use format and options instead + def set(e, *args, &block) + case e + when :option + option(args[0]) + when :format + format(args[0], args[1], &block) + end + end + + def run comm_name="" - if @script - comm=@script + if @main + comm=@main elsif if @args[0] && !@args[0].match(/^-/) comm_name=@args.shift.to_sym @@ -160,7 +173,7 @@ EOT end if comm.nil? - help + print_help exit -1 end @@ -175,133 +188,17 @@ EOT puts rc[1] exit rc.first else - exit rc + exit(@exit_code || rc) end end end - def help - puts @usage if @usage - puts - puts @description if @description - puts - print_options - puts - print_commands - puts - print_formatters - puts - if @version - puts "## LICENSE" - puts @version - end - end - private - def print_options - puts "## OPTIONS" - - shown_opts = Array.new - opt_format = "#{' '*5}%-25s %s" - @commands.each{ |key,value| - value[:options].flatten.each { |o| - if shown_opts.include?(o[:name]) - next - else - shown_opts << o[:name] - - str = "" - str << o[:short].split(' ').first << ', ' if o[:short] - str << o[:large] - - printf opt_format, str, o[:description] - puts - end - } - } - - @opts.each{ |o| - str = "" - str << o[:short].split(' ').first << ', ' if o[:short] - str << o[:large] - - printf opt_format, str, o[:description] - puts - } - end - - def print_commands - puts "## COMMANDS" - - cmd_format5 = "#{' '*3}%s" - cmd_format10 = "#{' '*8}%s" - @commands.each{ |key,value| - printf cmd_format5, "* #{key} " - - args_str=value[:args_format].collect{ |a| - if a.include?(nil) - "[<#{a.compact.join("|")}>]" - else - "<#{a.join("|")}>" - end - }.join(' ') - printf "#{args_str}" - puts - - value[:desc].split("\n").each { |l| - printf cmd_format10, l - puts - } - - unless value[:options].empty? - opts_str=value[:options].flatten.collect{|o| - o[:name] - }.join(', ') - printf cmd_format10, "valid options: #{opts_str}" - puts - end - puts - } - end - - def print_formatters - puts "## ARGUMENT FORMATS" - - cmd_format5 = "#{' '*3}%s" - cmd_format10 = "#{' '*8}%s" - @formats.each{ |key,value| - printf cmd_format5, "* #{key}" - puts - - value[:desc].split("\n").each { |l| - printf cmd_format10, l - puts - } - - puts - } - end - - def add_option(option) - if option.instance_of?(Array) - option.each { |o| @opts << o } - elsif option.instance_of?(Hash) - @opts << option - end - end - - def add_format(format, description, block) - @formats[format] = { - :desc => description, - :proc => block - } - end - def parse(extra_options) @cmdparse=OptionParser.new do |opts| - merge = @opts - merge = @opts + extra_options if extra_options + merge = @available_options + merge = @available_options + extra_options if extra_options merge.flatten.each do |e| args = [] args << e[:short] if e[:short] @@ -311,9 +208,16 @@ EOT opts.on(*args) do |o| if e[:proc] - e[:proc].call(o, @options) + rc = e[:proc].call(o, @options) + if rc.instance_of?(Array) && rc[0] == 0 + options[e[:name].to_sym] = rc[1] + else + puts rc[1] + puts "option #{e[:name]}: Parsing error" + exit -1 + end elsif e[:name]=="help" - help + print_help exit elsif e[:name]=="version" puts @version @@ -399,7 +303,126 @@ EOT end ######################################################################## - # Formatters for arguments + # Printers + ######################################################################## + + def print_help + if @usage + puts "## SYNOPSIS" + puts + puts @usage + puts + end + puts @description if @description + puts + print_options + puts + print_commands + puts + print_formatters + puts + if @version + puts "## LICENSE" + puts @version + end + end + + + def print_options + puts "## OPTIONS" + + shown_opts = Array.new + opt_format = "#{' '*5}%-25s %s" + @commands.each{ |key,value| + value[:options].flatten.each { |o| + if shown_opts.include?(o[:name]) + next + else + shown_opts << o[:name] + + str = "" + str << o[:short].split(' ').first << ', ' if o[:short] + str << o[:large] + + printf opt_format, str, o[:description] + puts + end + } + } + + @available_options.each{ |o| + str = "" + str << o[:short].split(' ').first << ', ' if o[:short] + str << o[:large] + + printf opt_format, str, o[:description] + puts + } + end + + def print_commands + cmd_format5 = "#{' '*3}%s" + cmd_format10 = "#{' '*8}%s" + + if @main + print_command(@main) + else + puts "## COMMANDS" + + @commands.each{ |key,value| + printf cmd_format5, "* #{key} " + + print_command(value) + } + end + end + + def print_command(command) + args_str=command[:args_format].collect{ |a| + if a.include?(nil) + "[<#{a.compact.join("|")}>]" + else + "<#{a.join("|")}>" + end + }.join(' ') + printf "#{args_str}" + puts + + command[:desc].split("\n").each { |l| + printf cmd_format10, l + puts + } + + unless command[:options].empty? + opts_str=command[:options].flatten.collect{|o| + o[:name] + }.join(', ') + printf cmd_format10, "valid options: #{opts_str}" + puts + end + puts + end + + def print_formatters + puts "## ARGUMENT FORMATS" + + cmd_format5 = "#{' '*3}%s" + cmd_format10 = "#{' '*8}%s" + @formats.each{ |key,value| + printf cmd_format5, "* #{key}" + puts + + value[:desc].split("\n").each { |l| + printf cmd_format10, l + puts + } + + puts + } + end + + ######################################################################## + # Default Formatters for arguments ######################################################################## def format_text(arg) arg.instance_of?(String) ? [0,arg] : [-1] @@ -432,6 +455,20 @@ EOT return 0,ids.uniq end + + def define_default_formats + format :file, "Path to a file" do |arg| + format_file(arg) + end + + format :range, "List of id's in the form 1,8..15" do |arg| + format_range(arg) + end + + format :text, "String" do |arg| + format_text(arg) + end + end end end diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb index d427c4a8f5..7235f2eb6f 100644 --- a/src/cli/one_helper/onecluster_helper.rb +++ b/src/cli/one_helper/onecluster_helper.rb @@ -25,18 +25,10 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper :description => "Selects the cluster", :format => String, :proc => lambda { |o, options| - ch = OneClusterHelper.new - rc, cid = ch.to_id(o) - if rc == 0 - options[:cluster] = cid - else - puts cid - puts "option cluster: Parsing error" - exit -1 - end + OpenNebulaHelper.rname_to_id(o, "CLUSTER") } } - + def self.rname "CLUSTER" end diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 3ec15e30f7..d8495bfa71 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -24,15 +24,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper :description => "Selects the datastore", :format => String, :proc => lambda { |o, options| - ch = OneDatastoreHelper.new - rc, dsid = ch.to_id(o) - if rc == 0 - options[:datastore] = dsid - else - puts dsid - puts "option datastore: Parsing error" - exit -1 - end + OpenNebulaHelper.rname_to_id(o, "DATASTORE") } } diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb index 7de8e51a32..e6bafadab4 100644 --- a/src/cli/one_helper/onevm_helper.rb +++ b/src/cli/one_helper/onevm_helper.rb @@ -32,14 +32,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper :description => "Selects the image", :format => String, :proc => lambda { |o, options| - rc, imid = OpenNebulaHelper.rname_to_id(o, "IMAGE") - if rc == 0 - options[:image] = imid - else - puts imid - puts "option image: Parsing error" - exit -1 - end + OpenNebulaHelper.rname_to_id(o, "IMAGE") } } @@ -188,13 +181,13 @@ class OneVMHelper < OpenNebulaHelper::OneHelper "USED CPU" => "CPU", "NET_TX" => "NET_TX", "NET_RX" => "NET_RX" - } + } - poll_attrs.each { |k,v| + poll_attrs.each { |k,v| if k == "USED CPU" - puts str % [k,vm[v]] + puts str % [k,vm[v]] elsif k == "USED MEMORY" - puts str % [k, OpenNebulaHelper.unit_to_str(vm[v].to_i, {})] + puts str % [k, OpenNebulaHelper.unit_to_str(vm[v].to_i, {})] else puts str % [k, OpenNebulaHelper.unit_to_str(vm[v].to_i/1024, {})] end