class Puppet::Util::Autoload

Autoload paths, either based on names or all at once.

Attributes

loaded[RW]
object[RW]
path[RW]

Public Class Methods

changed?(name, env) click to toggle source

@api private

   # File lib/puppet/util/autoload.rb
59 def changed?(name, env)
60   name = cleanpath(name).chomp('.rb')
61   return true unless loaded.include?(name)
62   file, old_mtime = loaded[name]
63   return true unless file == get_file(name, env)
64   begin
65     old_mtime.to_i != File.mtime(file).to_i
66   rescue Errno::ENOENT
67     true
68   end
69 end
cleanpath(path) click to toggle source

Normalize a path. This converts ALT_SEPARATOR to SEPARATOR on Windows and eliminates unnecessary parts of a path.

    # File lib/puppet/util/autoload.rb
168 def cleanpath(path)
169   Pathname.new(path).cleanpath.to_s
170 end
files_in_dir(dir, path) click to toggle source

@api private

    # File lib/puppet/util/autoload.rb
119 def files_in_dir(dir, path)
120   dir = Pathname.new(File.expand_path(dir))
121   Dir.glob(File.join(dir, path, "*.rb")).collect do |file|
122     Pathname.new(file).relative_path_from(dir).to_s
123   end
124 end
files_to_load(path, env) click to toggle source
    # File lib/puppet/util/autoload.rb
114 def files_to_load(path, env)
115   search_directories(env).map {|dir| files_in_dir(dir, path) }.flatten.uniq
116 end
gem_directories() click to toggle source

@api private

    # File lib/puppet/util/autoload.rb
134 def gem_directories
135   gem_source.directories
136 end
gem_source() click to toggle source
   # File lib/puppet/util/autoload.rb
33 def gem_source
34   @gem_source ||= Puppet::Util::RubyGems::Source.new
35 end
get_file(name, env) click to toggle source

Get the correct file to load for a given path returns nil if no file is found @api private

    # File lib/puppet/util/autoload.rb
108 def get_file(name, env)
109   name = name + '.rb' unless name =~ /\.rb$/
110   path = search_directories(env).find { |dir| Puppet::FileSystem.exist?(File.join(dir, name)) }
111   path and File.join(path, name)
112 end
load_file(name, env) click to toggle source

Load a single plugin by name. We use 'load' here so we can reload a given plugin.

   # File lib/puppet/util/autoload.rb
73 def load_file(name, env)
74   file = get_file(name.to_s, env)
75   return false unless file
76   begin
77     mark_loaded(name, file)
78     Kernel.load file
79     return true
80   rescue SystemExit,NoMemoryError
81     raise
82   rescue Exception => detail
83     message = _("Could not autoload %{name}: %{detail}") % { name: name, detail: detail }
84     Puppet.log_exception(detail, message)
85     raise Puppet::Error, message, detail.backtrace
86   end
87 end
loadall(path, env) click to toggle source
   # File lib/puppet/util/autoload.rb
89 def loadall(path, env)
90   # Load every instance of everything we can find.
91   files_to_load(path, env).each do |file|
92     name = file.chomp(".rb")
93     load_file(name, env) unless loaded?(name)
94   end
95 end
loaded?(path) click to toggle source

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.

   # File lib/puppet/util/autoload.rb
42 def loaded?(path)
43   path = cleanpath(path).chomp('.rb')
44   loaded.include?(path)
45 end
mark_loaded(name, file) click to toggle source

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. @api private

   # File lib/puppet/util/autoload.rb
51 def mark_loaded(name, file)
52   name = cleanpath(name).chomp('.rb')
53   file = File.expand_path(file)
54   $LOADED_FEATURES << file unless $LOADED_FEATURES.include?(file)
55   loaded[name] = [file, File.mtime(file)]
56 end
module_directories(env) click to toggle source

@api private

    # File lib/puppet/util/autoload.rb
127 def module_directories(env)
128   raise ArgumentError, "Autoloader requires an environment" unless env
129 
130   Puppet::Util::ModuleDirectoriesAdapter.adapt(env).directories
131 end
new(obj, path) click to toggle source
    # File lib/puppet/util/autoload.rb
175 def initialize(obj, path)
176   @path = path.to_s
177   raise ArgumentError, _("Autoload paths cannot be fully qualified") if Puppet::Util.absolute_path?(@path)
178   @object = obj
179 end
reload_changed(env) click to toggle source
    # File lib/puppet/util/autoload.rb
 97 def reload_changed(env)
 98   loaded.keys.each do |file|
 99     if changed?(file, env)
100       load_file(file, env)
101     end
102   end
103 end
search_directories(env) click to toggle source

@api private

    # File lib/puppet/util/autoload.rb
139 def search_directories(env)
140   # This is a little bit of a hack.  Basically, the autoloader is being
141   # called indirectly during application bootstrapping when we do things
142   # such as check "features".  However, during bootstrapping, we haven't
143   # yet parsed all of the command line parameters nor the config files,
144   # and thus we don't yet know with certainty what the module path is.
145   # This should be irrelevant during bootstrapping, because anything that
146   # we are attempting to load during bootstrapping should be something
147   # that we ship with puppet, and thus the module path is irrelevant.
148   #
149   # In the long term, I think the way that we want to handle this is to
150   # have the autoloader ignore the module path in all cases where it is
151   # not specifically requested (e.g., by a constructor param or
152   # something)... because there are very few cases where we should
153   # actually be loading code from the module path.  However, until that
154   # happens, we at least need a way to prevent the autoloader from
155   # attempting to access the module path before it is initialized.  For
156   # now we are accomplishing that by calling the
157   # "app_defaults_initialized?" method on the main puppet Settings object.
158   # --cprice 2012-03-16
159   if Puppet.settings.app_defaults_initialized?
160     gem_directories + module_directories(env) + $LOAD_PATH
161   else
162     gem_directories + $LOAD_PATH
163   end
164 end

Public Instance Methods

changed?(name, env) click to toggle source

@api private

    # File lib/puppet/util/autoload.rb
204 def changed?(name, env)
205   self.class.changed?(expand(name), env)
206 end
expand(name) click to toggle source
    # File lib/puppet/util/autoload.rb
212 def expand(name)
213   ::File.join(@path, name.to_s)
214 end
files_to_load(env) click to toggle source
    # File lib/puppet/util/autoload.rb
208 def files_to_load(env)
209   self.class.files_to_load(@path, env)
210 end
load(name, env) click to toggle source
    # File lib/puppet/util/autoload.rb
181 def load(name, env)
182   self.class.load_file(expand(name), env)
183 end
loadall(env) click to toggle source

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.

    # File lib/puppet/util/autoload.rb
195 def loadall(env)
196   self.class.loadall(@path, env)
197 end
loaded?(name) click to toggle source
    # File lib/puppet/util/autoload.rb
199 def loaded?(name)
200   self.class.loaded?(expand(name))
201 end