class Incline::CLI

Public Class Methods

new() click to toggle source
# File lib/incline/cli.rb, line 16
def initialize

end
valid_commands() click to toggle source
# File lib/incline/cli.rb, line 71
def self.valid_commands
  command_list.map do |cmd_info|
    [ cmd_info[:method], cmd_info[:klass], cmd_info[:new_params] ]
  end
end

Private Class Methods

command_list() click to toggle source
# File lib/incline/cli.rb, line 79
def self.command_list
  @command_list ||=
      begin
        constants.map do |c|
          klass = const_get c
          # class must have a :new class method (:initialize instance method) and a :run instance method.
          if klass.instance_methods.include?(:run) && klass.methods.include?(:new)
            m = klass.instance_method(:initialize)
            new_params = m.parameters.select{ |p| p[1] && (p[0] == :req || p[0] == :opt || p[0] == :rest) }.freeze
            m = klass.instance_method(:run)
            run_params = m.parameters.select{ |p| p[1] && (p[0] == :req || p[0] == :opt || p[0] == :rest) }.freeze
            if run_params.count == 0
              {
                  name: c.to_s,
                  method: c.to_s.gsub(/(.)([A-Z])/,"\\1_\\2").downcase.to_sym,
                  new_params: new_params,
                  klass: klass,
                  valid: true
              }
            else
              {
                  name: c.to_s,
                  valid: false,
                  failure_reason: 'Method :run expects parameters.'
              }
            end
          else
            {
                name: c,
                valid: false,
                failure_reason: 'Missing :new or :run.'
            }
          end
        end.select do |c|
          c[:valid]
        end
      end
end

Public Instance Methods

execute(*args) click to toggle source
# File lib/incline/cli.rb, line 20
def execute(*args)
  begin
    if args.empty? || %w(help /? -? -help --help).include?(args.first)
      process_command(:usage)
    else
      process_command(*args)
    end
  rescue UsageError => err
    STDERR.puts err.message
    process_command(:usage, err.command)
  rescue CliError => err
    STDERR.puts ANSI.code(:red) { 'ERROR:' }
    STDERR.puts err.message
  rescue RuntimeError => err
    STDERR.puts ANSI.code(:red) { 'FATAL ERROR:' }
    STDERR.puts err.inspect
  end
end
process_command(command, *args) click to toggle source
# File lib/incline/cli.rb, line 39
def process_command(command, *args)
  command = command.to_sym
  cmd_info = self.class.command_list.find{|c| c[:method] == command}
  if cmd_info
    args = args.dup
    command_args = []
    cmd_info[:new_params].each do |(type,name)|
      if type == :rest
        command_args += args
        break
      elsif type == :req
        if args.empty?
          raise UsageError, "Missing required parameter '#{name}' for command '#{command}'."
        end
        command_args << args.delete_at(0)
      elsif type == :opt
        if args.empty?
          break
        else
          command_args << args.delete_at(0)
        end
      else
        raise UsageError, "Unknown parameter type '#{type}' for command '#{command}'."
      end
    end
    cmd_object = cmd_info[:klass].new(*command_args)
    cmd_object.send(:run)
  else
    raise UsageError, "Unknown command '#{command}'."
  end
end