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
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 62 def feature(name, docs, hash = {}) 63 @features ||= {} 64 raise Puppet::DevError, _("Feature %{name} is already defined") % { name: name } if @features.include?(name) 65 begin 66 obj = ProviderFeature.new(name, docs, **hash) 67 @features[obj.name] = obj 68 rescue ArgumentError => detail 69 error = ArgumentError.new( 70 _("Could not create feature %{name}: %{detail}") % { name: name, detail: detail } 71 ) 72 error.set_backtrace(detail.backtrace) 73 raise error 74 end 75 end
Generates a module that sets up the boolean predicate methods to test for given features.
# File lib/puppet/util/provider_features.rb 115 def feature_module 116 unless defined?(@feature_module) 117 @features ||= {} 118 @feature_module = ::Module.new 119 const_set("FeatureModule", @feature_module) 120 features = @features 121 # Create a feature? method that can be passed a feature name and 122 # determine if the feature is present. 123 @feature_module.send(:define_method, :feature?) do |name| 124 method = name.to_s + "?" 125 return !!(respond_to?(method) and send(method)) 126 end 127 128 # Create a method that will list all functional features. 129 @feature_module.send(:define_method, :features) do 130 return false unless defined?(features) 131 features.keys.find_all { |n| feature?(n) }.sort_by(&:to_s) 132 end 133 134 # Create a method that will determine if a provided list of 135 # features are satisfied by the curred provider. 136 @feature_module.send(:define_method, :satisfies?) do |*needed| 137 ret = true 138 needed.flatten.each do |feature| 139 unless feature?(feature) 140 ret = false 141 break 142 end 143 end 144 ret 145 end 146 147 # Create a boolean method for each feature so you can test them 148 # individually as you might need. 149 @features.each do |name, feature| 150 method = name.to_s + "?" 151 @feature_module.send(:define_method, method) do 152 (is_a?(Class) ? declared_feature?(name) : self.class.declared_feature?(name)) or feature.available?(self) 153 end 154 end 155 156 # Allow the provider to declare that it has a given feature. 157 @feature_module.send(:define_method, :has_features) do |*names| 158 @declared_features ||= [] 159 names.each do |name| 160 @declared_features << name.intern 161 end 162 end 163 # Aaah, grammatical correctness 164 @feature_module.send(:alias_method, :has_feature, :has_features) 165 end 166 @feature_module 167 end
@return [String] Returns a string with documentation covering all features.
# File lib/puppet/util/provider_features.rb 78 def featuredocs 79 str = String.new 80 @features ||= {} 81 return nil if @features.empty? 82 names = @features.keys.sort_by(&:to_s) 83 names.each do |name| 84 doc = @features[name].docs.gsub(/\n\s+/, " ") 85 str << "- *#{name}*: #{doc}\n" 86 end 87 88 if providers.length > 0 89 headers = ["Provider", names].flatten 90 data = {} 91 providers.each do |provname| 92 data[provname] = [] 93 prov = provider(provname) 94 names.each do |name| 95 if prov.feature?(name) 96 data[provname] << "*X*" 97 else 98 data[provname] << "" 99 end 100 end 101 end 102 str << doctable(headers, data) 103 end 104 str 105 end
@return [Array<String>] Returns a list of features.
# File lib/puppet/util/provider_features.rb 108 def features 109 @features ||= {} 110 @features.keys 111 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 174 def provider_feature(name) 175 return nil unless defined?(@features) 176 177 @features[name] 178 end