class CommandLion::App

Public Class Methods

default_help(app) click to toggle source
# File lib/command_lion/app.rb, line 5
def self.default_help(app)
  flagz = []
  app.commands.each do |_, cmd|
    if cmd.options?
      cmd.options.each do |_, opt| 
        if opt.flags?
          if opt.flags.long?
            flagz << opt.flags.short + opt.flags.long
          else  
            flagz << opt.flags.short
          end  
        elsif opt.index?
          flagz << opt.index.to_s if opt.index?
        end
      end
    end
    if cmd.flags?
      if cmd.flags.long?
        flagz << cmd.flags.short + cmd.flags.long
      else  
        flagz << cmd.flags.short
      end  
    elsif cmd.index?
      flagz << cmd.index.to_s if cmd.index?
    else
      raise "No flags or index was given!"
    end
  end 
  max_flag = flagz.map(&:length).max + 4
  max_desc = app.commands.values.map(&:description).select{|d| d unless d.nil? }.map(&:length).max
  puts app.name
  if app.version?
    puts
    puts "VERSION"
    puts app.version
    puts unless app.description?
  end
  if app.description?
    puts 
    puts "DESCRIPTION"
    puts app.description
    puts
  end
  if app.usage?
    puts
    puts "USAGE"
    puts usage
    puts
  end
  puts unless app.version? || app.description? || app.usage?
  puts "COMMANDS"
  app.commands.values.select { |cmd| cmd unless cmd.is_a? CommandLion::Option }.each do |command|
    if command.flags?
      short = command.flags.long? ? command.flags.short + ", " : command.flags.short
      short_long = "#{short}#{command.flags.long}".ljust(max_flag)
    else
      short_long = "#{command.index.to_s}".ljust(max_flag)
    end
    puts "#{short_long}  #{command.description}"
    if command.options?
      command.options.each do |_, option|
        if option.flags?
          short = option.flags.long? ? option.flags.short + ", " : option.flags.short
          short_long = "  " + "#{short}#{option.flags.long}".ljust(max_flag - 2)
        else
          short_long = "  " + "#{option.index.to_s}".ljust(max_flag - 2)
        end
        puts "#{short_long}  #{option.description}"
      end
    end
    puts
  end
end
run(&block) click to toggle source

The run method will run a given block of code using the Commmand Lion DSL.

# File lib/command_lion/app.rb, line 82
def self.run(&block)
  # Initialize an instance of an App object.
  app = new
  # Evaluate the block of code within the context of that App object.
  app.instance_eval(&block)
  # Parse the application logic out.
  app.parse
  # Sometimes a command-line application is run without being given any arguments.
  if ARGV.empty?
    # Default to a help menu.
    if cmd = app.commands[:help]
      cmd.before.call if cmd.before?
      cmd.action.call if cmd.action?
      cmd.after.call  if cmd.after?
      exit 0
    else
      # Use the default help menu for the application unless that's been
      # explictly removed by the author for whatever reason.
      default_help(app) unless app.default_help_menu_removed?
    end
  else
    app.commands.each do |_, cmd|
      next unless cmd.given?
      cmd.options.each do |_, opt|
        next unless opt.given?
        opt.before.call if opt.before?
        opt.action.call if opt.action?
        opt.after.call  if opt.after?
      end if cmd.options?
      cmd.before.call if cmd.before?
      cmd.action.call if cmd.action?
      cmd.after.call  if cmd.after?
    end
  end
end

Public Instance Methods

command(index, &block) click to toggle source

An application usually has multiple commands.

Example

app = CommandLion::App.build
  # meta information

  command :example1 do
    # more code
  end

  command :example2 do
    # more code
  end
end

app.commands.map(&:name)
# => [:example1, :example2]
# File lib/command_lion/app.rb, line 160
def command(index, &block)
  if index.is_a? Command
    cmd = index
  else
    cmd = Command.new
    cmd.index= index
    cmd.instance_eval(&block)
  end
  @commands = {} unless @commands
  @flags = [] unless @flags
  if cmd.flags?
    @flags << cmd.flags.short if cmd.flags.short?
    @flags << cmd.flags.long  if cmd.flags.long?
  elsif cmd.index # just use index
    @flags << cmd.index.to_s
  else
    raise "No index or flags were given to use this command."
  end
  if cmd.options?
    cmd.options.each do |_, option|
      if option.flags?
        @flags << option.flags.short if option.flags.short?
        @flags << option.flags.long  if option.flags.long?
      else # just use index
        @flags << option.index.to_s
      end
      @commands[option.index] = option
    end
  end
  @commands[cmd.index] = cmd
  cmd
end
commands() click to toggle source

Direct access to the various commands an application has. Helpful for debugging.

# File lib/command_lion/app.rb, line 214
def commands
  @commands.reject { |_, v| v.is_a? CommandLion::Option }
end
ctrl_c(&block) click to toggle source
# File lib/command_lion/app.rb, line 193
def ctrl_c(&block)
  trap("SIGINT") { block.call }
end
default_help_menu_removed?() click to toggle source

Check if the default help menu for the application has been explicitly removed.

# File lib/command_lion/app.rb, line 130
def default_help_menu_removed?
  @remove_default_help_menu || false
end
flags() click to toggle source

Direct access to the various flags an application has. Helpfulp for debugging.

# File lib/command_lion/app.rb, line 209
def flags
  @flags
end
help(&block) click to toggle source
# File lib/command_lion/app.rb, line 197
def help(&block)
  command :help, &block
end
help?() click to toggle source

Check if there has been an indexed help command.

# File lib/command_lion/app.rb, line 119
def help?
  return true if @commands[:help]
  false
end
parse() { |cmd| ... } click to toggle source

Parse arguments off of ARGV.

@TODO Re-visit this.

# File lib/command_lion/app.rb, line 221
def parse
  @commands.each do |_, cmd|
    if cmd.flags?
      # or for the || seems to not do what I want it to do...
      next unless argv_index = ARGV.index(cmd.flags.short) || ARGV.index(cmd.flags.long)
    else
      next unless argv_index = ARGV.index(cmd.index.to_s)
    end
    cmd.given = true unless argv_index.nil?
    if cmd.type.nil?
      yield cmd if block_given?
    else
      if parsed = parse_cmd(cmd, flags)
        cmd.arguments = parsed || cmd.default
        yield cmd if block_given?
      elsif cmd.default
        cmd.arguments = cmd.default
        yield cmd if block_given?
      end
    end
  end
end
parse_cmd(cmd, flags) click to toggle source

Parse a given command with its given flags. @TODO Re-visit this.

# File lib/command_lion/app.rb, line 246
def parse_cmd(cmd, flags)
  if cmd.flags?
    args = Raw.arguments_to(cmd.flags.short, flags)
    if args.nil? || args.empty?
      args = Raw.arguments_to(cmd.flags.long, flags)
    end
  else
    args = Raw.arguments_to(cmd.index.to_s, flags)
  end
  unless cmd.type.to_s =~ /stdin/
    return nil if args.nil?
  end
  case cmd.type
  when :stdin
    args = STDIN.gets.strip
  when :stdin_stream
    args = STDIN
  when :stdin_string
    args = STDIN.gets.strip
  when :stdin_strings
    args = []
    while arg = STDIN.gets
      next if arg.nil?
      arg = arg.strip
      args << arg
    end
    args
  when :stdin_integer
    args = STDIN.gets.strip.to_i
  when :stdin_integers
    args = []
    while arg = STDIN.gets
      next if arg.nil?
      arg = arg.strip
      parse = arg.to_i
      if parse.to_s == arg
        args << parse
      end
    end
    args
  when :stdin_bool
    args = STDIN.gets.strip.downcase == "true"
  when :single, :string
    args = args.first
  when :strings, :multi
    if cmd.delimiter?
      if args.count > 1
        args = args.first.split(cmd.delimiter)
      else
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      end
    end
    args
  when :integer
    args = args.first.to_i
  when :integers
    if cmd.delimiter?
      if args.count > 1
        args = args.join
        args = args.select { |arg| arg if arg.include?(cmd.delimiter) }
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      else
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      end
    end
    args = args.map(&:to_i)
  when :bool, :bools
    if cmd.delimiter?
      if args.count > 1
        args = args.join
        args = args.select { |arg| arg if arg.include?(cmd.delimiter) }
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      else
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      end
    end
    args = args.map { |arg| arg == "true" }
  end
rescue => e# this is dangerous
  puts e
  nil
end
plugin(command) click to toggle source

Plugin a command that's probably been built outside of the application's run or build block. This is helpful for sharing or reusing commands in applications. @param command [Command]

# File lib/command_lion/app.rb, line 204
def plugin(command)
  command(command)
end
remove_default_help_menu() click to toggle source

Explicitly remove the default help menu from the application.

# File lib/command_lion/app.rb, line 125
def remove_default_help_menu
  @remove_default_help_menu = true
end
run!() click to toggle source
# File lib/command_lion/app.rb, line 329
def run!
  parse do |cmd|
    next unless cmd.given?
    cmd.options.each do |_, opt|
      next unless opt.given?
      opt.before.call if opt.before?
      opt.action.call if opt.action?
      opt.after.call  if opt.after?
    end if cmd.options?
    cmd.before.call if cmd.before?
    cmd.action.call if cmd.action?
    cmd.after.call  if cmd.after?
  end 
end