class Mercenary::Command

def action(&block)

Returns nothing

block - the Proc to be executed at runtime

Public: Add an action Proc to be executed at runtime
def action(&block)
  @actions << block
end

def add_default_options(opts)

Returns nothing

opts - instance of OptionParser

Public: Add version and help options to the command
def add_default_options(opts)
  option "show_help", "-h", "--help", "Show this message"
  option "show_version", "-v", "--version", "Print the name and version"
  option "show_backtrace", "-t", "--trace", "Show the full backtrace when an error occurs"
  opts.on("-v", "--version", "Print the version") do
    puts "#{name} #{version}"
    exit(0)
  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

def alias(cmd_name)

Returns nothing

cmd_name - the name of the alias

Public: Add an alias for this command's name to be attached to the parent
def alias(cmd_name)
  logger.debug "adding alias to parent for self: '#{cmd_name}'"
  aliases << cmd_name
  @parent.commands[cmd_name] = self
end

def command(cmd_name)

Returns nothing

modified (optional)
block - a block accepting the new instance of Mercenary::Command to be
cmd_name - the name of the command

Public: Adds a subcommand
def command(cmd_name)
  cmd = Command.new(cmd_name, self)
  yield cmd
  @commands[cmd_name] = cmd
end

def default_command(command_name = nil)

Returns the default command if there is one, `nil` otherwise

present
command_name - the command name to be executed in the event no args are

Public: Sets the default command
def default_command(command_name = nil)
  if command_name
    if commands.key?(command_name)
      @default_command = commands[command_name] if command_name
      @default_command
    else
      raise ArgumentError, "'#{command_name}' couldn't be found in this command's list of commands."
    end
  else
    @default_command
  end
end

def description(desc = nil)

Returns the description and sets it if an argument is present

description - the description of what the command does (optional)

Public: Sets or gets the command description
def description(desc = nil)
  @description = desc if desc
  @description
end

def execute(argv = [], config = {})

Returns nothing

config - (optional) the Hash configuration of string key to value
argv - (optional) command-line args (sans opts)

Public: Execute all actions given the inputted args and options
def execute(argv = [], config = {})
  if actions.empty? && !default_command.nil?
    default_command.execute
  else
    actions.each { |a| a.call(argv, config) }
  end
end

def full_name

Returns the full name of the command

its parent commands
Public: Get the name of the current command plus that of
def full_name
  the_name = []
  the_name << parent.full_name if parent&.full_name
  the_name << name
  the_name.join(" ")
end

def go(argv, opts, config)

Returns the command to be executed

config - the output config hash
opts - the instance of OptionParser
argv - an array of string args

Public: Run the command
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)
  else
    logger.debug "No additional command found, time to exec"
    self
  end
end

def has_command?(sub_command)

'sub_command' and false otherwise
Returns true if this command is the parent of a command of name

sub_command - the name of the subcommand

Public: Check if this command has a subcommand
def has_command?(sub_command)
  commands.key?(sub_command)
end

def ident

Returns a string which identifies this command

Public: Identify this command
def ident
  "<Command name=#{identity}>"
end

def identity

Returns a string containing the name and version if it exists

Public: Get the full identity (name & version) of this command
def identity
  "#{full_name} #{version}".strip
end

def initialize(name, parent = nil)

Returns nothing

be the parent of this command
parent - (optional) the instancce of Mercenary::Command which you wish to
name - the name of the command

Public: Creates a new Command
def initialize(name, parent = nil)
  @name     = name
  @options  = []
  @commands = {}
  @actions  = []
  @map      = {}
  @parent   = parent
  @trace    = false
  @aliases  = []
end

def logger(level = nil)

def logger(level = nil)
  unless @logger
    @logger = Logger.new(STDOUT)
    @logger.level = level || Logger::INFO
    @logger.formatter = proc do |severity, _datetime, _progname, msg|
      "#{identity} | " << "#{severity.downcase.capitalize}:".ljust(7) << " #{msg}\n"
    end
  end
  @logger.level = level unless level.nil?
  @logger
end

def names_and_aliases

Returns a comma-separated String list of the name followed by its aliases

Public: Return all the names and aliases for this command.
def names_and_aliases
  ([name.to_s] + aliases).compact.join(", ")
end

def option(sym, *options)

Returns nothing

at runtime in the options hash
sym - the variable key which is used to identify the value of the switch

Public: Adds an option switch
def option(sym, *options)
  new_option = Option.new(sym, options)
  @options << new_option
  @map[new_option] = sym
end

def process_options(opts, config)

Returns nothing

config - the Hash in which the option values should be placed
opts - instance of OptionParser

action of setting the value of the option to the inputted hash
Public: Add this command's options to OptionParser and set a default
def process_options(opts, config)
  options.each do |option|
    opts.on(*option.for_option_parser) do |x|
      config[map[option]] = x
    end
  end
end

def summarize

Returns a one-line summary of the command.

Public: Build a string containing a summary of the command
def summarize
  "  #{names_and_aliases.ljust(20)}  #{description}"
end

def syntax(syntax = nil)

Returns the syntax string and sets it if an argument is present

syntax - the string which describes this command's usage syntax (optional)

Public: Sets or gets the syntax string
def syntax(syntax = nil)
  @syntax = syntax if syntax
  syntax_list = []
  syntax_list << parent.syntax.to_s.gsub(%r!<[\w\s-]+>!, "").gsub(%r!\[[\w\s-]+\]!, "").strip if parent
  syntax_list << (@syntax || name.to_s)
  syntax_list.join(" ")
end

def to_s

Returns the string identifying this command, its options and its subcommands

Public: Build a string containing the command name, options and any subcommands
def to_s
  Presenter.new(self).print_command
end

def version(version = nil)

Returns the version and sets it if an argument is non-nil

version - the command version (optional)

Public: Sets or gets the command version
def version(version = nil)
  @version = version if version
  @version
end