[SCM] ci-tooling packaging branch, master, updated. 2177d2a534db3455d80cf1f63851e81ad7203228

Harald Sitter apachelogger-guest at moszumanska.debian.org
Mon Apr 27 12:22:05 UTC 2015


Gitweb-URL: http://git.debian.org/?p=pkg-kde/ci-tooling.git;a=commitdiff;h=38a565e

The following commit has been merged in the master branch:
commit 38a565ed6abf870852d5b9e04a7590c9cf92049f
Author: Harald Sitter <sitter at kde.org>
Date:   Mon Apr 27 13:40:00 2015 +0200

    add a somewhat generic pattern class and helpers
    
    patterns are File.fnmatch posix regex patterns. primary use of having
    classes to handle them is to be able to sort and filter conveniently.
    not too sure about the design right now, seems a bit cumbersome because of
    overengineering. possibly considering a pattern always a string and
    simply having a helper module for enumerables introduce logics would
    be less overhead in the long run
---
 lib/ci/pattern.rb       | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
 test/test_ci_pattern.rb |  62 +++++++++++++++++++++++++
 2 files changed, 181 insertions(+)

diff --git a/lib/ci/pattern.rb b/lib/ci/pattern.rb
new file mode 100644
index 0000000..10f3ac0
--- /dev/null
+++ b/lib/ci/pattern.rb
@@ -0,0 +1,119 @@
+require 'yaml'
+
+module CI
+  # Implements pattern filtering for enumerables.
+  module PatternFilter
+    # Filters all patterns that do not match reference.
+    # @return new enumerable with patterns removed that do not match
+    def filter(reference)
+      reject(&filter_proc(reference))
+    end
+
+    # @see filter
+    # This method removes items in-place.
+    def filter!(reference)
+      reject!(&filter_proc(reference))
+    end
+
+    private
+
+    def filter_proc(reference)
+      proc { |k, *_| !k.match?(reference) }
+    end
+  end
+
+  # A PatternHash.
+  # PatternHash is a specific Hash meant to be used for Pattern objects.
+  # PatternHash includes PatternFilter to filter patterns that do not match
+  # a reference value.
+  class PatternHash < Hash
+    include PatternFilter
+
+    # Constructs a new PatternHash. Can do so by converting a normal Hash.
+    # @param hash a Hash to covert into a PatternHash
+    # @param recurse whether or not to recursively convert hash
+    def initialize(hash = {}, recurse: true)
+      hash.each_with_object(self) do |(key, value), memo|
+        if recurse && value.is_a?(Hash)
+          value = PatternHash.new(value, recurse: recurse)
+        end
+        memo[CI::Pattern.new(key)] = value
+        memo
+      end
+    end
+  end
+
+  # A PatternArray.
+  # PatternArray is a specific Array meant to be used for Pattern objects.
+  # PatternArray includes PatternFilter to filter patterns that do not match
+  # a reference value.
+  class PatternArray < Array
+    include PatternFilter
+
+    def self.matches(array, reference)
+      a = PatternArray.new
+      array.each do |v|
+        pattern = Pattern.new(v) unless v.is_a?(Pattern)
+        a << pattern
+      end
+      a.filter(reference).sort
+    end
+  end
+
+  # A POSIX regex match pattern.
+  # Pattern matching is implemented by File.fnmatch and reperesents a POSIX
+  # regex match. Namely a simplified regex as often used for file or path
+  # patterns.
+  class Pattern
+    attr_reader :pattern
+
+    def initialize(pattern)
+      @pattern = pattern
+    end
+
+    # @param reference [String] reference the pattern might match
+    # @return true if the pattern matches the refernece
+    def match?(reference)
+      reference = reference.pattern if reference.respond_to?(:pattern)
+      File.fnmatch(@pattern, reference)
+    end
+
+    # Compare self to other.
+    # Patterns are
+    #   - equal when self matches other and other matches self
+    #   - lower than when other matches self (i.e. self is more concrete)
+    #   - greater than when self matches other (i.e. self is less concrete)
+    #   - uncomparable when other is not a Pattern or none of the above applies,
+    #     in which case they are both Patterns but incompatible ones.
+    #     For example vivid_* and utopic_* do not match one another and thus
+    #     can not be sorted according the outline here.
+    # Sorting pattern thusly means that the lowest pattern is the most concrete
+    # pattern.
+    def <=>(other)
+      return nil unless other.is_a?(Pattern)
+      if match?(other)
+        return 0 if other.match?(self)
+        return 1
+      end
+      # We don't match other. If other matches us other is greater.
+      return -1 if other.match?(self)
+      # If we don't match other and other doesn't match us then the patterns are
+      # not comparable
+      nil
+    end
+
+    # Convenience equality.
+    # Patterns are considered equal when compared with another Pattern object
+    # with wich the pattern attribute matches. When compared with a String that
+    # matches the pattern attribute. Otherwise defers to super.
+    def ==(other)
+      return true if other.respond_to?(:pattern) && other.pattern == @pattern
+      return true if other.is_a?(String) && other == @pattern
+      super(other)
+    end
+
+    def to_s
+      "#{@pattern}"
+    end
+  end
+end
diff --git a/test/test_ci_pattern.rb b/test/test_ci_pattern.rb
new file mode 100644
index 0000000..d8a22c3
--- /dev/null
+++ b/test/test_ci_pattern.rb
@@ -0,0 +1,62 @@
+require_relative '../lib/ci/pattern'
+require_relative 'lib/testcase'
+
+# Test ci/pattern
+class CIPatternHashTest < TestCase
+  def test_all
+    hash = {
+      'a*' => {'x*' => false}
+    }
+    p = CI::PatternHash.new(hash, recurse: true)
+    assert_equal(1, p.size)
+    assert(p.flatten.first.is_a?(CI::Pattern))
+    assert(p.flatten.last.flatten.first.is_a?(CI::Pattern))
+  end
+end
+
+# Test ci/pattern
+class CIPatternArrayTest < TestCase
+  def test_all
+    patterns = CI::PatternArray.new
+    utopic_stable_pattern = CI::Pattern.new('utopic_stable_*')
+    vivid_stable_pattern = CI::Pattern.new('vivid_stable_*') # used later
+    vivid_pattern = CI::Pattern.new('vivid_*')
+    patterns << utopic_stable_pattern << vivid_pattern
+    assert_equal(2, patterns.size)
+
+    assert_equal(patterns.filter('utopic_stable_foo'), [utopic_stable_pattern])
+    patterns.filter!('vivid_stable_foo')
+    assert_equal(patterns, [vivid_pattern])
+    patterns << vivid_stable_pattern
+    assert_equal(patterns.sort, [vivid_stable_pattern, vivid_pattern])
+  end
+end
+
+# Test ci/pattern
+class CIPatternTest < TestCase
+  def test_match
+    assert(CI::Pattern.new('a*').match?('ab'))
+    assert(!CI::Pattern.new('a*').match?('ba'))
+  end
+
+  def test_spaceship_op
+    a = CI::Pattern.new('a*')
+    assert_equal(nil, a.<=>('a'))
+    assert_equal(-1, a.<=>(CI::Pattern.new('*')))
+    assert_equal(0, a.<=>(a))
+    assert_equal(1, a.<=>(CI::Pattern.new('ab')))
+  end
+
+  def test_equal_op
+    a = CI::Pattern.new('a*')
+    assert(a == 'a*')
+    assert(a != 'b')
+    assert(a == CI::Pattern.new('a*'))
+  end
+
+  def test_to_s
+    assert_equal(CI::Pattern.new('a*').to_s, 'a*')
+    assert_equal(CI::Pattern.new('a').to_s, 'a')
+    assert_equal(CI::Pattern.new(nil).to_s, '')
+  end
+end

-- 
ci-tooling packaging



More information about the pkg-kde-commits mailing list