Module: Puppet::Util::ProviderFeatures

Includes:
Docs
Included in:
Type
Defined in:
lib/puppet/util/provider_features.rb

Overview

TODO:

Unclear what is api and what is private in this module.

This module models provider features and handles checking whether the features are present.

Defined Under Namespace

Classes: ProviderFeature

Constant Summary

Constants included from Docs

Docs::HEADER_LEVELS

Instance Attribute Summary

Attributes included from Docs

#doc, #nodoc

Instance Method Summary collapse

Methods included from Docs

#desc, #dochook, #doctable, #markdown_definitionlist, #markdown_header, #nodoc?, #pad, scrub

Instance Method Details

#feature(name, docs, hash = {}) ⇒ Object

TODO:

How methods that determine if the feature is present are specified.

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.

Raises:


61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/puppet/util/provider_features.rb', line 61

def feature(name, docs, hash = {})
  @features ||= {}
  raise Puppet::DevError, _("Feature %{name} is already defined") % { name: name } 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}") % { name: name, detail: detail }
    )
    error.set_backtrace(detail.backtrace)
    raise error
  end
end

#feature_moduleObject

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


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/puppet/util/provider_features.rb', line 114

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_by(&: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

#featuredocsString


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/puppet/util/provider_features.rb', line 77

def featuredocs
  str = ""
  @features ||= {}
  return nil if @features.empty?
  names = @features.keys.sort_by(&: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

#featuresArray<String>


107
108
109
110
# File 'lib/puppet/util/provider_features.rb', line 107

def features
  @features ||= {}
  @features.keys
end

#provider_feature(name) ⇒ ProviderFeature

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

Should only be used for testing.

Returns a provider feature instance by name.


173
174
175
176
177
# File 'lib/puppet/util/provider_features.rb', line 173

def provider_feature(name)
  return nil unless defined?(@features)

  @features[name]
end