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.
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
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
@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
@return [Array<String>] Returns a list of features.
# File lib/puppet/util/provider_features.rb, line 110 def features @features ||= {} @features.keys end
@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