Introduce new formula specs
This commit is contained in:
parent
ca71c038a1
commit
98a11b8e57
@ -3,8 +3,8 @@ require 'extend/ARGV'
|
|||||||
|
|
||||||
def bottle_filename f, bottle_version=nil
|
def bottle_filename f, bottle_version=nil
|
||||||
name = f.name.downcase
|
name = f.name.downcase
|
||||||
version = f.version || f.standard.detect_version
|
version = f.stable.version
|
||||||
bottle_version = bottle_version || f.bottle_version
|
bottle_version ||= f.bottle.revision.to_i
|
||||||
"#{name}-#{version}#{bottle_native_suffix(bottle_version)}"
|
"#{name}-#{version}#{bottle_native_suffix(bottle_version)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ def built_bottle? f
|
|||||||
end
|
end
|
||||||
|
|
||||||
def bottle_current? f
|
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
|
end
|
||||||
|
|
||||||
def bottle_file_outdated? f, file
|
def bottle_file_outdated? f, file
|
||||||
@ -39,7 +39,7 @@ end
|
|||||||
|
|
||||||
def bottle_new_version f
|
def bottle_new_version f
|
||||||
return 0 unless bottle_current? f
|
return 0 unless bottle_current? f
|
||||||
f.bottle_version + 1
|
f.bottle.revision + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def bottle_native_suffix version=nil
|
def bottle_native_suffix version=nil
|
||||||
|
|||||||
@ -91,6 +91,10 @@ class Formula
|
|||||||
def std_cmake_parameters
|
def std_cmake_parameters
|
||||||
"-DCMAKE_INSTALL_PREFIX='#{prefix}' -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev"
|
"-DCMAKE_INSTALL_PREFIX='#{prefix}' -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
attr_rw :bottle_sha1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class UnidentifiedFormula < Formula
|
class UnidentifiedFormula < Formula
|
||||||
|
|||||||
@ -7,13 +7,12 @@ require 'extend/fileutils'
|
|||||||
require 'patches'
|
require 'patches'
|
||||||
require 'compilers'
|
require 'compilers'
|
||||||
|
|
||||||
# Derive and define at least @url, see Library/Formula for examples
|
|
||||||
class Formula
|
class Formula
|
||||||
include FileUtils
|
include FileUtils
|
||||||
|
|
||||||
attr_reader :name, :path, :url, :version, :homepage, :specs, :downloader
|
attr_reader :name, :path, :homepage, :downloader
|
||||||
attr_reader :standard, :unstable, :head
|
attr_reader :stable, :bottle, :devel, :head, :active_spec
|
||||||
attr_reader :bottle_version, :bottle_url, :bottle_sha1
|
|
||||||
|
|
||||||
# The build folder, usually in /tmp.
|
# The build folder, usually in /tmp.
|
||||||
# Will only be non-nil during the stage method.
|
# Will only be non-nil during the stage method.
|
||||||
@ -21,50 +20,76 @@ class Formula
|
|||||||
|
|
||||||
# Homebrew determines the name
|
# Homebrew determines the name
|
||||||
def initialize name='__UNKNOWN__', path=nil
|
def initialize name='__UNKNOWN__', path=nil
|
||||||
set_instance_variable 'homepage'
|
set_instance_variable :homepage
|
||||||
set_instance_variable 'url'
|
set_instance_variable :stable
|
||||||
set_instance_variable 'bottle_version'
|
set_instance_variable :bottle
|
||||||
set_instance_variable 'bottle_url'
|
set_instance_variable :devel
|
||||||
set_instance_variable 'bottle_sha1'
|
set_instance_variable :head
|
||||||
set_instance_variable 'head'
|
|
||||||
set_instance_variable 'specs'
|
|
||||||
set_instance_variable 'standard'
|
|
||||||
set_instance_variable 'unstable'
|
|
||||||
|
|
||||||
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
|
@name = name
|
||||||
validate_variable :name
|
validate_variable :name
|
||||||
|
|
||||||
# If we got an explicit path, use that, else determine from the name
|
# Legacy formulae can set specs via class ivars
|
||||||
@path = path.nil? ? self.class.path(name) : Pathname.new(path)
|
ensure_specs_set if @stable.nil?
|
||||||
|
|
||||||
# Use a provided version, if any
|
# If a checksum or version was set in the DSL, but no stable URL
|
||||||
set_instance_variable 'version'
|
# was defined, make @stable nil and save callers some trouble
|
||||||
# Otherwise detect the version from the URL
|
@stable = nil if @stable and @stable.url.nil?
|
||||||
@version ||= @spec_to_use.detect_version
|
|
||||||
# Only validate if a version was set; GitHubGistFormula needs to get
|
# Ensure the bottle URL is set. If it does not have a checksum,
|
||||||
# the URL to determine the version
|
# 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
|
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
|
# If we got an explicit path, use that, else determine from the name
|
||||||
|
@path = path.nil? ? self.class.path(name) : Pathname.new(path)
|
||||||
@bottle_url ||= bottle_base_url + bottle_filename(self) if @bottle_sha1
|
@downloader = download_strategy.new(@active_spec.url, name, @active_spec.version, @active_spec.specs)
|
||||||
end
|
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
|
# if the dir is there, but it's empty we consider it not installed
|
||||||
def installed?
|
def installed?
|
||||||
return installed_prefix.children.length > 0
|
return installed_prefix.children.length > 0
|
||||||
@ -84,9 +109,18 @@ class Formula
|
|||||||
end
|
end
|
||||||
|
|
||||||
def installed_prefix
|
def installed_prefix
|
||||||
head_prefix = HOMEBREW_CELLAR+@name+'HEAD'
|
devel_prefix = unless @devel.nil?
|
||||||
if @version == 'HEAD' || head_prefix.directory?
|
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
|
head_prefix
|
||||||
|
elsif @active_spec == @devel || @devel and devel_prefix.directory?
|
||||||
|
devel_prefix
|
||||||
else
|
else
|
||||||
prefix
|
prefix
|
||||||
end
|
end
|
||||||
@ -126,10 +160,10 @@ class Formula
|
|||||||
def plist_name; 'homebrew.mxcl.'+name end
|
def plist_name; 'homebrew.mxcl.'+name end
|
||||||
def plist_path; prefix+(plist_name+'.plist') 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
|
# Can be overriden to force a custom download strategy
|
||||||
def download_strategy
|
def download_strategy
|
||||||
@spec_to_use.download_strategy
|
@active_spec.download_strategy
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached_download
|
def cached_download
|
||||||
@ -388,8 +422,6 @@ class Formula
|
|||||||
HOMEBREW_REPOSITORY+"Library/Formula/#{name.downcase}.rb"
|
HOMEBREW_REPOSITORY+"Library/Formula/#{name.downcase}.rb"
|
||||||
end
|
end
|
||||||
|
|
||||||
def mirrors; self.class.mirrors or []; end
|
|
||||||
|
|
||||||
def deps; self.class.dependencies.deps; end
|
def deps; self.class.dependencies.deps; end
|
||||||
def external_deps; self.class.dependencies.external_deps; end
|
def external_deps; self.class.dependencies.external_deps; end
|
||||||
|
|
||||||
@ -456,19 +488,17 @@ public
|
|||||||
|
|
||||||
# For brew-fetch and others.
|
# For brew-fetch and others.
|
||||||
def fetch
|
def fetch
|
||||||
if install_bottle? self
|
downloader = @downloader
|
||||||
downloader = CurlBottleDownloadStrategy.new bottle_url, name, version, nil
|
mirror_list = case @active_spec
|
||||||
mirror_list = []
|
when @stable, @devel then @active_spec.mirrors
|
||||||
else
|
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 : []
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Ensure the cache exists
|
# Ensure the cache exists
|
||||||
HOMEBREW_CACHE.mkpath
|
HOMEBREW_CACHE.mkpath
|
||||||
|
|
||||||
|
# TODO teach download strategies to take a SoftwareSpec
|
||||||
|
# object, and move mirror handling into CurlDownloadStrategy
|
||||||
begin
|
begin
|
||||||
fetched = downloader.fetch
|
fetched = downloader.fetch
|
||||||
rescue CurlDownloadStrategyError => e
|
rescue CurlDownloadStrategyError => e
|
||||||
@ -482,34 +512,27 @@ public
|
|||||||
return fetched, downloader
|
return fetched, downloader
|
||||||
end
|
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.
|
# For FormulaInstaller.
|
||||||
def verify_download_integrity fn, *args
|
def verify_download_integrity fn
|
||||||
require 'digest'
|
# Checksums don't apply to HEAD
|
||||||
if args.length != 2
|
return if @active_spec == @head
|
||||||
type = checksum_type || :md5
|
|
||||||
supplied = instance_variable_get("@#{type}")
|
|
||||||
# Convert symbol to readable string
|
|
||||||
type = type.to_s.upcase
|
|
||||||
else
|
|
||||||
supplied, type = args
|
|
||||||
end
|
|
||||||
|
|
||||||
|
type = @active_spec.checksum_type || :md5
|
||||||
|
supplied = @active_spec.send(type)
|
||||||
|
type = type.to_s.upcase
|
||||||
|
|
||||||
|
require 'digest'
|
||||||
hasher = Digest.const_get(type)
|
hasher = Digest.const_get(type)
|
||||||
hash = fn.incremental_hash(hasher)
|
hash = fn.incremental_hash(hasher)
|
||||||
|
|
||||||
if supplied and not supplied.empty?
|
if supplied and not supplied.empty?
|
||||||
message = <<-EOF
|
message = <<-EOS.undent
|
||||||
#{type} mismatch
|
#{type} mismatch
|
||||||
Expected: #{supplied}
|
Expected: #{supplied}
|
||||||
Got: #{hash}
|
Got: #{hash}
|
||||||
Archive: #{fn}
|
Archive: #{fn}
|
||||||
(To retry an incomplete download, remove the file above.)
|
(To retry an incomplete download, remove the file above.)
|
||||||
EOF
|
EOS
|
||||||
raise message unless supplied.upcase == hash.upcase
|
raise message unless supplied.upcase == hash.upcase
|
||||||
else
|
else
|
||||||
opoo "Cannot verify package integrity"
|
opoo "Cannot verify package integrity"
|
||||||
@ -520,8 +543,6 @@ EOF
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
CHECKSUM_TYPES=[:md5, :sha1, :sha256].freeze
|
|
||||||
|
|
||||||
def stage
|
def stage
|
||||||
fetched, downloader = fetch
|
fetched, downloader = fetch
|
||||||
verify_download_integrity fetched if fetched.kind_of? Pathname
|
verify_download_integrity fetched if fetched.kind_of? Pathname
|
||||||
@ -571,7 +592,6 @@ private
|
|||||||
|
|
||||||
class << self
|
class << self
|
||||||
# The methods below define the formula DSL.
|
# The methods below define the formula DSL.
|
||||||
attr_reader :standard, :unstable
|
|
||||||
|
|
||||||
def self.attr_rw(*attrs)
|
def self.attr_rw(*attrs)
|
||||||
attrs.each do |attr|
|
attrs.each do |attr|
|
||||||
@ -583,79 +603,61 @@ private
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_rw :version, :homepage, :mirrors, :specs
|
attr_rw :homepage, :keg_only_reason, :skip_clean_all, :cc_failures
|
||||||
attr_rw :keg_only_reason, :skip_clean_all, :cc_failures
|
|
||||||
attr_rw :bottle_version, :bottle_url, :bottle_sha1
|
|
||||||
attr_rw(*CHECKSUM_TYPES)
|
|
||||||
|
|
||||||
def head val=nil, specs=nil
|
SoftwareSpec::CHECKSUM_TYPES.each do |cksum|
|
||||||
return @head if val.nil?
|
class_eval %Q{
|
||||||
@unstable = SoftwareSpecification.new(val, specs)
|
def #{cksum}(val=nil)
|
||||||
@head = val
|
unless val.nil?
|
||||||
@specs = specs
|
@stable ||= SoftwareSpec.new
|
||||||
|
@stable.#{cksum}(val)
|
||||||
|
end
|
||||||
|
return @stable ? @stable.#{cksum} : @#{cksum}
|
||||||
|
end
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def url val=nil, specs=nil
|
def url val=nil, specs=nil
|
||||||
return @url if val.nil?
|
if val.nil?
|
||||||
@standard = SoftwareSpecification.new(val, specs)
|
return @stable.url if @stable
|
||||||
@url = val
|
return @url if @url
|
||||||
@specs = specs
|
end
|
||||||
|
@stable ||= SoftwareSpec.new
|
||||||
|
@stable.url(val, specs)
|
||||||
end
|
end
|
||||||
|
|
||||||
def stable &block
|
def stable &block
|
||||||
raise "url and md5 must be specified in a block" unless block_given?
|
return @stable unless block_given?
|
||||||
instance_eval(&block) unless ARGV.build_devel? or ARGV.build_head?
|
instance_eval(&block)
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def bottle url=nil, &block
|
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 devel &block
|
||||||
def self.version version
|
return @devel unless block_given?
|
||||||
@version = version
|
@devel ||= SoftwareSpec.new
|
||||||
end
|
@devel.instance_eval(&block)
|
||||||
|
end
|
||||||
|
|
||||||
def self.url url
|
def head val=nil, specs=nil
|
||||||
@url = url
|
return @head if val.nil?
|
||||||
end
|
@head ||= HeadSoftwareSpec.new
|
||||||
|
@head.url(val, specs)
|
||||||
|
end
|
||||||
|
|
||||||
def self.sha1 sha1
|
def version val=nil
|
||||||
case sha1
|
return @version if val.nil?
|
||||||
when Hash
|
@stable ||= SoftwareSpec.new
|
||||||
key, value = sha1.shift
|
@stable.version(val)
|
||||||
@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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def mirror val, specs=nil
|
def mirror val, specs=nil
|
||||||
@mirrors ||= []
|
@stable ||= SoftwareSpec.new
|
||||||
@mirrors << {:url => val, :specs => specs}
|
@stable.mirror(val, 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!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def dependencies
|
def dependencies
|
||||||
|
|||||||
@ -29,7 +29,7 @@ class FormulaInstaller
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Building head-only without --HEAD is an error
|
# 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
|
raise CannotInstallFormulaError, <<-EOS.undent
|
||||||
#{f} is a head-only formula
|
#{f} is a head-only formula
|
||||||
Install with `brew install --HEAD #{f.name}
|
Install with `brew install --HEAD #{f.name}
|
||||||
@ -37,7 +37,7 @@ class FormulaInstaller
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Building stable-only with --HEAD is an error
|
# 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}"
|
raise CannotInstallFormulaError, "No head is defined for #{f.name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ class FormulaInstaller
|
|||||||
|
|
||||||
def pour
|
def pour
|
||||||
fetched, downloader = f.fetch
|
fetched, downloader = f.fetch
|
||||||
f.verify_download_integrity fetched, f.bottle_sha1, "SHA1"
|
f.verify_download_integrity fetched
|
||||||
HOMEBREW_CELLAR.cd do
|
HOMEBREW_CELLAR.cd do
|
||||||
downloader.stage
|
downloader.stage
|
||||||
end
|
end
|
||||||
|
|||||||
@ -11,7 +11,9 @@ end
|
|||||||
class GithubGistFormula < ScriptFileFormula
|
class GithubGistFormula < ScriptFileFormula
|
||||||
def initialize name='__UNKNOWN__', path=nil
|
def initialize name='__UNKNOWN__', path=nil
|
||||||
super name, path
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
require 'download_strategy'
|
require 'download_strategy'
|
||||||
|
|
||||||
|
class SoftwareSpec
|
||||||
|
attr_reader :checksum, :mirrors, :specs, :strategy
|
||||||
|
|
||||||
# Defines a URL and download method for a stable or HEAD build
|
CHECKSUM_TYPES = [:md5, :sha1, :sha256].freeze
|
||||||
class SoftwareSpecification
|
|
||||||
attr_reader :url, :specs, :using
|
|
||||||
|
|
||||||
VCS_SYMBOLS = {
|
VCS_SYMBOLS = {
|
||||||
:bzr => BazaarDownloadStrategy,
|
:bzr => BazaarDownloadStrategy,
|
||||||
@ -16,34 +16,122 @@ class SoftwareSpecification
|
|||||||
:svn => SubversionDownloadStrategy,
|
:svn => SubversionDownloadStrategy,
|
||||||
}
|
}
|
||||||
|
|
||||||
def initialize url, specs=nil
|
# Detect which type of checksum is being used, or nil if none
|
||||||
raise "No url provided" if url.nil?
|
def checksum_type
|
||||||
@url = url
|
@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?
|
if specs.nil?
|
||||||
@using = nil
|
@strategy = nil
|
||||||
else
|
else
|
||||||
# Get download strategy hint, if any
|
@strategy = specs.delete :using
|
||||||
@using = specs.delete :using
|
|
||||||
# The rest of the specs are for source control
|
|
||||||
@specs = specs
|
@specs = specs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a suitable DownloadStrategy class that can be
|
def version val=nil
|
||||||
# used to retreive this software package.
|
unless val.nil?
|
||||||
def download_strategy
|
@version = val
|
||||||
return detect_download_strategy(@url) if @using.nil?
|
@explicit_version = true
|
||||||
|
end
|
||||||
# If a class is passed, assume it is a download strategy
|
@version ||= Pathname.new(@url).version
|
||||||
return @using if @using.kind_of? Class
|
return @version
|
||||||
|
|
||||||
detected = VCS_SYMBOLS[@using]
|
|
||||||
raise "Unknown strategy #{@using} was requested." unless detected
|
|
||||||
return detected
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def detect_version
|
def mirror val, specs=nil
|
||||||
Pathname.new(@url).version
|
@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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -66,4 +66,238 @@ class FormulaTests < Test::Unit::TestCase
|
|||||||
assert_equal downloader.url, "file:///#{TEST_FOLDER}/tarballs/testball-0.1.tbz"
|
assert_equal downloader.url, "file:///#{TEST_FOLDER}/tarballs/testball-0.1.tbz"
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|||||||
@ -94,3 +94,133 @@ class TestBlockWithoutBuildCompilerFailure < TestCompilerFailures
|
|||||||
cause "failure"
|
cause "failure"
|
||||||
end
|
end
|
||||||
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
|
||||||
|
|||||||
@ -52,4 +52,9 @@ def shutup
|
|||||||
end
|
end
|
||||||
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
|
require 'test/unit' # must be after at_exit
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user