summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/parser')
-rw-r--r--lib/puppet/parser/lexer.rb2
-rw-r--r--lib/puppet/parser/resource/param.rb12
-rw-r--r--lib/puppet/parser/scope.rb19
-rw-r--r--lib/puppet/parser/templatewrapper.rb56
4 files changed, 71 insertions, 18 deletions
diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb
index 51026ea1b..2c5f66e5a 100644
--- a/lib/puppet/parser/lexer.rb
+++ b/lib/puppet/parser/lexer.rb
@@ -131,7 +131,7 @@ class Puppet::Parser::Lexer
TOKENS.add_tokens "Whatever" => :DQTEXT, "Nomatter" => :SQTEXT, "alsonomatter" => :BOOLEAN
- TOKENS.add_token :NAME, %r{[a-z][-\w]*} do |lexer, value|
+ TOKENS.add_token :NAME, %r{[a-z0-9][-\w]*} do |lexer, value|
string_token = self
# we're looking for keywords here
if tmp = KEYWORDS.lookup(value)
diff --git a/lib/puppet/parser/resource/param.rb b/lib/puppet/parser/resource/param.rb
index 9dd3f26d2..c8dd78a26 100644
--- a/lib/puppet/parser/resource/param.rb
+++ b/lib/puppet/parser/resource/param.rb
@@ -66,6 +66,14 @@ class Puppet::Parser::Resource::Param
def to_s
"%s => %s" % [self.name, self.value]
end
+
+ def compare(v,db_value)
+ if (v.is_a?(Puppet::Parser::Resource::Reference))
+ return v.to_s == db_value.to_s
+ else
+ return v == db_value
+ end
+ end
def values_to_remove(db_values)
values = munge_for_rails(value)
@@ -73,7 +81,7 @@ class Puppet::Parser::Resource::Param
db_values.collect do |db|
db unless (db.line == line_number &&
values.find { |v|
- v == db.value
+ compare(v,db.value)
} )
end.compact
end
@@ -82,7 +90,7 @@ class Puppet::Parser::Resource::Param
values = munge_for_rails(value)
line_number = line_to_i()
values.collect do |v|
- v unless db_values.find { |db| (v == db.value &&
+ v unless db_values.find { |db| (compare(v,db.value) &&
line_number == db.line) }
end.compact
end
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index a6e43e7b3..32b127a6b 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -183,6 +183,25 @@ class Puppet::Parser::Scope
end
end
+ # Return a hash containing our variables and their values, optionally (and
+ # by default) including the values defined in our parent. Local values
+ # shadow parent values.
+ def to_hash(recursive = true)
+ if recursive and parent then
+ target = parent.to_hash(recursive)
+ end
+ target ||= Hash.new
+ @symtable.keys.each { |name|
+ value = @symtable[name]
+ if value == :undef then
+ target.delete(name)
+ else
+ target[name] = value
+ end
+ }
+ return target
+ end
+
def namespaces
@namespaces.dup
end
diff --git a/lib/puppet/parser/templatewrapper.rb b/lib/puppet/parser/templatewrapper.rb
index 4790cea30..3b74e62d4 100644
--- a/lib/puppet/parser/templatewrapper.rb
+++ b/lib/puppet/parser/templatewrapper.rb
@@ -5,50 +5,76 @@ class Puppet::Parser::TemplateWrapper
include Puppet::Util
Puppet::Util.logmethods(self)
- def initialize(scope, file)
- @scope = scope
- @file = Puppet::Module::find_template(file, @scope.compiler.environment)
+ def initialize(scope, filename)
+ @__scope__ = scope
+ @__file__ = Puppet::Module::find_template(filename, scope.compiler.environment)
- unless FileTest.exists?(@file)
+ unless FileTest.exists?(file)
raise Puppet::ParseError,
"Could not find template %s" % file
end
# We'll only ever not have a parser in testing, but, eh.
- if @scope.parser
- @scope.parser.watch_file(@file)
+ if scope.parser
+ scope.parser.watch_file(file)
end
end
+ def scope
+ @__scope__
+ end
+
+ def file
+ @__file__
+ 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
+ if scope.lookupvar(name.to_s, false) != :undefined
true
else
false
end
end
- # Ruby treats variables like methods, so we can cheat here and
- # trap missing vars like they were missing methods.
+ # Ruby treats variables like methods, so we used to expose variables
+ # within scope to the ERB code via method_missing. As per RedMine #1427,
+ # though, this means that conflicts between methods in our inheritance
+ # tree (Kernel#fork) and variable names (fork => "yes/no") could arise.
+ #
+ # Worse, /new/ conflicts could pop up when a new kernel or object method
+ # was added to Ruby, causing templates to suddenly fail mysteriously when
+ # Ruby was upgraded.
+ #
+ # To ensure that legacy templates using unqualified names work we retain
+ # 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, false)
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 '%s'" % name
+ raise Puppet::ParseError, "Could not find value for '%s'" % name
end
end
def result
+ # Expose all the variables in our scope as instance variables of the
+ # current object, making it possible to access them without conflict
+ # to the regular methods.
+ benchmark(:debug, "Bound template variables for #{file}") do
+ scope.to_hash.each { |name, value|
+ instance_variable_set("@#{name}", value)
+ }
+ end
+
result = nil
- benchmark(:debug, "Interpolated template #{@file}") do
- template = ERB.new(File.read(@file), 0, "-")
+ benchmark(:debug, "Interpolated template #{file}") do
+ template = ERB.new(File.read(file), 0, "-")
result = template.result(binding)
end
@@ -56,7 +82,7 @@ class Puppet::Parser::TemplateWrapper
end
def to_s
- "template[%s]" % @file
+ "template[%s]" % file
end
end