summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Wolfe <jes5199@gmail.com>2010-10-05 11:43:32 -0700
committerJesse Wolfe <jes5199@gmail.com>2010-10-05 11:43:32 -0700
commite6c829617ccc120e04f945e8714f792ce29c284d (patch)
tree75718ca64fcc7699069f16a755141a676491a53f
parent7bdbd132634f61d91aeee401de15248d936ce71e (diff)
parent6b278503021c4404904f56ced6995d0fbfa5b8fe (diff)
downloadpuppet-e6c829617ccc120e04f945e8714f792ce29c284d.tar.gz
puppet-e6c829617ccc120e04f945e8714f792ce29c284d.tar.xz
puppet-e6c829617ccc120e04f945e8714f792ce29c284d.zip
Merge remote branch 'paul/ticket/next/4657' into next
This patch conflicts with a backport of itself. This merge resolution favors the original patch for the code changes, and the 2.6.2 patch for the specs. Manually Resolved Conflicts: lib/puppet/dsl/resource_type_api.rb lib/puppet/parser/ast/definition.rb lib/puppet/parser/parser_support.rb spec/integration/parser/ruby_manifest_spec.rb spec/unit/dsl/resource_type_api_spec.rb
-rw-r--r--lib/puppet/dsl/resource_type_api.rb50
-rw-r--r--lib/puppet/parser/ast/definition.rb7
-rw-r--r--lib/puppet/parser/ast/hostclass.rb7
-rw-r--r--lib/puppet/parser/ast/node.rb7
-rw-r--r--lib/puppet/parser/parser_support.rb9
-rwxr-xr-xspec/unit/dsl/resource_type_api_spec.rb56
6 files changed, 62 insertions, 74 deletions
diff --git a/lib/puppet/dsl/resource_type_api.rb b/lib/puppet/dsl/resource_type_api.rb
index ecb914189..8810d5368 100644
--- a/lib/puppet/dsl/resource_type_api.rb
+++ b/lib/puppet/dsl/resource_type_api.rb
@@ -1,46 +1,34 @@
require 'puppet/resource/type'
+# Type of the objects inside of which pure ruby manifest files are
+# executed. Provides methods for creating defines, hostclasses, and
+# nodes.
class Puppet::DSL::ResourceTypeAPI
+ def initialize
+ @__created_ast_objects__ = []
+ end
+
def define(name, *args, &block)
- result = __mk_resource_type__(:definition, name, Hash.new, block)
- result.set_arguments(__munge_type_arguments__(args))
+ args = args.inject([]) do |result, item|
+ if item.is_a?(Hash)
+ item.each { |p, v| result << [p, v] }
+ else
+ result << item
+ end
+ result
+ end
+ @__created_ast_objects__.push Puppet::Parser::AST::Definition.new(name, {:arguments => args}, &block)
nil
end
def hostclass(name, options = {}, &block)
- __mk_resource_type__(:hostclass, name, options, block)
+ @__created_ast_objects__.push Puppet::Parser::AST::Hostclass.new(name, options, &block)
nil
end
def node(name, options = {}, &block)
- __mk_resource_type__(:node, name, options, block)
+ name = [name] unless name.is_a?(Array)
+ @__created_ast_objects__.push Puppet::Parser::AST::Node.new(name, options, &block)
nil
end
-
- # Note: we don't want the user to call the following methods
- # directly. However, we can't stop them by making the methods
- # private because the user's .rb code gets instance_eval'ed on an
- # instance of this class. So instead we name the methods using
- # double underscores to discourage customers from calling them.
-
- def __mk_resource_type__(type, name, options, code)
- klass = Puppet::Resource::Type.new(type, name, options)
-
- klass.ruby_code = code if code
-
- Thread.current[:known_resource_types].add klass
-
- klass
- end
-
- def __munge_type_arguments__(args)
- args.inject([]) do |result, item|
- if item.is_a?(Hash)
- item.each { |p, v| result << [p, v] }
- else
- result << item
- end
- result
- end
- end
end
diff --git a/lib/puppet/parser/ast/definition.rb b/lib/puppet/parser/ast/definition.rb
index 287845ade..c43422f82 100644
--- a/lib/puppet/parser/ast/definition.rb
+++ b/lib/puppet/parser/ast/definition.rb
@@ -3,12 +3,15 @@ require 'puppet/parser/ast/top_level_construct'
class Puppet::Parser::AST::Definition < Puppet::Parser::AST::TopLevelConstruct
attr_accessor :context
- def initialize(name, context = {})
+ def initialize(name, context = {}, &ruby_code)
@name = name
@context = context
+ @ruby_code = ruby_code
end
def instantiate(modname)
- return [Puppet::Resource::Type.new(:definition, @name, @context.merge(:module_name => modname))]
+ new_definition = Puppet::Resource::Type.new(:definition, @name, @context.merge(:module_name => modname))
+ new_definition.ruby_code = @ruby_code if @ruby_code
+ [new_definition]
end
end
diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb
index d539e4deb..cab5e4a24 100644
--- a/lib/puppet/parser/ast/hostclass.rb
+++ b/lib/puppet/parser/ast/hostclass.rb
@@ -3,13 +3,16 @@ require 'puppet/parser/ast/top_level_construct'
class Puppet::Parser::AST::Hostclass < Puppet::Parser::AST::TopLevelConstruct
attr_accessor :name, :context
- def initialize(name, context = {})
+ def initialize(name, context = {}, &ruby_code)
@context = context
@name = name
+ @ruby_code = ruby_code
end
def instantiate(modname)
- all_types = [Puppet::Resource::Type.new(:hostclass, @name, @context.merge(:module_name => modname))]
+ new_class = Puppet::Resource::Type.new(:hostclass, @name, @context.merge(:module_name => modname))
+ new_class.ruby_code = @ruby_code if @ruby_code
+ all_types = [new_class]
if code
code.each do |nested_ast_node|
if nested_ast_node.respond_to? :instantiate
diff --git a/lib/puppet/parser/ast/node.rb b/lib/puppet/parser/ast/node.rb
index 4951a6365..b69a5c4e0 100644
--- a/lib/puppet/parser/ast/node.rb
+++ b/lib/puppet/parser/ast/node.rb
@@ -3,15 +3,18 @@ require 'puppet/parser/ast/top_level_construct'
class Puppet::Parser::AST::Node < Puppet::Parser::AST::TopLevelConstruct
attr_accessor :names, :context
- def initialize(names, context = {})
+ def initialize(names, context = {}, &ruby_code)
raise ArgumentError, "names should be an array" unless names.is_a? Array
@names = names
@context = context
+ @ruby_code = ruby_code
end
def instantiate(modname)
@names.collect do |name|
- Puppet::Resource::Type.new(:node, name, @context.merge(:module_name => modname))
+ new_node = Puppet::Resource::Type.new(:node, name, @context.merge(:module_name => modname))
+ new_node.ruby_code = @ruby_code if @ruby_code
+ new_node
end
end
end
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index 288abb582..16cd0ee0f 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -146,8 +146,7 @@ class Puppet::Parser::Parser
# how should I do error handling here?
def parse(string = nil)
if self.file =~ /\.rb$/
- parse_ruby_file
- main = nil
+ main = parse_ruby_file
else
self.string = string if string
begin
@@ -189,7 +188,11 @@ class Puppet::Parser::Parser
def parse_ruby_file
# Execute the contents of the file inside its own "main" object so
# that it can call methods in the resource type API.
- Puppet::DSL::ResourceTypeAPI.new.instance_eval(File.read(self.file))
+ main_object = Puppet::DSL::ResourceTypeAPI.new
+ main_object.instance_eval(File.read(self.file))
+
+ # Then extract any types that were created.
+ Puppet::Parser::AST::ASTArray.new :children => main_object.instance_eval { @__created_ast_objects__ }
end
def string=(string)
diff --git a/spec/unit/dsl/resource_type_api_spec.rb b/spec/unit/dsl/resource_type_api_spec.rb
index 4f4eb7e01..c9a5d272f 100755
--- a/spec/unit/dsl/resource_type_api_spec.rb
+++ b/spec/unit/dsl/resource_type_api_spec.rb
@@ -5,62 +5,50 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/dsl/resource_type_api'
describe Puppet::DSL::ResourceTypeAPI do
- # Run the given block in the context of a new ResourceTypeAPI
- # object.
+ # Verify that the block creates a single AST node through the API,
+ # instantiate that AST node into a types, and return that type.
def test_api_call(&block)
- Thread.current[:known_resource_types] = Puppet::Resource::TypeCollection.new(:env)
- Puppet::DSL::ResourceTypeAPI.new.instance_eval(&block)
+ main_object = Puppet::DSL::ResourceTypeAPI.new
+ main_object.instance_eval(&block)
+ created_ast_objects = main_object.instance_eval { @__created_ast_objects__ }
+ created_ast_objects.length.should == 1
+ new_types = created_ast_objects[0].instantiate('')
+ new_types.length.should == 1
+ new_types[0]
ensure
- Thread.current[:known_resource_types] = nil
+ Thread.current[:ruby_file_parse_result] = nil
end
[:definition, :node, :hostclass].each do |type|
method = type == :definition ? "define" : type
it "should be able to create a #{type}" do
- newtype = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).with { |t, n, args| t == type }.returns newtype
- test_api_call { send(method, "myname") }
+ newtype = test_api_call { send(method, "myname").should == nil }
+ newtype.should be_a(Puppet::Resource::Type)
+ newtype.type.should == type
end
it "should use the provided name when creating a #{type}" do
- type = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).with { |t, n, args| n == "myname" }.returns type
- test_api_call { send(method, "myname") }
+ newtype = test_api_call { send(method, "myname") }
+ newtype.name.should == "myname"
end
unless type == :definition
- it "should pass in any provided options" do
- type = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).with { |t, n, args| args == {:myarg => :myvalue} }.returns type
- test_api_call { send(method, "myname", :myarg => :myvalue) }
+ it "should pass in any provided options when creating a #{type}" do
+ newtype = test_api_call { send(method, "myname", :line => 200) }
+ newtype.line.should == 200
end
end
it "should set any provided block as the type's ruby code" do
- Puppet::Resource::Type.any_instance.expects(:ruby_code=).with { |blk| blk.call == 'foo' }
- test_api_call { send(method, "myname") { 'foo' } }
- end
-
- it "should add the type to the current environment's known resource types" do
- begin
- newtype = Puppet::Resource::Type.new(:hostclass, "foo")
- Puppet::Resource::Type.expects(:new).returns newtype
- known_resource_types = Puppet::Resource::TypeCollection.new(:env)
- Thread.current[:known_resource_types] = known_resource_types
- known_resource_types.expects(:add).with(newtype)
- Puppet::DSL::ResourceTypeAPI.new.instance_eval { hostclass "myname" }
- ensure
- Thread.current[:known_resource_types] = nil
- end
+ newtype = test_api_call { send(method, "myname") { 'method_result' } }
+ newtype.ruby_code.call.should == 'method_result'
end
end
describe "when creating a definition" do
it "should use the provided options to define valid arguments for the resource type" do
- newtype = Puppet::Resource::Type.new(:definition, "foo")
- Puppet::Resource::Type.expects(:new).returns newtype
- test_api_call { define("myname", :arg1, :arg2) }
- newtype.instance_eval { @arguments }.should == { 'arg1' => nil, 'arg2' => nil }
+ newtype = test_api_call { define("myname", :arg1, :arg2) }
+ newtype.arguments.should == { 'arg1' => nil, 'arg2' => nil }
end
end
end