class Benry::CLI::Application
Attributes
desc[R]
script_name[R]
version[R]
Public Class Methods
new(desc=nil, version: '0.0', script_name: nil, action_classes: nil)
click to toggle source
# File lib/benry/cli.rb, line 406 def initialize(desc=nil, version: '0.0', script_name: nil, action_classes: nil) @desc = desc @version = version @script_name = script_name || File.basename($0) @action_dict = accept(action_classes || Action::SUBCLASSES) end
Public Instance Methods
help_message(command, action_name=nil)
click to toggle source
# File lib/benry/cli.rb, line 542 def help_message(command, action_name=nil) if action_name action_info = @action_dict[action_name] or raise err("#{action_name}: no such action.") return action_info.help_message(command) end # msg = "" #; [!1zpv4] adds command desc if it is specified at initializer. if @desc #msg << "#{command} -- #{@desc}\n" #msg << "\n" msg << @desc << "\n\n" end msg << "Usage:\n" msg << " #{command} [<options>] <action> [<args>...]\n" msg << "\n" msg << "Options:\n" self.class.instance_variable_get('@_global_option_schemas').each do |schema| msg << " %-20s : %s\n" % [schema.option_string, schema.desc] end msg << "\n" msg << "Actions:\n" #msg << " %-20s : %s\n" % ["help", "show this help"] @action_dict.keys.sort.each do |action_full_name| action_info = @action_dict[action_full_name] #; [!m3mry] skips action name when description is not provided. msg << " %-20s : %s\n" % [action_full_name, action_info.desc] if action_info.desc end msg << "\n" msg << "(Run `#{command} help <action>' to show help message of each action.)\n" return msg end
main(argv=ARGV)
click to toggle source
# File lib/benry/cli.rb, line 469 def main(argv=ARGV) begin ret = run(*argv) rescue OptionError => ex $stderr.puts "ERROR: #{ex}" exit 1 else case ret when String output = ret puts output exit 0 when Integer status = ret exit status else exit 0 end end end
run(*args)
click to toggle source
# File lib/benry/cli.rb, line 438 def run(*args) ## global options gopt_values = parse_global_options(args) output = handle_global_options(args, gopt_values) return output if output ## global help #; [!p5pr6] returns global help message when action is 'help'. #; [!3hyvi] returns help message of action when action is 'help' with action name. action_full_name = args.shift || "help" if action_full_name == "help" return help_message(self.script_name, args[0]) end ## action and options #; [!mb92l] raises error when action name is unknown. action_info = @action_dict[action_full_name] or raise err("#{action_full_name}: unknown action.") option_values = parse_options(args, action_info.option_schemas) ## show help #; [!13m3q] returns help message if '-h' or '--help' specified to action. if option_values['help'] return action_info.help_message(self.script_name) end ## validation obj = action_info.action_class.new() method_name = action_info.action_method validate_args(obj, method_name, args, action_full_name) ## do action ret = kick_action(obj, method_name, args, option_values) return ret end
Protected Instance Methods
handle_global_options(args, global_option_values)
click to toggle source
# File lib/benry/cli.rb, line 498 def handle_global_options(args, global_option_values) g_opts = global_option_values #; [!b8isy] returns help message when global option '-h' or '--help' is specified. if g_opts['help'] return help_message(self.script_name, nil) end #; [!4irzw] returns version string when global option '--version' is specified. if g_opts['version'] return @version || '0.0' end end
kick_action(action_obj, method_name, args, option_values)
click to toggle source
# File lib/benry/cli.rb, line 527 def kick_action(action_obj, method_name, args, option_values) #; [!rph9y] converts 'foo-bar' option name into :foo_bar keyword. kwargs = Hash[option_values.map {|k, v| [k.gsub(/-/, '_').intern, v] }] #; [!qwd9x] passes command arguments and options as method arguments and options. method_obj = action_obj.method(method_name) has_kwargs = method_obj.parameters.any? {|x| x[0] == :key } if has_kwargs return method_obj.call(*args, kwargs) else return method_obj.call(*args) end end
parse_global_options(args)
click to toggle source
# File lib/benry/cli.rb, line 492 def parse_global_options(args) gopt_schemas = self.class.instance_variable_get('@_global_option_schemas') gopt_values = parse_options(args, gopt_schemas) return gopt_values end
validate_args(action_obj, method_name, args, action_full_name)
click to toggle source
# File lib/benry/cli.rb, line 510 def validate_args(action_obj, method_name, args, action_full_name) #; [!yhry7] raises error when required argument is missing. meth = action_obj.method(method_name) n_min = meth.parameters.count {|x| x[0] == :req } args.length >= n_min or raise err("too few arguments (at least #{n_min} args expected).\n" +\ "(run `#{@script_name} help #{action_full_name}' for details.)") #; [!h5522] raises error when too much arguments specified. #; [!hq8b0] not raise error when many argument specified but method has *args. unless meth.parameters.find {|x| x[0] == :rest } n_max = meth.parameters.count {|x| x[0] == :req || x[0] == :opt } args.length <= n_max or raise err("too many arguments (at most #{n_max} args expected).\n" +\ "(run `#{@script_name} help #{action_full_name}' for details.)") end end
Private Instance Methods
accept(action_classes)
click to toggle source
# File lib/benry/cli.rb, line 417 def accept(action_classes) #; [!ue26k] builds action dictionary. action_dict = {} action_classes.each do |klass| prefix = klass.instance_variable_get('@prefix') (klass.instance_variable_get('@__mappings') || []).each do |tuple| action_name, desc, option_schemas, method_name = tuple action_name ||= method_name full_name = prefix ? "#{prefix}:#{action_name}" : action_name.to_s #; [!x6rh1] registers action name replacing '_' with '-'. full_name = full_name.gsub('_', '-') # action_dict[full_name] = ActionInfo.new(full_name, action_name, desc, option_schemas, klass, method_name) end end return action_dict end
err(msg)
click to toggle source
# File lib/benry/cli.rb, line 582 def err(msg) return OptionError.new(msg) end
parse_options(args, option_schemas)
click to toggle source
# File lib/benry/cli.rb, line 578 def parse_options(args, option_schemas) return OptionParser.new(option_schemas).parse(args) end