Command-Line Applications

44.1 OptionParser

#!/usr/bin/env ruby
require "optparse"

options = { count: 1, verbose: false }
parser = OptionParser.new do |opts|
  opts.banner = "Usage: greet [options] NAME"
  opts.on("-c", "--count N", Integer, "Repeat N times") { |n| options[:count] = n }
  opts.on("-v", "--[no-]verbose", "Verbose output") { |v| options[:verbose] = v }
  opts.on("-h", "--help", "Show help") { puts opts; exit }
  opts.on("--version") { puts "1.0.0"; exit }
end

begin
  parser.parse!
rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
  abort "#{e.message}\n#{parser}"
end

name = ARGV.first or abort(parser.to_s)
options[:count].times { puts "Hello, #{name}!" }
warn "Done (verbose)" if options[:verbose]

44.2 Thor and Other Frameworks

Others: dry-cli, GLI, TTY toolkit (tty-prompt, tty-table, tty-spinner, tty-progressbar), Pastel/rainbow (colors), highline.

Distribution: package as a gem with an exe/ executable (gem install mytool). Tebako/ocran can package standalone executables.

require "thor"

class TodoCLI < Thor
  desc "add TASK", "Add a task"
  option :priority, type: :string, default: "normal", aliases: "-p"
  def add(task)
    puts "Added '#{task}' (#{options[:priority]})"
  end

  desc "list", "List tasks"
  def list = puts("No tasks yet")

  def self.exit_on_failure? = true
end

TodoCLI.start(ARGV)