diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/parser/ast/leaf.rb | 4 | ||||
-rw-r--r-- | lib/puppet/parser/ast/vardef.rb | 2 | ||||
-rw-r--r-- | lib/puppet/parser/functions/extlookup.rb | 9 | ||||
-rw-r--r-- | lib/puppet/parser/functions/fqdn_rand.rb | 2 | ||||
-rw-r--r-- | lib/puppet/parser/resource.rb | 2 | ||||
-rw-r--r-- | lib/puppet/parser/scope.rb | 132 | ||||
-rw-r--r-- | lib/puppet/parser/templatewrapper.rb | 18 | ||||
-rw-r--r-- | lib/puppet/resource/type.rb | 13 | ||||
-rw-r--r-- | lib/puppet/util/logging.rb | 11 |
9 files changed, 61 insertions, 132 deletions
diff --git a/lib/puppet/parser/ast/leaf.rb b/lib/puppet/parser/ast/leaf.rb index 77617e992..c8ebc9483 100644 --- a/lib/puppet/parser/ast/leaf.rb +++ b/lib/puppet/parser/ast/leaf.rb @@ -124,7 +124,7 @@ class Puppet::Parser::AST # not include syntactical constructs, like '$' and '{}'). def evaluate(scope) parsewrap do - if (var = scope.lookupvar(@value, false)) == :undefined + if (var = scope.lookupvar(@value, :file => file, :line => line)) == :undefined var = :undef end var @@ -141,7 +141,7 @@ class Puppet::Parser::AST def evaluate_container(scope) container = variable.respond_to?(:evaluate) ? variable.safeevaluate(scope) : variable - (container.is_a?(Hash) or container.is_a?(Array)) ? container : scope.lookupvar(container) + (container.is_a?(Hash) or container.is_a?(Array)) ? container : scope.lookupvar(container, :file => file, :line => line) end def evaluate_key(scope) diff --git a/lib/puppet/parser/ast/vardef.rb b/lib/puppet/parser/ast/vardef.rb index 6de1860c8..b766311dd 100644 --- a/lib/puppet/parser/ast/vardef.rb +++ b/lib/puppet/parser/ast/vardef.rb @@ -20,7 +20,7 @@ class Puppet::Parser::AST name = @name.safeevaluate(scope) parsewrap do - scope.setvar(name,value, :file => @file, :line => @line, :append => @append) + scope.setvar(name,value, :file => file, :line => line, :append => @append) end end end diff --git a/lib/puppet/parser/functions/extlookup.rb b/lib/puppet/parser/functions/extlookup.rb index bc55410b9..5fbf26cec 100644 --- a/lib/puppet/parser/functions/extlookup.rb +++ b/lib/puppet/parser/functions/extlookup.rb @@ -91,14 +91,9 @@ This is for back compatibility to interpolate variables with %. % interpolation raise Puppet::ParseError, ("extlookup(): wrong number of arguments (#{args.length}; must be <= 3)") if args.length > 3 - extlookup_datadir = lookupvar('extlookup_datadir') - extlookup_precedence = Array.new + extlookup_datadir = undef_as('',lookupvar('::extlookup_datadir')) - extlookup_precedence = lookupvar('extlookup_precedence').collect do |var| - var.gsub(/%\{(.+?)\}/) do |capture| - lookupvar($1) - end - end + extlookup_precedence = undef_as([],lookupvar('::extlookup_precedence')).collect { |var| var.gsub(/%\{(.+?)\}/) { lookupvar("::#{$1}") } } datafiles = Array.new diff --git a/lib/puppet/parser/functions/fqdn_rand.rb b/lib/puppet/parser/functions/fqdn_rand.rb index 91157a148..93ab98bcd 100644 --- a/lib/puppet/parser/functions/fqdn_rand.rb +++ b/lib/puppet/parser/functions/fqdn_rand.rb @@ -7,6 +7,6 @@ Puppet::Parser::Functions::newfunction(:fqdn_rand, :type => :rvalue, :doc => $random_number_seed = fqdn_rand(30,30)") do |args| require 'digest/md5' max = args.shift - srand(Digest::MD5.hexdigest([lookupvar('fqdn'),args].join(':')).hex) + srand(Digest::MD5.hexdigest([lookupvar('::fqdn'),args].join(':')).hex) rand(max).to_s end diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb index c007d4dbe..ace01bb4b 100644 --- a/lib/puppet/parser/resource.rb +++ b/lib/puppet/parser/resource.rb @@ -241,7 +241,7 @@ class Puppet::Parser::Resource < Puppet::Resource def add_backward_compatible_relationship_param(name) # Skip metaparams for which we get no value. - return unless val = scope.lookupvar(name.to_s, false) and val != :undefined + return unless val = scope.lookupvar(name.to_s) and val != :undefined # The default case: just set the value set_parameter(name, val) and return unless @parameters[name] diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb index 24f1d01f7..8de9d60b1 100644 --- a/lib/puppet/parser/scope.rb +++ b/lib/puppet/parser/scope.rb @@ -18,10 +18,10 @@ class Puppet::Parser::Scope include Enumerable include Puppet::Util::Errors - attr_accessor :level, :source, :resource + attr_accessor :source, :resource attr_accessor :base, :keyword attr_accessor :top, :translated, :compiler - attr_accessor :parent + attr_accessor :parent, :dynamic attr_reader :namespaces # thin wrapper around an ephemeral @@ -104,11 +104,6 @@ class Puppet::Parser::Scope compiler.environment end - # Are we the top scope? - def topscope? - @level == 1 - end - def find_hostclass(name) known_resource_types.find_hostclass(namespaces, name) end @@ -215,45 +210,41 @@ class Puppet::Parser::Scope find_definition(name) || find_hostclass(name) end - def lookup_qualified_var(name, usestring) - parts = name.split(/::/) - shortname = parts.pop - klassname = parts.join("::") - klass = find_hostclass(klassname) - unless klass - warning "Could not look up qualified variable '#{name}'; class #{klassname} could not be found" - return usestring ? "" : :undefined - end - unless kscope = class_scope(klass) - warning "Could not look up qualified variable '#{name}'; class #{klassname} has not been evaluated" - return usestring ? "" : :undefined - end - kscope.lookupvar(shortname, usestring) + def undef_as(x,v) + (v == :undefined) ? x : (v == :undef) ? x : v end - private :lookup_qualified_var + def qualified_scope(classname) + raise "class #{classname} could not be found" unless klass = find_hostclass(classname) + raise "class #{classname} has not been evaluated" unless kscope = class_scope(klass) + kscope + end + + private :qualified_scope - # Look up a variable. The simplest value search we do. Default to returning - # an empty string for missing values, but support returning a constant. - def lookupvar(name, usestring = true) + # Look up a variable. The simplest value search we do. + def lookupvar(name, options = {}) table = ephemeral?(name) ? @ephemeral.last : @symtable # If the variable is qualified, then find the specified scope and look the variable up there instead. - if name =~ /::/ - return lookup_qualified_var(name, usestring) - end - # We can't use "if table[name]" here because the value might be false - if ephemeral_include?(name) or table.include?(name) - if usestring and table[name] == :undef - return "" - else - return table[name] + if name =~ /^(.*)::(.+)$/ + begin + qualified_scope($1).lookupvar($2,options) + rescue RuntimeError => e + location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : '' + warning "Could not look up qualified variable '#{name}'; #{e.message}#{location}" + :undefined end - elsif self.parent - return parent.lookupvar(name, usestring) - elsif usestring - return "" + elsif ephemeral_include?(name) or table.include?(name) + # We can't use "if table[name]" here because the value might be false + if options[:dynamic] and self != compiler.topscope + location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : '' + Puppet.deprecation_warning "Dynamic lookup of $#{name}#{location} will not be supported in future versions. Use a fully-qualified variable name or parameterized classes." + end + table[name] + elsif parent + parent.lookupvar(name,options.merge(:dynamic => (dynamic || options[:dynamic]))) else - return :undefined + :undefined end end @@ -323,8 +314,6 @@ class Puppet::Parser::Scope # to be reassigned. def setvar(name,value, options = {}) table = options[:ephemeral] ? @ephemeral.last : @symtable - #Puppet.debug "Setting %s to '%s' at level %s mode append %s" % - # [name.inspect,value,self.level, append] if table.include?(name) unless options[:append] error = Puppet::ParseError.new("Cannot reassign variable #{name}") @@ -340,7 +329,7 @@ class Puppet::Parser::Scope table[name] = value else # append case # lookup the value in the scope if it exists and insert the var - table[name] = lookupvar(name) + table[name] = undef_as('',lookupvar(name)) # concatenate if string, append if array, nothing for other types case value when Array @@ -354,65 +343,6 @@ class Puppet::Parser::Scope end end - # Return an interpolated string. - def strinterp(string, file = nil, line = nil) - # Most strings won't have variables in them. - ss = StringScanner.new(string) - out = "" - while not ss.eos? - if ss.scan(/^\$\{((\w*::)*\w+|[0-9]+)\}|^\$([0-9])|^\$((\w*::)*\w+)/) - # If it matches the backslash, then just retun the dollar sign. - if ss.matched == '\\$' - out << '$' - else # look the variable up - # make sure $0-$9 are lookupable only if ephemeral - var = ss[1] || ss[3] || ss[4] - if var and var =~ /^[0-9]+$/ and not ephemeral_include?(var) - next - end - out << lookupvar(var).to_s || "" - end - elsif ss.scan(/^\\(.)/) - # Puppet.debug("Got escape: pos:%d; m:%s" % [ss.pos, ss.matched]) - case ss[1] - when 'n' - out << "\n" - when 't' - out << "\t" - when 's' - out << " " - when '\\' - out << '\\' - when '$' - out << '$' - else - str = "Unrecognised escape sequence '#{ss.matched}'" - str += " in file #{file}" if file - str += " at line #{line}" if line - Puppet.warning str - out << ss.matched - end - elsif ss.scan(/^\$/) - out << '$' - elsif ss.scan(/^\\\n/) # an escaped carriage return - next - else - tmp = ss.scan(/[^\\$]+/) - # Puppet.debug("Got other: pos:%d; m:%s" % [ss.pos, tmp]) - unless tmp - error = Puppet::ParseError.new("Could not parse string #{string.inspect}") - {:file= => file, :line= => line}.each do |m,v| - error.send(m, v) if v - end - raise error - end - out << tmp - end - end - - out - end - # Return the tags associated with this scope. It's basically # just our parents' tags, plus our type. We don't cache this value # because our parent tags might change between calls. diff --git a/lib/puppet/parser/templatewrapper.rb b/lib/puppet/parser/templatewrapper.rb index 6864aa1a9..180a03dc9 100644 --- a/lib/puppet/parser/templatewrapper.rb +++ b/lib/puppet/parser/templatewrapper.rb @@ -18,13 +18,14 @@ class Puppet::Parser::TemplateWrapper @__scope__ end + def script_line + # find which line in the template (if any) we were called from + caller.find { |l| l =~ /#{file}:/ }.first[/:(\d+):/,1] + end + # Should return true if a variable is defined, false if it is not def has_variable?(name) - if scope.lookupvar(name.to_s, false) != :undefined - true - else - false - end + scope.lookupvar(name.to_s, :file => file, :line => script_line) != :undefined end # Allow templates to access the defined classes @@ -55,15 +56,13 @@ class Puppet::Parser::TemplateWrapper # the missing_method definition here until we declare the syntax finally # dead. def method_missing(name, *args) - # We have to tell lookupvar to return :undefined to us when - # appropriate; otherwise it converts to "". - value = scope.lookupvar(name.to_s, false) + value = scope.lookupvar(name.to_s,:file => file,:line => script_line) if value != :undefined return value else # Just throw an error immediately, instead of searching for # other missingmethod things or whatever. - raise Puppet::ParseError, "Could not find value for '#{name}'" + raise Puppet::ParseError.new("Could not find value for '#{name}'",@file,script_line) end end @@ -103,6 +102,7 @@ class Puppet::Parser::TemplateWrapper result = nil benchmark(:debug, "Interpolated template #{template_source}") do template = ERB.new(self.string, 0, "-") + template.filename = file result = template.result(binding) end diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb index 48d8c1f48..f8d820b77 100644 --- a/lib/puppet/resource/type.rb +++ b/lib/puppet/resource/type.rb @@ -62,13 +62,11 @@ class Puppet::Resource::Type # Now evaluate the code associated with this class or definition. def evaluate_code(resource) - scope = resource.scope - if tmp = evaluate_parent_type(resource) - scope = tmp - end + static_parent = evaluate_parent_type(resource) + scope = static_parent || resource.scope - scope = subscope(scope, resource) unless resource.title == :main + scope = scope.newscope(:namespace => namespace, :source => self, :resource => resource, :dynamic => !static_parent) unless resource.title == :main scope.compiler.add_class(name) unless definition? set_resource_parameters(resource, scope) @@ -263,11 +261,6 @@ class Puppet::Resource::Type end - # Create a new subscope in which to evaluate our code. - def subscope(scope, resource) - scope.newscope :resource => resource, :namespace => self.namespace, :source => self - end - # Check whether a given argument is valid. def valid_parameter?(param) param = param.to_s diff --git a/lib/puppet/util/logging.rb b/lib/puppet/util/logging.rb index bc52b17f0..4e76ae414 100644 --- a/lib/puppet/util/logging.rb +++ b/lib/puppet/util/logging.rb @@ -15,6 +15,17 @@ module Puppet::Util::Logging end end + def deprecation_warning(message) + $deprecation_warnings ||= Hash.new(0) + if $deprecation_warnings.length < 100 and ($deprecation_warnings[message] += 1) == 1 + warning message + end + end + + def clear_deprecation_warnings + $deprecation_warnings.clear if $deprecation_warnings + end + private def is_resource? |