require File.dirname(__FILE__) + '/dsl' # An ode to the Rat Pack (Dean Martin) with a Sinatra style DSL for creating # Command Line Interfaces to your applications module Martin module InstanceMethods end module ClassMethods Configures, Commands, Errors = [], [], [] # Runs once, at the beginning of the application # If there are multiple configure blocks, then each one will run in the # order the were created. # # @param [Regexp] cmd the regexp you want to match to run the command def configure(&block) Configures << DSL::Configure.new(block) end # Adds a command # # @param [Regexp] cmd the regexp you want to match to run the command def command(regexp, &block) Commands << DSL::Command.new(regexp, block) end # When the user input matches non of the user's commands then this # method will run # If there are multiple error blocks, then each one will run in the # order the were created. # # @param [Regexp] cmd the regexp you want to match to run the command def error(&block) Errors << DSL::Error.new(block) end # Runs the application on the given arguments # # @param [String] args The arguments to run the application on. Default is ARGV.join(' ') def run(args = ARGV.join(' ')) got_error = false Configures.each do |configure| configure.block.call end Commands.each do |command| match = command.regexp.match(args) unless match.nil? command.block.call(*match.captures) got_error = false else got_error = true end end Errors.each do |error| error.block.call(args) if got_error end self end end # The base class for command line applications # Subclass this class for the functionality class Base def self.inherited(base) extend ClassMethods include InstanceMethods end end end