[Pkg-puppet-devel] [facter] 193/352: (#19845) Allow a block to be supplied as a confine

Stig Sandbeck Mathisen ssm at debian.org
Sun Apr 6 22:21:45 UTC 2014


This is an automated email from the git hooks/post-receive script.

ssm pushed a commit to branch master
in repository facter.

commit e4c86894fdf38f84303031c6559b4fe1d7638e8e
Author: Erik Dalén <dalen at spotify.com>
Date:   Thu Mar 21 16:09:57 2013 +0100

    (#19845) Allow a block to be supplied as a confine
    
    Allows a confine to take only a block parameter like:
    
    confine { File.exist? '/bin/foo' }
    
    Or take a fact name and a block:
    
    confine :ipaddress do |addr|
      require 'ipaddr'
      IPAddr.new('192.168.0.0/16').include? addr
    end
    
    This is similar to what Puppet allows in provider confines.
    
    Backported onto facter-2 by Adrien Thebo <adrien at puppetlabs.com>
    
    Conflicts:
    	lib/facter/util/resolution.rb
    	spec/unit/util/resolution_spec.rb
---
 lib/facter/core/suitable.rb     | 18 +++++++++++++++---
 lib/facter/util/confine.rb      | 38 +++++++++++++++++++++++++++++++++----
 spec/unit/core/suitable_spec.rb | 42 +++++++++++++++++++++++++++++++++--------
 spec/unit/util/confine_spec.rb  | 21 +++++++++++++++++++++
 4 files changed, 104 insertions(+), 15 deletions(-)

diff --git a/lib/facter/core/suitable.rb b/lib/facter/core/suitable.rb
index 3f4a7bc..e34b5e8 100644
--- a/lib/facter/core/suitable.rb
+++ b/lib/facter/core/suitable.rb
@@ -46,9 +46,21 @@ module Facter::Core::Suitable
   # @return [void]
   #
   # @api public
-  def confine(confines)
-    confines.each do |fact, values|
-      @confines.push Facter::Util::Confine.new(fact, *values)
+  def confine(confines = nil, &block)
+    case confines
+    when Hash
+      confines.each do |fact, values|
+        @confines.push Facter::Util::Confine.new(fact, *values)
+      end
+    else
+      if block
+        if confines
+          @confines.push Facter::Util::Confine.new(confines, &block)
+        else
+          @confines.push Facter::Util::Confine.new(&block)
+        end
+      else
+      end
     end
   end
 
diff --git a/lib/facter/util/confine.rb b/lib/facter/util/confine.rb
index 3bb504b..eac539c 100644
--- a/lib/facter/util/confine.rb
+++ b/lib/facter/util/confine.rb
@@ -10,19 +10,40 @@ class Facter::Util::Confine
 
   # Add the restriction.  Requires the fact name, an operator, and the value
   # we're comparing to.
-  def initialize(fact, *values)
-    raise ArgumentError, "The fact name must be provided" unless fact
-    raise ArgumentError, "One or more values must be provided" if values.empty?
+  #
+  # @param fact [Symbol] Name of the fact
+  # @param values [Array] One or more values to match against.
+  #   They can be any type that provides a === method.
+  # @param block [Proc] Alternatively a block can be supplied as a check.  The fact
+  #   value will be passed as the argument to the block.  If the block returns
+  #   true then the fact will be enabled, otherwise it will be disabled.
+  def initialize(fact = nil, *values, &block)
+    raise ArgumentError, "The fact name must be provided" unless fact or block_given?
+    if values.empty? and not block_given?
+      raise ArgumentError, "One or more values or a block must be provided"
+    end
     @fact = fact
     @values = values
+    @block = block
   end
 
   def to_s
+    return @block.to_s if @block
     return "'%s' '%s'" % [@fact, @values.join(",")]
   end
 
   # Evaluate the fact, returning true or false.
+  # if we have a block paramter then we only evaluate that instead
   def true?
+    if @block and not @fact then
+      begin
+        return !! @block.call
+      rescue StandardError => error
+        Facter.debug "Confine raised #{error.class} #{error}"
+        return false
+      end
+    end
+
     unless fact = Facter[@fact]
       Facter.debug "No fact for %s" % @fact
       return false
@@ -31,6 +52,15 @@ class Facter::Util::Confine
 
     return false if value.nil?
 
-    return @values.any? { |v| convert(v) === value }
+    if @block then
+      begin
+        return !! @block.call(value)
+      rescue StandardError => error
+        Facter.debug "Confine raised #{error.class} #{error}"
+        return false
+      end
+    end
+
+    return @values.any? do |v| convert(v) === value end
   end
 end
diff --git a/spec/unit/core/suitable_spec.rb b/spec/unit/core/suitable_spec.rb
index feadb41..4c0b1fd 100644
--- a/spec/unit/core/suitable_spec.rb
+++ b/spec/unit/core/suitable_spec.rb
@@ -13,16 +13,42 @@ describe Facter::Core::Suitable do
 
   subject { SuitableClass.new }
 
-  it "can add confines" do
-    subject.confine :kernel => 'Linux'
+  describe "confining on facts" do
+    it "can add confines with a fact and a single value" do
+      subject.confine :kernel => 'Linux'
+    end
+
+    it "creates a Facter::Util::Confine object for the confine call" do
+      subject.confine :kernel => 'Linux'
+      conf = subject.confines.first
+      expect(conf).to be_a_kind_of Facter::Util::Confine
+      expect(conf.fact).to eq :kernel
+      expect(conf.values).to eq ['Linux']
+    end
   end
 
-  it "creates a Facter::Util::Confine object for the confine call" do
-    subject.confine :kernel => 'Linux'
-    conf = subject.confines.first
-    expect(conf).to be_a_kind_of Facter::Util::Confine
-    expect(conf.fact).to eq :kernel
-    expect(conf.values).to eq ['Linux']
+  describe "confining on blocks" do
+    it "can add a single fact with a block parameter" do
+      subject.confine(:one) { true }
+    end
+
+    it "creates a Util::Confine instance for the provided fact with block parameter" do
+      block = lambda { true }
+      Facter::Util::Confine.expects(:new).with("one")
+
+      subject.confine("one", &block)
+    end
+
+    it "should accept a single block parameter" do
+      subject.confine() { true }
+    end
+
+    it "should create a Util::Confine instance for the provided block parameter" do
+      block = lambda { true }
+      Facter::Util::Confine.expects(:new)
+
+      subject.confine(&block)
+    end
   end
 
   describe "determining weight" do
diff --git a/spec/unit/util/confine_spec.rb b/spec/unit/util/confine_spec.rb
index 5bdd8da..f6b11b5 100755
--- a/spec/unit/util/confine_spec.rb
+++ b/spec/unit/util/confine_spec.rb
@@ -123,5 +123,26 @@ describe Facter::Util::Confine do
     it "should return false if none of the provided ranges matches the fact's value" do
       confined(8, (5..7)).should be_false
     end
+
+    it "should accept and evaluate a block argument against the fact" do
+      @fact.expects(:value).returns 'foo'
+      confine = Facter::Util::Confine.new :yay do |f| f === 'foo' end
+      confine.true?.should be_true
+    end
+
+    it "should return false if the block raises a StandardError when checking a fact" do
+      @fact.stubs(:value).returns 'foo'
+      confine = Facter::Util::Confine.new :yay do |f| raise StandardError end
+      confine.true?.should be_false
+    end
+
+    it "should accept and evaluate only a block argument" do
+      Facter::Util::Confine.new { true }.true?.should be_true
+      Facter::Util::Confine.new { false }.true?.should be_false
+    end
+
+    it "should return false if the block raises a StandardError" do
+      Facter::Util::Confine.new { raise StandardError }.true?.should be_false
+    end
   end
 end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-puppet/facter.git



More information about the Pkg-puppet-devel mailing list