Class: Puppet::Util::Autoload
Overview
Autoload paths, either based on names or all at once.
Class Attribute Summary collapse
-
.loaded ⇒ Object
Returns the value of attribute loaded.
Instance Attribute Summary collapse
-
#object ⇒ Object
Returns the value of attribute object.
-
#path ⇒ Object
Returns the value of attribute path.
Class Method Summary collapse
- .changed?(name, env) ⇒ Boolean private
-
.cleanpath(path) ⇒ Object
Normalize a path.
- .files_in_dir(dir, path) ⇒ Object private
- .files_to_load(path, env) ⇒ Object
- .gem_directories ⇒ Object private
- .gem_source ⇒ Object
-
.get_file(name, env) ⇒ Object
private
Get the correct file to load for a given path returns nil if no file is found.
-
.load_file(name, env) ⇒ Object
Load a single plugin by name.
- .loadall(path, env) ⇒ Object
-
.loaded?(path) ⇒ Boolean
Has a given path been loaded? This is used for testing whether a changed file should be loaded or just ignored.
-
.mark_loaded(name, file) ⇒ Object
private
Save the fact that a given path has been loaded.
- .module_directories(env) ⇒ Object private
- .reload_changed(env) ⇒ Object
- .search_directories(env) ⇒ Object private
- .vendored_modules ⇒ Object private
Instance Method Summary collapse
- #changed?(name, env) ⇒ Boolean private
- #expand(name) ⇒ Object
- #files_to_load(env) ⇒ Object
-
#initialize(obj, path) ⇒ Autoload
constructor
A new instance of Autoload.
- #load(name, env) ⇒ Object
-
#loadall(env) ⇒ Object
Load all instances from a path of Autoload.search_directories matching the relative path this Autoloader was initialized with.
- #loaded?(name) ⇒ Boolean
Constructor Details
#initialize(obj, path) ⇒ Autoload
Returns a new instance of Autoload.
194 195 196 197 198 |
# File 'lib/puppet/util/autoload.rb', line 194 def initialize(obj, path) @path = path.to_s raise ArgumentError, _("Autoload paths cannot be fully qualified") if Puppet::Util.absolute_path?(@path) @object = obj end |
Class Attribute Details
.loaded ⇒ Object
Returns the value of attribute loaded.
19 20 21 |
# File 'lib/puppet/util/autoload.rb', line 19 def loaded @loaded end |
Instance Attribute Details
#object ⇒ Object
Returns the value of attribute object.
192 193 194 |
# File 'lib/puppet/util/autoload.rb', line 192 def object @object end |
#path ⇒ Object
Returns the value of attribute path.
192 193 194 |
# File 'lib/puppet/util/autoload.rb', line 192 def path @path end |
Class Method Details
.changed?(name, env) ⇒ Boolean
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.
47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/puppet/util/autoload.rb', line 47 def changed?(name, env) name = cleanpath(name).chomp('.rb') return true unless loaded.include?(name) file, old_mtime = loaded[name] return true unless file == get_file(name, env) begin old_mtime.to_i != File.mtime(file).to_i rescue Errno::ENOENT true end end |
.cleanpath(path) ⇒ Object
Normalize a path. This converts ALT_SEPARATOR to SEPARATOR on Windows and eliminates unnecessary parts of a path.
180 181 182 183 184 185 186 187 188 189 |
# File 'lib/puppet/util/autoload.rb', line 180 def cleanpath(path) # There are two cases here because cleanpath does not handle absolute # paths correctly on windows (c:\ and c:/ are treated as distinct) but # we don't want to convert relative paths to absolute if Puppet::Util.absolute_path?(path) File.(path) else Pathname.new(path).cleanpath.to_s end end |
.files_in_dir(dir, path) ⇒ Object
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.
107 108 109 110 111 112 |
# File 'lib/puppet/util/autoload.rb', line 107 def files_in_dir(dir, path) dir = Pathname.new(File.(dir)) Dir.glob(File.join(dir, path, "*.rb")).collect do |file| Pathname.new(file).relative_path_from(dir).to_s end end |
.files_to_load(path, env) ⇒ Object
102 103 104 |
# File 'lib/puppet/util/autoload.rb', line 102 def files_to_load(path, env) search_directories(env).map {|dir| files_in_dir(dir, path) }.flatten.uniq end |
.gem_directories ⇒ Object
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.
141 142 143 |
# File 'lib/puppet/util/autoload.rb', line 141 def gem_directories gem_source.directories end |
.gem_source ⇒ Object
21 22 23 |
# File 'lib/puppet/util/autoload.rb', line 21 def gem_source @gem_source ||= Puppet::Util::RubyGems::Source.new end |
.get_file(name, env) ⇒ Object
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.
Get the correct file to load for a given path returns nil if no file is found
96 97 98 99 100 |
# File 'lib/puppet/util/autoload.rb', line 96 def get_file(name, env) name = name + '.rb' unless name =~ /\.rb$/ path = search_directories(env).find { |dir| Puppet::FileSystem.exist?(File.join(dir, name)) } path and File.join(path, name) end |
.load_file(name, env) ⇒ Object
Load a single plugin by name. We use ‘load’ here so we can reload a given plugin.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/puppet/util/autoload.rb', line 61 def load_file(name, env) file = get_file(name.to_s, env) return false unless file begin mark_loaded(name, file) Kernel.load file return true rescue SystemExit,NoMemoryError raise rescue Exception => detail = _("Could not autoload %{name}: %{detail}") % { name: name, detail: detail } Puppet.log_exception(detail, ) raise Puppet::Error, , detail.backtrace end end |
.loadall(path, env) ⇒ Object
77 78 79 80 81 82 83 |
# File 'lib/puppet/util/autoload.rb', line 77 def loadall(path, env) # Load every instance of everything we can find. files_to_load(path, env).each do |file| name = file.chomp(".rb") load_file(name, env) unless loaded?(name) end end |
.loaded?(path) ⇒ Boolean
Has a given path been loaded? This is used for testing whether a changed file should be loaded or just ignored. This is only used in network/client/master, when downloading plugins, to see if a given plugin is currently loaded and thus should be reloaded.
30 31 32 33 |
# File 'lib/puppet/util/autoload.rb', line 30 def loaded?(path) path = cleanpath(path).chomp('.rb') loaded.include?(path) end |
.mark_loaded(name, file) ⇒ Object
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.
Save the fact that a given path has been loaded. This is so we can load downloaded plugins if they’ve already been loaded into memory.
39 40 41 42 43 44 |
# File 'lib/puppet/util/autoload.rb', line 39 def mark_loaded(name, file) name = cleanpath(name).chomp('.rb') file = File.(file) $LOADED_FEATURES << file unless $LOADED_FEATURES.include?(file) loaded[name] = [file, File.mtime(file)] end |
.module_directories(env) ⇒ Object
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.
115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/puppet/util/autoload.rb', line 115 def module_directories(env) raise ArgumentError, "Autoloader requires an environment" unless env Puppet::Util::ModuleDirectoriesAdapter.adapt(env) do |a| a.directories ||= env.modulepath.collect do |dir| Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f, "lib") } end.flatten.find_all do |d| FileTest.directory?(d) end end.directories end |
.reload_changed(env) ⇒ Object
85 86 87 88 89 90 91 |
# File 'lib/puppet/util/autoload.rb', line 85 def reload_changed(env) loaded.keys.each do |file| if changed?(file, env) load_file(file, env) end end end |
.search_directories(env) ⇒ Object
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.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/puppet/util/autoload.rb', line 146 def search_directories(env) # This is a little bit of a hack. Basically, the autoloader is being # called indirectly during application bootstrapping when we do things # such as check "features". However, during bootstrapping, we haven't # yet parsed all of the command line parameters nor the config files, # and thus we don't yet know with certainty what the module path is. # This should be irrelevant during bootstrapping, because anything that # we are attempting to load during bootstrapping should be something # that we ship with puppet, and thus the module path is irrelevant. # # In the long term, I think the way that we want to handle this is to # have the autoloader ignore the module path in all cases where it is # not specifically requested (e.g., by a constructor param or # something)... because there are very few cases where we should # actually be loading code from the module path. However, until that # happens, we at least need a way to prevent the autoloader from # attempting to access the module path before it is initialized. For # now we are accomplishing that by calling the # "app_defaults_initialized?" method on the main puppet Settings object. # --cprice 2012-03-16 if Puppet.settings.app_defaults_initialized? unless @initialized $LOAD_PATH.unshift(Puppet[:libdir]) $LOAD_PATH.concat(vendored_modules) @initialized = true end gem_directories + module_directories(env) + $LOAD_PATH else gem_directories + $LOAD_PATH end end |
.vendored_modules ⇒ Object
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.
128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/puppet/util/autoload.rb', line 128 def vendored_modules dir = Puppet[:vendormoduledir] if dir && File.directory?(dir) Dir.entries(dir) .reject { |f| f =~ /^\./ } .collect { |f| File.join(dir, f, "lib") } .find_all { |d| FileTest.directory?(d) } else [] end end |
Instance Method Details
#changed?(name, env) ⇒ Boolean
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.
223 224 225 |
# File 'lib/puppet/util/autoload.rb', line 223 def changed?(name, env) self.class.changed?((name), env) end |
#expand(name) ⇒ Object
231 232 233 |
# File 'lib/puppet/util/autoload.rb', line 231 def (name) ::File.join(@path, name.to_s) end |
#files_to_load(env) ⇒ Object
227 228 229 |
# File 'lib/puppet/util/autoload.rb', line 227 def files_to_load(env) self.class.files_to_load(@path, env) end |
#load(name, env) ⇒ Object
200 201 202 |
# File 'lib/puppet/util/autoload.rb', line 200 def load(name, env) self.class.load_file((name), env) end |
#loadall(env) ⇒ Object
Load all instances from a path of Autoload.search_directories matching the relative path this Autoloader was initialized with. For example, if we have created a Puppet::Util::Autoload for Puppet::Type::User with a path of ‘puppet/provider/user’, the search_directories path will be searched for all ruby files matching puppet/provider/user/*.rb and they will then be loaded from the first directory in the search path providing them. So earlier entries in the search path may shadow later entries.
This uses require, rather than load, so that already-loaded files don’t get reloaded unnecessarily.
214 215 216 |
# File 'lib/puppet/util/autoload.rb', line 214 def loadall(env) self.class.loadall(@path, env) end |
#loaded?(name) ⇒ Boolean
218 219 220 |
# File 'lib/puppet/util/autoload.rb', line 218 def loaded?(name) self.class.loaded?((name)) end |