summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/puppet/resource/type.rb19
-rwxr-xr-xspec/unit/resource/type.rb45
2 files changed, 61 insertions, 3 deletions
diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb
index c615a2ccb..e102cb0fd 100644
--- a/lib/puppet/resource/type.rb
+++ b/lib/puppet/resource/type.rb
@@ -25,8 +25,13 @@ 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 = resource.scope
+
+ if tmp = evaluate_parent_type(resource)
+ scope = tmp
+ end
+
+ scope = subscope(scope, resource)
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 1a19cf4f0..d1ee024ef 100755
--- a/spec/unit/resource/type.rb
+++ b/spec/unit/resource/type.rb
@@ -329,7 +329,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
@@ -350,6 +350,15 @@ describe Puppet::Resource::Type do
@type.evaluate_code(@resource)
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
@@ -364,6 +373,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