fluke/devops-client/lib/devops-client/options/common_options.rb
2015-04-14 16:29:02 +04:00

131 lines
3.2 KiB
Ruby

require "devops-client/version"
require "devops-client/options/helpers/extendable"
require "devops-client/options/helpers/devops_options_parser"
class CommonOptions
extend Options::Helpers::Extendable
attr_accessor :header, :args, :default_options
attr_writer :banner_header
TABLE_FORMAT = "table"
JSON_FORMAT = "json"
CSV_FORMAT = "csv"
OUTPUT_FROMATS = [TABLE_FORMAT, JSON_FORMAT, CSV_FORMAT]
def initialize args, def_options
self.args = args
self.default_options = def_options
end
def self.commands *cmds
define_method :available_commands do
cmds
end
cmds.each do |cmd|
if cmd.is_a?(Hash)
key = cmd.keys[0]
cmd[key].each do |subcmd|
create_command key.to_s, subcmd.to_s
end
invalid_command_method = "invalid_#{key}_command"
banner_method = "#{key}_banner"
define_method invalid_command_method do
puts "#{self.header}:\n#{self.send(banner_method)}"
end
define_method banner_method do
cmd[key].map{|sc| self.send("#{key}_#{sc}_banner")}.join("") + "\n"
end
else
create_command cmd.to_s
end
end
define_method "banners" do
r = []
cmds.each do |cmd|
if cmd.is_a?(Hash)
key = cmd.keys[0]
cmd[key].each do |subcmd|
r.push self.send("#{key}_#{subcmd}_banner")
end
else
r.push self.send("#{cmd.to_s}_banner")
end
end
r
end
end
def self.create_command cmd, subcmd=nil
name = (subcmd.nil? ? cmd : "#{cmd}_#{subcmd}")
banner = (subcmd.nil? ? cmd : "#{cmd} #{subcmd}")
invalid_command_method = "invalid_#{name}_command"
banner_method = "#{name}_banner"
define_method invalid_command_method do
puts "#{self.header}:\n#{self.send(banner_method)}"
end
params_method = "#{name}_params"
define_method banner_method do
self.banner_header + " #{banner} #{(self.send(params_method) || []).join(" ")}\n"
end
options_method = "#{name}_options"
define_method options_method do
self.options do |opts, options|
opts.banner << self.send(banner_method)
end
end
attr_accessor params_method
end
# You could use block to extend default functionality:
# self.options do |parser, options|
# parser.banner << 'banner'
# options[:any_option] = {a: 123}
# end
def options(&block)
parser = Options::Helpers::DevopsOptionsParser.new(default_options, &block)
parser.parse!(self.args)
parser.parsed_options
end
def invalid_command
options do |opts, options|
opts.banner << self.error_banner
puts opts.banner
exit(2)
end
end
# returns [options, args] because they are always needed together
# will exit if operation is unsupported
def parse_options_for!(command)
# available_commands method is defined dinamically in .commands method
if available_commands.include?(command)
options = send("#{command}_options")
[options, args]
else
invalid_command
end
end
def error_banner
"\t#{self.header}:\n\t#{self.banners.join("\t")}\n"
end
def banner_header
"\t" + @banner_header
end
end