No release in over 3 years
simple-cli-options is a small Ruby library for parsing command-line flags with validation and conversion. Define options with short/long forms, then parse ARGV and read values by name. This gem is currently in BETA; APIs may change in future releases.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

simple-cli-options

A small Ruby library for parsing command-line flags (short and long options with values). The way you define flags (short/long, description, validation, conversion) is inspired by Cobra. Define options, then parse ARGV and read values by name.

Installation

Note: This project is in beta. APIs may change in future releases.

From a built gem

After building the gem (gem build simple-cli-options.gemspec in the repo), install and require:

gem install simple-cli-options-0.1.3.gem
require 'simple-cli-options'
# Option and Options are now available

Without a gem (copy or clone)

Use the library as plain Ruby files. No gem packaging or Gemfile required.

  1. Clone or download the repo, or copy the lib/ folder (containing option.rb and options.rb) into your project.
  2. Install the runtime dependency (needed for type hints):
    gem install sorbet-runtime
  3. Require the files from your script (adjust paths if needed):
    require_relative 'lib/option'
    require_relative 'lib/options'
    If you keep the library in a subdirectory (e.g. vendor/simple-options/):
    require_relative 'vendor/simple-options/lib/option'
    require_relative 'vendor/simple-options/lib/options'

A stable gem may be published to RubyGems.org later.

With Bundler (optional)

If you use a Gemfile, add the dependency and require as above:

# Gemfile
gem 'sorbet-runtime'

Quick start

require_relative 'lib/options'
require_relative 'lib/option'

opts = Options.new(description: 'My CLI')
opts.add Option.new(:name, short: '-n', long: '--name', desc: 'Your name', required: true)
opts.add Option.new(:count, short: '-c', long: '--count', desc: 'Repeat count', required: false)
       .convert(&:to_i)

opts.parse!
puts "Hello, #{opts.get(:name)}!" * (opts.get(:count) || 1)

Running with ruby app.rb -n Alice -c 3 prints Hello, Alice! three times. -h or --help prints usage and exits.

API reference

Option

Represents a single flag: short form (e.g. -l), long form (e.g. --length), description, and optional validation/conversion.

Method / attribute Description
Option.new(name, short:, long:, desc:, required: false, **options) name (Symbol), short / long (String), desc (String). At least one of short or long must be non-empty. options may include :validate (callable) and :convert (callable).
#name, #short, #long, #desc, #required_flag Read-only attributes.
#validate(&block) Appends a validator (block takes a String, returns nil on success or an error message String on failure). Returns self.
#convert(&block) Sets the converter (block takes a String, returns the value to store). Returns self.
#process(value) Runs all validators on value, then the converter; returns the converted value. Raises if validation fails.

Example

opt = Option.new(:port, short: '-p', long: '--port', desc: 'Port number')
             .validate { |v| (1..65535).cover?(v.to_i) ? nil : 'Port must be between 1 and 65535' }
             .convert(&:to_i)

opt.process('8080')  # => 8080
opt.process('99999') # => raises ArgumentError, "Port must be between 1 and 65535 for -p or --port option"

Options

Collects options, parses an argument array, and provides access to parsed values.

Method Description
Options.new(description: '') Creates a parser. description is shown above usage in help.
#add(option) Registers an Option.
#parse!(argv) Parses argv (defaults to ARGV when omitted). If -h or --help is present, prints help and exits 0. Missing required options or validation failures print an error to stderr and exit 1. Parsed values are stored by option name.
#get(name) Returns the parsed value for the option named name (Symbol), or nil if not given.
#show_help Prints description, usage line, and all flags (short/long and description).

Behavior

  • Each option expects the next argument as its value (e.g. --length 10).
  • Help is built from the options you add; -h / --help are handled automatically.
  • Validators return nil on success or an error message string on failure; failed validation raises ArgumentError with a message like "Please input positive number for -l or --length option". parse! catches it, prints Error: <message> to stderr, and exits 1.

Usage examples

Required and optional options

opts = Options.new(description: 'Greeter')
opts.add Option.new(:name, short: '-n', long: '--name', desc: 'Your name', required: true)
opts.add Option.new(:times, short: '-t', long: '--times', desc: 'Repeat N times').convert(&:to_i)
opts.parse!
name = opts.get(:name)       # required; parse! would have exited if missing
times = opts.get(:times) || 1

Validation and conversion

Option.new(:size, short: '-s', long: '--size', desc: 'Size (s/m/l)',
           validate: ->(v) { %w[s m l].include?(v) ? nil : 'Size must be one of s/m/l' })
      .convert(&:upcase)

Short-only or long-only

Option.new(:verbose, short: '', long: '--verbose', desc: 'Verbose output')
Option.new(:x, short: '-x', long: '', desc: 'Enable X')

Example scripts

File Description
examples/paint_calculator.rb Room dimensions via -l/--length and -w/--width; computes area and gallons of paint.
examples/greet.rb Simple greeter using --name and optional --count.

Run an example (from project root):

ruby examples/paint_calculator.rb --length 10 --width 5
ruby examples/greet.rb --name World --count 2

Development

Running tests

Install dependencies, then run RSpec from the project root:

bundle install
bundle exec rspec spec/

Using test_helper.rb in your own specs

test_helper.rb loads RSpec and the library (option.rb, options.rb), so your specs can use Option and Options without requiring them yourself.

  • Specs under spec/: use spec_helper, which already requires test_helper:
    # spec/my_feature_spec.rb
    require_relative 'spec_helper'
    
    RSpec.describe Option do
      it 'does something' do
        opt = Option.new(:x, short: '-x', long: '--x', desc: 'X')
        expect(opt.process('value')).to eq 'value'
      end
    end
  • Specs elsewhere (e.g. in your app): require test_helper by path so the library and RSpec are loaded:
    require_relative '/path/to/simple-options/test_helper'
    # Now Option, Options are available and RSpec is configured

Then run your spec with bundle exec rspec path/to/your_spec.rb.

Linting

RuboCop (and rubocop-performance, rubocop-rspec) are in the Gemfile. Run with bundle exec rubocop.

License

MIT (see LICENSE).