class QB::Options
Constants
- QB_DEFAULTS
Default initial values for {#qb}.
@return [Hash]
- SPACER
Appended on the end of an `opts.on` call to create a newline after the option (making the help output a bit easier to read)
You might think the empty string would be reasonable, but OptionParser blows up if you do that.
@return [String]
Attributes
@!attribute [r] ansible
@return [Hash<String, String>] options to pass through to ansible-playbook.
@!attribute [r] qb
@return [Hash<String, *>] common qb-level options.
@!attribute [r] role_options
@return [Hash<String, QB::Options::Option>] options to pass through to ansible-playbook.
Public Class Methods
Add the options from a role to the OptionParser
@param [OptionParser] opts
The option parser to add options to.
# File lib/qb/options.rb, line 137 def self.add opts, options, role, include_path = [] QB.debug "adding options", "role" => role role.option_metas.each do |option_meta| if option_meta.key? 'include' include_role opts, options, option_meta, include_path else # create an option option = Option.new role, option_meta, include_path option.option_parser_add opts, included: !include_path.empty? options[option.cli_name] = option end end # each var end
turn a name into a “command line” version by replacing underscores with dashes.
@param [String] option_name
the input option name.
@return [String]
the CLI-ized name.
@example
QB::Options.cli_ize_name "my_var" # => "my-var"
# File lib/qb/options.rb, line 86 def self.cli_ize_name option_name option_name.gsub '_', '-' end
# File lib/qb/options.rb, line 106 def self.include_role opts, options, include_meta, include_path role_name = include_meta['include'] role = QB::Role.require role_name new_include_path = if include_meta.key? 'as' case include_meta['as'] when nil, false # include it in with the parent role's options include_path when String include_path + [include_meta['as']] else raise QB::Role::MetadataError.new, "bad 'as' value: #{ include_meta.inspect }" end else include_path + [role.namespaceless] end QB.debug "including #{ role.name } as #{ new_include_path.join('-') }" opts.separator "Options for included #{ role.name } role:" add opts, options, role, new_include_path end
@param [Role] role
the role to parse the args for.
# File lib/qb/options.rb, line 187 def initialize role, argv @role = role @argv = argv @qb = QB_DEFAULTS.dup parse! end
Destructively removes options from `@argv` and populates ansible, role, and qb option hashes.
@param [QB::Role] role
the role to parse the options for.
@param [Array<String>] args
CLI args -- `ARGV` with the role arg shifted off.
@return [Array<Hash<String, Option|Object>>]
a two-element array: 1. the options for the role, hash of Option#cli_name to Option instances. 2. the general qb options, hash of String key to option values.
@raise if bad options are found.
# File lib/qb/options.rb, line 175 def self.parse! role, argv options = self.new role, argv [options.role_options, options.qb] end
turn a name into a “ruby / ansible variable” version by replacing dashes with underscores.
@param [String] option_name
the input option name.
@return [String]
the ruby / ansible var-ized name.
@example
QB::Options.cli_ize_name "my-var" # => "my_var"
# File lib/qb/options.rb, line 102 def self.var_ize_name option_name option_name.gsub '-', '_' end
Public Instance Methods
Does the option accept `false` as value?
If it does, and is not a boolean option, we also accept a `–no-<name>` option format to set the value to `false`.
This is useful to explicitly tell QB
“no, I don't want this”, since we treat `nil`/`null` as the same as absent, which will cause a default value to be used (if available).
This feature does not apply to {#boolean?} options themselves, only options that accept other values (though this method will of course return `true` for {#boolean?} options, since they do accept `false`).
@return [Boolean]
# File lib/qb/options/option.rb, line 305 def accept_false? return true if meta[:accept_false] return false if type.is_a?( Class ) && type < NRSER::Props type.test?( false ) end
@todo Document ask? method.
@param [type] arg_name
@todo Add name param description.
@return [return_type]
@todo Document return value.
# File lib/qb/options.rb, line 204 def ask? @qb['ask'] end
# File lib/qb/options/option.rb, line 258 def boolean? type == t.bool end
Description of the option.
@return [String]
# File lib/qb/options/option.rb, line 250 def description meta( :description, default: "Set the #{ @var_name } role variable" ).to_s end
get an array of examples for the option. returns `[]` if no examples are defined.
@return [Array<String>]
# File lib/qb/options/option.rb, line 285 def examples Array meta( *EXAMPLES_KEYS, type: (t.nil | t.str | t.array( t.str )) ) end
test if the option has any examples.
@return [Boolean]
# File lib/qb/options/option.rb, line 276 def has_examples? meta? *EXAMPLES_KEYS end
# File lib/qb/options/option.rb, line 214 def meta? *keys keys.any? { |key| @meta.key? key } end
Is the option is required in the CLI
?
@return [Boolean]
# File lib/qb/options/option.rb, line 232 def required? meta :required, :require, type: t.bool, default: false end
Should we save the option value in `./.qb-options.yml`?
@return [Boolean]
# File lib/qb/options/option.rb, line 241 def save? meta :save, type: t.bool, default: true end
# File lib/qb/options/option.rb, line 263 def usage if boolean? "--[no-]#{ cli_name }" else "--#{ cli_name }=#{ meta_name.upcase }" end end
# File lib/qb/options/option.rb, line 219 def value_data if value.respond_to? :to_data value.to_data else value end end
Protected Instance Methods
Pull options that start with
-
`–ANSIBLE_`
-
`–ANSIBLE-`
-
`—`
out of `@argv` and stick them in `@ansible`.
@return [nil]
**Mutates** `@argv`.
# File lib/qb/options.rb, line 368 def parse_ansible! logger.debug "Parsing Ansible options...", argv: @argv.dup @ansible = @role.default_ansible_options.clone reg_exs = [ /\A\-\-ANSIBLE[\-\_]/, /\A\-\-\-/, ] @argv.reject! {|shellword| if re = reg_exs.find {|re| re =~ shellword} name = shellword.sub re, '' value = true if name.include? '=' name, value = name.split('=', 2) end @ansible[name] = value true end } nil end
Private Instance Methods
destructively removes options from `@argv` and populates ansible, role, and qb option hashes.
# File lib/qb/options.rb, line 215 def parse! parse_ansible! @role_options = {} if @role.meta['default_user'] @qb['user'] = @role.meta['default_user'] end opt_parser = OptionParser.new do |opts| opts.accept(QB::Package::Version) do |string| QB::Package::Version.from( string ).to_h end opts.banner = @role.banner opts.separator "Common options:" opts.on( '-H', '--HOSTS=HOSTS', Array, "set playbook host", "DEFAULT: localhost", SPACER ) do |value| @qb['hosts'] = value end opts.on( '-I', '--INVENTORY=FILEPATH', String, "set inventory file", SPACER ) do |value| @qb['inventory'] = value end opts.on( '-U', '--USER=USER', String, "ansible become user for the playbook", SPACER ) do |value| @qb['user'] = value end opts.on( '-T', '--TAGS=TAGS', Array, "playbook tags", SPACER ) do |value| @qb['tags'] = value end opts.on( '-V[LEVEL]', "run playbook in verbose mode. use like -VVV or -V3.", SPACER ) do |value| # QB.debug "verbose", value: value @qb['verbose'] = if value.nil? 1 else case value when '0' false when /^[1-4]$/ value.to_i when /^[V]{1,3}$/i value.length + 1 else raise "bad verbose value: #{ value.inspect }" end end end opts.on( '--NO-FACTS', "don't gather facts", SPACER ) do |value| @qb['facts'] = false end opts.on( '--PRINT=FLAGS', Array, "set what to print before running: options, env, cmd, playbook", SPACER ) do |value| @qb['print'] = value end opts.on( '--NO-RUN', "don't run the playbook (useful to just print stuff)", SPACER ) do |value| @qb['run'] = false end opts.on( '-A', '--ASK', "interactively ask for argument and option values", SPACER ) do |value| if value && !$stdin.isatty raise ArgumentError.squished <<-END Interactive args & options only works with TTY $stdin. END end @qb['ask'] = value end opts.separator "Role options:" self.class.add opts, @role_options, @role opts.on_tail("-h", "--help", "Show this message") do puts opts @role.puts_examples exit end end opt_parser.parse! @argv end