summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrice Figureau <brice-puppet@daysofwonder.com>2009-05-31 15:38:14 +0200
committerJames Turnbull <james@lovedthanlost.net>2009-06-10 15:28:21 +1000
commitb5a8c4db028c69793c1c9172adca4d9930c8cd1d (patch)
treec88e3776255d34385328ac4df9b23897015225ff
parent74730df475f21848027a4d2dda9ab849d3038c49 (diff)
downloadpuppet-b5a8c4db028c69793c1c9172adca4d9930c8cd1d.tar.gz
puppet-b5a8c4db028c69793c1c9172adca4d9930c8cd1d.tar.xz
puppet-b5a8c4db028c69793c1c9172adca4d9930c8cd1d.zip
Fix #1907 (or sort) - 'require' puppet function
This function acts exactly as the 'include' function, but also adds an ordering relation between the included class and the class where the require function is. Signed-off-by: Brice Figureau <brice-puppet@daysofwonder.com>
-rw-r--r--lib/puppet/parser/functions/require.rb34
-rwxr-xr-xspec/integration/parser/functions/require.rb27
-rwxr-xr-xspec/unit/parser/functions/require.rb36
3 files changed, 97 insertions, 0 deletions
diff --git a/lib/puppet/parser/functions/require.rb b/lib/puppet/parser/functions/require.rb
new file mode 100644
index 000000000..7d73831b8
--- /dev/null
+++ b/lib/puppet/parser/functions/require.rb
@@ -0,0 +1,34 @@
+# Requires the specified classes
+Puppet::Parser::Functions::newfunction(:require,
+ :doc =>"Evaluate one or more classes, adding the required class as a dependency.
+
+The relationship metaparameters work well for specifying relationships
+between individual resources, but they can be clumsy for specifying
+relationships between classes. This function is a superset of the
+'include' function, adding a class relationship so that the requiring
+class depends on the required class.
+
+.. Warning::
+ using require in place of include can lead to unwanted dependency cycles.
+ For instance the following manifest, with 'require' instead of 'include'
+ would produce a nasty dependence cycle, because notify imposes a before
+ between File[/foo] and Service[foo]::
+
+ class myservice {
+ service { foo: ensure => running }
+ }
+
+ class otherstuff {
+ include myservice
+ file { '/foo': notify => Service[foo] }
+ }
+
+") do |vals|
+ send(:function_include, vals)
+ vals = [vals] unless vals.is_a?(Array)
+
+ # add a relation from ourselves to each required klass
+ vals.each do |klass|
+ compiler.catalog.add_edge(resource, findresource(:class, klass))
+ end
+end
diff --git a/spec/integration/parser/functions/require.rb b/spec/integration/parser/functions/require.rb
new file mode 100755
index 000000000..68a1e0b54
--- /dev/null
+++ b/spec/integration/parser/functions/require.rb
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "the require function" do
+
+ before :each do
+ @parser = Puppet::Parser::Parser.new :Code => ""
+ @node = Puppet::Node.new("mynode")
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+
+ @compiler.send(:evaluate_main)
+ @scope = @compiler.topscope
+ # preload our functions
+ Puppet::Parser::Functions.function(:include)
+ Puppet::Parser::Functions.function(:require)
+ end
+
+ it "should add a relationship between the 'required' class and our class" do
+ @parser.newclass("requiredclass")
+
+ @scope.function_require("requiredclass")
+
+ @compiler.catalog.edge?(@scope.resource,@compiler.findresource(:class,"requiredclass")).should be_true
+ end
+
+end
diff --git a/spec/unit/parser/functions/require.rb b/spec/unit/parser/functions/require.rb
new file mode 100755
index 000000000..67a5baeb9
--- /dev/null
+++ b/spec/unit/parser/functions/require.rb
@@ -0,0 +1,36 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "the require function" do
+
+ before :each do
+ @catalog = stub 'catalog'
+ @compiler = stub 'compiler', :catalog => @catalog
+ @scope = Puppet::Parser::Scope.new()
+ @scope.stubs(:resource).returns("ourselves")
+ @scope.stubs(:findresource)
+ @scope.stubs(:compiler).returns(@compiler)
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("require").should == "function_require"
+ end
+
+ it "should delegate to the 'include' puppet function" do
+ @catalog.stubs(:add_edge)
+ @scope.expects(:function_include).with("myclass")
+
+ @scope.function_require("myclass")
+ end
+
+ it "should add a catalog edge from our parent resource to the included one" do
+ @scope.stubs(:function_include).with("myclass")
+ @scope.stubs(:findresource).with(:class, "myclass").returns("includedclass")
+
+ @catalog.expects(:add_edge).with("ourselves","includedclass")
+
+ @scope.function_require("myclass")
+ end
+
+end