routemaster/cli/base.rb
require 'routemaster/cli/helper'
require 'optparse'
require 'hashie'
module Routemaster
module CLI
class Base
def self.inherited(by)
by.extend(ClassMethods)
end
module ClassMethods
def prefix(ary = nil)
@prefix ||= ary
end
def syntax(string = nil)
string ? (@syntax = string) : ['rtm', *@prefix, @syntax, '[options]'].compact.join(' ')
end
def descr(string = nil)
string ? (@descr = string) : @descr
end
def defaults(hash = nil)
hash ? (@defaults = hash) : (@defaults || {})
end
def options(&block)
block_given? ? (@options = block) : @options
end
def action(&block)
block_given? ? (@action = block) : @action || lambda { |*| }
end
end
def initialize(stderr:, stdout:)
@stderr = stderr
@stdout = stdout
end
def run(argv)
@argv = argv
_parser.parse!(@argv)
instance_eval(&self.class.action)
rescue Exit
raise
rescue StandardError => e
log "#{e.class.name}: #{e.message}"
if config.verbose
e.backtrace.each { |l| log "\t#{l}" }
end
raise Exit, 2
end
protected
def argv
@argv || []
end
def config
@config ||= Hashie::Mash.new(_default_options).merge(self.class.defaults)
end
def helper
Helper.new(config)
end
def log(message)
@stderr.puts(message)
end
def puts(message)
@stdout.puts(message)
end
def usage!
log "Usage:"
log _parser
raise Exit, 1
end
def bad_argc!
log "Wrong number of arguments."
usage!
end
private
def _default_options
{ verbose: false }
end
def _parser
@parser ||= OptionParser.new do |p|
p.banner = self.class.syntax
p.separator self.class.descr
if self.class.options
p.separator 'Options:'
instance_exec(p, &self.class.options)
end
p.separator 'Common options:'
p.on('-b', '--bus DOMAIN|@NAME', %{
The domain name of the bus to interact with, or a reference (`NAME`)
to global configuration.
}) do |v|
config.bus = v
end
p.on('-t', '--token TOKEN', %{
An API token to use when querying the bus.
}) do |v|
config.token = v
end
p.on('-v', '--verbose', %{
Increase logging verbosity
}) do
config.verbose = true
end
end
end
def _description
self.class.descr.split(/\n/).map(&:strip).reject(&:empty?).join("\n")
end
end
end
end