palkan / anyway_config

Configuration library for Ruby gems and applications
MIT License
778 stars 52 forks source link

Add OptionParse integration #17

Closed palkan closed 6 years ago

palkan commented 6 years ago

Add an ability to use config as option parser (e.g. for CLI apps/libraries).

Example usage:

class MyConfig < Anyway::Config
  attr_config :host, :port, :log_level
end

config = MyConfig.new

# For CLI that would be: config.parse_options!(ARGV)
config.parse_options!(%w(--host localhost --port 3333 --log-level debug))

config.host #=> "localhost"
config.port #=> 3333 (number)
config.log_level #=> "debug"

Under the hood an [OptionParser]() instance is created with all the configuration parameters:

OptionParser.new do |o|
  # one-letter shortcut automatically added if:
  # - param name is a one word (i.e. "host" and not "http_host")
  # - the shortcut hasn't been defined already (i.e. the order config params defined matters)
  o.on "-h", "--host" do |arg|
    # we can re-use serialization from Anyway::Env class
    config.host = serialize_val(arg)
  end

  o.on "-p", "--port" do |arg|
    config.port = serialize_val(arg)
  end

  # snake_case params transformed into list-case (or kebab-case, choose yours)
  o.on "--log-level" do |arg|
    config.log_level = serialize_val(arg)
  end
end

There should be a way to customize the parser object (i.e. add banner or version/help handlers). For that, parser generation should be extracted into a separate method (to make it easy to override/extend it):

class MyConfig < Anyway::Config
  # ...
  def build_option_parser
    super.tap do |parser|
      parser.banner = "mycli [options]"

      parser.on_tail "-h", "--help" do
        # ...
      end 
    end
  end
end

There should be a way to configure the configuration params for parser (e.g. you might want to exclude some parameters). For example:

class MyConfig < Anyway::Config
  attr_config :host, :log_level, :concurrency, server_args: {}

  # define which parameters could be accepted as options
  # (all by default) (i.e. we don't want to accept server_args)
  parser_options :host, :log_level, :concurrency

  # you can also provide a description for some params
  parse_options :host, :log_level, concurrency: "number of threads to use"
end
palkan commented 6 years ago

Closed by #18