Introduce new formula specs

This commit is contained in:
Jack Nagel 2012-04-05 21:09:24 -05:00
parent ca71c038a1
commit 98a11b8e57
9 changed files with 630 additions and 165 deletions

View File

@ -3,8 +3,8 @@ require 'extend/ARGV'
def bottle_filename f, bottle_version=nil
name = f.name.downcase
version = f.version || f.standard.detect_version
bottle_version = bottle_version || f.bottle_version
version = f.stable.version
bottle_version ||= f.bottle.revision.to_i
"#{name}-#{version}#{bottle_native_suffix(bottle_version)}"
end
@ -22,7 +22,7 @@ def built_bottle? f
end
def bottle_current? f
f.bottle_url && f.bottle_sha1 && Pathname.new(f.bottle_url).version == f.version
f.bottle.url && f.bottle.has_checksum? && f.bottle.version == f.stable.version
end
def bottle_file_outdated? f, file
@ -39,7 +39,7 @@ end
def bottle_new_version f
return 0 unless bottle_current? f
f.bottle_version + 1
f.bottle.revision + 1
end
def bottle_native_suffix version=nil

View File

@ -91,6 +91,10 @@ class Formula
def std_cmake_parameters
"-DCMAKE_INSTALL_PREFIX='#{prefix}' -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev"
end
class << self
attr_rw :bottle_sha1
end
end
class UnidentifiedFormula < Formula

View File

@ -7,13 +7,12 @@ require 'extend/fileutils'
require 'patches'
require 'compilers'
# Derive and define at least @url, see Library/Formula for examples
class Formula
include FileUtils
attr_reader :name, :path, :url, :version, :homepage, :specs, :downloader
attr_reader :standard, :unstable, :head
attr_reader :bottle_version, :bottle_url, :bottle_sha1
attr_reader :name, :path, :homepage, :downloader
attr_reader :stable, :bottle, :devel, :head, :active_spec
# The build folder, usually in /tmp.
# Will only be non-nil during the stage method.
@ -21,50 +20,76 @@ class Formula
# Homebrew determines the name
def initialize name='__UNKNOWN__', path=nil
set_instance_variable 'homepage'
set_instance_variable 'url'
set_instance_variable 'bottle_version'
set_instance_variable 'bottle_url'
set_instance_variable 'bottle_sha1'
set_instance_variable 'head'
set_instance_variable 'specs'
set_instance_variable 'standard'
set_instance_variable 'unstable'
set_instance_variable :homepage
set_instance_variable :stable
set_instance_variable :bottle
set_instance_variable :devel
set_instance_variable :head
if @head and (not @url or ARGV.build_head?)
@url = @head
@version = 'HEAD'
@spec_to_use = @unstable
else
if @standard.nil?
@spec_to_use = SoftwareSpecification.new(@url, @specs)
else
@spec_to_use = @standard
end
end
raise "No url provided for formula #{name}" if @url.nil?
@name = name
validate_variable :name
# If we got an explicit path, use that, else determine from the name
@path = path.nil? ? self.class.path(name) : Pathname.new(path)
# Legacy formulae can set specs via class ivars
ensure_specs_set if @stable.nil?
# Use a provided version, if any
set_instance_variable 'version'
# Otherwise detect the version from the URL
@version ||= @spec_to_use.detect_version
# Only validate if a version was set; GitHubGistFormula needs to get
# the URL to determine the version
# If a checksum or version was set in the DSL, but no stable URL
# was defined, make @stable nil and save callers some trouble
@stable = nil if @stable and @stable.url.nil?
# Ensure the bottle URL is set. If it does not have a checksum,
# then a bottle is not available for the current platform.
if @bottle and @bottle.has_checksum?
@bottle.url ||= bottle_base_url + bottle_filename(self)
else
@bottle = nil
end
@active_spec = if @head and ARGV.build_head? then @head # --HEAD
elsif @devel and ARGV.build_devel? then @devel # --devel
elsif @bottle and install_bottle?(self) then @bottle # bottle available
elsif @stable.nil? and @head then @head # head-only
else @stable # default
end
@version = @active_spec.version
validate_variable :version if @version
CHECKSUM_TYPES.each { |type| set_instance_variable type }
raise "No url provided for formula #{name}" if @active_spec.url.nil?
@downloader = download_strategy.new @spec_to_use.url, name, version, @spec_to_use.specs
@bottle_url ||= bottle_base_url + bottle_filename(self) if @bottle_sha1
# If we got an explicit path, use that, else determine from the name
@path = path.nil? ? self.class.path(name) : Pathname.new(path)
@downloader = download_strategy.new(@active_spec.url, name, @active_spec.version, @active_spec.specs)
end
# Derive specs from class ivars
def ensure_specs_set
set_instance_variable :url
set_instance_variable :version
set_instance_variable :md5
set_instance_variable :sha1
set_instance_variable :sha256
unless @url.nil?
@stable = SoftwareSpec.new
@stable.url(@url)
@stable.version(@version)
@stable.md5(@md5)
@stable.sha1(@sha1)
@stable.sha256(@sha256)
end
if @head.kind_of? String
url = @head
@head = HeadSoftwareSpec.new
@head.url(url, self.class.instance_variable_get("@specs"))
end
end
def url; @active_spec.url; end
def version; @active_spec.version; end
def specs; @active_spec.specs; end
def mirrors; @active_spec.mirrors or []; end
# if the dir is there, but it's empty we consider it not installed
def installed?
return installed_prefix.children.length > 0
@ -84,9 +109,18 @@ class Formula
end
def installed_prefix
head_prefix = HOMEBREW_CELLAR+@name+'HEAD'
if @version == 'HEAD' || head_prefix.directory?
devel_prefix = unless @devel.nil?
HOMEBREW_CELLAR/@name/@devel.version
end
head_prefix = unless @head.nil?
HOMEBREW_CELLAR/@name/@head.version
end
if @active_spec == @head || @head and head_prefix.directory?
head_prefix
elsif @active_spec == @devel || @devel and devel_prefix.directory?
devel_prefix
else
prefix
end
@ -126,10 +160,10 @@ class Formula
def plist_name; 'homebrew.mxcl.'+name end
def plist_path; prefix+(plist_name+'.plist') end
# Use the @spec_to_use to detect the download strategy.
# Use the @active_spec to detect the download strategy.
# Can be overriden to force a custom download strategy
def download_strategy
@spec_to_use.download_strategy
@active_spec.download_strategy
end
def cached_download
@ -388,8 +422,6 @@ class Formula
HOMEBREW_REPOSITORY+"Library/Formula/#{name.downcase}.rb"
end
def mirrors; self.class.mirrors or []; end
def deps; self.class.dependencies.deps; end
def external_deps; self.class.dependencies.external_deps; end
@ -456,19 +488,17 @@ public
# For brew-fetch and others.
def fetch
if install_bottle? self
downloader = CurlBottleDownloadStrategy.new bottle_url, name, version, nil
mirror_list = []
else
downloader = @downloader
# Don't attempt mirrors if this install is not pointed at a "stable" URL.
# This can happen when options like `--HEAD` are invoked.
mirror_list = @spec_to_use == @standard ? mirrors : []
downloader = @downloader
mirror_list = case @active_spec
when @stable, @devel then @active_spec.mirrors
else []
end
# Ensure the cache exists
HOMEBREW_CACHE.mkpath
# TODO teach download strategies to take a SoftwareSpec
# object, and move mirror handling into CurlDownloadStrategy
begin
fetched = downloader.fetch
rescue CurlDownloadStrategyError => e
@ -482,34 +512,27 @@ public
return fetched, downloader
end
# Detect which type of checksum is being used, or nil if none
def checksum_type
CHECKSUM_TYPES.detect { |type| instance_variable_defined?("@#{type}") }
end
# For FormulaInstaller.
def verify_download_integrity fn, *args
require 'digest'
if args.length != 2
type = checksum_type || :md5
supplied = instance_variable_get("@#{type}")
# Convert symbol to readable string
type = type.to_s.upcase
else
supplied, type = args
end
def verify_download_integrity fn
# Checksums don't apply to HEAD
return if @active_spec == @head
type = @active_spec.checksum_type || :md5
supplied = @active_spec.send(type)
type = type.to_s.upcase
require 'digest'
hasher = Digest.const_get(type)
hash = fn.incremental_hash(hasher)
if supplied and not supplied.empty?
message = <<-EOF
#{type} mismatch
Expected: #{supplied}
Got: #{hash}
Archive: #{fn}
(To retry an incomplete download, remove the file above.)
EOF
message = <<-EOS.undent
#{type} mismatch
Expected: #{supplied}
Got: #{hash}
Archive: #{fn}
(To retry an incomplete download, remove the file above.)
EOS
raise message unless supplied.upcase == hash.upcase
else
opoo "Cannot verify package integrity"
@ -520,8 +543,6 @@ EOF
private
CHECKSUM_TYPES=[:md5, :sha1, :sha256].freeze
def stage
fetched, downloader = fetch
verify_download_integrity fetched if fetched.kind_of? Pathname
@ -571,7 +592,6 @@ private
class << self
# The methods below define the formula DSL.
attr_reader :standard, :unstable
def self.attr_rw(*attrs)
attrs.each do |attr|
@ -583,79 +603,61 @@ private
end
end
attr_rw :version, :homepage, :mirrors, :specs
attr_rw :keg_only_reason, :skip_clean_all, :cc_failures
attr_rw :bottle_version, :bottle_url, :bottle_sha1
attr_rw(*CHECKSUM_TYPES)
attr_rw :homepage, :keg_only_reason, :skip_clean_all, :cc_failures
def head val=nil, specs=nil
return @head if val.nil?
@unstable = SoftwareSpecification.new(val, specs)
@head = val
@specs = specs
SoftwareSpec::CHECKSUM_TYPES.each do |cksum|
class_eval %Q{
def #{cksum}(val=nil)
unless val.nil?
@stable ||= SoftwareSpec.new
@stable.#{cksum}(val)
end
return @stable ? @stable.#{cksum} : @#{cksum}
end
}
end
def url val=nil, specs=nil
return @url if val.nil?
@standard = SoftwareSpecification.new(val, specs)
@url = val
@specs = specs
if val.nil?
return @stable.url if @stable
return @url if @url
end
@stable ||= SoftwareSpec.new
@stable.url(val, specs)
end
def stable &block
raise "url and md5 must be specified in a block" unless block_given?
instance_eval(&block) unless ARGV.build_devel? or ARGV.build_head?
end
def devel &block
raise "url and md5 must be specified in a block" unless block_given?
if ARGV.build_devel?
@mirrors = nil # clear out mirrors from the stable release
instance_eval(&block)
end
return @stable unless block_given?
instance_eval(&block)
end
def bottle url=nil, &block
return unless block_given?
return @bottle unless block_given?
@bottle ||= Bottle.new
@bottle.instance_eval(&block)
end
bottle_block = Class.new do
def self.version version
@version = version
end
def devel &block
return @devel unless block_given?
@devel ||= SoftwareSpec.new
@devel.instance_eval(&block)
end
def self.url url
@url = url
end
def head val=nil, specs=nil
return @head if val.nil?
@head ||= HeadSoftwareSpec.new
@head.url(val, specs)
end
def self.sha1 sha1
case sha1
when Hash
key, value = sha1.shift
@sha1 = key if value == MacOS.cat
when String
@sha1 = sha1 if MacOS.lion?
end
end
def self.data
@version = 0 unless @version
return @version, @url, @sha1 if @sha1 && @url
return @version, nil, @sha1 if @sha1
end
end
bottle_block.instance_eval(&block)
@bottle_version, @bottle_url, @bottle_sha1 = bottle_block.data
def version val=nil
return @version if val.nil?
@stable ||= SoftwareSpec.new
@stable.version(val)
end
def mirror val, specs=nil
@mirrors ||= []
@mirrors << {:url => val, :specs => specs}
# Added the uniq after some inspection with Pry---seems `mirror` gets
# called three times. The first two times only one copy of the input is
# left in `@mirrors`. On the final call, two copies are present. This
# happens with `@deps` as well. Odd.
@mirrors.uniq!
@stable ||= SoftwareSpec.new
@stable.mirror(val, specs)
end
def dependencies

View File

@ -29,7 +29,7 @@ class FormulaInstaller
end
# Building head-only without --HEAD is an error
if not ARGV.build_head? and f.standard.nil?
if not ARGV.build_head? and f.stable.nil?
raise CannotInstallFormulaError, <<-EOS.undent
#{f} is a head-only formula
Install with `brew install --HEAD #{f.name}
@ -37,7 +37,7 @@ class FormulaInstaller
end
# Building stable-only with --HEAD is an error
if ARGV.build_head? and f.unstable.nil?
if ARGV.build_head? and f.head.nil?
raise CannotInstallFormulaError, "No head is defined for #{f.name}"
end
@ -261,7 +261,7 @@ class FormulaInstaller
def pour
fetched, downloader = f.fetch
f.verify_download_integrity fetched, f.bottle_sha1, "SHA1"
f.verify_download_integrity fetched
HOMEBREW_CELLAR.cd do
downloader.stage
end

View File

@ -11,7 +11,9 @@ end
class GithubGistFormula < ScriptFileFormula
def initialize name='__UNKNOWN__', path=nil
super name, path
@version=File.basename(File.dirname(url))[0,6]
@stable.version(File.basename(File.dirname(url))[0,6])
@version = @active_spec.version
validate_variable :version
end
end

View File

@ -1,9 +1,9 @@
require 'download_strategy'
class SoftwareSpec
attr_reader :checksum, :mirrors, :specs, :strategy
# Defines a URL and download method for a stable or HEAD build
class SoftwareSpecification
attr_reader :url, :specs, :using
CHECKSUM_TYPES = [:md5, :sha1, :sha256].freeze
VCS_SYMBOLS = {
:bzr => BazaarDownloadStrategy,
@ -16,34 +16,122 @@ class SoftwareSpecification
:svn => SubversionDownloadStrategy,
}
def initialize url, specs=nil
raise "No url provided" if url.nil?
@url = url
# Detect which type of checksum is being used, or nil if none
def checksum_type
@checksum_type ||= CHECKSUM_TYPES.detect do |type|
instance_variable_defined?("@#{type}")
end
end
def has_checksum?
(checksum_type and self.send(checksum_type)) || false
end
# Was the version defined in the DSL, or detected from the URL?
def explicit_version?
@explicit_version || false
end
# Returns a suitable DownloadStrategy class that can be
# used to retrieve this software package.
def download_strategy
return detect_download_strategy(@url) if @strategy.nil?
# If a class is passed, assume it is a download strategy
return @strategy if @strategy.kind_of? Class
detected = VCS_SYMBOLS[@strategy]
raise "Unknown strategy #{@strategy} was requested." unless detected
return detected
end
# The methods that follow are used in the block-form DSL spec methods
CHECKSUM_TYPES.each do |cksum|
class_eval %Q{
def #{cksum}(val=nil)
val.nil? ? @#{cksum} : @#{cksum} = val
end
}
end
def url val=nil, specs=nil
return @url if val.nil?
@url = val
if specs.nil?
@using = nil
@strategy = nil
else
# Get download strategy hint, if any
@using = specs.delete :using
# The rest of the specs are for source control
@strategy = specs.delete :using
@specs = specs
end
end
# Returns a suitable DownloadStrategy class that can be
# used to retreive this software package.
def download_strategy
return detect_download_strategy(@url) if @using.nil?
# If a class is passed, assume it is a download strategy
return @using if @using.kind_of? Class
detected = VCS_SYMBOLS[@using]
raise "Unknown strategy #{@using} was requested." unless detected
return detected
def version val=nil
unless val.nil?
@version = val
@explicit_version = true
end
@version ||= Pathname.new(@url).version
return @version
end
def detect_version
Pathname.new(@url).version
def mirror val, specs=nil
@mirrors ||= []
@mirrors << { :url => val, :specs => specs }
end
end
class HeadSoftwareSpec < SoftwareSpec
def initialize
super
@version = 'HEAD'
@checksum = nil
end
def verify_download_integrity fn
return
end
end
class Bottle < SoftwareSpec
attr_writer :url
attr_reader :revision
def initialize
@revision = 0
@strategy = CurlBottleDownloadStrategy
end
# Checksum methods in the DSL's bottle block optionally take
# a Hash, which indicates the platform the checksum applies on.
CHECKSUM_TYPES.each do |cksum|
class_eval %Q{
def #{cksum}(val=nil)
@#{cksum} ||= Hash.new
case val
when nil
@#{cksum}[MacOS.cat]
when String
@#{cksum}[:lion] = val
when Hash
key, value = val.shift
@#{cksum}[value] = key
end
end
}
end
def url val=nil
val.nil? ? @url : @url = val
end
# Used in the bottle DSL to set @revision, but acts as an
# as accessor for @version to preserve the interface
def version val=nil
if val.nil?
return @version ||= Pathname.new(@url).version
else
@revision = val
end
end
end

View File

@ -66,4 +66,238 @@ class FormulaTests < Test::Unit::TestCase
assert_equal downloader.url, "file:///#{TEST_FOLDER}/tarballs/testball-0.1.tbz"
end
end
def test_formula_specs
f = SpecTestBall.new
assert_equal 'http://example.com', f.homepage
assert_equal 'file:///foo.com/testball-0.1.tbz', f.url
assert_equal 1, f.mirrors.length
assert_equal '0.1', f.version
assert_equal f.stable, f.active_spec
assert_equal CurlDownloadStrategy, f.download_strategy
assert_instance_of CurlDownloadStrategy, f.downloader
assert_instance_of SoftwareSpec, f.stable
assert_instance_of Bottle, f.bottle
assert_instance_of SoftwareSpec, f.devel
assert_instance_of HeadSoftwareSpec, f.head
assert_equal 'file:///foo.com/testball-0.1.tbz', f.stable.url
assert_equal "https://downloads.sf.net/project/machomebrew/Bottles/spectestball-0.1.#{MacOS.cat}.bottle.tar.gz",
f.bottle.url
assert_equal 'file:///foo.com/testball-0.2.tbz', f.devel.url
assert_equal 'https://github.com/mxcl/homebrew.git', f.head.url
assert_nil f.stable.specs
assert_nil f.bottle.specs
assert_nil f.devel.specs
assert_equal({ :tag => 'foo' }, f.head.specs)
assert_equal CurlDownloadStrategy, f.stable.download_strategy
assert_equal CurlBottleDownloadStrategy, f.bottle.download_strategy
assert_equal CurlDownloadStrategy, f.devel.download_strategy
assert_equal GitDownloadStrategy, f.head.download_strategy
assert f.stable.has_checksum?
assert f.bottle.has_checksum?
assert f.devel.has_checksum?
assert !f.head.has_checksum?
assert_equal :sha1, f.stable.checksum_type
assert_equal :sha1, f.bottle.checksum_type
assert_equal :sha256, f.devel.checksum_type
assert_nil f.head.checksum_type
assert_equal case MacOS.cat
when :snowleopard then 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'
when :lion then 'baadf00dbaadf00dbaadf00dbaadf00dbaadf00d'
end, f.bottle.sha1
assert_match /[0-9a-fA-F]{40}/, f.stable.sha1
assert_match /[0-9a-fA-F]{64}/, f.devel.sha256
assert_nil f.stable.md5
assert_nil f.stable.sha256
assert_nil f.bottle.md5
assert_nil f.bottle.sha256
assert_nil f.devel.md5
assert_nil f.devel.sha1
assert_equal 1, f.stable.mirrors.length
assert_nil f.bottle.mirrors
assert_equal 1, f.devel.mirrors.length
assert_nil f.head.mirrors
assert !f.stable.explicit_version?
assert !f.bottle.explicit_version?
assert !f.devel.explicit_version?
assert_equal '0.1', f.stable.version
assert_equal '0.1', f.bottle.version
assert_equal '0.2', f.devel.version
assert_equal 'HEAD', f.head.version
assert_equal 0, f.bottle.revision
end
def test_ancient_formula_specs
f = AncientSpecTestBall.new
assert_equal 'http://example.com', f.homepage
assert_equal 'file:///foo.com/testball-0.1.tbz', f.url
assert_equal '0.1', f.version
assert_equal f.stable, f.active_spec
assert_equal CurlDownloadStrategy, f.download_strategy
assert_instance_of CurlDownloadStrategy, f.downloader
assert_instance_of SoftwareSpec, f.stable
assert_instance_of HeadSoftwareSpec, f.head
assert_equal 'file:///foo.com/testball-0.1.tbz', f.stable.url
assert_equal 'https://github.com/mxcl/homebrew.git', f.head.url
assert_nil f.stable.specs
assert_equal({ :tag => 'foo' }, f.head.specs)
assert f.stable.has_checksum?
assert !f.head.has_checksum?
assert_equal :md5, f.stable.checksum_type
assert_nil f.head.checksum_type
assert_match /[0-9a-fA-F]{32}/, f.stable.md5
assert !f.stable.explicit_version?
assert_equal '0.1', f.stable.version
assert_equal 'HEAD', f.head.version
end
def test_devel_active_spec
ARGV.push '--devel'
f = SpecTestBall.new
assert_equal f.devel, f.active_spec
assert_equal '0.2', f.version
assert_equal 'file:///foo.com/testball-0.2.tbz', f.url
assert_equal CurlDownloadStrategy, f.download_strategy
assert_instance_of CurlDownloadStrategy, f.downloader
ARGV.delete '--devel'
end
def test_head_active_spec
ARGV.push '--HEAD'
f = SpecTestBall.new
assert_equal f.head, f.active_spec
assert_equal 'HEAD', f.version
assert_equal 'https://github.com/mxcl/homebrew.git', f.url
assert_equal GitDownloadStrategy, f.download_strategy
assert_instance_of GitDownloadStrategy, f.downloader
ARGV.delete '--HEAD'
end
def test_explicit_version_spec
f = ExplicitVersionSpecTestBall.new
assert_equal '0.3', f.version
assert_equal '0.3', f.stable.version
assert_equal '0.4', f.devel.version
assert f.stable.explicit_version?
assert f.devel.explicit_version?
end
def test_old_bottle_specs
f = OldBottleSpecTestBall.new
case MacOS.cat
when :lion
assert_instance_of Bottle, f.bottle
assert_equal CurlBottleDownloadStrategy, f.bottle.download_strategy
assert_nil f.bottle.specs
assert_nil f.bottle.mirrors
assert_equal 'file:///foo.com/testball-0.1-bottle.tar.gz', f.bottle.url
assert f.bottle.has_checksum?
assert_equal :sha1, f.bottle.checksum_type
assert_equal 'baadf00dbaadf00dbaadf00dbaadf00dbaadf00d', f.bottle.sha1
assert_nil f.bottle.md5
assert_nil f.bottle.sha256
assert !f.bottle.explicit_version?
assert_equal 0, f.bottle.revision
assert_equal '0.1', f.bottle.version
else
assert_nil f.bottle
end
end
def test_ancient_bottle_specs
f = AncientBottleSpecTestBall.new
assert_nil f.bottle
end
def test_head_only_specs
f = HeadOnlySpecTestBall.new
assert_not_nil f.head
assert_nil f.stable
assert_nil f.bottle
assert_nil f.devel
assert_equal f.head, f.active_spec
assert_equal 'HEAD', f.version
assert !f.head.has_checksum?
assert_equal 'https://github.com/mxcl/homebrew.git', f.url
assert_equal GitDownloadStrategy, f.download_strategy
assert_instance_of GitDownloadStrategy, f.downloader
assert_instance_of HeadSoftwareSpec, f.head
end
def test_incomplete_stable_specs
f = IncompleteStableSpecTestBall.new
assert_not_nil f.head
assert_nil f.stable
assert_nil f.bottle
assert_nil f.devel
assert_equal f.head, f.active_spec
assert_equal 'HEAD', f.version
assert !f.head.has_checksum?
assert_equal 'https://github.com/mxcl/homebrew.git', f.url
assert_equal GitDownloadStrategy, f.download_strategy
assert_instance_of GitDownloadStrategy, f.downloader
assert_instance_of HeadSoftwareSpec, f.head
end
def test_head_only_with_version_specs
f = IncompleteStableSpecTestBall.new
assert_not_nil f.head
assert_nil f.stable
assert_nil f.bottle
assert_nil f.devel
assert_equal f.head, f.active_spec
assert_equal 'HEAD', f.version
assert !f.head.has_checksum?
assert_equal 'https://github.com/mxcl/homebrew.git', f.url
assert_equal GitDownloadStrategy, f.download_strategy
assert_instance_of GitDownloadStrategy, f.downloader
assert_instance_of HeadSoftwareSpec, f.head
end
def test_explicit_strategy_specs
f = ExplicitStrategySpecTestBall.new
assert_not_nil f.stable
assert_not_nil f.devel
assert_not_nil f.head
assert_equal f.stable, f.active_spec
assert !f.stable.has_checksum?
assert !f.devel.has_checksum?
assert !f.head.has_checksum?
assert_equal MercurialDownloadStrategy, f.stable.download_strategy
assert_equal BazaarDownloadStrategy, f.devel.download_strategy
assert_equal SubversionDownloadStrategy, f.head.download_strategy
assert_equal({ :tag => '0.2' }, f.stable.specs)
assert_equal({ :tag => '0.3' }, f.devel.specs)
assert f.head.specs.empty?
end
end

View File

@ -94,3 +94,133 @@ class TestBlockWithoutBuildCompilerFailure < TestCompilerFailures
cause "failure"
end
end
class SpecTestBall < Formula
homepage 'http://example.com'
url 'file:///foo.com/testball-0.1.tbz'
mirror 'file:///foo.org/testball-0.1.tbz'
sha1 '482e737739d946b7c8cbaf127d9ee9c148b999f5'
head 'https://github.com/mxcl/homebrew.git', :tag => 'foo'
devel do
url 'file:///foo.com/testball-0.2.tbz'
mirror 'file:///foo.org/testball-0.2.tbz'
sha256 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef'
end
bottle do
sha1 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef' => :snowleopard
sha1 'baadf00dbaadf00dbaadf00dbaadf00dbaadf00d' => :lion
end
def initialize name=nil
super "spectestball"
end
end
class AncientSpecTestBall < Formula
@homepage='http://example.com'
@url='file:///foo.com/testball-0.1.tbz'
@md5='060844753f2a3b36ecfc3192d307dab2'
@head='https://github.com/mxcl/homebrew.git'
@specs={ :tag => 'foo' }
def initialize name=nil
super "ancientspectestball"
end
end
class ExplicitVersionSpecTestBall < Formula
homepage 'http://example.com'
url 'file:///foo.com/testball-stable.tbz'
sha1 '482e737739d946b7c8cbaf127d9ee9c148b999f5'
version '0.3'
devel do
url 'file:///foo.com/testball-devel.tbz'
sha1 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'
version '0.4'
end
bottle do
version '1'
url 'file:///foo.com/test-0.3.lion.bottle.tar.gz'
sha1 'baadf00dbaadf00dbaadf00dbaadf00dbaadf00d'
end
def initialize name=nil
super "explicitversionspectestball"
end
end
class OldBottleSpecTestBall < Formula
homepage 'http://example.com'
url 'file:///foo.com/testball-0.1.tbz'
sha1 '482e737739d946b7c8cbaf127d9ee9c148b999f5'
bottle do
url 'file:///foo.com/testball-0.1-bottle.tar.gz'
sha1 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'
end
def initialize name=nil
super "oldbottlespectestball"
end
end
class AncientBottleSpecTestBall < Formula
homepage 'http://example.com'
url 'file:///foo.com/testball-0.1.tbz'
sha1 '482e737739d946b7c8cbaf127d9ee9c148b999f5'
bottle 'file:///foo.com/testball-0.1-bottle.tar.gz'
bottle_sha1 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'
def initialize name=nil
super "ancientbottlespectestball"
end
end
class HeadOnlySpecTestBall < Formula
homepage 'http://example.com'
head 'https://github.com/mxcl/homebrew.git'
def initialize name=nil
super "headyonlyspectestball"
end
end
class IncompleteStableSpecTestBall < Formula
homepage 'http://example.com'
head 'https://github.com/mxcl/homebrew.git'
sha1 '482e737739d946b7c8cbaf127d9ee9c148b999f5'
def initialize name=nil
super "incompletestablespectestball"
end
end
class HeadOnlyWithVersionSpecTestBall < Formula
homepage 'http://example.com'
head 'https://github.com/mxcl/homebrew.git'
version '0.3'
def initialize name=nil
super "headonlywithversionspectestball"
end
end
class ExplicitStrategySpecTestBall < Formula
homepage 'http://example.com'
url 'file:///foo.com/testball-stable', :using => :hg, :tag => '0.2'
head 'file:///foo.com/testball-head', :using => :svn
devel do
url 'file:///foo.com/testball-devel', :using => :bzr, :tag => '0.3'
end
def initialize name=nil
super "explicitstrategyspectestball"
end
end

View File

@ -52,4 +52,9 @@ def shutup
end
end
unless ARGV.include? "--no-compat" or ENV['HOMEBREW_NO_COMPAT']
$:.unshift(File.expand_path("#{ABS__FILE__}/../../compat"))
require 'compatibility'
end
require 'test/unit' # must be after at_exit