lib/mercenary/command.rb in mercenary-0.2.1 vs lib/mercenary/command.rb in mercenary-0.3.0

- old
+ new

@@ -6,35 +6,52 @@ attr_accessor :options attr_accessor :commands attr_accessor :actions attr_reader :map attr_accessor :parent + attr_reader :trace # Public: Creates a new Command # # name - the name of the command # parent - (optional) the instancce of Mercenary::Command which you wish to # be the parent of this command # # Returns nothing def initialize(name, parent = nil) - @name = name - @options = [] - @commands = {} - @actions = [] - @map = {} - @parent = parent + @name = name + @options = [] + @commands = {} + @actions = [] + @map = {} + @parent = parent + @trace = false end + # Public: Sets or gets the command version + # + # version - the command version (optional) + # + # Returns the version and sets it if an argument is non-nil + def version(version = nil) + @version = version if version + @version + end + # Public: Sets or gets the syntax string # # syntax - the string which describes this command's usage syntax (optional) # # Returns the syntax string and sets it if an argument is present def syntax(syntax = nil) @syntax = syntax if syntax - @syntax + syntax_list = [] + if parent + syntax_list << parent.syntax.to_s.gsub(/<[\w\s-]+>/, '').gsub(/\[[\w\s-]+\]/, '').strip + end + syntax_list << (@syntax || name.to_s) + syntax_list.join(" ") end # Public: Sets or gets the command description # # description - the description of what the command does (optional) @@ -69,12 +86,13 @@ # sym - the variable key which is used to identify the value of the switch # at runtime in the options hash # # Returns nothing def option(sym, *options) - @options << options - @map[options[0]] = sym + new_option = Option.new(sym, options) + @options << new_option + @map[new_option.hash] = sym end # Public: Adds a subcommand # # cmd_name - the name of the command @@ -110,19 +128,20 @@ # Public: Fetch a Logger (stdlib) # # level - the logger level (a Logger constant, see docs for more info) # # Returns the instance of Logger - def logger(level = Logger::INFO) + def logger(level = nil) unless @logger @logger = Logger.new(STDOUT) + @logger.level = level || Logger::INFO @logger.formatter = proc do |severity, datetime, progname, msg| - "#{ident} (#{severity}): #{msg}\n" + "#{identity} | " << "#{severity.downcase.capitalize}:".ljust(7) << " #{msg}\n" end end - @logger.level = level + @logger.level = level unless level.nil? @logger end # Public: Run the command # @@ -132,10 +151,11 @@ # # Returns the command to be executed def go(argv, opts, config) opts.banner = "Usage: #{syntax}" process_options(opts, config) + add_default_options(opts) if argv[0] && cmd = commands[argv[0].to_sym] logger.debug "Found subcommand '#{cmd.name}'" argv.shift cmd.go(argv, opts, config) @@ -151,17 +171,40 @@ # opts - instance of OptionParser # config - the Hash in which the option values should be placed # # Returns nothing def process_options(opts, config) - options.each do |o| - opts.on(*o) do |x| - config[map[o[0]]] = x + options.each do |option| + opts.on(*option.for_option_parser) do |x| + config[map[option.hash]] = x end end end + # Public: Add version and help options to the command + # + # opts - instance of OptionParser + # + # Returns nothing + def add_default_options(opts) + option 'show_help', '-h', '--help', 'Show this message' + option 'show_version', '-v', '--version', 'Print the name and version' + opts.on("-v", "--version", "Print the version") do + puts "#{name} #{version}" + abort + end + + opts.on('-t', '--trace', 'Show full backtrace if an error occurs') do + @trace = true + end + + opts.on_tail("-h", "--help", "Show this message") do + puts self + exit + end + end + # Public: Execute all actions given the inputted args and options # # argv - (optional) command-line args (sans opts) # config - (optional) the Hash configuration of string key to value # @@ -186,21 +229,41 @@ # Public: Identify this command # # Returns a string which identifies this command def ident - "<Command name=#{name}>" + "<Command name=#{identity}>" end + # Public: Get the full identity (name & version) of this command + # + # Returns a string containing the name and version if it exists + def identity + "#{full_name} #{version if version}".strip + end + + # Public: Get the name of the current command plus that of + # its parent commands + # + # Returns the full name of the command + def full_name + the_name = [] + the_name << parent.full_name if parent && parent.full_name + the_name << name + the_name.join(" ") + end + + # Public: Build a string containing a summary of the command + # + # Returns a one-line summary of the command. + def summarize + " #{name.to_s.ljust(20)} #{description}" + end + # Public: Build a string containing the command name, options and any subcommands # # Returns the string identifying this command, its options and its subcommands def to_s - msg = '' - msg += "Command: #{name}\n" - options.each { |o| msg += " " + o.inspect + "\n"} - msg += "\n" - commands.each { |k, v| msg += commands[k].inspect } - msg + Presenter.new(self).print_command end end end