Infer dependencies from download strategies and URLs

Closes Homebrew/homebrew#20849.
Closes Homebrew/homebrew#22871.
This commit is contained in:
Jack Nagel 2013-09-28 16:37:05 -05:00
parent a2c949bfb7
commit c5289f2503
5 changed files with 70 additions and 12 deletions

View File

@ -57,6 +57,8 @@ class DependencyCollector
case spec
when String
parse_string_spec(spec, tags)
when Resource
resource_dep(spec, tags)
when Symbol
parse_symbol_spec(spec, tags)
when Requirement, Dependency
@ -138,4 +140,35 @@ class DependencyCollector
Dependency.new(spec.to_s, tags)
end
end
def resource_dep(spec, tags)
tags << :build
strategy = spec.download_strategy
case
when strategy <= CurlDownloadStrategy
parse_url_spec(spec.url, tags)
when strategy <= GitDownloadStrategy
GitDependency.new(tags)
when strategy <= MercurialDownloadStrategy
MercurialDependency.new(tags)
when strategy <= FossilDownloadStrategy
Dependency.new("fossil", tags)
when strategy <= BazaarDownloadStrategy
Dependency.new("bazaar", tags)
when strategy < AbstractDownloadStrategy
# allow unknown strategies to pass through
else
raise TypeError,
"#{strategy.inspect} is not an AbstractDownloadStrategy subclass"
end
end
def parse_url_spec(url, tags)
case File.extname(url)
when '.xz' then Dependency.new('xz', tags)
when '.rar' then Dependency.new('unrar', tags)
when '.7z' then Dependency.new('p7zip', tags)
end
end
end

View File

@ -126,17 +126,14 @@ class CurlDownloadStrategy < AbstractDownloadStrategy
with_system_path { safe_system 'tar', 'xf', tarball_path }
chdir
when :xz
raise "You must install XZutils: brew install xz" unless File.executable? xzpath
with_system_path { safe_system "#{xzpath} -dc \"#{tarball_path}\" | tar xf -" }
chdir
when :pkg
safe_system '/usr/sbin/pkgutil', '--expand', tarball_path, basename_without_params
chdir
when :rar
raise "You must install unrar: brew install unrar" unless which "unrar"
quiet_safe_system 'unrar', 'x', {:quiet_flag => '-inul'}, tarball_path
when :p7zip
raise "You must install 7zip: brew install p7zip" unless which "7zr"
safe_system '7zr', 'x', tarball_path
else
FileUtils.cp tarball_path, basename_without_params
@ -416,8 +413,6 @@ class GitDownloadStrategy < AbstractDownloadStrategy
end
def fetch
raise "You must: brew install git" unless which "git"
ohai "Cloning #@url"
if @clone.exist? && repo_valid?
@ -634,8 +629,6 @@ class MercurialDownloadStrategy < AbstractDownloadStrategy
end
def fetch
raise "You must: brew install mercurial" unless hgpath
ohai "Cloning #{@url}"
unless @clone.exist?
@ -684,8 +677,6 @@ class BazaarDownloadStrategy < AbstractDownloadStrategy
end
def fetch
raise "You must: brew install bazaar" unless bzrpath
ohai "Cloning #{@url}"
unless @clone.exist?
url=@url.sub(%r[^bzr://], '')
@ -737,8 +728,6 @@ class FossilDownloadStrategy < AbstractDownloadStrategy
end
def fetch
raise "You must: brew install fossil" unless fossilpath
ohai "Cloning #{@url}"
unless @clone.exist?
url=@url.sub(%r[^fossil://], '')

View File

@ -93,3 +93,9 @@ class MercurialDependency < Requirement
satisfy { which('hg') }
end
class GitDependency < Requirement
fatal true
default_formula 'git'
satisfy { which('git') }
end

View File

@ -15,7 +15,7 @@ class SoftwareSpec
def_delegators :@resource, :stage, :fetch
def_delegators :@resource, :download_strategy, :verify_download_integrity
def_delegators :@resource, :checksum, :mirrors, :specs, :using, :downloader
def_delegators :@resource, :url, :version, :mirror, *Checksum::TYPES
def_delegators :@resource, :version, :mirror, *Checksum::TYPES
def initialize
@resource = Resource.new
@ -30,6 +30,12 @@ class SoftwareSpec
resources.each_value { |r| r.owner = self }
end
def url val=nil, specs={}
return @resource.url if val.nil?
@resource.url(val, specs)
dependency_collector.add(@resource)
end
def resource? name
resources.has_key?(name)
end

View File

@ -135,4 +135,28 @@ class DependencyCollectorTests < Test::Unit::TestCase
@d.add(spec)
assert_equal copy, spec
end
def test_resource_dep_git_url
resource = Resource.new
resource.url("git://github.com/foo/bar.git")
assert_instance_of GitDependency, @d.add(resource)
end
def test_resource_dep_gzip_url
resource = Resource.new
resource.url("http://foo.com/bar.tar.gz")
assert_nil @d.add(resource)
end
def test_resource_dep_xz_url
resource = Resource.new
resource.url("http://foo.com/bar.tar.xz")
assert_equal Dependency.new("xz", [:build]), @d.add(resource)
end
def test_resource_dep_raises_for_unknown_classes
resource = Resource.new
resource.url "foo", :using => Class.new
assert_raises(TypeError) { @d.add(resource) }
end
end