class QB::Options::Option

Definitions

Constants

EXAMPLES_KEYS

Constants

Attributes

cli_name[R]

the name that this option will be available in the cli as

include_path[R]

array of strings representing how this option was included empty for top-level options

meta_name[R]

the name of the option in the qb metadata, equal to meta[‘name’]

role[R]

the role that this option is for

type[R]

TODO document `type` attribute.

@return [attr_type]

value[RW]

the value of the option, or `nil` if we never assign one

var_name[R]

the name that the value will be passed to ansible as

Public Class Methods

new(role, meta, include_path) click to toggle source

Construction

# File lib/qb/options/option.rb, line 92
def initialize role, meta, include_path
  @role = role
  @meta = meta.with_indifferent_access
  @include_path = include_path
  
  @meta_name = meta.fetch 'name'
  
  @cli_name = if @include_path.empty?
    QB::Options.cli_ize_name @meta_name
  else
    QB::Options.cli_ize_name "#{ @include_path.join('-') }-#{ @meta_name }"
  end
  
  @var_name = if self.meta?( :var_name )
    # prefer an explicit, exact variable name if provided
    self.meta( :var_name, type: Types.var_name )
  elsif role.var_prefix
    QB::Options.var_ize_name "#{ role.var_prefix }_#{ meta_name }"
  else
    QB::Options.var_ize_name meta_name
  end
  
  # Will be set when we find it out!
  @value = nil
  
  # Initialize `@type` var
  init_type!
end

Public Instance Methods

option_parser_add(option_parser, included: args = option_parser_args( included: included ).to_a) click to toggle source
# File lib/qb/options/option/option_parser_concern.rb, line 202
def option_parser_add option_parser, included:
  args = option_parser_args( included: included ).to_a
  
  args.find do |arg|
    if arg.is_a?( Class )
      option_parser.accept( arg ) do |value|
        arg.parse value
      end
      
      true
    end
  end
  
  logger.trace "Adding option to {OptionParser}",
    option_meta_name: meta_name,
    args: args
  
  option_parser.on( *args ) do |value|
    logger.debug "Setting option value",
      option_meta_name: meta_name,
      value: value
    
    self.value = value
  end
end
option_parser_args(included:) { |"REQUIRED."| ... } click to toggle source
# File lib/qb/options/option/option_parser_concern.rb, line 180
def option_parser_args included:, &block
  if boolean?
    option_parser_bool_args included: included, &block
  else
    option_parser_non_bool_args included: included, &block
  end
  
  option_parser_description &block
  
  yield "REQUIRED." if required?
  
  option_parser_type &block
  
  option_parser_default &block
  
  option_parser_examples &block
  
  yield option_parser_spacer
  
end
option_parser_bool_args(included:) { |"-#{ meta }"| ... } click to toggle source
# File lib/qb/options/option/option_parser_concern.rb, line 108
def option_parser_bool_args included:, &block
  # Don't use short names when included (for now)
  if !included && meta[:short]
    yield "-#{ meta[:short] }"
  end
  
  yield "--[no-]#{ cli_name }"
end
option_parser_default() { |"DEFAULT: --#{ ans_src_default ? '' : 'no-' }#{ cli_name }"| ... } click to toggle source
# File lib/qb/options/option/option_parser_concern.rb, line 137
def option_parser_default &block
  ans_src_default = role.defaults[var_name]
  
  # If we don't have shit in the role default Ansible source file, nothing
  # to do here
  return if ans_src_default.nil?
  
  if boolean?
    yield "DEFAULT: --#{ ans_src_default ? '' : 'no-' }#{ cli_name }"
  else
    # This is just the Ansible "source code", which is shitty and ugly
    # for anything that's not a literal, but it at least gives you something
    # to see
    option_parser_format_multiline "DEFAULT: #{ ans_src_default }", &block
  end
end
option_parser_description(&block) click to toggle source
# File lib/qb/options/option/option_parser_concern.rb, line 102
def option_parser_description &block
  option_parser_format_multiline description, &block
end
option_parser_examples() { |'Examples:'| ... } click to toggle source
# File lib/qb/options/option/option_parser_concern.rb, line 156
def option_parser_examples &block
  return unless has_examples?
  
  yield 'Examples:'
  
  examples.each_with_index do |example, index|
    lines = example.lines.to_a
    
    yield ((index + 1).to_s + '.').ljust(4) + lines.first.chomp
    
    lines[1..-1].each do |line|
      yield " ".ljust(4) + line.chomp
    end
  end
end
option_parser_non_bool_args(included:) { |"-#{ meta } #{ option_parser_value_name }"| ... } click to toggle source
# File lib/qb/options/option/option_parser_concern.rb, line 119
def option_parser_non_bool_args included:, &block
  # don't use short names when included (for now)
  if !included && meta[:short]
    yield "-#{ meta[:short] } #{ option_parser_value_name }"
  end
  
  # We allow options to also accept
  if accept_false?
    yield "--[no-]#{ cli_name }=#{ option_parser_value_name }"
  else
    yield "--#{ cli_name }=#{ option_parser_value_name }"
  end
  
  yield option_parser_type_acceptable
end
option_parser_type(&block) click to toggle source
# File lib/qb/options/option/option_parser_concern.rb, line 174
def option_parser_type &block
  option_parser_format_multiline "TYPE: #{ type }", &block
end

Protected Instance Methods

init_type!() click to toggle source

Initialize `@type` to the {NRSER::Types::Type} loaded from the option meta's `type` value.

@protected

@return [nil]

# File lib/qb/options/option.rb, line 132
def init_type!
  type_meta = meta[:type]
  
  if type_meta.nil?
    raise QB::Role::MetadataError.new \
      "Option", meta_name, "for role", role.name, "missing `type`",
      role_meta_path: role.meta_path,
      option_meta: meta
  end
  
  if  t.non_empty_str === type_meta &&
      type_meta.include?( '::' )
    
    const = type_meta.safe_constantize
    
    if  const &&
        const.is_a?( Class ) &&
        ( const < NRSER::Types::Type ||
          const < NRSER::Props )
      @type = const
      return
    end
    
  end
  
  message = t.match type_meta,
    t.non_empty_str, ->( str ) {
      NRSER::Message.new str
    },
    
    t.pair( value: (t.hash_ | t.array) ), ->( hash_pair ) {
      name, params = hash_pair.first
      
      NRSER::Message.from( name, params ).symbolize_options
    }
  
  @type = [
    QB::Options::Types,
    t,
  ].find_map { |mod|
    if mod.respond_to? message.symbol
      begin
        type = message.send_to mod
      rescue Exception => error
        logger.warn "Type factory failed",
          { message: message },
          error
        
        nil
      else
        type if type.is_a?( t::Type )
      end
    end
  }
  
  if @type.nil?
    raise QB::Role::MetadataError.new \
      "Unable to find type factory for", type_meta,
      role_meta_path: role.meta_path,
      option_meta: meta,
      message: message
  end
  
end