Make bottle implementation more generic
This commit is contained in:
parent
97dd5f61c4
commit
7da459874f
@ -3,12 +3,9 @@ require 'os/mac'
|
|||||||
require 'extend/ARGV'
|
require 'extend/ARGV'
|
||||||
require 'bottle_version'
|
require 'bottle_version'
|
||||||
|
|
||||||
def bottle_filename f, options={}
|
def bottle_filename options={}
|
||||||
options = { :tag => bottle_tag }.merge(options)
|
options = { :tag => bottle_tag }.merge(options)
|
||||||
name = f.name.downcase
|
"#{options[:name]}-#{options[:version]}#{bottle_native_suffix(options)}"
|
||||||
version = PkgVersion.new(f.stable.version, f.revision)
|
|
||||||
options[:revision] ||= f.bottle.revision.to_i if f.bottle
|
|
||||||
"#{name}-#{version}#{bottle_native_suffix(options)}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def install_bottle? f, options={:warn=>false}
|
def install_bottle? f, options={:warn=>false}
|
||||||
@ -16,7 +13,8 @@ def install_bottle? f, options={:warn=>false}
|
|||||||
return true if ARGV.force_bottle?
|
return true if ARGV.force_bottle?
|
||||||
return false unless f.pour_bottle?
|
return false unless f.pour_bottle?
|
||||||
return false unless f.default_build?
|
return false unless f.default_build?
|
||||||
return false unless bottle_current?(f)
|
return false unless f.bottle
|
||||||
|
|
||||||
if f.bottle.cellar != :any && f.bottle.cellar != HOMEBREW_CELLAR.to_s
|
if f.bottle.cellar != :any && f.bottle.cellar != HOMEBREW_CELLAR.to_s
|
||||||
if options[:warn]
|
if options[:warn]
|
||||||
opoo "Building source; cellar of #{f}'s bottle is #{f.bottle.cellar}"
|
opoo "Building source; cellar of #{f}'s bottle is #{f.bottle.cellar}"
|
||||||
@ -33,10 +31,6 @@ def built_as_bottle? f
|
|||||||
tab.built_as_bottle
|
tab.built_as_bottle
|
||||||
end
|
end
|
||||||
|
|
||||||
def bottle_current? f
|
|
||||||
f.bottle and f.bottle.url and not f.bottle.checksum.empty?
|
|
||||||
end
|
|
||||||
|
|
||||||
def bottle_file_outdated? f, file
|
def bottle_file_outdated? f, file
|
||||||
filename = file.basename.to_s
|
filename = file.basename.to_s
|
||||||
return nil unless f and f.bottle and f.bottle.url \
|
return nil unless f and f.bottle and f.bottle.url \
|
||||||
@ -66,8 +60,8 @@ def bottle_regex
|
|||||||
Pathname::BOTTLE_EXTNAME_RX
|
Pathname::BOTTLE_EXTNAME_RX
|
||||||
end
|
end
|
||||||
|
|
||||||
def bottle_url f, tag=bottle_tag
|
def bottle_url(root_url, filename_options={})
|
||||||
"#{f.bottle.root_url}/#{bottle_filename(f, :tag => tag)}"
|
"#{root_url}/#{bottle_filename(filename_options)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def bottle_tag
|
def bottle_tag
|
||||||
|
|||||||
@ -18,7 +18,7 @@ class Formula
|
|||||||
extend BuildEnvironmentDSL
|
extend BuildEnvironmentDSL
|
||||||
|
|
||||||
attr_reader :name, :path, :homepage, :build
|
attr_reader :name, :path, :homepage, :build
|
||||||
attr_reader :stable, :bottle, :devel, :head, :active_spec
|
attr_reader :stable, :devel, :head, :active_spec
|
||||||
attr_reader :pkg_version, :revision
|
attr_reader :pkg_version, :revision
|
||||||
|
|
||||||
# The current working directory during builds and tests.
|
# The current working directory during builds and tests.
|
||||||
@ -41,31 +41,11 @@ class Formula
|
|||||||
set_spec :stable
|
set_spec :stable
|
||||||
set_spec :devel
|
set_spec :devel
|
||||||
set_spec :head
|
set_spec :head
|
||||||
set_spec :bottle do |bottle|
|
|
||||||
# Ensure the bottle URL is set. If it does not have a checksum,
|
|
||||||
# then a bottle is not available for the current platform.
|
|
||||||
# TODO: push this down into Bottle; we can pass the formula instance
|
|
||||||
# into a validation method on the bottle instance.
|
|
||||||
unless bottle.checksum.nil? || bottle.checksum.empty?
|
|
||||||
@bottle = bottle
|
|
||||||
bottle.url ||= bottle_url(self, bottle.current_tag)
|
|
||||||
bottle.version = PkgVersion.new(stable.version, revision)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@active_spec = determine_active_spec
|
@active_spec = determine_active_spec
|
||||||
validate_attributes :url, :name, :version
|
validate_attributes :url, :name, :version
|
||||||
@build = determine_build_options
|
@build = determine_build_options
|
||||||
|
|
||||||
# TODO: @pkg_version is already set for bottles, since constructing it
|
|
||||||
# requires passing in the active_spec version. This should be fixed by
|
|
||||||
# making the bottle an attribute of SoftwareSpec rather than a separate
|
|
||||||
# spec itself.
|
|
||||||
if active_spec == bottle
|
|
||||||
@pkg_version = bottle.version
|
|
||||||
else
|
|
||||||
@pkg_version = PkgVersion.new(version, revision)
|
@pkg_version = PkgVersion.new(version, revision)
|
||||||
end
|
|
||||||
|
|
||||||
@pin = FormulaPin.new(self)
|
@pin = FormulaPin.new(self)
|
||||||
|
|
||||||
@ -74,21 +54,16 @@ class Formula
|
|||||||
|
|
||||||
def set_spec(name)
|
def set_spec(name)
|
||||||
spec = self.class.send(name)
|
spec = self.class.send(name)
|
||||||
if block_given? && yield(spec) || spec.url
|
if spec.url
|
||||||
spec.owner = self
|
spec.owner = self
|
||||||
instance_variable_set("@#{name}", spec)
|
instance_variable_set("@#{name}", spec)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def select_bottle?
|
|
||||||
!ARGV.build_bottle? && install_bottle?(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
def determine_active_spec
|
def determine_active_spec
|
||||||
case
|
case
|
||||||
when head && ARGV.build_head? then head # --HEAD
|
when head && ARGV.build_head? then head # --HEAD
|
||||||
when devel && ARGV.build_devel? then devel # --devel
|
when devel && ARGV.build_devel? then devel # --devel
|
||||||
when bottle && select_bottle? then bottle # bottle available
|
|
||||||
when stable then stable
|
when stable then stable
|
||||||
when devel && stable.nil? then devel # devel-only
|
when devel && stable.nil? then devel # devel-only
|
||||||
when head && stable.nil? then head # head-only
|
when head && stable.nil? then head # head-only
|
||||||
@ -115,6 +90,10 @@ class Formula
|
|||||||
build
|
build
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bottle
|
||||||
|
Bottle.new(self, active_spec.bottle_specification) if active_spec.bottled?
|
||||||
|
end
|
||||||
|
|
||||||
def url; active_spec.url; end
|
def url; active_spec.url; end
|
||||||
def version; active_spec.version; end
|
def version; active_spec.version; end
|
||||||
def mirrors; active_spec.mirrors; end
|
def mirrors; active_spec.mirrors; end
|
||||||
@ -699,7 +678,7 @@ class Formula
|
|||||||
attr_rw :homepage, :plist_startup, :plist_manual, :revision
|
attr_rw :homepage, :plist_startup, :plist_manual, :revision
|
||||||
|
|
||||||
def specs
|
def specs
|
||||||
@specs ||= [stable, devel, head, bottle].freeze
|
@specs ||= [stable, devel, head].freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
def url val, specs={}
|
def url val, specs={}
|
||||||
@ -722,6 +701,10 @@ class Formula
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bottle *, &block
|
||||||
|
stable.bottle(&block)
|
||||||
|
end
|
||||||
|
|
||||||
def build
|
def build
|
||||||
stable.build
|
stable.build
|
||||||
end
|
end
|
||||||
@ -732,13 +715,6 @@ class Formula
|
|||||||
@stable.instance_eval(&block)
|
@stable.instance_eval(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def bottle *, &block
|
|
||||||
@bottle ||= Bottle.new
|
|
||||||
return @bottle unless block_given?
|
|
||||||
@bottle.instance_eval(&block)
|
|
||||||
@bottle.version = @stable.version
|
|
||||||
end
|
|
||||||
|
|
||||||
def devel &block
|
def devel &block
|
||||||
@devel ||= SoftwareSpec.new
|
@devel ||= SoftwareSpec.new
|
||||||
return @devel unless block_given?
|
return @devel unless block_given?
|
||||||
|
|||||||
@ -12,6 +12,7 @@ class SoftwareSpec
|
|||||||
attr_reader :name
|
attr_reader :name
|
||||||
attr_reader :build, :resources, :owner
|
attr_reader :build, :resources, :owner
|
||||||
attr_reader :dependency_collector
|
attr_reader :dependency_collector
|
||||||
|
attr_reader :bottle_specification
|
||||||
|
|
||||||
def_delegators :@resource, :stage, :fetch, :verify_download_integrity
|
def_delegators :@resource, :stage, :fetch, :verify_download_integrity
|
||||||
def_delegators :@resource, :cached_download, :clear_cache
|
def_delegators :@resource, :cached_download, :clear_cache
|
||||||
@ -23,6 +24,7 @@ class SoftwareSpec
|
|||||||
@resources = {}
|
@resources = {}
|
||||||
@build = BuildOptions.new(ARGV.options_only)
|
@build = BuildOptions.new(ARGV.options_only)
|
||||||
@dependency_collector = DependencyCollector.new
|
@dependency_collector = DependencyCollector.new
|
||||||
|
@bottle_specification = BottleSpecification.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def owner= owner
|
def owner= owner
|
||||||
@ -41,6 +43,14 @@ class SoftwareSpec
|
|||||||
dependency_collector.add(@resource)
|
dependency_collector.add(@resource)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bottled?
|
||||||
|
bottle_specification.fully_specified?
|
||||||
|
end
|
||||||
|
|
||||||
|
def bottle &block
|
||||||
|
bottle_specification.instance_eval(&block)
|
||||||
|
end
|
||||||
|
|
||||||
def resource? name
|
def resource? name
|
||||||
resources.has_key?(name)
|
resources.has_key?(name)
|
||||||
end
|
end
|
||||||
@ -87,20 +97,47 @@ class HeadSoftwareSpec < SoftwareSpec
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Bottle < SoftwareSpec
|
class Bottle
|
||||||
attr_rw :root_url, :prefix, :cellar, :revision
|
extend Forwardable
|
||||||
attr_accessor :current_tag
|
|
||||||
|
|
||||||
def_delegators :@resource, :version=, :url=
|
attr_reader :resource, :prefix, :cellar, :revision
|
||||||
|
|
||||||
|
def_delegators :resource, :url, :fetch, :verify_download_integrity
|
||||||
|
def_delegators :resource, :downloader, :cached_download, :clear_cache
|
||||||
|
|
||||||
|
def initialize(f, spec)
|
||||||
|
@resource = Resource.new
|
||||||
|
@resource.owner = f
|
||||||
|
@resource.url = bottle_url(
|
||||||
|
spec.root_url,
|
||||||
|
:name => f.name,
|
||||||
|
:version => f.pkg_version,
|
||||||
|
:revision => spec.revision,
|
||||||
|
:tag => spec.current_tag
|
||||||
|
)
|
||||||
|
@resource.version = f.pkg_version
|
||||||
|
@resource.checksum = spec.checksum
|
||||||
|
@prefix = spec.prefix
|
||||||
|
@cellar = spec.cellar
|
||||||
|
@revision = spec.revision
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class BottleSpecification
|
||||||
|
attr_rw :root_url, :prefix, :cellar, :revision
|
||||||
|
attr_reader :current_tag, :checksum
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super
|
|
||||||
@revision = 0
|
@revision = 0
|
||||||
@prefix = '/usr/local'
|
@prefix = '/usr/local'
|
||||||
@cellar = '/usr/local/Cellar'
|
@cellar = '/usr/local/Cellar'
|
||||||
@root_url = 'https://downloads.sf.net/project/machomebrew/Bottles'
|
@root_url = 'https://downloads.sf.net/project/machomebrew/Bottles'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fully_specified?
|
||||||
|
checksum && !checksum.empty?
|
||||||
|
end
|
||||||
|
|
||||||
# Checksum methods in the DSL's bottle block optionally take
|
# Checksum methods in the DSL's bottle block optionally take
|
||||||
# a Hash, which indicates the platform the checksum applies on.
|
# a Hash, which indicates the platform the checksum applies on.
|
||||||
Checksum::TYPES.each do |cksum|
|
Checksum::TYPES.each do |cksum|
|
||||||
@ -115,7 +152,7 @@ class Bottle < SoftwareSpec
|
|||||||
end
|
end
|
||||||
|
|
||||||
cksum, current_tag = @#{cksum}.fetch_bottle_for(bottle_tag)
|
cksum, current_tag = @#{cksum}.fetch_bottle_for(bottle_tag)
|
||||||
@resource.checksum = cksum if cksum
|
@checksum = cksum if cksum
|
||||||
@current_tag = current_tag if cksum
|
@current_tag = current_tag if cksum
|
||||||
end
|
end
|
||||||
EOS
|
EOS
|
||||||
|
|||||||
@ -182,7 +182,6 @@ class FormulaTests < Test::Unit::TestCase
|
|||||||
assert_equal f.stable, f.active_spec
|
assert_equal f.stable, f.active_spec
|
||||||
|
|
||||||
assert_instance_of SoftwareSpec, f.stable
|
assert_instance_of SoftwareSpec, f.stable
|
||||||
assert_instance_of Bottle, f.bottle
|
|
||||||
assert_instance_of SoftwareSpec, f.devel
|
assert_instance_of SoftwareSpec, f.devel
|
||||||
assert_instance_of HeadSoftwareSpec, f.head
|
assert_instance_of HeadSoftwareSpec, f.head
|
||||||
end
|
end
|
||||||
@ -216,7 +215,7 @@ class FormulaTests < Test::Unit::TestCase
|
|||||||
def test_class_specs_are_always_initialized
|
def test_class_specs_are_always_initialized
|
||||||
f = formula { url 'foo-1.0' }
|
f = formula { url 'foo-1.0' }
|
||||||
|
|
||||||
%w{stable devel head bottle}.each do |spec|
|
%w{stable devel head}.each do |spec|
|
||||||
assert_kind_of SoftwareSpec, f.class.send(spec)
|
assert_kind_of SoftwareSpec, f.class.send(spec)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -224,7 +223,7 @@ class FormulaTests < Test::Unit::TestCase
|
|||||||
def test_incomplete_instance_specs_are_not_accessible
|
def test_incomplete_instance_specs_are_not_accessible
|
||||||
f = formula { url 'foo-1.0' }
|
f = formula { url 'foo-1.0' }
|
||||||
|
|
||||||
%w{devel head bottle}.each { |spec| assert_nil f.send(spec) }
|
%w{devel head}.each { |spec| assert_nil f.send(spec) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_honors_attributes_declared_before_specs
|
def test_honors_attributes_declared_before_specs
|
||||||
@ -234,7 +233,7 @@ class FormulaTests < Test::Unit::TestCase
|
|||||||
devel { url 'foo-1.1' }
|
devel { url 'foo-1.1' }
|
||||||
end
|
end
|
||||||
|
|
||||||
%w{stable devel head bottle}.each do |spec|
|
%w{stable devel head}.each do |spec|
|
||||||
assert_equal 'foo', f.class.send(spec).deps.first.name
|
assert_equal 'foo', f.class.send(spec).deps.first.name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -34,17 +34,6 @@ class FormulaSpecSelectionTests < Test::Unit::TestCase
|
|||||||
assert_spec_selected :devel
|
assert_spec_selected :devel
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_selects_bottle_when_available
|
|
||||||
formula do
|
|
||||||
def install_bottle?(*); true; end
|
|
||||||
|
|
||||||
url 'foo-1.0'
|
|
||||||
bottle { sha1 TEST_SHA1 => bottle_tag }
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_spec_selected :bottle
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_selects_stable_by_default
|
def test_selects_stable_by_default
|
||||||
formula do
|
formula do
|
||||||
url 'foo-1.0'
|
url 'foo-1.0'
|
||||||
@ -119,14 +108,4 @@ class FormulaSpecSelectionTests < Test::Unit::TestCase
|
|||||||
assert_spec_unset :devel
|
assert_spec_unset :devel
|
||||||
assert_spec_selected :stable
|
assert_spec_selected :stable
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_incomplete_bottle_not_set
|
|
||||||
formula do
|
|
||||||
url 'foo-1.0'
|
|
||||||
bottle { sha1 TEST_SHA1 => :some_nonexistent_thing }
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_spec_unset :bottle
|
|
||||||
assert_spec_selected :stable
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -98,9 +98,9 @@ class HeadSoftwareSpecTests < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class BottleTests < Test::Unit::TestCase
|
class BottleSpecificationTests < Test::Unit::TestCase
|
||||||
def setup
|
def setup
|
||||||
@spec = Bottle.new
|
@spec = BottleSpecification.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_checksum_setters
|
def test_checksum_setters
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user