Module: Rubycom

Defined in:
lib/rubycom.rb,
lib/rubycom/helpers.rb,
lib/rubycom/sources.rb,
lib/rubycom/version.rb,
lib/rubycom/executor.rb,
lib/rubycom/yard_doc.rb,
lib/rubycom/arg_parse.rb,
lib/rubycom/completions.rb,
lib/rubycom/error_handler.rb,
lib/rubycom/output_handler.rb,
lib/rubycom/command_interface.rb,
lib/rubycom/parameter_extract.rb,
lib/rubycom/singleton_commands.rb

Overview

Upon inclusion in another Module, Rubycom will attempt to call a method in the including module by parsing ARGV for a method name and a list of arguments. If found Rubycom will call the method specified in ARGV with the parameters parsed from the remaining arguments If a Method match can not be made, Rubycom will print help instead by parsing code comments from the including module.

Defined Under Namespace

Modules: ArgParse, CommandInterface, Completions, ErrorHandler, Executor, Helpers, OutputHandler, ParameterExtract, SingletonCommands, Sources, YardDoc Classes: ArgParseError, ExecutorError, ParameterExtractError, RubycomError

Constant Summary collapse

VERSION =
"0.4.0"

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object

Detects that Rubycom was included in another module and calls Rubycom#run

Parameters:

  • base (Module)

    the module which invoked ‘include Rubycom’



50
51
52
53
54
55
56
57
58
# File 'lib/rubycom.rb', line 50

def self.included(base)
  base_file_path = caller.first.gsub(/:\d+:.+/, '')
  if base.class == Module && (base_file_path == $0 || self.is_executed_by_gem?(base_file_path))
    base.module_eval {
      Rubycom.run(base, ARGV)
    }
  end
  nil
end

.is_executed_by_gem?(base_file_path) ⇒ Boolean

Determines whether the including module was executed by a gem binary

Parameters:

  • base_file_path (String)

    the path to the including module’s source file

Returns:

  • (Boolean)

    true|false



39
40
41
42
43
44
45
# File 'lib/rubycom.rb', line 39

def self.is_executed_by_gem?(base_file_path)
  Gem.loaded_specs.map { |k, s|
    {k => {name: "#{s.name}-#{s.version}", executables: s.executables}}
  }.reduce({}, &:merge).map { |_, s|
    base_file_path.include?(s[:name]) && s[:executables].include?(File.basename(base_file_path))
  }.flatten.reduce(&:|)
end

.process(base, args = [], steps = {}) ⇒ Object

Calls the given steps with the required parameters and ordering to locate and call a method on base or one of it’s included modules. This method expresses a procedure and calls the methods in steps to execute each step in the procedure. If not overridden in steps, then method called for each step will be determined by the return from #step_methods.

:arguments, :discover, :documentation, :source, :parameters, :executor, :output, :interface, :error matched to parameters by the :parameters method

Parameters:

  • base (Module)

    the Module containing the Method or sub Module to run

  • args (Array) (defaults to: [])

    a String Array representing the command to run followed by arguments to be passed

  • steps (Hash) (defaults to: {})

    should have the following keys mapped to Methods or Procs which will be called by the process method

Returns:

  • (Object)

    the result of calling the method selected by the :discover method using the args from the :arguments method



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rubycom.rb', line 121

def self.process(base, args=[], steps={})
  steps = self.step_methods.merge(steps)

  parsed_command_line = steps[:arguments].call(args)
  command = steps[:discover].call(base, parsed_command_line)
  begin
    command_doc = steps[:documentation].call(command, steps[:source])
    parameters = steps[:parameters].call(command, parsed_command_line, command_doc)
    command_result = steps[:executor].call(command, parameters)
    steps[:output].call(command_result)
  rescue RubycomError => e
    cli_output = steps[:interface].call(command, command_doc)
    steps[:error].call(e, cli_output)
  end
  command_result
end

.run(base, args = []) ⇒ Object

Main entry point for Rubycom. Uses #run_command to discover and run commands

Parameters:

  • base (Module)

    this will be used to determine available commands

  • args (Array) (defaults to: [])

    a String Array representing the command to run followed by arguments to be passed

Returns:

  • (Object)

    the result of calling #run_command! or a String representing a default help message



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rubycom.rb', line 65

def self.run(base, args=[])
  begin
    raise RubycomError, "base should should not be nil" if base.nil?
    case args[0]
      when 'register_completions'
        puts Rubycom::Completions.register_completions(base)
      when 'tab_complete'
        puts Rubycom::Completions.tab_complete(base, args, Rubycom::SingletonCommands)
      when 'help'
        help_topic = args[1]
        if help_topic == 'register_completions'
          puts "Usage: #{base} register_completions"
        elsif help_topic == 'tab_complete'
          usage = "Usage: #{base} tab_complete <word>\nParameters:\n  [String] word the word or partial word to find matches for"
          puts usage
          return usage
        else
          self.run_command(base, (args[1..-1] << '-h'))
          $stderr.puts "          Default Commands:\n            help                 - prints this help page\n            register_completions - setup bash tab completion\n            tab_complete         - print a list of possible matches for a given word\n          END\n        end\n      else\n        self.run_command(base, args)\n    end\n  rescue RubycomError => e\n    $stderr.puts e\n  end\nend\n".gsub(/^ {12}/, '')

.run_command(base, args = [], steps = {}, process = Rubycom.public_method(:process)) ⇒ Object

Calls the given process method with the given base, args, and steps.

:arguments, :discover, :documentation, :source, :parameters, :executor, :output, :interface, :error matched to parameters by the :parameters method

Parameters:

  • base (Module)

    the Module containing the Method or sub Module to run

  • args (Array) (defaults to: [])

    a String Array representing the command to run followed by arguments to be passed

  • steps (Hash) (defaults to: {})

    should have the following keys mapped to Methods or Procs which will be called by the process method

  • process (Method|Proc) (defaults to: Rubycom.public_method(:process))

    a Method or Proc which calls the step_methods in order to parse args and run a command on base

Returns:

  • (Object)

    the result of calling the method selected by the :discover method using the args from the :arguments method



107
108
109
# File 'lib/rubycom.rb', line 107

def self.run_command(base, args=[], steps={}, process=Rubycom.public_method(:process))
  process.call(base, args, steps)
end

.step_methodsHash

Convenience call for use with #process when the default Rubycom functionality is required.

to the default methods which carry out the step referred to by the key.

Returns:

  • (Hash)

    mapping :arguments, :discover, :documentation, :source, :parameters, :executor, :output, :interface, :error



142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/rubycom.rb', line 142

def self.step_methods()
  {
      arguments: Rubycom::ArgParse.public_method(:parse_command_line),
      discover: Rubycom::SingletonCommands.public_method(:discover_command),
      documentation: Rubycom::YardDoc.public_method(:document_command),
      source: Rubycom::Sources.public_method(:source_command),
      parameters: Rubycom::ParameterExtract.public_method(:extract_parameters),
      executor: Rubycom::Executor.public_method(:execute_command),
      output: Rubycom::OutputHandler.public_method(:process_output),
      interface: Rubycom::CommandInterface.public_method(:build_interface),
      error: Rubycom::ErrorHandler.public_method(:handle_error)
  }
end