merge devops_options_parser
This commit is contained in:
parent
13eed304b1
commit
9228193da4
@ -1,5 +1,5 @@
|
|||||||
require "optparse"
|
|
||||||
require "devops-client/version"
|
require "devops-client/version"
|
||||||
|
require "devops-client/options/helpers/devops_options_parser"
|
||||||
|
|
||||||
class CommonOptions
|
class CommonOptions
|
||||||
|
|
||||||
@ -82,78 +82,15 @@ class CommonOptions
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def options
|
# You could use block to extend default functionality:
|
||||||
o = {}
|
# self.options do |parser, options|
|
||||||
optparse = OptionParser.new do |opts|
|
# parser.banner << 'banner'
|
||||||
|
# options[:any_option] = {a: 123}
|
||||||
opts.banner = "\n" + I18n.t("options.usage", :cmd => $0) + "\n\n" + I18n.t("options.commands") + ":\n"
|
# end
|
||||||
|
def options(&block)
|
||||||
if block_given?
|
parser = Options::Helpers::DevopsOptionsParser.new(default_options, &block)
|
||||||
opts.separator(I18n.t("options.options") + ":\n")
|
parser.parse!(self.args)
|
||||||
yield opts, o
|
parser.parsed_options
|
||||||
end
|
|
||||||
|
|
||||||
opts.separator("\n" + I18n.t("options.common_options") + ":\n")
|
|
||||||
opts.on("-h", "--help", I18n.t("options.common.help")) do
|
|
||||||
opts.banner << "\n"
|
|
||||||
puts opts
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
|
|
||||||
o[:no_ask] = false
|
|
||||||
opts.on("-y", "--assumeyes", I18n.t("options.common.confirmation")) do
|
|
||||||
o[:no_ask] = true;
|
|
||||||
end
|
|
||||||
|
|
||||||
#Not used, just for banner purposes. This should be fixed when we find how to deal with options separetely
|
|
||||||
opts.on("-c", "--config CONFIG", I18n.t("options.common.config", :file => DevopsClient.config_file)) do
|
|
||||||
puts "Not implemented yet"
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on("-v", "--version", I18n.t("options.common.version")) do
|
|
||||||
puts I18n.t("options.common.version") + ": #{DevopsClient::VERSION}"
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on("--host HOST", I18n.t("options.common.host", :host => default_options[:host])) do |h|
|
|
||||||
o[:host] = h
|
|
||||||
end
|
|
||||||
|
|
||||||
o[:api] = default_options[:api]
|
|
||||||
opts.on("--api VER", I18n.t("options.common.api", :api => o[:api])) do |a|
|
|
||||||
o[:api] = a
|
|
||||||
end
|
|
||||||
|
|
||||||
o[:prefix] = default_options[:prefix]
|
|
||||||
opts.on("--prefix PREFIX", I18n.t("options.common.prefix", :prefix => o[:prefix])) do |p|
|
|
||||||
o[:prefix] = p
|
|
||||||
end
|
|
||||||
|
|
||||||
o[:username] = default_options[:username]
|
|
||||||
opts.on("--user USERNAME", I18n.t("options.common.username", :username => o[:username])) do |u|
|
|
||||||
o[:username] = u.strip
|
|
||||||
print I18n.t("handler.user.password_for", :user => o[:username])
|
|
||||||
begin
|
|
||||||
system("stty -echo")
|
|
||||||
o[:password] = STDIN.gets.strip
|
|
||||||
ensure
|
|
||||||
system("stty echo")
|
|
||||||
end
|
|
||||||
puts
|
|
||||||
end
|
|
||||||
|
|
||||||
o[:format] = TABLE_FORMAT
|
|
||||||
opts.on("--format FORMAT", I18n.t("options.common.format", :formats => OUTPUT_FROMATS.join("', '"), :format => TABLE_FORMAT)) do |f|
|
|
||||||
o[:format] = f if OUTPUT_FROMATS.include?(f)
|
|
||||||
end
|
|
||||||
|
|
||||||
# should be handled in lib/devops-client.rb
|
|
||||||
opts.on("", "--completion", I18n.t("options.common.completion"))
|
|
||||||
|
|
||||||
end
|
|
||||||
optparse.parse!(self.args)
|
|
||||||
o
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def invalid_command
|
def invalid_command
|
||||||
|
|||||||
@ -0,0 +1,189 @@
|
|||||||
|
require "optparse"
|
||||||
|
require 'forwardable'
|
||||||
|
require_relative 'option_value_recognizer'
|
||||||
|
|
||||||
|
module Options
|
||||||
|
module Helpers
|
||||||
|
class DevopsOptionsParser
|
||||||
|
extend Forwardable
|
||||||
|
attr_reader :parsed_options
|
||||||
|
|
||||||
|
# leave this duplication for a while
|
||||||
|
TABLE_FORMAT = "table"
|
||||||
|
JSON_FORMAT = "json"
|
||||||
|
CSV_FORMAT = "csv"
|
||||||
|
OUTPUT_FROMATS = [TABLE_FORMAT, JSON_FORMAT, CSV_FORMAT]
|
||||||
|
|
||||||
|
def_delegators :@parser, :banner, :separator, :on, :parse!
|
||||||
|
|
||||||
|
def initialize(default_options, &block)
|
||||||
|
@parser = OptionParser.new
|
||||||
|
@default_options = default_options
|
||||||
|
@parsed_options = {}
|
||||||
|
|
||||||
|
banner_usage
|
||||||
|
if block
|
||||||
|
@parser.separator(I18n.t("options.options") + ":\n")
|
||||||
|
block.call(self, @parsed_options)
|
||||||
|
end
|
||||||
|
|
||||||
|
common_options_separator
|
||||||
|
recognize_help
|
||||||
|
recognize_assume_yes
|
||||||
|
recognize_config
|
||||||
|
recognize_version
|
||||||
|
recognize_host
|
||||||
|
recognize_api
|
||||||
|
recognize_prefix
|
||||||
|
recognize_username
|
||||||
|
recognize_format
|
||||||
|
recognize_completion
|
||||||
|
|
||||||
|
@parser
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# it is used to set options values without later quiz.
|
||||||
|
# Arguments description:
|
||||||
|
# option_name - name of option;
|
||||||
|
# resource_name - used for description lookup. Lookup path is "options.descriptions.#{resource_name}.#{option_name}".
|
||||||
|
# attrs - hash with following options:
|
||||||
|
# :type - could be one of following values:
|
||||||
|
# :required (default)
|
||||||
|
# :optional
|
||||||
|
# :switch
|
||||||
|
# :default - default value. nil by default
|
||||||
|
# :switch_value - set this value, if type is :switch and option've been recognized.
|
||||||
|
# :option_key - key in result_options hash. Default - option_name.to_sym
|
||||||
|
# :variable - default - option_name.upcase
|
||||||
|
# :description - default - I18n.t("options.descriptions.#{resource_name}.#{option_name}")
|
||||||
|
# :i18n_scope - if present, change I18n lookup path to "options.descriptions.#{resource_name}.#{i18n_scope}.#{option_name}"
|
||||||
|
# :short - short option name
|
||||||
|
#
|
||||||
|
# EXAMPLES:
|
||||||
|
# 1)
|
||||||
|
# parser.recognize_option_value(:provider, 'stack')
|
||||||
|
# is equal to
|
||||||
|
# opts.on("--provider provider", I18n.t("options.descriptions.stack.provider)) do |provider|
|
||||||
|
# options[:provider] = provider
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# 2)
|
||||||
|
# parser.recognize_option_value(:provider, 'stack', type: :optional, default: 'openstack')
|
||||||
|
# is equal to
|
||||||
|
# options[:provider] = 'openstack'
|
||||||
|
# opts.on("--provider [provider]", I18n.t("options.descriptions.stack.provider)) do |provider|
|
||||||
|
# options[:provider] = provider
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# 3)
|
||||||
|
# parser.recognize_option_value(:no_template, 'image', type: :switch, default: false, switch_value: true)
|
||||||
|
# is equal to
|
||||||
|
# options[:no_template] = false
|
||||||
|
# opts.on("--no_template", I18n.t("options.descriptions.image.no_template)) do
|
||||||
|
# options[:no_template] = true
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# 4)
|
||||||
|
# parser.recognize_option_value(:parameters, 'stack') do |parameters|
|
||||||
|
# options[:parameters] = JSON.parse(parameters)
|
||||||
|
# end
|
||||||
|
# is equal to
|
||||||
|
# opts.on("--parameters parameters", I18n.t("options.descriptions.stack.parameters)) do |parameters|
|
||||||
|
# options[:parameters] = JSON.parse(parameters)
|
||||||
|
# end
|
||||||
|
def recognize_option_value(option_name, resource_name, attrs={}, &block)
|
||||||
|
recognizer = OptionValueRecognizer.new(option_name, resource_name, attrs)
|
||||||
|
recognizer.recognize(@parser, @parsed_options, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def banner_usage
|
||||||
|
@parser.banner = "\n" + I18n.t("options.usage", :cmd => $0) + "\n\n" + I18n.t("options.commands") + ":\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
def common_options_separator
|
||||||
|
@parser.separator("\n" + I18n.t("options.common_options") + ":\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_help
|
||||||
|
@parser.on("-h", "--help", I18n.t("options.common.help")) do
|
||||||
|
@parser.banner << "\n"
|
||||||
|
puts @parser
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_assume_yes
|
||||||
|
@parsed_options[:no_ask] = false
|
||||||
|
@parser.on("-y", "--assumeyes", I18n.t("options.common.confirmation")) do
|
||||||
|
@parsed_options[:no_ask] = true;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_config
|
||||||
|
#Not used, just for banner purposes. This should be fixed when we find how to deal with options separetely
|
||||||
|
@parser.on("-c", "--config CONFIG", I18n.t("options.common.config", :file => DevopsClient.config_file)) do
|
||||||
|
puts "Not implemented yet"
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_version
|
||||||
|
@parser.on("-v", "--version", I18n.t("options.common.version")) do
|
||||||
|
puts I18n.t("options.common.version") + ": #{DevopsClient::VERSION}"
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_host
|
||||||
|
@parser.on("--host HOST", I18n.t("options.common.host", :host => @default_options[:host])) do |h|
|
||||||
|
@parsed_options[:host] = h
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_api
|
||||||
|
@parsed_options[:api] = @default_options[:api]
|
||||||
|
@parser.on("--api VER", I18n.t("options.common.api", :api => @parsed_options[:api])) do |a|
|
||||||
|
@parsed_options[:api] = a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_prefix
|
||||||
|
@parsed_options[:prefix] = @default_options[:prefix]
|
||||||
|
@parser.on("--prefix PREFIX", I18n.t("options.common.prefix", :prefix => @parsed_options[:prefix])) do |p|
|
||||||
|
@parsed_options[:prefix] = p
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_username
|
||||||
|
@parsed_options[:username] = @default_options[:username]
|
||||||
|
@parser.on("--user USERNAME", I18n.t("options.common.username", :username => @parsed_options[:username])) do |u|
|
||||||
|
@parsed_options[:username] = u.strip
|
||||||
|
print I18n.t("handler.user.password_for", :user => @parsed_options[:username])
|
||||||
|
begin
|
||||||
|
system("stty -echo")
|
||||||
|
@parsed_options[:password] = STDIN.gets.strip
|
||||||
|
ensure
|
||||||
|
system("stty echo")
|
||||||
|
end
|
||||||
|
puts
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_format
|
||||||
|
@parsed_options[:format] = TABLE_FORMAT
|
||||||
|
@parser.on("--format FORMAT", I18n.t("options.common.format", :formats => OUTPUT_FROMATS.join("', '"), :format => TABLE_FORMAT)) do |f|
|
||||||
|
@parsed_options[:format] = f if OUTPUT_FROMATS.include?(f)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize_completion
|
||||||
|
# should be handled in lib/devops-client.rb
|
||||||
|
@parser.on("", "--completion", I18n.t("options.common.completion"))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
# This class is used only in devops_option_parser.
|
||||||
|
# It was extracted because #recognize_option_value method became too large.
|
||||||
|
# Description and examples of usage are in devops_option_parser.rb.
|
||||||
|
class OptionValueRecognizer
|
||||||
|
|
||||||
|
def initialize(option_name, resource_name, attrs={})
|
||||||
|
@option_name, @attrs = option_name, attrs
|
||||||
|
|
||||||
|
set_type(option_name, resource_name)
|
||||||
|
set_option_key(option_name, resource_name)
|
||||||
|
set_description(option_name, resource_name)
|
||||||
|
set_variable(option_name, resource_name)
|
||||||
|
set_options_to_recognize(option_name, resource_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def recognize(parser, parsed_options, &block)
|
||||||
|
parsed_options[@option_key] = @attrs[:default] if @attrs.keys.include?(:default)
|
||||||
|
|
||||||
|
parser.on(*@options_to_recognize, @description) do |value|
|
||||||
|
value = @attrs[:switch_value] if @type == :switch
|
||||||
|
|
||||||
|
if block
|
||||||
|
block.call(value)
|
||||||
|
else
|
||||||
|
parsed_options[@option_key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_type(option_name, resource_name)
|
||||||
|
@type = @attrs[:type] || :required
|
||||||
|
raise "Illegal optional type: '#{@type}'" unless [:required, :optional, :switch].include?(@type)
|
||||||
|
if @type == :switch && !@attrs.keys.include?(:switch_value)
|
||||||
|
raise 'Missing switch value'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_option_key(option_name, resource_name)
|
||||||
|
@option_key = @attrs[:option_key] || option_name.to_sym
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_description(option_name, resource_name)
|
||||||
|
if @attrs[:description]
|
||||||
|
@description = @attrs[:description]
|
||||||
|
else
|
||||||
|
lookup_path = [:options, :descriptions, resource_name]
|
||||||
|
lookup_path << @attrs[:i18n_scope] if @attrs[:i18n_scope]
|
||||||
|
lookup_path << option_name
|
||||||
|
@description = I18n.t(lookup_path.join('.'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_variable(option_name, resource_name)
|
||||||
|
variable = @attrs[:variable] || option_name.upcase
|
||||||
|
|
||||||
|
@variable = case @type
|
||||||
|
when :optional
|
||||||
|
" [#{variable}]"
|
||||||
|
when :switch
|
||||||
|
''
|
||||||
|
else # required by default
|
||||||
|
" #{variable}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_options_to_recognize(option_name, resource_name)
|
||||||
|
full = "--#{@option_name}#{@variable}"
|
||||||
|
@options_to_recognize = [full]
|
||||||
|
@options_to_recognize.unshift(@attrs[:short]) if @attrs[:short]
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue
Block a user