summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/parser/ast/definition.rb304
-rw-r--r--lib/puppet/parser/ast/hostclass.rb113
-rw-r--r--lib/puppet/parser/ast/node.rb96
-rw-r--r--lib/puppet/parser/resource.rb2
-rw-r--r--lib/puppet/parser/resource/param.rb2
-rw-r--r--lib/puppet/parser/scope.rb5
6 files changed, 256 insertions, 266 deletions
diff --git a/lib/puppet/parser/ast/definition.rb b/lib/puppet/parser/ast/definition.rb
index 2e39e7332..bf57942d7 100644
--- a/lib/puppet/parser/ast/definition.rb
+++ b/lib/puppet/parser/ast/definition.rb
@@ -1,152 +1,145 @@
require 'puppet/parser/ast/branch'
-class Puppet::Parser::AST
- # Evaluate the stored parse tree for a given component. This will
- # receive the arguments passed to the component and also the type and
- # name of the component.
- class Definition < AST::Branch
- include Puppet::Util
- include Puppet::Util::Warnings
- include Puppet::Util::MethodHelper
- class << self
- attr_accessor :name
- end
+require 'puppet/util/warnings'
- # The class name
- @name = :definition
+# The AST class for defined types, which is also the base class
+# nodes and classes.
+class Puppet::Parser::AST::Definition < Puppet::Parser::AST::Branch
+ include Puppet::Util::Warnings
+ class << self
+ attr_accessor :name
+ end
- attr_accessor :classname, :arguments, :code, :scope, :keyword
- attr_accessor :exported, :namespace, :parser, :virtual
+ # The class name
+ @name = :definition
- # These are retrieved when looking up the superclass
- attr_accessor :name
+ attr_accessor :classname, :arguments, :code, :scope, :keyword
+ attr_accessor :exported, :namespace, :parser, :virtual, :name
- attr_reader :parentclass
+ attr_reader :parentclass
- def child_of?(klass)
- false
- end
+ def child_of?(klass)
+ false
+ end
- def evaluate(origscope, resource)
- # Create a new scope.
- scope = subscope(origscope, resource)
+ # Create a resource that knows how to evaluate our actual code.
+ def evaluate(scope)
+ resource = Puppet::Parser::Resource.new(:type => "class", :title => klass.classname, :scope => scope, :source => scope.source)
- # Additionally, add a tag for whatever kind of class
- # we are
- if @classname != "" and ! @classname.nil?
- @classname.split(/::/).each { |tag| scope.resource.tag(tag) }
- end
+ scope.compile.store_resource(scope, resource)
- [resource.name, resource.title].each do |str|
- unless str.nil? or str =~ /[^\w]/ or str == ""
- scope.resource.tag(str)
- end
- end
+ return resource
+ end
- set_resource_parameters(scope, resource)
+ # Now evaluate the code associated with this class or definition.
+ def evaluate_code(resource)
+ # Create a new scope.
+ scope = subscope(resource.scope, resource)
- if self.code
- return self.code.safeevaluate(scope)
- else
- return nil
- end
+ set_resource_parameters(scope, resource)
+
+ if self.code
+ return self.code.safeevaluate(scope)
+ else
+ return nil
end
+ end
- def initialize(hash = {})
- @arguments = nil
- @parentclass = nil
- super
+ def initialize(hash = {})
+ @arguments = nil
+ @parentclass = nil
+ super
- # Convert the arguments to a hash for ease of later use.
- if @arguments
- unless @arguments.is_a? Array
- @arguments = [@arguments]
- end
- oldargs = @arguments
- @arguments = {}
- oldargs.each do |arg, val|
- @arguments[arg] = val
- end
- else
- @arguments = {}
+ # Convert the arguments to a hash for ease of later use.
+ if @arguments
+ unless @arguments.is_a? Array
+ @arguments = [@arguments]
end
-
- # Deal with metaparams in the argument list.
- @arguments.each do |arg, defvalue|
- next unless Puppet::Type.metaparamclass(arg)
- if defvalue
- warnonce "%s is a metaparam; this value will inherit to all contained resources" % arg
- else
- raise Puppet::ParseError, "%s is a metaparameter; please choose another parameter name in the %s definition" % [arg, self.classname]
- end
+ oldargs = @arguments
+ @arguments = {}
+ oldargs.each do |arg, val|
+ @arguments[arg] = val
end
+ else
+ @arguments = {}
end
- def find_parentclass
- @parser.findclass(namespace, parentclass)
+ # Deal with metaparams in the argument list.
+ @arguments.each do |arg, defvalue|
+ next unless Puppet::Type.metaparamclass(arg)
+ if defvalue
+ warnonce "%s is a metaparam; this value will inherit to all contained resources" % arg
+ else
+ raise Puppet::ParseError, "%s is a metaparameter; please choose another parameter name in the %s definition" % [arg, self.classname]
+ end
end
+ end
- # Set our parent class, with a little check to avoid some potential
- # weirdness.
- def parentclass=(name)
- if name == self.classname
- parsefail "Parent classes must have dissimilar names"
- end
+ def find_parentclass
+ @parser.findclass(namespace, parentclass)
+ end
- @parentclass = name
+ # Set our parent class, with a little check to avoid some potential
+ # weirdness.
+ def parentclass=(name)
+ if name == self.classname
+ parsefail "Parent classes must have dissimilar names"
end
- # Hunt down our class object.
- def parentobj
- if @parentclass
- # Cache our result, since it should never change.
- unless defined?(@parentobj)
- unless tmp = find_parentclass
- parsefail "Could not find %s %s" % [self.class.name, @parentclass]
- end
+ @parentclass = name
+ end
- if tmp == self
- parsefail "Parent classes must have dissimilar names"
- end
+ # Hunt down our class object.
+ def parentobj
+ if @parentclass
+ # Cache our result, since it should never change.
+ unless defined?(@parentobj)
+ unless tmp = find_parentclass
+ parsefail "Could not find %s %s" % [self.class.name, @parentclass]
+ end
- @parentobj = tmp
+ if tmp == self
+ parsefail "Parent classes must have dissimilar names"
end
- @parentobj
- else
- nil
+
+ @parentobj = tmp
end
+ @parentobj
+ else
+ nil
end
+ end
- # Create a new subscope in which to evaluate our code.
- def subscope(scope, resource)
- args = {
- :resource => resource,
- :keyword => self.keyword,
- :namespace => self.namespace,
- :source => self
- }
+ # Create a new subscope in which to evaluate our code.
+ def subscope(scope, resource)
+ args = {
+ :resource => resource,
+ :keyword => self.keyword,
+ :namespace => self.namespace,
+ :source => self
+ }
- oldscope = scope
- scope = scope.newscope(args)
- scope.source = self
+ oldscope = scope
+ scope = scope.newscope(args)
+ scope.source = self
- return scope
- end
+ return scope
+ end
- def to_s
- classname
- end
+ def to_s
+ classname
+ end
- # Check whether a given argument is valid. Searches up through
- # any parent classes that might exist.
- def validattr?(param)
- param = param.to_s
+ # Check whether a given argument is valid. Searches up through
+ # any parent classes that might exist.
+ def validattr?(param)
+ param = param.to_s
- if @arguments.include?(param)
- # It's a valid arg for us
- return true
- elsif param == "name"
- return true
+ if @arguments.include?(param)
+ # It's a valid arg for us
+ return true
+ elsif param == "name"
+ return true
# elsif defined? @parentclass and @parentclass
# # Else, check any existing parent
# if parent = @scope.lookuptype(@parentclass) and parent != []
@@ -157,53 +150,52 @@ class Puppet::Parser::AST
# raise Puppet::Error, "Could not find parent class %s" %
# @parentclass
# end
- elsif Puppet::Type.metaparam?(param)
- return true
- else
- # Or just return false
- return false
- end
+ elsif Puppet::Type.metaparam?(param)
+ return true
+ else
+ # Or just return false
+ return false
end
+ end
- private
-
- # Set any arguments passed by the resource as variables in the scope.
- def set_resource_parameters(scope, resource)
- args = symbolize_options(resource.to_hash || {})
-
- # Verify that all required arguments are either present or
- # have been provided with defaults.
- if self.arguments
- self.arguments.each { |arg, default|
- arg = symbolize(arg)
- unless args.include?(arg)
- if defined? default and ! default.nil?
- default = default.safeevaluate scope
- args[arg] = default
- #Puppet.debug "Got default %s for %s in %s" %
- # [default.inspect, arg.inspect, @name.inspect]
- else
- parsefail "Must pass %s to %s of type %s" %
- [arg, resource.title, @classname]
- end
+ private
+
+ # Set any arguments passed by the resource as variables in the scope.
+ def set_resource_parameters(scope, resource)
+ args = symbolize_options(resource.to_hash || {})
+
+ # Verify that all required arguments are either present or
+ # have been provided with defaults.
+ if self.arguments
+ self.arguments.each { |arg, default|
+ arg = arg.to_sym
+ unless args.include?(arg)
+ if defined? default and ! default.nil?
+ default = default.safeevaluate scope
+ args[arg] = default
+ #Puppet.debug "Got default %s for %s in %s" %
+ # [default.inspect, arg.inspect, @name.inspect]
+ else
+ parsefail "Must pass %s to %s of type %s" %
+ [arg, resource.title, @classname]
end
- }
- end
-
- # Set each of the provided arguments as variables in the
- # definition's scope.
- args.each { |arg,value|
- unless validattr?(arg)
- parsefail "%s does not accept attribute %s" % [@classname, arg]
- end
-
- exceptwrap do
- scope.setvar(arg.to_s, args[arg])
end
}
-
- scope.setvar("title", resource.title) unless args.include? :title
- scope.setvar("name", resource.name) unless args.include? :name
end
+
+ # Set each of the provided arguments as variables in the
+ # definition's scope.
+ args.each { |arg,value|
+ unless validattr?(arg)
+ parsefail "%s does not accept attribute %s" % [@classname, arg]
+ end
+
+ exceptwrap do
+ scope.setvar(arg.to_s, args[arg])
+ end
+ }
+
+ scope.setvar("title", resource.title) unless args.include? :title
+ scope.setvar("name", resource.name) unless args.include? :name
end
end
diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb
index 42d13f4b2..251d5eba6 100644
--- a/lib/puppet/parser/ast/hostclass.rb
+++ b/lib/puppet/parser/ast/hostclass.rb
@@ -1,78 +1,73 @@
require 'puppet/parser/ast/definition'
-class Puppet::Parser::AST
- # The code associated with a class. This is different from definitions
- # in that each class is a singleton -- only one will exist for a given
- # node.
- class HostClass < AST::Definition
- @name = :class
+# The code associated with a class. This is different from definitions
+# in that each class is a singleton -- only one will exist for a given
+# node.
+class Puppet::Parser::AST::HostClass < Puppet::Parser::AST::Definition
+ @name = :class
- # Are we a child of the passed class? Do a recursive search up our
- # parentage tree to figure it out.
- def child_of?(klass)
- return false unless self.parentclass
+ # Are we a child of the passed class? Do a recursive search up our
+ # parentage tree to figure it out.
+ def child_of?(klass)
+ return false unless self.parentclass
- if klass == self.parentobj
- return true
- else
- return self.parentobj.child_of?(klass)
- end
+ if klass == self.parentobj
+ return true
+ else
+ return self.parentobj.child_of?(klass)
end
+ end
- # Evaluate the code associated with this class.
- def evaluate(scope, resource)
- # Verify that we haven't already been evaluated. This is
- # what provides the singleton aspect.
- if existing_scope = scope.compile.class_scope(self)
- Puppet.debug "Class '%s' already evaluated; not evaluating again" % (classname == "" ? "main" : classname)
- return nil
- end
-
- scope.compile.catalog.tag(self.classname)
+ # Evaluate the code associated with this class.
+ def evaluate_code(resource)
+ scope = resource.scope
+ # Verify that we haven't already been evaluated. This is
+ # what provides the singleton aspect.
+ if existing_scope = scope.compile.class_scope(self)
+ Puppet.debug "Class '%s' already evaluated; not evaluating again" % (classname == "" ? "main" : classname)
+ return nil
+ end
- pnames = nil
- if pklass = self.parentobj
- pklass.safeevaluate(scope, resource)
+ pnames = nil
+ if pklass = self.parentobj
+ pklass.evaluate_code(resource)
- scope = parent_scope(scope, pklass)
- pnames = scope.namespaces
- end
+ scope = parent_scope(scope, pklass)
+ pnames = scope.namespaces
+ end
- # Don't create a subscope for the top-level class, since it already
- # has its own scope.
- unless resource.title == :main
- scope = subscope(scope, resource)
- end
+ # Don't create a subscope for the top-level class, since it already
+ # has its own scope.
+ scope = subscope(scope, resource) unless resource.title == :main
- if pnames
- pnames.each do |ns|
- scope.add_namespace(ns)
- end
+ if pnames
+ pnames.each do |ns|
+ scope.add_namespace(ns)
end
+ end
- # Set the class before we do anything else, so that it's set
- # during the evaluation and can be inspected.
- scope.compile.class_set(self.classname, scope)
+ # Set the class before we do anything else, so that it's set
+ # during the evaluation and can be inspected.
+ scope.compile.class_set(self.classname, scope)
- # Now evaluate our code, yo.
- if self.code
- return self.code.safeevaluate(scope)
- else
- return nil
- end
+ # Now evaluate our code, yo.
+ if self.code
+ return self.code.safeevaluate(scope)
+ else
+ return nil
end
+ end
- def initialize(options)
- @parentclass = nil
- super
- end
+ def initialize(options)
+ @parentclass = nil
+ super
+ end
- def parent_scope(scope, klass)
- if s = scope.compile.class_scope(klass)
- return s
- else
- raise Puppet::DevError, "Could not find scope for %s" % klass.classname
- end
+ def parent_scope(scope, klass)
+ if s = scope.compile.class_scope(klass)
+ return s
+ else
+ raise Puppet::DevError, "Could not find scope for %s" % klass.classname
end
end
end
diff --git a/lib/puppet/parser/ast/node.rb b/lib/puppet/parser/ast/node.rb
index 3c5d44d1b..7ff7a18e1 100644
--- a/lib/puppet/parser/ast/node.rb
+++ b/lib/puppet/parser/ast/node.rb
@@ -1,59 +1,57 @@
require 'puppet/parser/ast/hostclass'
-class Puppet::Parser::AST
- # The specific code associated with a host. Nodes are annoyingly unlike
- # other objects. That's just the way it is, at least for now.
- class Node < AST::HostClass
- @name = :node
- attr_accessor :name
-
- def evaluate(scope, resource)
- # We don't have to worry about the declarativeness of node parentage,
- # because the entry point is always a single node definition.
- if parent = self.parentobj
- scope = parent.safeevaluate scope, resource
- end
-
- scope = scope.newscope(
- :resource => resource,
- :keyword => @keyword,
- :source => self,
- :namespace => "" # nodes are always in ""
- )
-
- # Mark our node name as a class, too, but strip it of the domain
- # name. Make the mark before we evaluate the code, so that it is
- # marked within the code itself.
- scope.compile.class_set(self.classname, scope)
-
- # And then evaluate our code if we have any
- if self.code
- @code.safeevaluate(scope)
- end
-
- return scope
+# The specific code associated with a host. Nodes are annoyingly unlike
+# other objects. That's just the way it is, at least for now.
+class Puppet::Parser::AST::Node < Puppet::Parser::AST::HostClass
+ @name = :node
+
+ # Evaluate the code associated with our node definition.
+ def evaluate_code(resource)
+ scope = resource.scope
+
+ # We don't have to worry about the declarativeness of node parentage,
+ # because the entry point is always a single node definition.
+ if parent = self.parentobj
+ scope = parent.evaluate_code(resource)
end
- def initialize(options)
- @parentclass = nil
- super
+ scope = scope.newscope(
+ :resource => resource,
+ :keyword => @keyword,
+ :source => self,
+ :namespace => "" # nodes are always in ""
+ )
- # Do some validation on the node name
- if @name =~ /[^-\w.]/
- raise Puppet::ParseError, "Invalid node name %s" % @name
- end
- end
+ # Mark our node name as a class, too, but strip it of the domain
+ # name. Make the mark before we evaluate the code, so that it is
+ # marked within the code itself.
+ scope.compile.class_set(self.classname, scope)
- # Make sure node scopes are marked as such.
- def subscope(*args)
- scope = super
- scope.nodescope = true
- end
+ # And then evaluate our code if we have any
+ @code.safeevaluate(scope) if self.code
+
+ return scope
+ end
+
+ def initialize(options)
+ @parentclass = nil
+ super
- private
- # Search for the object matching our parent class.
- def find_parentclass
- @parser.findnode(parentclass)
+ # Do some validation on the node name
+ if @name =~ /[^-\w.]/
+ raise Puppet::ParseError, "Invalid node name %s" % @name
end
end
+
+ # Make sure node scopes are marked as such.
+ def subscope(*args)
+ scope = super
+ scope.nodescope = true
+ end
+
+ private
+ # Search for the object matching our parent class.
+ def find_parentclass
+ @parser.findnode(parentclass)
+ end
end
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index ea6038299..f8701578c 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -59,7 +59,7 @@ class Puppet::Parser::Resource
if klass = @ref.definedtype
finish()
scope.compile.delete_resource(self)
- return klass.evaluate(scope, self)
+ return klass.evaluate_code(self)
elsif builtin?
devfail "Cannot evaluate a builtin type"
else
diff --git a/lib/puppet/parser/resource/param.rb b/lib/puppet/parser/resource/param.rb
index 9352311d6..9dd3f26d2 100644
--- a/lib/puppet/parser/resource/param.rb
+++ b/lib/puppet/parser/resource/param.rb
@@ -12,7 +12,7 @@ class Puppet::Parser::Resource::Param
end
def inspect
- "#<#{self.class} @name => #{self.name}, @value => #{self.value}, @source => #{self.source.name}>"
+ "#<#{self.class} @name => #{name}, @value => #{value}, @source => #{source.name}>"
end
def line_to_i
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index 028414cc0..81d4ac71a 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -19,6 +19,11 @@ class Puppet::Parser::Scope
attr_accessor :base, :keyword, :nodescope
attr_accessor :top, :translated, :compile
+ # A demeterific shortcut to the catalog.
+ def catalog
+ compile.catalog
+ end
+
# Proxy accessors
def host
@compile.node.name