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.
182 183 184 185 186 |
# File 'lib/puppet/util/autoload.rb', line 182 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.
31 32 33 |
# File 'lib/puppet/util/autoload.rb', line 31 def loaded @loaded end |
Instance Attribute Details
#object ⇒ Object
Returns the value of attribute object.
180 181 182 |
# File 'lib/puppet/util/autoload.rb', line 180 def object @object end |
#path ⇒ Object
Returns the value of attribute path.
180 181 182 |
# File 'lib/puppet/util/autoload.rb', line 180 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.
59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/puppet/util/autoload.rb', line 59 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.
168 169 170 171 172 173 174 175 176 177 |
# File 'lib/puppet/util/autoload.rb', line 168 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.
119 120 121 122 123 124 |
# File 'lib/puppet/util/autoload.rb', line 119 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
114 115 116 |
# File 'lib/puppet/util/autoload.rb', line 114 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.
134 135 136 |
# File 'lib/puppet/util/autoload.rb', line 134 def gem_directories gem_source.directories end |
.gem_source ⇒ Object
33 34 35 |
# File 'lib/puppet/util/autoload.rb', line 33 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
108 109 110 111 112 |
# File 'lib/puppet/util/autoload.rb', line 108 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.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/puppet/util/autoload.rb', line 73 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
89 90 91 92 93 94 95 |
# File 'lib/puppet/util/autoload.rb', line 89 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.
42 43 44 45 |
# File 'lib/puppet/util/autoload.rb', line 42 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.
51 52 53 54 55 56 |
# File 'lib/puppet/util/autoload.rb', line 51 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.
127 128 129 130 131 |
# File 'lib/puppet/util/autoload.rb', line 127 def module_directories(env) raise ArgumentError, "Autoloader requires an environment" unless env Puppet::Util::ModuleDirectoriesAdapter.adapt(env).directories end |
.reload_changed(env) ⇒ Object
97 98 99 100 101 102 103 |
# File 'lib/puppet/util/autoload.rb', line 97 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.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/puppet/util/autoload.rb', line 139 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.
211 212 213 |
# File 'lib/puppet/util/autoload.rb', line 211 def changed?(name, env) self.class.changed?((name), env) end |
#expand(name) ⇒ Object
219 220 221 |
# File 'lib/puppet/util/autoload.rb', line 219 def (name) ::File.join(@path, name.to_s) end |
#files_to_load(env) ⇒ Object
215 216 217 |
# File 'lib/puppet/util/autoload.rb', line 215 def files_to_load(env) self.class.files_to_load(@path, env) end |
#load(name, env) ⇒ Object
188 189 190 |
# File 'lib/puppet/util/autoload.rb', line 188 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.
202 203 204 |
# File 'lib/puppet/util/autoload.rb', line 202 def loadall(env) self.class.loadall(@path, env) end |
#loaded?(name) ⇒ Boolean
206 207 208 |
# File 'lib/puppet/util/autoload.rb', line 206 def loaded?(name) self.class.loaded?((name)) end |