Skip to content

Instantly share code, notes, and snippets.

@johncarney
Created July 12, 2020 23:42
Show Gist options
  • Save johncarney/c3107b44064604a13c8fa6e08de729af to your computer and use it in GitHub Desktop.
Save johncarney/c3107b44064604a13c8fa6e08de729af to your computer and use it in GitHub Desktop.
Wrapper for OptionParser
# frozen_string_literal: true
require "active_support/all"
require "optparse"
module Options
extend ActiveSupport::Concern
included do
delegate :arguments, :options, to: :Options
end
class << self
delegate :[], to: :options
def arguments
@arguments ||= []
end
def options
@options ||= defaults.dup
end
def defaults
@defaults ||= OptionsHash.new
end
def declare(&block)
Builder.new(parser, defaults).instance_exec(&block) if block_given?
@arguments = ARGV.dup
@options = defaults.dup
parser.parse!(@arguments, into: options)
end
def parser
@parser ||= OptionParser.new
end
end
class Builder
def initialize(parser, defaults)
@parser = parser
@defaults = defaults
end
def banner(message)
@parser.banner = message
end
def default(option, default_value)
defaults option => default_value
end
def defaults(**option_defaults)
option_defaults.each_with_object(@defaults) do |(key, value), memo|
memo[key.to_s.tr("-", "_").to_sym] = value
end
end
def option(*args, &block)
@parser.on(*args, &block)
end
def usage
@parser.to_s
end
end
class OptionsHash
def initialize(hash = {})
@hash = hash.transform_keys(&method(:normalize_key))
end
def [](key)
@hash[normalize_key(key)]
end
def []=(key, value)
@hash[normalize_key(key)] = value
end
def dup
self.class.new(@hash.dup)
end
def to_h
@hash.dup
end
def method_missing(name, *args, &block)
if name.to_s =~ /=\z/
@hash[normalize_key(name.to_s.sub(/=\z/, ""))] = args.first
else
@hash.fetch(normalize_key(name), nil)
end
end
private
def normalize_key(key)
key.to_s.tr("_", "-").to_sym
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment