diff --git a/Library/Homebrew/dependencies.rb b/Library/Homebrew/dependencies.rb index 16d2768f25..3526888399 100644 --- a/Library/Homebrew/dependencies.rb +++ b/Library/Homebrew/dependencies.rb @@ -61,17 +61,17 @@ private case spec when :autoconf, :automake, :bsdmake, :libtool # Xcode no longer provides autotools or some other build tools - Dependency.new(spec.to_s) unless MacOS::Xcode.provides_autotools? + Dependency.new(spec.to_s, tag) unless MacOS::Xcode.provides_autotools? when :libpng, :freetype, :pixman, :fontconfig, :cairo if MacOS.version >= :mountain_lion - Dependency.new(spec.to_s) + Dependency.new(spec.to_s, tag) else X11Dependency.new(tag) end when :x11 X11Dependency.new(tag) when :xcode - XCodeDependency.new + XcodeDependency.new(tag) else raise "Unsupported special dependency #{spec}" end @@ -82,47 +82,76 @@ end # A list of formula dependencies. class Dependencies < Array - def include? dependency_name - self.any?{|d| d.name == dependency_name} + def <<(o) + super(o) unless include? o + end +end + +module Dependable + RESERVED_TAGS = [:build, :optional, :recommended] + + def build? + tags.include? :build + end + + def optional? + tags.include? :optional + end + + def recommended? + tags.include? :recommended + end + + def options + tags.reject { |tag| RESERVED_TAGS.include? tag }.map { |tag| '--'+tag.to_s } end end # A dependency on another Homebrew formula. class Dependency + include Dependable + attr_reader :name, :tags - def initialize name, tags=nil + def initialize(name, *tags) @name = name - @tags = case tags - when Array then tags.each {|s| s.to_s} - when nil then [] - else [tags.to_s] - end + @tags = [tags].flatten.compact + end + + def hash + @name.hash end def to_s @name end - def ==(other_dep) - @name == other_dep.to_s + def ==(other) + @name == other.to_s end - def <=>(other_dep) - @name <=> other_dep.to_s + def <=>(other) + @name <=> other.to_s end - def options - @tags.select{|p|p.start_with? '--'} + def eql?(other) + other.is_a? self.class and hash == other.hash end end - # A base class for non-formula requirements needed by formulae. # A "fatal" requirement is one that will fail the build if it is not present. # By default, Requirements are non-fatal. class Requirement + include Dependable + + attr_reader :tags + + def initialize(*tags) + @tags = tags.flatten.compact + end + # Should return true if this requirement is met. def satisfied?; false; end # Should return true if not meeting this requirement should fail the build. diff --git a/Library/Homebrew/requirements.rb b/Library/Homebrew/requirements.rb index b7cc68a7c8..00c1612969 100644 --- a/Library/Homebrew/requirements.rb +++ b/Library/Homebrew/requirements.rb @@ -53,8 +53,10 @@ class X11Dependency < Requirement include Comparable attr_reader :min_version - def initialize min_version=nil - @min_version = min_version + def initialize(*tags) + tags.flatten! + @min_version = tags.shift if /(\d\.)+\d/ === tags.first + super end def fatal?; true; end @@ -193,7 +195,7 @@ class ConflictRequirement < Requirement end end -class XCodeDependency < Requirement +class XcodeDependency < Requirement def fatal?; true; end def satisfied? @@ -201,7 +203,7 @@ class XCodeDependency < Requirement end def message; <<-EOS.undent - A full installation of XCode.app is required to compile this software. + A full installation of Xcode.app is required to compile this software. Installing just the Command Line Tools is not sufficent. EOS end diff --git a/Library/Homebrew/test/test_comparableset.rb b/Library/Homebrew/test/test_comparableset.rb index d39ad51d6d..39f9b6f320 100644 --- a/Library/Homebrew/test/test_comparableset.rb +++ b/Library/Homebrew/test/test_comparableset.rb @@ -1,5 +1,6 @@ require 'testing_env' require 'extend/set' +require 'dependencies' class ComparableSetTests < Test::Unit::TestCase def setup diff --git a/Library/Homebrew/test/test_dependencies.rb b/Library/Homebrew/test/test_dependencies.rb new file mode 100644 index 0000000000..4758aad0a9 --- /dev/null +++ b/Library/Homebrew/test/test_dependencies.rb @@ -0,0 +1,36 @@ +require 'testing_env' +require 'test/testball' +require 'dependencies' + +class DependencyCollector + def find_dependency(name) + deps.find { |dep| dep.name == name } + end +end + +class DependencyTests < Test::Unit::TestCase + def setup + @d = DependencyCollector.new + end + + def test_dependency_creation + @d.add 'foo' => :build + @d.add 'bar' => ['--universal', :optional] + assert_not_nil @d.find_dependency('foo') + assert_equal 2, @d.find_dependency('bar').tags.length + end + + def test_dependency_tags + assert Dependency.new('foo', :build).build? + assert Dependency.new('foo', [:build, :optional]).optional? + assert Dependency.new('foo', [:universal]).options.include? '--universal' + assert_empty Dependency.new('foo').tags + end + + def test_no_duplicate_dependencies + @d.add 'foo' + @d.add 'foo' => :build + assert_equal 1, @d.deps.length + assert_empty @d.find_dependency('foo').tags + end +end diff --git a/Library/Homebrew/test/test_external_deps.rb b/Library/Homebrew/test/test_requirements.rb similarity index 60% rename from Library/Homebrew/test/test_external_deps.rb rename to Library/Homebrew/test/test_requirements.rb index b4ca0f6e6a..c8a8e1ba87 100644 --- a/Library/Homebrew/test/test_external_deps.rb +++ b/Library/Homebrew/test/test_requirements.rb @@ -1,8 +1,66 @@ require 'testing_env' -require 'extend/string' require 'test/testball' -require 'formula_installer' +require 'dependencies' +class DependencyCollector + def find_requirement(klass) + requirements.find do |req| + klass === req + end + end +end + +class RequirementTests < Test::Unit::TestCase + def setup + @d = DependencyCollector.new + end + + def test_requirement_creation + @d.add :x11 + assert_not_nil @d.find_requirement(X11Dependency) + end + + + def test_no_duplicate_requirements + 2.times { @d.add :x11 } + assert_equal 1, @d.requirements.length + end +end + +class RequirementTagTests < Test::Unit::TestCase + def setup + @d = DependencyCollector.new + end + + def test_requirement_tags + @d.add :x11 => '2.5.1' + @d.add :xcode => :build + assert_empty @d.find_requirement(X11Dependency).tags + assert @d.find_requirement(XcodeDependency).build? + end + + def test_x11_no_tag + @d.add :x11 + assert_empty @d.find_requirement(X11Dependency).tags + end + + def test_x11_min_version + @d.add :x11 => '2.5.1' + assert_equal '2.5.1', @d.find_requirement(X11Dependency).min_version + end + + def test_x11_tag + @d.add :x11 => :optional + assert @d.find_requirement(X11Dependency).optional? + end + + def test_x11_min_version_and_tag + @d.add :x11 => ['2.5.1', :optional] + dep = @d.find_requirement(X11Dependency) + assert_equal '2.5.1', dep.min_version + assert dep.optional? + end +end class ExternalDepsTests < Test::Unit::TestCase def check_deps_fail specs