Flagabowski

Bunny says you're good for it.

A wrapper around Ruby's OptionParser that adds validation, conflict groups, one-of constraints, and automatic short option conflict resolution.

Deeply inspired by micro-optparse but with some additional features.

Installation

Add this line to your application's Gemfile:

gem 'flagabowski'

Or install it yourself:

gem install flagabowski

Usage

Basic Example

require 'flagabowski'

parser = Flagabowski::OptionParser.new do |p|
  p.banner "Usage: myapp [options]"

  p.option name: :get_a_toe,
           desc: "Get me a toe"

  p.option name: :by,
           default: "3 o'clock",
           desc: "You don't want to know how... trust me!"

  p.option name: :dollars,
           default: 1000000,
           desc: "amount we thought we were getting"
end

result = parser.process!(ARGV)
puts result['get_a_toe']  # true/false
puts result['by']         # "3 o'clock" or user-provided value
puts result['dollars']    # 1000000 or user-provided value
puts result[:pos_args]    # Array of positional arguments

Required Options

parser.option name: :id,
              default: '',
              required: true,
              desc: "is this your only?"

# Raises OptionParser::MissingArgument if not provided

Validation with Arrays

parser.option name: :the_money,
              default: 'ringer',
              valid: ['ringer', 'ringer for a ringer'],
              desc: "to be thrown"

# Raises OptionParser::InvalidArgument if value not in array

Validation with Regex

parser.option name: :email,
              default: '',
              valid: /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i,
              desc: "Email address"

# Raises OptionParser::InvalidArgument if value doesn't match regex

Custom Long and Short Options

parser.option name: :verbose,
              short: 'x',
              long: 'debug',
              desc: "Debug mode"

# Can be invoked with -x or --debug

Automatic Short Option Conflict Resolution

parser.option name: :verbose, desc: "Verbose output"
parser.option name: :version, desc: "Show version"

# First option gets -v, second automatically gets -e
# Both can still use --verbose and --version

Conflict Groups

Ensure only one option from a group is used:

parser.option name: :json, desc: "JSON output"
parser.option name: :xml, desc: "XML output"
parser.option name: :yaml, desc: "YAML output"

parser.add_conflicts_constraint(['json', 'xml', 'yaml'])

# Raises OptionParser::InvalidOption if more than one is provided

One-Of Groups

Require exactly one option from a group:

parser.option name: :input, default: '', desc: "Input file"
parser.option name: :stdin, desc: "Read from stdin"

parser.add_one_of_constraint(['input', 'stdin'])

# Raises OptionParser::MissingArgument if neither is provided
# Raises OptionParser::InvalidOption if both are provided

Help Text

# Get help text as a string
help_text = parser.usage
puts help_text

Option Parameters

  • name: (required) - Symbol or string, the option name
  • desc: - Description shown in help text (default: "Lazy option authors have failed you.")
  • default: - Default value (also determines type casting if cast: not specified)
  • required: - Boolean, whether option is required (default: false)
  • valid: - Array or Regex for validation
  • short: - Custom short option letter
  • long: - Custom long option name
  • cast: - Explicit type to cast to (overrides type inferred from default)

Type Casting

Types are inferred from the default value, or can be explicitly specified with cast::

  • default: "text" → String
  • default: 42 → Integer
  • default: nil → Boolean flag (no argument)
  • cast: Integer → Integer (regardless of default)
  • cast: Float → Float (can override default's type)

Example with explicit casting:

parser.option name: :percentage,
              default: 0,
              cast: Float,
              desc: "Percentage as decimal"

# Accepts: --percentage 0.75

Error Handling

Flagabowski raises standard OptionParser exceptions:

  • OptionParser::MissingArgument - Required option not provided, or no option from one-of group
  • OptionParser::InvalidArgument - Validation failed
  • OptionParser::InvalidOption - Conflicting options used, or multiple from one-of group
  • OptionParser::ParseError - General parsing errors (base class)

License

GPLv2