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
60 def changed?(name, env)
61   name = cleanpath(name).chomp('.rb')
62   return true unless loaded.include?(name)
63   file, old_mtime = loaded[name]
64   return true unless file == get_file(name, env)
65   begin
66     old_mtime.to_i != File.mtime(file).to_i
67   rescue Errno::ENOENT
68     true
69   end
70 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
169 def cleanpath(path)
170   Pathname.new(path).cleanpath.to_s
171 end
files_in_dir(dir, path) click to toggle source

@api private

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

@api private

    # File lib/puppet/util/autoload.rb
135 def gem_directories
136   gem_source.directories
137 end
gem_source() click to toggle source
   # File lib/puppet/util/autoload.rb
34 def gem_source
35   @gem_source ||= Puppet::Util::RubyGems::Source.new
36 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
109 def get_file(name, env)
110   name = name + '.rb' unless name =~ /\.rb$/
111   path = search_directories(env).find { |dir| Puppet::FileSystem.exist?(File.join(dir, name)) }
112   path and File.join(path, name)
113 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
74 def load_file(name, env)
75   file = get_file(name.to_s, env)
76   return false unless file
77   begin
78     mark_loaded(name, file)
79     Kernel.load file
80     return true
81   rescue SystemExit,NoMemoryError
82     raise
83   rescue Exception => detail
84     message = _("Could not autoload %{name}: %{detail}") % { name: name, detail: detail }
85     Puppet.log_exception(detail, message)
86     raise Puppet::Error, message, detail.backtrace
87   end
88 end
loadall(path, env) click to toggle source
   # File lib/puppet/util/autoload.rb
90 def loadall(path, env)
91   # Load every instance of everything we can find.
92   files_to_load(path, env).each do |file|
93     name = file.chomp(".rb")
94     load_file(name, env) unless loaded?(name)
95   end
96 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
43 def loaded?(path)
44   path = cleanpath(path).chomp('.rb')
45   loaded.include?(path)
46 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
52 def mark_loaded(name, file)
53   name = cleanpath(name).chomp('.rb')
54   file = File.expand_path(file)
55   $LOADED_FEATURES << file unless $LOADED_FEATURES.include?(file)
56   loaded[name] = [file, File.mtime(file)]
57 end
module_directories(env) click to toggle source

@api private

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

@api private

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

Public Instance Methods

changed?(name, env) click to toggle source

@api private

    # File lib/puppet/util/autoload.rb
205 def changed?(name, env)
206   self.class.changed?(expand(name), env)
207 end
expand(name) click to toggle source
    # File lib/puppet/util/autoload.rb
213 def expand(name)
214   ::File.join(@path, name.to_s)
215 end
files_to_load(env) click to toggle source
    # File lib/puppet/util/autoload.rb
209 def files_to_load(env)
210   self.class.files_to_load(@path, env)
211 end
load(name, env) click to toggle source
    # File lib/puppet/util/autoload.rb
182 def load(name, env)
183   self.class.load_file(expand(name), env)
184 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
196 def loadall(env)
197   self.class.loadall(@path, env)
198 end
loaded?(name) click to toggle source
    # File lib/puppet/util/autoload.rb
200 def loaded?(name)
201   self.class.loaded?(expand(name))
202 end