# module Puppet::Util::ProviderFeatures

This module models provider features and handles checking whether the features are present. @todo Unclear what is api and what is private in this module.

### Public Instance Methods

feature(name, docs, hash = {}) click to toggle source

Defines one feature. At a minimum, a feature requires a name and docs, and at this point they should also specify a list of methods required to determine if the feature is present. @todo How methods that determine if the feature is present are specified.

    # File lib/puppet/util/provider_features.rb, line 64
    def feature(name, docs, hash = {})
      @features ||= {}
      raise(Puppet::DevError, "Feature #{name} is already defined") if @features.include?(name)
      begin
        obj = ProviderFeature.new(name, docs, hash)
        @features[obj.name] = obj
      rescue ArgumentError => detail
        error = ArgumentError.new(
          "Could not create feature #{name}: #{detail}"
        )
        error.set_backtrace(detail.backtrace)
        raise error
      end
    end

feature_module() click to toggle source

Generates a module that sets up the boolean predicate methods to test for given features.

    # File lib/puppet/util/provider_features.rb, line 117
    def feature_module
      unless defined?(@feature_module)
        @features ||= {}
        @feature_module = ::Module.new
        const_set("FeatureModule", @feature_module)
        features = @features
        # Create a feature? method that can be passed a feature name and
        # determine if the feature is present.
        @feature_module.send(:define_method, :feature?) do |name|
          method = name.to_s + "?"
          return !!(respond_to?(method) and send(method))
        end

        # Create a method that will list all functional features.
        @feature_module.send(:define_method, :features) do
          return false unless defined?(features)
          features.keys.find_all { |n| feature?(n) }.sort { |a,b|
            a.to_s <=> b.to_s
          }
        end

        # Create a method that will determine if a provided list of
        # features are satisfied by the curred provider.
        @feature_module.send(:define_method, :satisfies?) do |*needed|
          ret = true
          needed.flatten.each do |feature|
            unless feature?(feature)
              ret = false
              break
            end
          end
          ret
        end

        # Create a boolean method for each feature so you can test them
        # individually as you might need.
        @features.each do |name, feature|
          method = name.to_s + "?"
          @feature_module.send(:define_method, method) do
            (is_a?(Class) ?  declared_feature?(name) : self.class.declared_feature?(name)) or feature.available?(self)
          end
        end

        # Allow the provider to declare that it has a given feature.
        @feature_module.send(:define_method, :has_features) do |*names|
          @declared_features ||= []
          names.each do |name|
            @declared_features << name.intern
          end
        end
        # Aaah, grammatical correctness
        @feature_module.send(:alias_method, :has_feature, :has_features)
      end
      @feature_module
    end

featuredocs() click to toggle source

@return [String] Returns a string with documentation covering all features.

    # File lib/puppet/util/provider_features.rb, line 80
    def featuredocs
      str = ""
      @features ||= {}
      return nil if @features.empty?
      names = @features.keys.sort { |a,b| a.to_s <=> b.to_s }
      names.each do |name|
        doc = @features[name].docs.gsub(/\n\s+/, " ")
        str += "- *#{name}*: #{doc}\n"
      end

      if providers.length > 0
        headers = ["Provider", names].flatten
        data = {}
        providers.each do |provname|
          data[provname] = []
          prov = provider(provname)
          names.each do |name|
            if prov.feature?(name)
              data[provname] << "*X*"
            else
              data[provname] << ""
            end
          end
        end
        str += doctable(headers, data)
      end
      str
    end

features() click to toggle source

@return [Array<String>] Returns a list of features.

    # File lib/puppet/util/provider_features.rb, line 110
    def features
      @features ||= {}
      @features.keys
    end

provider_feature(name) click to toggle source

@return [ProviderFeature] Returns a provider feature instance by name. @param name [String] the name of the feature to return @note Should only be used for testing. @api private

    # File lib/puppet/util/provider_features.rb, line 178
    def provider_feature(name)
      return nil unless defined?(@features)

      @features[name]
    end