# class Puppet::Interface::Option

This represents an option on an action or face (to be globally applied to its actions). Options should be constructed by calling {Puppet::Interface::OptionManager#option}, which is available on {Puppet::Interface}, and then calling methods of {Puppet::Interface::OptionBuilder} in the supplied block. @api public

### Attributes

after_action[RW]
aliases[R]
before_action[RW]
name[R]
optparse[R]
parent[R]
required[RW]

### Public Class Methods

new(parent, *declaration, &block) click to toggle source

@api private

    # File lib/puppet/interface/option.rb, line 13
    def initialize(parent, *declaration, &block)
      @parent   = parent
      @optparse = []
      @default  = nil

      # Collect and sort the arguments in the declaration.
      dups = {}
      declaration.each do |item|
        if item.is_a? String and item.to_s =~ /^-/ then
          unless item =~ /^-[a-z]\b/ or item =~ /^--[^-]/ then
            raise ArgumentError, "#{item.inspect}: long options need two dashes (--)"
          end
          @optparse << item

          # Duplicate checking...
          # for our duplicate checking purpose, we don't make a check with the
          # translated '-' -> '_'. Right now, we do that on purpose because of
          # a duplicated option made publicly available on certificate and ca
          # faces for dns alt names. Puppet defines 'dns_alt_names', those
          # faces include 'dns-alt-names'.  We can't get rid of 'dns-alt-names'
          # yet, so we need to do our duplicate checking on the untranslated
          # version of the option.
          # jeffweiss 17 april 2012
          name = optparse_to_optionname(item)
          if Puppet.settings.include? name then
            raise ArgumentError, "#{item.inspect}: already defined in puppet"
          end
          if dup = dups[name] then
            raise ArgumentError, "#{item.inspect}: duplicates existing alias #{dup.inspect} in #{@parent}"
          else
            dups[name] = item
          end
        else
          raise ArgumentError, "#{item.inspect} is not valid for an option argument"
        end
      end

      if @optparse.empty? then
        raise ArgumentError, "No option declarations found while building"
      end

      # Now, infer the name from the options; we prefer the first long option as
      # the name, rather than just the first option.
      @name = optparse_to_name(@optparse.find do |a| a =~ /^--/ end || @optparse.first)
      @aliases = @optparse.map { |o| optparse_to_name(o) }

      # Do we take an argument?  If so, are we consistent about it, because
      # incoherence here makes our life super-difficult, and we can more easily
      # relax this rule later if we find a valid use case for it. --daniel 2011-03-30
      @argument = @optparse.any? { |o| o =~ /[ =]/ }
      if @argument and not @optparse.all? { |o| o =~ /[ =]/ } then
        raise ArgumentError, "Option #{@name} is inconsistent about taking an argument"
      end

      # Is our argument optional?  The rules about consistency apply here, also,
      # just like they do to taking arguments at all. --daniel 2011-03-30
      @optional_argument = @optparse.any? { |o| o=~/[ =]\[/ }
      @optional_argument and raise ArgumentError, "Options with optional arguments are not supported"
      if @optional_argument and not @optparse.all? { |o| o=~/[ =]\[/ } then
        raise ArgumentError, "Option #{@name} is inconsistent about the argument being optional"
      end
    end

### Public Instance Methods

__decoration_name(type) click to toggle source

    # File lib/puppet/interface/option.rb, line 145
    def __decoration_name(type)
      if @parent.is_a? Puppet::Interface::Action then
        :"option #{name} from #{parent.name} #{type} decoration"
      else
        :"option #{name} #{type} decoration"
      end
    end

after_action=(proc) click to toggle source

    # File lib/puppet/interface/option.rb, line 139
    def after_action=(proc)
      proc.is_a? Proc or raise ArgumentError, "after action hook for #{self} is a #{proc.class.name.inspect}, not a proc"
      @after_action =
        @parent.__send__(:__add_method, __decoration_name(:after), proc)
    end

before_action=(proc) click to toggle source

    # File lib/puppet/interface/option.rb, line 132
    def before_action=(proc)
      proc.is_a? Proc or raise ArgumentError, "before action hook for #{self} is a #{proc.class.name.inspect}, not a proc"
      @before_action =
        @parent.__send__(:__add_method, __decoration_name(:before), proc)
    end

default() click to toggle source

    # File lib/puppet/interface/option.rb, line 120
    def default
      @default and @default.call
    end

default=(proc) click to toggle source

    # File lib/puppet/interface/option.rb, line 114
    def default=(proc)
      required and raise ArgumentError, "#{self} can't be optional and have a default value"
      proc.is_a? Proc or raise ArgumentError, "default value for #{self} is a #{proc.class.name.inspect}, not a proc"
      @default = proc
    end

has_default?() click to toggle source

    # File lib/puppet/interface/option.rb, line 110
    def has_default?
      !!@default
    end

optional_argument?() click to toggle source

    # File lib/puppet/interface/option.rb, line 103
    def optional_argument?
      !!@optional_argument
    end

optparse_to_name(declaration) click to toggle source

@api private

    # File lib/puppet/interface/option.rb, line 93
    def optparse_to_name(declaration)
      name = optparse_to_optionname(declaration).tr('-', '_')
      raise "#{name.inspect} is an invalid option name" unless name.to_s =~ /^[a-z]\w*$/
      name.to_sym
    end

optparse_to_optionname(declaration) click to toggle source

@api private

    # File lib/puppet/interface/option.rb, line 85
    def optparse_to_optionname(declaration)
      unless found = declaration.match(/^-+(?:\[no-\])?([^ =]+)/) then
        raise ArgumentError, "Can't find a name in the declaration #{declaration.inspect}"
      end
      name = found.captures.first
    end

required=(value) click to toggle source

    # File lib/puppet/interface/option.rb, line 126
    def required=(value)
      has_default? and raise ArgumentError, "#{self} can't be optional and have a default value"
      @required = value
    end

required?() click to toggle source

    # File lib/puppet/interface/option.rb, line 106
    def required?
      !!@required
    end

takes_argument?() click to toggle source

    # File lib/puppet/interface/option.rb, line 100
    def takes_argument?
      !!@argument
    end

to_s() click to toggle source

#to_s and #optparse_to_name are roughly mirrored, because they are used to transform options to name symbols, and vice-versa. This isn't a full bidirectional transformation though. --daniel 2011-04-07

    # File lib/puppet/interface/option.rb, line 80
    def to_s
      @name.to_s.tr('_', '-')
    end