summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/parser_support.rb
diff options
context:
space:
mode:
authorLuke Kanies <luke@puppetlabs.com>2010-04-28 21:52:06 -0700
committertest branch <puppet-dev@googlegroups.com>2010-02-17 06:50:53 -0800
commitd61a69a0e5a87a95846a4d39115eac80e4984cac (patch)
tree4d611b0b6280e8ccbb3702dcfe619f22d5e3ecd2 /lib/puppet/parser/parser_support.rb
parentf66095d35bc5f9645eb19bbb8cefa342c0181d2d (diff)
downloadpuppet-d61a69a0e5a87a95846a4d39115eac80e4984cac.tar.gz
puppet-d61a69a0e5a87a95846a4d39115eac80e4984cac.tar.xz
puppet-d61a69a0e5a87a95846a4d39115eac80e4984cac.zip
Fixing #3668 - fixed autoloading classes from modules
This involved essentially moving all of the importing and loading code out of the Parser and into a new 'TypeLoader' class. The parser and the ResourceTypeCollection classes now delegate to that class for all file handling. Most of the code paths are also now much cleaner, and a bit of redundancy was removed. Signed-off-by: Luke Kanies <luke@puppetlabs.com>
Diffstat (limited to 'lib/puppet/parser/parser_support.rb')
-rw-r--r--lib/puppet/parser/parser_support.rb154
1 files changed, 3 insertions, 151 deletions
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index d43b0d37d..24ee5fab3 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -107,91 +107,15 @@ class Puppet::Parser::Parser
end
def find_hostclass(namespace, name)
- find_or_load(namespace, name, :hostclass)
+ known_resource_types.find_or_load(namespace, name, :hostclass)
end
def find_definition(namespace, name)
- find_or_load(namespace, name, :definition)
+ known_resource_types.find_or_load(namespace, name, :definition)
end
- def find_or_load(namespace, name, type)
- method = "find_#{type}"
- namespace = namespace.downcase
- name = name.downcase
- fullname = (namespace + "::" + name).sub(/^::/, '')
-
- if name =~ /^::/
- names_to_try = [name.sub(/^::/, '')]
- else
- names_to_try = [fullname]
-
- # Try to load the module init file if we're a qualified name
- names_to_try << fullname.split("::")[0] if fullname.include?("::")
-
- # Otherwise try to load the bare name on its own. This
- # is appropriate if the class we're looking for is in a
- # module that's different from our namespace.
- names_to_try << name
- names_to_try.compact!
- end
-
- until (result = known_resource_types.send(method, namespace, name)) or names_to_try.empty? do
- self.load(names_to_try.shift)
- end
- return result
- end
-
- # Import our files.
def import(file)
- if Puppet[:ignoreimport]
- return AST::ASTArray.new(:children => [])
- end
- # use a path relative to the file doing the importing
- if @lexer.file
- dir = @lexer.file.sub(%r{[^/]+$},'').sub(/\/$/, '')
- else
- dir = "."
- end
- if dir == ""
- dir = "."
- end
- result = ast AST::ASTArray
-
- # We can't interpolate at this point since we don't have any
- # scopes set up. Warn the user if they use a variable reference
- raise "Got no file" unless file
- pat = file
- if pat.index("$")
- Puppet.warning(
- "The import of #{pat} contains a variable reference;" +
- " variables are not interpolated for imports " +
- "in file #{@lexer.file} at line #{@lexer.line}"
- )
- end
- files = Puppet::Parser::Files.find_manifests(pat, :cwd => dir, :environment => @environment)
- if files.size == 0
- raise Puppet::ImportError.new("No file(s) found for import " +
- "of '#{pat}'")
- end
-
- files.collect { |file|
- parser = Puppet::Parser::Parser.new(@environment)
- parser.files = self.files
- Puppet.debug("importing '%s'" % file)
-
- unless file =~ /^#{File::SEPARATOR}/
- file = File.join(dir, file)
- end
- begin
- parser.file = file
- rescue Puppet::AlreadyImportedError
- # This file has already been imported to just move on
- next
- end
-
- # This will normally add code to the 'main' class.
- parser.parse
- }
+ known_resource_types.loader.import(file, @lexer.file)
end
def initialize(env)
@@ -203,69 +127,6 @@ class Puppet::Parser::Parser
# Initialize or reset all of our variables.
def initvars
@lexer = Puppet::Parser::Lexer.new()
- @files = {}
- @loaded = []
- @loading = {}
- @loading.extend(MonitorMixin)
- class << @loading
- def done_with(item)
- synchronize do
- delete(item)[:busy].signal if self.has_key?(item) and self[item][:loader] == Thread.current
- end
- end
- def owner_of(item)
- synchronize do
- if !self.has_key? item
- self[item] = { :loader => Thread.current, :busy => self.new_cond}
- :nobody
- elsif self[item][:loader] == Thread.current
- :this_thread
- else
- flag = self[item][:busy]
- flag.wait
- flag.signal
- :another_thread
- end
- end
- end
- end
- end
-
- # Utility method factored out of load
- def able_to_import?(classname,item,msg)
- unless @loaded.include?(item)
- begin
- case @loading.owner_of(item)
- when :this_thread
- return
- when :another_thread
- return able_to_import?(classname,item,msg)
- when :nobody
- import(item)
- Puppet.info "Autoloaded #{msg}"
- @loaded << item
- end
- rescue Puppet::ImportError => detail
- # We couldn't load the item
- ensure
- @loading.done_with(item)
- end
- end
- # We don't know whether we're looking for a class or definition, so we have
- # to test for both.
- return known_resource_types.hostclass(classname) || known_resource_types.definition(classname)
- end
-
- # Try to load a class, since we could not find it.
- def load(classname)
- return false if classname == ""
- filename = classname.gsub("::", File::SEPARATOR)
- mod = filename.scan(/^[\w-]+/).shift
-
- # First try to load the top-level module then the individual file
- [[mod, "module %s" % mod ],
- [filename,"file %s from module %s" % [filename, mod]]
- ].any? { |item,description| able_to_import?(classname,item,description) }
end
# Split an fq name into a namespace and name
@@ -365,15 +226,6 @@ class Puppet::Parser::Parser
require self.file
end
- # See if any of the files have changed.
- def reparse?
- if file = @files.detect { |name, file| file.changed? }
- return file[1].stamp
- else
- return false
- end
- end
-
def string=(string)
@lexer.string = string
end