Class: Ronin::Core::CLI::CommandShell

Inherits:
Shell
  • Object
show all
Defined in:
lib/ronin/core/cli/command_shell.rb,
lib/ronin/core/cli/command_shell/command.rb

Overview

Base class for all custom command shells.

Example

class HTTPShell < Ronin::Core::CLI::Shell

  shell_name 'http'

  command :get, usage: 'PATH [HEADERS...]',
                summary: 'Sends a GET request'
  def get(path,*headers)
    # ...
  end

  command :post, usage: 'PATH DATA [HEADERS...]',
                 summary: 'Sends a POST request'
  def post(path,data,*headers)
    # ...
  end

end

HTTPShell.start
# http> get /foo

Defined Under Namespace

Classes: Command

Instance Attribute Summary

Attributes inherited from Shell

#prompt_sigil, #shell_name

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Shell

#initialize, #prompt, prompt_sigil, shell_name, start

Constructor Details

This class inherits a constructor from Ronin::Core::CLI::Shell

Class Method Details

.command(name, method_name: name, usage: nil, completions: nil, summary:, help: summary) ⇒ Object

Registers a shell command.

Parameters:

  • name (Symbol)

    The name of the shell command.

  • method_name (Symbol) (defaults to: name)

    Optional method name to use. Defaults to the name argument.

  • usage (String, nil) (defaults to: nil)

    A usage string indicating the shell command's options/arguments.

  • completions (Array<String>, Symbol, nil) (defaults to: nil)

    The possible tab completion values, or a method name, to complete the command's arguments.

  • summary (String)

    A one-line summary of the shell command.

  • help (String) (defaults to: summary)

    Multi-line help output for the shell command.



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ronin/core/cli/command_shell.rb', line 93

def self.command(name, method_name: name,
                       usage: nil,
                       completions: nil,
                       summary: ,
                       help: summary)
  commands[name.to_s] = Command.new(name, method_name: method_name,
                                          usage:       usage,
                                          completions: completions,
                                          summary:     summary,
                                          help:        help.strip)
end

.commandsHash{String => CommandShell::Command}

The registered shell commands.

Returns:



63
64
65
66
67
68
69
# File 'lib/ronin/core/cli/command_shell.rb', line 63

def self.commands
  @commands ||= if superclass <= CommandShell
                  superclass.commands.dup
                else
                  {}
                end
end

.parse_command(line) ⇒ String+

Parses a line of input.

Parameters:

  • line (String)

    A line of input.

Returns:

  • (String, Array<String>)

    The command name and any additional arguments.



114
115
116
# File 'lib/ronin/core/cli/command_shell.rb', line 114

def self.parse_command(line)
  Shellwords.shellsplit(line)
end

Instance Method Details

#call(name, *args) ⇒ Boolean

Invokes the command with the matching name.

Parameters:

  • name (String)

    The command name.

  • args (Array<String>)

    Additional arguments for the command.

Returns:

  • (Boolean)

    Indicates whether the command was successfully executed.

Raises:

  • (NotImplementedError)

    The method for the command was not defined.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/ronin/core/cli/command_shell.rb', line 187

def call(name,*args)
  unless (command = self.class.commands[name])
    return command_missing(name,*args)
  end

  method_name = command.method_name

  unless respond_to?(method_name,false)
    raise(NotImplementedError,"#{self.class}##{method_name} was not defined for the #{name.inspect} command")
  end

  unless method_arity_check(method_name,args)
    return false
  end

  begin
    send(method_name,*args)
  rescue => error
    print_exception(error)
    print_error "an unhandled exception occurred in the #{name} command"
    return false
  end

  return true
end

#command_missing(name, *args) ⇒ Object

Default method that is called when an unknown command is called.

Parameters:

  • name (String)
  • args (Array<String>)


220
221
222
223
# File 'lib/ronin/core/cli/command_shell.rb', line 220

def command_missing(name,*args)
  command_not_found(name)
  return false
end

#command_not_found(name) ⇒ Object

Prints an error message when an unknown command is given.

Parameters:

  • name (String)


230
231
232
# File 'lib/ronin/core/cli/command_shell.rb', line 230

def command_not_found(name)
  print_error "unknown command: #{name}"
end

#complete(word, preposing) ⇒ Array<String>?

The partially input being tab completed.

Parameters:

  • word (String)

    The partial input being tab completed.

  • preposing (String)

    The optional command name that precedes the argument that's being tab completed.

Returns:

  • (Array<String>, nil)

    The possible completion values.

Raises:

  • (NotImplementedError)

    The command defined a completion method name but the command shell does not define the complete method name.



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/ronin/core/cli/command_shell.rb', line 135

def complete(word,preposing)
  if preposing.empty?
    self.class.commands.keys.select { |name| name.start_with?(word) }
  else
    name = preposing.split(/\s+/,2).first

    if (command = self.class.commands[name])
      completions = case command.completions
                    when Array then command.completions
                    when Symbol
                      unless respond_to?(command.completions)
                        raise(NotImplementedError,"#{self.class}##{command.completions} was not defined")
                      end

                      send(command.completions,word,preposing)
                    end

      if completions
        completions.select { |arg| arg.start_with?(word) }
      end
    end
  end
end

#exec(command) ⇒ Boolean

Executes a command.

Parameters:

  • command (String)

    The command to execute.

Returns:

  • (Boolean)

    Indicates whether the command was successfully executed.



168
169
170
# File 'lib/ronin/core/cli/command_shell.rb', line 168

def exec(command)
  call(*self.class.parse_command(command))
end

#help(command = nil) ⇒ Object

Prints all commands or help information for the given command.

Parameters:

  • command (String, nil) (defaults to: nil)

    Optional command name to print help information for.



243
244
245
246
247
# File 'lib/ronin/core/cli/command_shell.rb', line 243

def help(command=nil)
  if command then help_command(command)
  else            help_commands
  end
end