class Opto::Group

A group of Opto::Option instances. Members of Groups can see their relatives and their values. Such as `option.value_of('another_option')`

Most Array instance methods are delegated, such as .map, .each, .find etc.

Public Class Methods

new(*opts) click to toggle source

Initialize a new Option Group. You can also pass in :defaults.

@param [Array<Hash,Opto::Option>,Hash,NilClass] opts An array of Option definition hashes or Option objects or a hash like { var_name: { opts } }. @return [Opto::Group]

# File lib/opto/group.rb, line 20
def initialize(*opts)
  case opts.first
  when NilClass
  when Hash
    defaults.merge!(opts.first.delete(:defaults)) if opts.first.key?(:defaults)
    setters.merge!(opts.first.delete(:setters)) if opts.first.key?(:setters)
    resolvers.merge!(opts.first.delete(:resolvers)) if opts.first.key?(:resolvers)
    options.concat(opts.first.map {|k,v| Option.new({name: k.to_s, group: self}.merge(v))})
  when ::Array
    if opts.last.is_a?(Hash) && !opts.last.key?(:type)
      opts.pop.tap do |settings|
        defaults.merge!(settings[:defaults]) if settings.key?(:defaults)
        setters.merge!(settings[:setters]) if settings.key?(:setters)
        resolvers.merge!(settings[:resolvers]) if settings.key?(:resolvers)
      end
    end
    if opts.first.kind_of?(Array)
      options.concat(opts.first.map { |opt| opt.kind_of?(Opto::Option) ? opt : Option.new(opt.merge(group: self)) })
    end
  else
    raise TypeError, "Invalid type #{opts.class} for Opto::Group.new"
  end
end

Public Instance Methods

all_true?(conditions) click to toggle source
# File lib/opto/group.rb, line 144
def all_true?(conditions)
  normalize_ifs(conditions).all? { |s| s.call(self) == true }
end
any_true?(conditions) click to toggle source
# File lib/opto/group.rb, line 140
def any_true?(conditions)
  normalize_ifs(conditions).any? { |s| s.call(self) == true }
end
build_option(args={}) click to toggle source

Initialize a new Option to this group. Takes the same arguments as Opto::Option @param [Hash] option_definition @return [Opto::Option]

# File lib/opto/group.rb, line 102
def build_option(args={})
  options << Option.new(args.merge(group: self))
  options.last
end
defaults() click to toggle source
# File lib/opto/group.rb, line 56
def defaults
  @defaults ||= {}
end
errors() click to toggle source

Collect validation errors from members @return [Hash] { option_name => { validator_name => “Too short” } }

# File lib/opto/group.rb, line 68
def errors
  Hash[*options_with_errors.flat_map {|o| [o.name, o.errors] }]
end
normalize_ifs(ifs) click to toggle source
# File lib/opto/group.rb, line 148
def normalize_ifs(ifs)
  case ifs
  when NilClass
    []
  when ::Array
    ifs.map do |iff|
      lambda { |grp| grp.option(iff).true?  }
    end
  when Hash
    ifs.each_with_object([]) do |(k, v), arr|
      if v.kind_of?(Hash)
        if v.has_key?(:lt)
          arr << lambda { |grp| grp.value_of(k.to_s) < v[:lt] }
        end

        if v.has_key?(:lte)
          arr << lambda { |grp| grp.value_of(k.to_s) <= v[:lte] }
        end

        if v.has_key?(:gt)
          arr << lambda { |grp| grp.value_of(k.to_s) > v[:gt] }
        end

        if v.has_key?(:gte)
          arr << lambda { |grp| grp.value_of(k.to_s) > v[:gte] }
        end

        if v.has_key?(:eq)
          arr << lambda { |grp| grp.value_of(k.to_s) == v[:eq] }
        end

        if v.has_key?(:ne)
          arr << lambda { |grp| grp.value_of(k.to_s) != v[:ne] }
        end

        if v.has_key?(:start_with)
          arr << lambda { |grp| grp.value_of(k.to_s).to_s.start_with?(v[:start_with]) }
        end

        if v.has_key?(:end_with)
          arr << lambda { |grp| grp.value_of(k.to_s).to_s.end_with?(v[:end_with]) }
        end

        if v.has_key?(:contain)
          arr << lambda { |grp| grp.value_of(k.to_s).kind_of?(::Array) ? grp.value_of(k.to_s).include?(v[:contain]) : grp.value_of(k.to_s).to_s.include?(v[:contain]) }
        end

        if v.has_key?(:any_of)
          arr << lambda do |grp|
            if v[:any_of].kind_of?(String)
              arr = v[:any_of].split(",")
            elsif v[:any_of].kind_of?(::Array)
              arr = v[:any_of]
            else
              raise TypeError, "Invalid list for 'any_of'. Expected: Array or a comma separated string"
            end
            arr.include?(grp.value_of(k.to_s))
          end
        end
      else
        arr << lambda { |grp| grp.value_of(k.to_s) == v }
      end
    end
  when String, Symbol
    normalize_ifs([ifs])
  else
    raise TypeError, "Invalid syntax for conditional"
  end
end
option(option_name) click to toggle source

Find a member by name @param  option_name @return [Opto::Option]

# File lib/opto/group.rb, line 110
def option(option_name)
  if option_name.to_s.include?('.')
    parts = option_name.to_s.split('.')
    var_name = parts.pop
    group = parts.inject(self) do |base, part|
      grp = base.option(part).value
      if grp.nil?
        raise NameError, "No such group: #{base.name}.#{part}"
      elsif grp.kind_of?(Opto::Group)
        grp
      else
        raise TypeError, "Is not a group: #{base.name}.#{part}"
      end
    end
  else
    group = self
    var_name = option_name
  end

  group.options.find { |opt| opt.name == var_name }
end
options() click to toggle source
# File lib/opto/group.rb, line 44
def options
  @options ||= []
end
options_with_errors() click to toggle source

Enumerate over all the options that are not valid @return [Array]

# File lib/opto/group.rb, line 74
def options_with_errors
  options.reject(&:valid?)
end
resolvers() click to toggle source
# File lib/opto/group.rb, line 52
def resolvers
  @resolvers ||= {}
end
run() click to toggle source

Runs outputters for all valid non-skipped options

# File lib/opto/group.rb, line 95
def run
  options.reject(&:skip?).select(&:valid?).each(&:output)
end
setters() click to toggle source
# File lib/opto/group.rb, line 48
def setters
  @setters ||= {}
end
to_a(with_errors: false, with_values: false) click to toggle source

Convert Group to an Array of Hashes (by calling .to_h on each member) @return [Array<Hash>]

# File lib/opto/group.rb, line 80
def to_a(with_errors: false, with_values: false)
  options.map {|opt| opt.to_h(with_errors: with_errors, with_value: with_values) }
end
to_h(values_only: false, with_values: false, with_errors: false) click to toggle source

Convert a Group to a hash that has { option_name => option_value } @return [Hash]

# File lib/opto/group.rb, line 86
def to_h(values_only: false, with_values: false, with_errors: false)
  if values_only
    Hash[*options.flat_map {|opt| [opt.name, opt.type == 'group' ? opt.value.to_h(values_only: true) : opt.value]}]
  else
    Hash[*options.flat_map {|opt| [opt.name, opt.to_h(with_value: with_values, with_errors: with_errors).reject {|k,_| k==:name}]}]
  end
end
valid?() click to toggle source

Are all options valid? (Option value passes validation) @return [Boolean]

# File lib/opto/group.rb, line 62
def valid?
  options.all? {|o| o.valid? }
end
value_of(option_name) click to toggle source

Get a value of a member by option name @param [String] option_name @return [option_value, NilClass]

# File lib/opto/group.rb, line 135
def value_of(option_name)
  opt = option(option_name)
  opt.nil? ? nil : opt.value
end