diff options
author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2007-07-10 04:00:28 +0000 |
---|---|---|
committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2007-07-10 04:00:28 +0000 |
commit | 7befe1bc5ac9d4524c4c43514a24f1bb19b74727 (patch) | |
tree | 430487cd060d719ab037e1778e1176e163086386 | |
parent | eabe0d1c31052c1fa3cb67cd8950d964cb137a19 (diff) | |
download | puppet-7befe1bc5ac9d4524c4c43514a24f1bb19b74727.tar.gz puppet-7befe1bc5ac9d4524c4c43514a24f1bb19b74727.tar.xz puppet-7befe1bc5ac9d4524c4c43514a24f1bb19b74727.zip |
Changing some of the internals of autoloading so that there is a class-level method to query whether a given file has been loaded.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2668 980ebf18-57e1-0310-9a29-db15c13687c0
-rw-r--r-- | lib/puppet/util/autoload.rb | 59 | ||||
-rwxr-xr-x | test/util/autoload.rb | 49 |
2 files changed, 76 insertions, 32 deletions
diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb index ac4939a0b..42aa56c32 100644 --- a/lib/puppet/util/autoload.rb +++ b/lib/puppet/util/autoload.rb @@ -3,20 +3,42 @@ class Puppet::Util::Autoload include Puppet::Util @autoloaders = {} - - attr_accessor :object, :path, :objwarn, :wrap - + @loaded = {} class << self attr_reader :autoloaders private :autoloaders end - Puppet::Util.classproxy self, :autoloaders, "[]", "[]=", :clear - attr_reader :loaded - private :loaded + # Send [], []=, and :clear to the @autloaders hash + Puppet::Util.classproxy self, :autoloaders, "[]", "[]=" + + # Clear the list of autoloaders and loaded files. + def self.clear + @autoloaders.clear + @loaded.clear + end + + # List all loaded files. + def self.list_loaded + @loaded.sort { |a,b| a[0] <=> b[0] }.collect do |path, hash| + "%s: %s" % [path, hash[:file]] + end + end + + # Has a given path been loaded? This is used for testing whether a + # changed file should be loaded or just ignored. + def self.loaded?(path) + path = path.to_s.sub(/\.rb$/, '') + @loaded[path] + end + + # Save the fact that a given path has been loaded + def self.loaded(path, file, loader) + @loaded[path] = {:file => file, :autoloader => loader} + end - Puppet::Util.proxy self, :loaded, :clear + attr_accessor :object, :path, :objwarn, :wrap def initialize(obj, path, options = {}) @path = path.to_s @@ -39,11 +61,10 @@ class Puppet::Util::Autoload unless defined? @wrap @wrap = true end - - @loaded = {} end - # Load a single plugin by name. + # Load a single plugin by name. We use 'load' here so we can reload a + # given plugin. def load(name) path = name.to_s + ".rb" @@ -53,7 +74,7 @@ class Puppet::Util::Autoload begin Kernel.load file, @wrap name = symbolize(name) - @loaded[name] = true + loaded name, file return true rescue LoadError => detail # I have no idea what's going on here, but different versions @@ -70,11 +91,19 @@ class Puppet::Util::Autoload return false end + # Mark the named object as loaded. Note that this supports unqualified + # queries, while we store the result as a qualified query in the class. + def loaded(name, file) + self.class.loaded(File.join(@path, name.to_s), file, object) + end + # Indicate whether the specfied plugin has been loaded. def loaded?(name) - @loaded[symbolize(name)] + self.class.loaded?(File.join(@path, name.to_s)) end + # Load all instances that we can. This uses require, rather than load, + # so that already-loaded files don't get reloaded unnecessarily. def loadall # Load every instance of everything we can find. eachdir do |dir| @@ -84,12 +113,12 @@ class Puppet::Util::Autoload # believe, but it works as long as real classes # aren't used. name = File.basename(file).sub(".rb", '').intern - next if @loaded.include? name + next if loaded?(name) next if $".include?(File.join(@path, name.to_s + ".rb")) filepath = File.join(@path, name.to_s + ".rb") begin - Kernel.require filepath - @loaded[name] = true + Kernel.require file + loaded(name, file) rescue => detail if Puppet[:trace] puts detail.backtrace diff --git a/test/util/autoload.rb b/test/util/autoload.rb index 4be6b3930..493fd7f60 100755 --- a/test/util/autoload.rb +++ b/test/util/autoload.rb @@ -30,12 +30,7 @@ TestAutoload.newthing(:#{name.to_s}) end end - def teardown - super - self.class.clear - end - - def test_load + def mk_loader(name) dir = tempfile() $: << dir cleanup do @@ -44,19 +39,26 @@ TestAutoload.newthing(:#{name.to_s}) Dir.mkdir(dir) - rbdir = File.join(dir, "yayness") + rbdir = File.join(dir, name.to_s) Dir.mkdir(rbdir) - # An object for specifying autoload - klass = self.class - loader = nil assert_nothing_raised { - loader = Puppet::Util::Autoload.new(klass, :yayness) + loader = Puppet::Util::Autoload.new(self.class, name) } + return rbdir, loader + end + + def teardown + super + Puppet::Util::Autoload.clear + end + + def test_load + dir, loader = mk_loader(:yayness) - assert_equal(loader.object_id, Puppet::Util::Autoload[klass].object_id, + assert_equal(loader.object_id, Puppet::Util::Autoload[self.class].object_id, "Did not retrieve loader object by class") # Make sure we don't fail on missing files @@ -66,9 +68,9 @@ TestAutoload.newthing(:#{name.to_s}) } # Now create a couple of files for testing - path = File.join(rbdir, "mything.rb") + path = File.join(dir, "mything.rb") mkfile(:mything, path) - opath = File.join(rbdir, "othing.rb") + opath = File.join(dir, "othing.rb") mkfile(:othing, opath) # Now try to actually load it. @@ -79,12 +81,12 @@ TestAutoload.newthing(:#{name.to_s}) assert(loader.loaded?(:mything), "Not considered loaded") - assert(klass.thing?(:mything), + assert(self.class.thing?(:mything), "Did not get loaded thing") # Now clear everything, and test loadall assert_nothing_raised { - loader.clear + Puppet::Util::Autoload.clear } self.class.clear @@ -95,10 +97,23 @@ TestAutoload.newthing(:#{name.to_s}) [:mything, :othing].each do |thing| assert(loader.loaded?(thing), "#{thing.to_s} not considered loaded") + assert(loader.loaded?("%s.rb" % thing), "#{thing.to_s} not considered loaded with .rb") + assert(Puppet::Util::Autoload.loaded?("yayness/%s" % thing), "%s not considered loaded by the main class" % thing) + assert(Puppet::Util::Autoload.loaded?("yayness/%s.rb" % thing), "%s not considered loaded by the main class with .rb" % thing) - assert(klass.thing?(thing), + loaded = Puppet::Util::Autoload.loaded?("yayness/%s.rb" % thing) + assert_equal("%s/%s.rb" % [dir, thing], loaded[:file], "File path was not set correctly in loaded store") + assert_equal(self.class, loaded[:autoloader], "Loader was not set correctly in loaded store") + + assert(self.class.thing?(thing), "Did not get loaded #{thing.to_s}") end + + Puppet::Util::Autoload.clear + [:mything, :othing].each do |thing| + assert(! loader.loaded?(thing), "#{thing.to_s} considered loaded after clear") + assert(! Puppet::Util::Autoload.loaded?("yayness/%s" % thing), "%s considered loaded by the main class after clear" % thing) + end end # Make sure that autoload dynamically modifies $: with the libdir as |