Class: Mercenary::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/mercenary/command.rb

Direct Known Subclasses

Program

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, parent = nil) ⇒ Command

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



23
24
25
26
27
28
29
30
31
32
# File 'lib/mercenary/command.rb', line 23

def initialize(name, parent = nil)
  @name     = name
  @options  = []
  @commands = {}
  @actions  = []
  @map      = {}
  @parent   = parent
  @trace    = false
  @aliases  = []
end

Instance Attribute Details

#actionsObject

Returns the value of attribute actions.



10
11
12
# File 'lib/mercenary/command.rb', line 10

def actions
  @actions
end

#aliasesObject (readonly)

Returns the value of attribute aliases.



14
15
16
# File 'lib/mercenary/command.rb', line 14

def aliases
  @aliases
end

#commandsObject

Returns the value of attribute commands.



9
10
11
# File 'lib/mercenary/command.rb', line 9

def commands
  @commands
end

#description(desc = nil) ⇒ Object (readonly)

Public: Sets or gets the command description

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

Returns the description and sets it if an argument is present



62
63
64
# File 'lib/mercenary/command.rb', line 62

def description
  @description
end

#mapObject (readonly)

Returns the value of attribute map.



11
12
13
# File 'lib/mercenary/command.rb', line 11

def map
  @map
end

#nameObject (readonly)

Returns the value of attribute name.



5
6
7
# File 'lib/mercenary/command.rb', line 5

def name
  @name
end

#optionsObject

Returns the value of attribute options.



8
9
10
# File 'lib/mercenary/command.rb', line 8

def options
  @options
end

#parentObject

Returns the value of attribute parent.



12
13
14
# File 'lib/mercenary/command.rb', line 12

def parent
  @parent
end

#syntax(syntax = nil) ⇒ Object (readonly)

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



49
50
51
# File 'lib/mercenary/command.rb', line 49

def syntax
  @syntax
end

#traceObject (readonly)

Returns the value of attribute trace.



13
14
15
# File 'lib/mercenary/command.rb', line 13

def trace
  @trace
end

Instance Method Details

#action(&block) ⇒ Object

Public: Add an action Proc to be executed at runtime

block - the Proc to be executed at runtime

Returns nothing



127
128
129
# File 'lib/mercenary/command.rb', line 127

def action(&block)
  @actions << block
end

#add_default_options(opts) ⇒ Object

Public: Add version and help options to the command

opts - instance of OptionParser

Returns nothing



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/mercenary/command.rb', line 192

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

#alias(cmd_name) ⇒ Object

Public: Add an alias for this command’s name to be attached to the parent

cmd_name - the name of the alias

Returns nothing



116
117
118
119
120
# File 'lib/mercenary/command.rb', line 116

def alias(cmd_name)
  logger.debug "adding alias to parent for self: '#{cmd_name}'"
  aliases << cmd_name
  @parent.commands[cmd_name] = self
end

#command(cmd_name) {|cmd| ... } ⇒ Object

Public: Adds a subcommand

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

modified (optional)

Returns nothing

Yields:

  • (cmd)


105
106
107
108
109
# File 'lib/mercenary/command.rb', line 105

def command(cmd_name)
  cmd = Command.new(cmd_name, self)
  yield cmd
  @commands[cmd_name] = cmd
end

#default_command(command_name = nil) ⇒ Object

Public: Sets the default command

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

present

Returns the default command if there is one, nil otherwise



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/mercenary/command.rb', line 73

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

#execute(argv = [], config = {}) ⇒ Object

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

Returns nothing



217
218
219
220
221
222
223
# File 'lib/mercenary/command.rb', line 217

def execute(argv = [], config = {})
  if actions.empty? && !default_command.nil?
    default_command.execute
  else
    actions.each { |a| a.call(argv, config) }
  end
end

#full_nameObject

Public: Get the name of the current command plus that of

its parent commands

Returns the full name of the command



253
254
255
256
257
258
# File 'lib/mercenary/command.rb', line 253

def full_name
  the_name = []
  the_name << parent.full_name if parent&.full_name
  the_name << name
  the_name.join(" ")
end

#go(argv, opts, config) ⇒ Object

Public: Run the command

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

Returns the command to be executed



157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/mercenary/command.rb', line 157

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

#has_command?(sub_command) ⇒ Boolean

Public: Check if this command has a subcommand

sub_command - the name of the subcommand

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

Returns:

  • (Boolean)


231
232
233
# File 'lib/mercenary/command.rb', line 231

def has_command?(sub_command)
  commands.key?(sub_command)
end

#identObject

Public: Identify this command

Returns a string which identifies this command



238
239
240
# File 'lib/mercenary/command.rb', line 238

def ident
  "<Command name=#{identity}>"
end

#identityObject

Public: Get the full identity (name & version) of this command

Returns a string containing the name and version if it exists



245
246
247
# File 'lib/mercenary/command.rb', line 245

def identity
  "#{full_name} #{version}".strip
end

#logger(level = nil) ⇒ Object

Public: Fetch a Logger (stdlib)

level - the logger level (a Logger constant, see docs for more info)

Returns the instance of Logger



137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/mercenary/command.rb', line 137

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

#names_and_aliasesObject

Public: Return all the names and aliases for this command.

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



263
264
265
# File 'lib/mercenary/command.rb', line 263

def names_and_aliases
  ([name.to_s] + aliases).compact.join(", ")
end

#option(sym, *options) ⇒ Object

Public: Adds an option switch

sym - the variable key which is used to identify the value of the switch

at runtime in the options hash

Returns nothing



92
93
94
95
96
# File 'lib/mercenary/command.rb', line 92

def option(sym, *options)
  new_option = Option.new(sym, options)
  @options << new_option
  @map[new_option] = sym
end

#process_options(opts, config) ⇒ Object

Public: Add this command’s options to OptionParser and set a default

action of setting the value of the option to the inputted hash

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

Returns nothing



179
180
181
182
183
184
185
# File 'lib/mercenary/command.rb', line 179

def process_options(opts, config)
  options.each do |option|
    opts.on(*option.for_option_parser) do |x|
      config[map[option]] = x
    end
  end
end

#summarizeObject

Public: Build a string containing a summary of the command

Returns a one-line summary of the command.



270
271
272
# File 'lib/mercenary/command.rb', line 270

def summarize
  "  #{names_and_aliases.ljust(20)}  #{description}"
end

#to_sObject

Public: Build a string containing the command name, options and any subcommands

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



277
278
279
# File 'lib/mercenary/command.rb', line 277

def to_s
  Presenter.new(self).print_command
end

#version(version = nil) ⇒ Object

Public: Sets or gets the command version

version - the command version (optional)

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



39
40
41
42
# File 'lib/mercenary/command.rb', line 39

def version(version = nil)
  @version = version if version
  @version
end