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