diff options
| author | Markus Roberts <Markus@reality.com> | 2010-06-10 22:51:12 -0700 |
|---|---|---|
| committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
| commit | ccc869ea48397235d7ba2a5695424eee4923cb9d (patch) | |
| tree | ffd534b345923f62733e4e48cc3e36377fa059fe /lib/puppet/parser | |
| parent | 7c6b8836453b2b1e8679923f98854be3b0022edd (diff) | |
| download | puppet-ccc869ea48397235d7ba2a5695424eee4923cb9d.tar.gz puppet-ccc869ea48397235d7ba2a5695424eee4923cb9d.tar.xz puppet-ccc869ea48397235d7ba2a5695424eee4923cb9d.zip | |
Part 2 of fix for #1175 (functions in environments)
Jesse and I are shooting for the minimal viable fix here, with the idea that
a great deal of refactoring is needed but isn't appropriate at this time. The
changes in this commit are:
* Index the function-holding modules by environment
* We need to know the "current environment" when we're defining a function so
we can attach it to the proper module, and this information isn't dynamically
available when user-defined functions are being created (we're being called by
user written code that doesn't "know" about environments) so we cheat and
stash the value in Puppet::Node::Environment
* since we must do this anyway, it turns out to be cleaner & safer to do the
same when we are evaluating a functon. This is the main change from the prior
version of this patch.
* Add a special *root* environment for the built in functions, and extend all
scopes with it.
* Index the function characteristics (name, type, docstring, etc.) by environment
* Make the autoloader environment aware, so that it uses the modulepath for the
specified environment rather than the default
* Turn off caching of the modulepath since it potentially changes for each node
* Tweak tests that weren't environment aware
Diffstat (limited to 'lib/puppet/parser')
| -rw-r--r-- | lib/puppet/parser/ast/function.rb | 3 | ||||
| -rw-r--r-- | lib/puppet/parser/compiler.rb | 1 | ||||
| -rw-r--r-- | lib/puppet/parser/functions.rb | 45 | ||||
| -rw-r--r-- | lib/puppet/parser/scope.rb | 3 | ||||
| -rw-r--r-- | lib/puppet/parser/type_loader.rb | 2 |
5 files changed, 22 insertions, 32 deletions
diff --git a/lib/puppet/parser/ast/function.rb b/lib/puppet/parser/ast/function.rb index 4c3a5dc05..ba4977935 100644 --- a/lib/puppet/parser/ast/function.rb +++ b/lib/puppet/parser/ast/function.rb @@ -13,7 +13,7 @@ class Puppet::Parser::AST def evaluate(scope) # Make sure it's a defined function - unless @fname + unless @fname = Puppet::Parser::Functions.function(@name) raise Puppet::ParseError, "Unknown function %s" % @name end @@ -48,7 +48,6 @@ class Puppet::Parser::AST super(hash) - @fname = Puppet::Parser::Functions.function(@name) # Lastly, check the parity end diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb index f869383dc..4357a3a34 100644 --- a/lib/puppet/parser/compiler.rb +++ b/lib/puppet/parser/compiler.rb @@ -127,6 +127,7 @@ class Puppet::Parser::Compiler @environment = nil end end + Puppet::Node::Environment.current = @environment @environment end diff --git a/lib/puppet/parser/functions.rb b/lib/puppet/parser/functions.rb index 6ba3669c0..e0973c19d 100644 --- a/lib/puppet/parser/functions.rb +++ b/lib/puppet/parser/functions.rb @@ -6,7 +6,7 @@ require 'puppet/parser/scope' # class. module Puppet::Parser::Functions - @functions = {} + @functions = Hash.new { |h,k| h[k] = {} } @modules = {} class << self @@ -24,15 +24,17 @@ module Puppet::Parser::Functions @autoloader end + Environment = Puppet::Node::Environment + def self.environment_module(env = nil) - @module ||= Module.new + @modules[ env || Environment.current || Environment.root ] ||= Module.new end # Create a new function type. def self.newfunction(name, options = {}, &block) name = symbolize(name) - if @functions.include? name + if functions.include?(name) raise Puppet::DevError, "Function %s already defined" % name end @@ -46,10 +48,10 @@ module Puppet::Parser::Functions environment_module.send(:define_method, fname, &block) # Someday we'll support specifying an arity, but for now, nope - #@functions[name] = {:arity => arity, :type => ftype} - @functions[name] = {:type => ftype, :name => fname} + #functions[name] = {:arity => arity, :type => ftype} + functions[name] = {:type => ftype, :name => fname} if options[:doc] - @functions[name][:doc] = options[:doc] + functions[name][:doc] = options[:doc] end end @@ -57,11 +59,11 @@ module Puppet::Parser::Functions def self.rmfunction(name) name = symbolize(name) - unless @functions.include? name + unless functions.include? name raise Puppet::DevError, "Function %s is not defined" % name end - @functions.delete(name) + functions.delete name fname = "function_" + name.to_s environment_module.send(:remove_method, fname) @@ -71,15 +73,11 @@ module Puppet::Parser::Functions def self.function(name) name = symbolize(name) - unless @functions.include? name - autoloader.load(name) + unless functions.include?(name) or functions(Puppet::Node::Environment.root).include?(name) + autoloader.load(name,Environment.current || Environment.root) end - if @functions.include? name - return @functions[name][:name] - else - return false - end + ( functions(Environment.root)[name] || functions[name] || {:name => false} )[:name] end def self.functiondocs @@ -87,7 +85,7 @@ module Puppet::Parser::Functions ret = "" - @functions.sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, hash| + functions.sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, hash| #ret += "%s\n%s\n" % [name, hash[:type]] ret += "%s\n%s\n" % [name, "-" * name.to_s.length] if hash[:doc] @@ -102,22 +100,13 @@ module Puppet::Parser::Functions return ret end - def self.functions - @functions.keys + def self.functions(env = nil) + @functions[ env || Environment.current || Environment.root ] end # Determine if a given function returns a value or not. def self.rvalue?(name) - name = symbolize(name) - - if @functions.include? name - case @functions[name][:type] - when :statement; return false - when :rvalue; return true - end - else - return false - end + (functions[symbolize(name)] || {})[:type] == :rvalue end # Runs a newfunction to create a function for each of the log levels diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb index 991e12302..140c8c1b5 100644 --- a/lib/puppet/parser/scope.rb +++ b/lib/puppet/parser/scope.rb @@ -505,6 +505,7 @@ class Puppet::Parser::Scope private def extend_with_functions_module - extend Puppet::Parser::Functions.environment_module(compiler ? environment : nil) + extend Puppet::Parser::Functions.environment_module(Puppet::Node::Environment.root) + extend Puppet::Parser::Functions.environment_module(compiler ? environment : nil ) end end diff --git a/lib/puppet/parser/type_loader.rb b/lib/puppet/parser/type_loader.rb index 3268eae37..bcb7fa322 100644 --- a/lib/puppet/parser/type_loader.rb +++ b/lib/puppet/parser/type_loader.rb @@ -114,7 +114,7 @@ class Puppet::Parser::TypeLoader end def parse_file(file) - Puppet.debug("importing '#{file}'") + Puppet.debug("importing '#{file}' in environment #{environment}") parser = Puppet::Parser::Parser.new(environment) parser.file = file parser.parse |
