aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorMisty De Meo2012-10-02 13:21:00 -0500
committerMisty De Meo2012-10-15 09:46:29 -0500
commit71ef411c22201d41c2dc4a8aadd8cde9a334221c (patch)
treec2da268908919bcb779461e55f7cf2d068e780dd /Library
parentb9bd40d990f3193fe89b4ab4957e206de3ae6d10 (diff)
downloadhomebrew-71ef411c22201d41c2dc4a8aadd8cde9a334221c.tar.bz2
Manage Requirements using ComparableSet
ComparableSet only allows a single object of a given class, choosing the object with the greatest value. This was mainly created for Requirements, so that, e.g., two X11Dependencies of differing strictness don't both end up in the same requirement set. Fixes #15240.
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/dependencies.rb20
-rw-r--r--Library/Homebrew/extend/set.rb24
-rw-r--r--Library/Homebrew/formula.rb7
-rw-r--r--Library/Homebrew/test/test_comparableset.rb40
4 files changed, 85 insertions, 6 deletions
diff --git a/Library/Homebrew/dependencies.rb b/Library/Homebrew/dependencies.rb
index 5d5b5ab0d..7c2ff7d1b 100644
--- a/Library/Homebrew/dependencies.rb
+++ b/Library/Homebrew/dependencies.rb
@@ -21,7 +21,7 @@ class DependencyCollector
def initialize
@deps = Dependencies.new
- @requirements = Set.new
+ @requirements = ComparableSet.new
end
def add spec
@@ -196,6 +196,9 @@ end
# This requirement is used to require an X11 implementation,
# optionally with a minimum version number.
class X11Dependency < Requirement
+ include Comparable
+ attr_reader :min_version
+
def initialize min_version=nil
@min_version = min_version
end
@@ -217,9 +220,20 @@ class X11Dependency < Requirement
ENV.x11
end
- def hash
- "X11".hash
+ def <=> other
+ unless other.is_a? X11Dependency
+ raise TypeError, "expected X11Dependency"
+ end
+
+ if other.min_version.nil?
+ 1
+ elsif @min_version.nil?
+ -1
+ else
+ @min_version <=> other.min_version
+ end
end
+
end
diff --git a/Library/Homebrew/extend/set.rb b/Library/Homebrew/extend/set.rb
new file mode 100644
index 000000000..b45b85de9
--- /dev/null
+++ b/Library/Homebrew/extend/set.rb
@@ -0,0 +1,24 @@
+require 'set'
+
+class ComparableSet < Set
+ def add new
+ # smileys only
+ return super new unless new.respond_to? :>
+
+ objs = find_all { |o| o.class == new.class }
+ objs.each do |o|
+ return self if o > new
+ delete o
+ end
+ super new
+ end
+
+ alias_method :<<, :add
+
+ # Set#merge bypasses enumerating the set's contents,
+ # so the subclassed #add would never be called
+ def merge enum
+ enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
+ enum.each { |o| add(o) }
+ end
+end
diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb
index d23aeea71..8f63cd705 100644
--- a/Library/Homebrew/formula.rb
+++ b/Library/Homebrew/formula.rb
@@ -6,6 +6,7 @@ require 'bottles'
require 'patches'
require 'compilers'
require 'build_environment'
+require 'extend/set'
class Formula
@@ -455,9 +456,9 @@ class Formula
end
def recursive_requirements
- reqs = recursive_deps.map { |dep| dep.requirements }.to_set
- reqs << requirements
- reqs.flatten
+ reqs = ComparableSet.new
+ recursive_deps.each { |dep| reqs.merge dep.requirements }
+ reqs.merge requirements
end
def to_hash
diff --git a/Library/Homebrew/test/test_comparableset.rb b/Library/Homebrew/test/test_comparableset.rb
new file mode 100644
index 000000000..d39ad51d6
--- /dev/null
+++ b/Library/Homebrew/test/test_comparableset.rb
@@ -0,0 +1,40 @@
+require 'testing_env'
+require 'extend/set'
+
+class ComparableSetTests < Test::Unit::TestCase
+ def setup
+ @set = ComparableSet.new
+ end
+
+ def test_merging_multiple_dependencies
+ @set << X11Dependency.new
+ @set << X11Dependency.new
+ assert_equal @set.count, 1
+ @set << Requirement.new
+ assert_equal @set.count, 2
+ end
+
+ def test_comparison_prefers_larger
+ @set << X11Dependency.new
+ @set << X11Dependency.new('2.6')
+ assert_equal @set.count, 1
+ assert_equal @set.to_a, [X11Dependency.new('2.6')]
+ end
+
+ def test_comparison_does_not_merge_smaller
+ @set << X11Dependency.new('2.6')
+ @set << X11Dependency.new
+ assert_equal @set.count, 1
+ assert_equal @set.to_a, [X11Dependency.new('2.6')]
+ end
+
+ def test_merging_sets
+ @set << X11Dependency.new
+ @set << Requirement.new
+ reqs = Set.new [X11Dependency.new('2.6'), Requirement.new]
+ @set.merge reqs
+
+ assert_equal @set.count, 2
+ assert_equal @set.find {|r| r.is_a? X11Dependency}, X11Dependency.new('2.6')
+ end
+end