Class: Puppet::Util::Autoload
- Extended by:
- Concurrent::Synchronized
- Includes:
- Concurrent::Synchronized
- Defined in:
- lib/puppet/util/autoload.rb
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
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.
180 181 182 183 184 185 |
# File 'lib/puppet/util/autoload.rb', line 180 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.
33 34 35 |
# File 'lib/puppet/util/autoload.rb', line 33 def loaded @loaded end |
Instance Attribute Details
#object ⇒ Object
Returns the value of attribute object.
178 179 180 |
# File 'lib/puppet/util/autoload.rb', line 178 def object @object end |
#path ⇒ Object
Returns the value of attribute path.
178 179 180 |
# File 'lib/puppet/util/autoload.rb', line 178 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.
61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/puppet/util/autoload.rb', line 61 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.
173 174 175 |
# File 'lib/puppet/util/autoload.rb', line 173 def cleanpath(path) Pathname.new(path).cleanpath.to_s 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.
124 125 126 127 128 129 |
# File 'lib/puppet/util/autoload.rb', line 124 def files_in_dir(dir, path) dir = Pathname.new(Puppet::FileSystem.(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
119 120 121 |
# File 'lib/puppet/util/autoload.rb', line 119 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.
139 140 141 |
# File 'lib/puppet/util/autoload.rb', line 139 def gem_directories gem_source.directories end |
.gem_source ⇒ Object
35 36 37 |
# File 'lib/puppet/util/autoload.rb', line 35 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
113 114 115 116 117 |
# File 'lib/puppet/util/autoload.rb', line 113 def get_file(name, env) 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.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/puppet/util/autoload.rb', line 77 def load_file(name, env) file = get_file(name.to_s, env) return false unless file begin mark_loaded(name, file) Kernel.load file 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
94 95 96 97 98 99 100 |
# File 'lib/puppet/util/autoload.rb', line 94 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.
44 45 46 47 |
# File 'lib/puppet/util/autoload.rb', line 44 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.
53 54 55 56 57 58 |
# File 'lib/puppet/util/autoload.rb', line 53 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.
132 133 134 135 136 |
# File 'lib/puppet/util/autoload.rb', line 132 def module_directories(env) raise ArgumentError, "Autoloader requires an environment" unless env Puppet::Util::ModuleDirectoriesAdapter.adapt(env).directories end |
.reload_changed(env) ⇒ Object
102 103 104 105 106 107 108 |
# File 'lib/puppet/util/autoload.rb', line 102 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.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/puppet/util/autoload.rb', line 144 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? gem_directories + module_directories(env) + $LOAD_PATH else gem_directories + $LOAD_PATH 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.
210 211 212 |
# File 'lib/puppet/util/autoload.rb', line 210 def changed?(name, env) self.class.changed?((name), env) end |
#expand(name) ⇒ Object
218 219 220 |
# File 'lib/puppet/util/autoload.rb', line 218 def (name) ::File.join(@path, name.to_s) end |
#files_to_load(env) ⇒ Object
214 215 216 |
# File 'lib/puppet/util/autoload.rb', line 214 def files_to_load(env) self.class.files_to_load(@path, env) end |
#load(name, env) ⇒ Object
187 188 189 |
# File 'lib/puppet/util/autoload.rb', line 187 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.
201 202 203 |
# File 'lib/puppet/util/autoload.rb', line 201 def loadall(env) self.class.loadall(@path, env) end |
#loaded?(name) ⇒ Boolean
205 206 207 |
# File 'lib/puppet/util/autoload.rb', line 205 def loaded?(name) self.class.loaded?((name)) end |