summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-10-10 20:54:15 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-10-10 20:54:15 +0000
commit194dab3c7af4d8e993ec8549a30773d68508a9b6 (patch)
treea2839d7fcaec754637fffa065b3bed387e2fabec /lib/puppet/parser
parent55d7bbdcbefd550cee46a628da2292be540401ad (diff)
downloadpuppet-194dab3c7af4d8e993ec8549a30773d68508a9b6.tar.gz
puppet-194dab3c7af4d8e993ec8549a30773d68508a9b6.tar.xz
puppet-194dab3c7af4d8e993ec8549a30773d68508a9b6.zip
Adding some semantic tagging. It is not exactly full-featured yet, and it is not used at all, but it was sufficient for some proof-of-concept stuff in preparation for the conference
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@716 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib/puppet/parser')
-rw-r--r--lib/puppet/parser/ast.rb26
-rw-r--r--lib/puppet/parser/grammar.ra2
-rw-r--r--lib/puppet/parser/parser.rb6
-rw-r--r--lib/puppet/parser/scope.rb104
4 files changed, 111 insertions, 27 deletions
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index 2848fd1fd..fa21f8a9e 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -1436,7 +1436,14 @@ module Puppet
def evaluate(scope, facts = {})
scope = scope.newscope
- scope.type = "node"
+
+ # nodes are never instantiated like a normal object,
+ # but we need the type to be the name users would use for
+ # instantiation, otherwise tags don't work out
+
+ # The name has already been evaluated, so it's a normal
+ # string.
+ scope.type = @name
scope.name = @name
# Mark this scope as a nodescope, so that classes will be
@@ -1469,15 +1476,24 @@ module Puppet
# We also can't just evaluate the node itself, because
# it would create a node scope within this scope,
# and that would cause mass havoc.
- hash = nil
+ node = nil
+
+ # The 'node' method just returns a hash of the node
+ # code and name. It's used here, and in 'evalnode'.
unless hash = scope.node(@parentclass)
raise Puppet::ParseError,
"Could not find parent node %s" %
@parentclass
end
+ node = hash[:node]
+ # Tag the scope with the parent's name/type.
+ name = node.name
+ Puppet.info "Tagging with parent node %s" % name
+ scope.tag(name)
+
begin
- code = hash[:node].code
+ code = node.code
code.safeevaluate(scope)
rescue Puppet::ParseError => except
except.line = self.line
@@ -1489,6 +1505,10 @@ module Puppet
error.file = self.file
raise error
end
+
+ if node.parentclass
+ node.evalparent(scope)
+ end
end
end
diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra
index 5fe801e15..96f043365 100644
--- a/lib/puppet/parser/grammar.ra
+++ b/lib/puppet/parser/grammar.ra
@@ -450,7 +450,7 @@ import: IMPORT QTEXT {
parser.files = self.files
Puppet.debug("importing '%s'" % file)
begin
- parser.file = file
+ parser.file = File.join(dir, file)
rescue Puppet::ImportError
Puppet.warning(
"Importing %s would result in an import loop" %
diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb
index 733de138c..fd570a81c 100644
--- a/lib/puppet/parser/parser.rb
+++ b/lib/puppet/parser/parser.rb
@@ -32,7 +32,7 @@ module Puppet
class Parser < Racc::Parser
-module_eval <<'..end grammar.ra modeval..idb211ea7fd3', 'grammar.ra', 638
+module_eval <<'..end grammar.ra modeval..id0af758a138', 'grammar.ra', 638
attr_reader :file
attr_accessor :files
@@ -145,7 +145,7 @@ end
def string=(string)
@lexer.string = string
end
-..end grammar.ra modeval..idb211ea7fd3
+..end grammar.ra modeval..id0af758a138
##### racc 1.4.4 generates ###
@@ -1122,7 +1122,7 @@ module_eval <<'.,.,', 'grammar.ra', 469
parser.files = self.files
Puppet.debug("importing '%s'" % file)
begin
- parser.file = file
+ parser.file = File.join(dir, file)
rescue Puppet::ImportError
Puppet.warning(
"Importing %s would result in an import loop" %
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index e9ad983a1..73c2e8f96 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -27,6 +27,40 @@ module Puppet
@@declarative = val
end
+ # Add a single object's tags to the global list of tags for
+ # that object.
+ def addtags(obj)
+ unless defined? @tagtable
+ raise Puppet::DevError, "Told to add tags, but no tag table"
+ end
+ list = @tagtable[obj.type][obj.name]
+
+ obj.tags.each { |tag|
+ unless list.include?(tag)
+ if tag.nil? or tag == ""
+ Puppet.warning "Got tag %s from %s(%s)" %
+ [tag.inspect, obj.type, obj.name]
+ else
+ list << tag
+ end
+ end
+ }
+ end
+
+ # Log the existing tags. At some point this should be in a better
+ # place, but eh.
+ def logtags
+ @tagtable.sort { |a, b|
+ a[0] <=> b[0]
+ }.each { |type, names|
+ names.sort { |a, b|
+ a[0] <=> b[0]
+ }.each { |name, tags|
+ Puppet.info "%s(%s): '%s'" % [type, name, tags.join("' '")]
+ }
+ }
+ end
+
# Create a new child scope.
def child=(scope)
@children.push(scope)
@@ -129,11 +163,16 @@ module Puppet
# And now return the whole thing
#return self.to_trans
- return self.to_trans
+ objects = self.to_trans
+
+ # I should do something to add the node as an object with tags
+ # but that will possibly end up with far too many tags.
+ self.logtags
+ return objects
end
- # Retrieve a specific node. This is basically only used from within
- # 'findnode'.
+ # Retrieve a specific node. This is used in ast.rb to find a
+ # parent node and in findnode to retrieve and evaluate a node.
def node(name)
@nodetable[name]
end
@@ -175,6 +214,8 @@ module Puppet
@parent = parent
@nodescope = false
+ @tags = []
+
if @parent.nil?
# the level is mostly used for debugging
@level = 1
@@ -191,6 +232,14 @@ module Puppet
# We're the top scope, so record that fact for our children
@topscope = self
+
+ # And create a tag table, so we can collect all of the tags
+ # associated with any objects created in this scope tree
+ @tagtable = Hash.new { |types, type|
+ types[type] = Hash.new { |names, name|
+ names[name] = []
+ }
+ }
else
@parent.child = self
@level = @parent.level + 1
@@ -489,27 +538,37 @@ module Puppet
end
end
+ # Add a tag to our current list. This is only currently used
+ # when nodes evaluate their parents.
+ def tag(*ary)
+ ary.each { |tag|
+ if tag.nil? or tag == ""
+ Puppet.warning "got told to tag with %s" % tag.inspect
+ end
+ unless @tags.include?(tag)
+ @tags << tag.to_s
+ end
+ }
+ end
+
# Return the tags associated with this scope. It's basically
# just our parents' tags, plus our type.
def tags
- unless defined? @tags
- @tags = []
- if @parent
- @tags += @parent.tags
- end
-
- # Add our type to the tag list
- @tags << @type
-
- # We could add the base (e.g., node or class) to the
- # tags, but for now, we're not going to
-
- # We also don't add the name
+ tmp = [] + @tags
+ unless @type.nil? or @type == ""
+ tmp << @type.to_s
end
-
- return @tags.collect { |tag|
- tag.to_s
- }
+ if @parent
+ @parent.tags.each { |tag|
+ if tag.nil? or tag == ""
+ Puppet.warning "parent returned tag %s" % tag.inspect
+ end
+ unless tmp.include?(tag)
+ tmp << tag
+ end
+ }
+ end
+ return tmp
end
# Convert our scope to a list of Transportable objects.
@@ -548,6 +607,11 @@ module Puppet
# Wait until the last minute to set tags, although this
# probably should not matter
child.tags = self.tags
+
+ # Then make sure this child's tags are stored in the
+ # central table. This should maybe be in the evaluate
+ # methods, but, eh.
+ @topscope.addtags(child)
results.push(child)
else
error = Puppet::DevError.new(