When a class is evaluated, its parent class
needs to be evaluated first.  This forces that
evaluation.  We somehow lost it when we converted
the resource types out of AST.

Signed-off-by: Luke Kanies <[email protected]>
---
 lib/puppet/resource/type.rb |   21 +++++++++++++++++--
 spec/unit/resource/type.rb  |   45 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb
index f82b6dc..0a0c3be 100644
--- a/lib/puppet/resource/type.rb
+++ b/lib/puppet/resource/type.rb
@@ -25,9 +25,14 @@ class Puppet::Resource::Type
 
     # Now evaluate the code associated with this class or definition.
     def evaluate_code(resource)
-        # Create a new scope.
-        scope = subscope(resource.scope, resource)
-        scope.compiler.class_set(name, scope)
+        scope = resource.scope
+
+        if tmp = evaluate_parent_type(resource)
+            scope = tmp
+        end
+
+        scope = subscope(scope, resource)
+        scope.compiler.class_set(name, scope) unless type == :definition
 
         set_resource_parameters(resource, scope)
 
@@ -206,6 +211,12 @@ class Puppet::Resource::Type
         end
     end
 
+    def evaluate_parent_type(resource)
+        return unless klass = parent_type and parent_resource = 
resource.scope.compiler.catalog.resource(:class, klass.name)
+        parent_resource.evaluate unless parent_resource.evaluated?
+        return parent_scope(resource.scope, klass)
+    end
+
     # Split an fq name into a namespace and name
     def namesplit(fullname)
         ary = fullname.split("::")
@@ -214,6 +225,10 @@ class Puppet::Resource::Type
         return ns, n
     end
 
+    def parent_scope(scope, klass)
+        scope.compiler.class_scope(klass) || raise(Puppet::DevError, "Could 
not find scope for #{klass.name}")
+    end
+
     def set_name_and_namespace(name)
         if name.is_a?(Regexp)
             @name = name
diff --git a/spec/unit/resource/type.rb b/spec/unit/resource/type.rb
index 2e592c0..fe839d9 100755
--- a/spec/unit/resource/type.rb
+++ b/spec/unit/resource/type.rb
@@ -324,7 +324,7 @@ describe Puppet::Resource::Type do
         before do
             @compiler = 
Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
             @scope = Puppet::Parser::Scope.new :compiler => @compiler
-            @resource = stub 'resource', :title => "yay", :name => "yea", :ref 
=> "Foo[bar]", :scope => @scope
+            @resource = Puppet::Parser::Resource.new(:foo, "yay", :scope => 
@scope)
             @type = Puppet::Resource::Type.new(:hostclass, "foo")
             @type.stubs(:set_resource_parameters)
         end
@@ -345,6 +345,15 @@ describe Puppet::Resource::Type do
             @compiler.class_scope(@type).should equal(subscope)
         end
 
+        it "should still create a scope but not store it if the type is a 
definition" do
+            subscope = stub 'subscope', :compiler => @compiler, :setvar => nil
+
+            @type = Puppet::Resource::Type.new(:definition, "foo")
+            @type.expects(:subscope).with(@scope, @resource).returns subscope
+            @type.evaluate_code(@resource)
+            @compiler.class_scope(@type).should be_nil
+        end
+
         it "should evaluate the code if any is provided" do
             code = stub 'code'
             @type.stubs(:code).returns code
@@ -359,6 +368,40 @@ describe Puppet::Resource::Type do
 
             @type.evaluate_code(@resource)
         end
+
+        describe "and it has a parent class" do
+            before do
+                @parent_type = Puppet::Resource::Type.new(:hostclass, "parent")
+                @compiler
+                @type.parent = "parent"
+                @parent_resource = Puppet::Parser::Resource.new(:class, 
"parent", :scope => @scope)
+
+                @compiler.add_resource @scope, @parent_resource
+
+                @type.code_collection = @scope.known_resource_types
+                @type.code_collection.add @parent_type
+            end
+
+            it "should evaluate the parent's resource" do
+                @type.evaluate_code(@resource)
+
+                @compiler.class_scope(@parent_type).should_not be_nil
+            end
+
+            it "should not evaluate the parent's resource if it has already 
been evaluated" do
+                @parent_resource.evaluate
+
+                @parent_resource.expects(:evaluate).never
+
+                @type.evaluate_code(@resource)
+            end
+
+            it "should use the parent's scope as its base scope" do
+                @type.evaluate_code(@resource)
+
+                @scope.compiler.class_scope(@type).parent.object_id.should == 
@scope.compiler.class_scope(@parent_type).object_id
+            end
+        end
     end
 
     describe "when creating a resource" do
-- 
1.6.1

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to