Created
July 12, 2020 23:42
-
-
Save johncarney/c3107b44064604a13c8fa6e08de729af to your computer and use it in GitHub Desktop.
Wrapper for OptionParser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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