diff --git a/Library/Homebrew/bottles.rb b/Library/Homebrew/bottles.rb deleted file mode 100644 index b18fde4770..0000000000 --- a/Library/Homebrew/bottles.rb +++ /dev/null @@ -1,141 +0,0 @@ -require "tab" -require "extend/ARGV" - -def built_as_bottle?(f) - return false unless f.installed? - tab = Tab.for_keg(f.installed_prefix) - tab.built_as_bottle -end - -def bottle_file_outdated?(f, file) - filename = file.basename.to_s - return unless f.bottle && filename.match(Pathname::BOTTLE_EXTNAME_RX) - - bottle_ext = filename[bottle_native_regex, 1] - bottle_url_ext = f.bottle.url[bottle_native_regex, 1] - - bottle_ext && bottle_url_ext && bottle_ext != bottle_url_ext -end - -def bottle_native_regex - /(\.#{bottle_tag}\.bottle\.(\d+\.)?tar\.gz)$/o -end - -def bottle_tag - if MacOS.version >= :lion - MacOS.cat - elsif MacOS.version == :snow_leopard - Hardware::CPU.is_64_bit? ? :snow_leopard : :snow_leopard_32 - else - # Return, e.g., :tiger_g3, :leopard_g5_64, :leopard_64 (which is Intel) - if Hardware::CPU.type == :ppc - tag = "#{MacOS.cat}_#{Hardware::CPU.family}".to_sym - else - tag = MacOS.cat - end - MacOS.prefer_64_bit? ? "#{tag}_64".to_sym : tag - end -end - -def bottle_receipt_path(bottle_file) - Utils.popen_read("/usr/bin/tar", "-tzf", bottle_file, "*/*/INSTALL_RECEIPT.json").chomp -end - -def bottle_resolve_formula_names(bottle_file) - receipt_file_path = bottle_receipt_path bottle_file - receipt_file = Utils.popen_read("tar", "-xOzf", bottle_file, receipt_file_path) - name = receipt_file_path.split("/").first - tap = Tab.from_file_content(receipt_file, "#{bottle_file}/#{receipt_file_path}").tap - - if tap.nil? || tap.core_tap? - full_name = name - else - full_name = "#{tap}/#{name}" - end - - [name, full_name] -end - -def bottle_resolve_version(bottle_file) - PkgVersion.parse bottle_receipt_path(bottle_file).split("/")[1] -end - -class Bintray - def self.package(formula_name) - formula_name.to_s.tr("+", "x") - end - - def self.repository(tap = nil) - if tap.nil? || tap.core_tap? - "bottles" - else - "bottles-#{tap.repo}" - end - end -end - -class BottleCollector - def initialize - @checksums = {} - end - - def fetch_checksum_for(tag) - tag = find_matching_tag(tag) - return self[tag], tag if tag - end - - def keys - @checksums.keys - end - - def [](key) - @checksums[key] - end - - def []=(key, value) - @checksums[key] = value - end - - def key?(key) - @checksums.key?(key) - end - - private - - def find_matching_tag(tag) - if key?(tag) - tag - else - find_altivec_tag(tag) || find_or_later_tag(tag) - end - end - - # This allows generic Altivec PPC bottles to be supported in some - # formulae, while also allowing specific bottles in others; e.g., - # sometimes a formula has just :tiger_altivec, other times it has - # :tiger_g4, :tiger_g5, etc. - def find_altivec_tag(tag) - if tag.to_s =~ /(\w+)_(g4|g4e|g5)$/ - altivec_tag = "#{$1}_altivec".to_sym - altivec_tag if key?(altivec_tag) - end - end - - # Allows a bottle tag to specify a specific OS or later, - # so the same bottle can target multiple OSs. - # Not used in core, used in taps. - def find_or_later_tag(tag) - begin - tag_version = MacOS::Version.from_symbol(tag) - rescue ArgumentError - return - end - - keys.find do |key| - if key.to_s.end_with?("_or_later") - later_tag = key.to_s[/(\w+)_or_later$/, 1].to_sym - MacOS::Version.from_symbol(later_tag) <= tag_version - end - end - end -end diff --git a/Library/Homebrew/cleanup.rb b/Library/Homebrew/cleanup.rb index 2dba60bb99..88d276bf4d 100644 --- a/Library/Homebrew/cleanup.rb +++ b/Library/Homebrew/cleanup.rb @@ -1,4 +1,4 @@ -require "bottles" +require "utils/bottles" require "formula" require "thread" @@ -67,7 +67,7 @@ module Homebrew file = path if Pathname::BOTTLE_EXTNAME_RX === file.to_s - version = bottle_resolve_version(file) rescue file.version + version = Utils::Bottles.resolve_version(file) rescue file.version else version = file.version end diff --git a/Library/Homebrew/cmd/bottle.rb b/Library/Homebrew/cmd/bottle.rb index 59e122f415..2f8f7f6159 100644 --- a/Library/Homebrew/cmd/bottle.rb +++ b/Library/Homebrew/cmd/bottle.rb @@ -1,5 +1,5 @@ require "formula" -require "bottles" +require "utils/bottles" require "tab" require "keg" require "formula_versions" @@ -155,7 +155,7 @@ module Homebrew return end - unless built_as_bottle? f + unless Utils::Bottles::built_as? f return ofail "Formula not installed with '--build-bottle': #{f.full_name}" end @@ -175,7 +175,7 @@ module Homebrew bottle_revision = bottle_revisions.any? ? bottle_revisions.max.to_i + 1 : 0 end - filename = Bottle::Filename.create(f, bottle_tag, bottle_revision) + filename = Bottle::Filename.create(f, Utils::Bottles.tag, bottle_revision) bottle_path = Pathname.pwd/filename tar_filename = filename.to_s.sub(/.gz$/, "") @@ -281,7 +281,7 @@ module Homebrew bottle.prefix prefix end bottle.revision bottle_revision - bottle.sha256 bottle_path.sha256 => bottle_tag + bottle.sha256 bottle_path.sha256 => Utils::Bottles.tag old_spec = f.bottle_specification if ARGV.include?("--keep-old") && !old_spec.checksums.empty? diff --git a/Library/Homebrew/cmd/pull.rb b/Library/Homebrew/cmd/pull.rb index 6f7136cf8f..654461edb9 100644 --- a/Library/Homebrew/cmd/pull.rb +++ b/Library/Homebrew/cmd/pull.rb @@ -32,7 +32,6 @@ require "utils/json" require "formula" require "formulary" require "tap" -require "bottles" require "version" require "pkg_version" @@ -402,8 +401,8 @@ module Homebrew # Publishes the current bottle files for a given formula to Bintray def publish_bottle_file_on_bintray(f, creds) - repo = Bintray.repository(f.tap) - package = Bintray.package(f.name) + repo = Utils::Bottles::Bintray.repository(f.tap) + package = Utils::Bottles::Bintray.package(f.name) info = FormulaInfoFromJson.lookup(f.name) if info.nil? raise "Failed publishing bottle: failed reading formula info for #{f.full_name}" diff --git a/Library/Homebrew/cmd/test-bot.rb b/Library/Homebrew/cmd/test-bot.rb index 13b5bd55cb..a01467036b 100644 --- a/Library/Homebrew/cmd/test-bot.rb +++ b/Library/Homebrew/cmd/test-bot.rb @@ -576,7 +576,7 @@ module Homebrew bottle_step = steps.last if bottle_step.passed? && bottle_step.has_output? bottle_filename = - bottle_step.output.gsub(/.*(\.\/\S+#{bottle_native_regex}).*/m, '\1') + bottle_step.output.gsub(/.*(\.\/\S+#{Utils::Bottles::native_regex}).*/m, '\1') bottle_rb_filename = bottle_filename.gsub(/\.(\d+\.)?tar\.gz$/, ".rb") bottle_merge_args = ["--merge", "--write", "--no-commit", bottle_rb_filename] bottle_merge_args << "--keep-old" if ARGV.include? "--keep-old" @@ -824,15 +824,15 @@ module Homebrew remote = "git@github.com:BrewTestBot/homebrew-#{tap.repo}.git" tag = pr ? "pr-#{pr}" : "testing-#{number}" - bintray_repo = Bintray.repository(tap) + bintray_repo = Utils::Bottles::Bintray.repository(tap) bintray_repo_url = "https://api.bintray.com/packages/homebrew/#{bintray_repo}" formula_packaged = {} Dir.glob("*.bottle*.tar.gz") do |filename| - formula_name, canonical_formula_name = bottle_resolve_formula_names filename + formula_name, canonical_formula_name = Utils::Bottles.resolve_formula_names filename formula = Formulary.factory canonical_formula_name version = formula.pkg_version - bintray_package = Bintray.package formula_name + bintray_package = Utils::Bottles::Bintray.package formula_name if system "curl", "-I", "--silent", "--fail", "--output", "/dev/null", "#{BottleSpecification::DEFAULT_DOMAIN}/#{bintray_repo}/#{filename}" diff --git a/Library/Homebrew/extend/os/bottles.rb b/Library/Homebrew/extend/os/bottles.rb new file mode 100644 index 0000000000..aff9300de1 --- /dev/null +++ b/Library/Homebrew/extend/os/bottles.rb @@ -0,0 +1,5 @@ +require "utils/bottles" + +if OS.mac? + require "extend/os/mac/utils/bottles" +end diff --git a/Library/Homebrew/extend/os/mac/utils/bottles.rb b/Library/Homebrew/extend/os/mac/utils/bottles.rb new file mode 100644 index 0000000000..6b83ad6c4c --- /dev/null +++ b/Library/Homebrew/extend/os/mac/utils/bottles.rb @@ -0,0 +1,59 @@ +module Utils + class Bottles + class << self + def tag + if MacOS.version >= :lion + MacOS.cat + elsif MacOS.version == :snow_leopard + Hardware::CPU.is_64_bit? ? :snow_leopard : :snow_leopard_32 + else + # Return, e.g., :tiger_g3, :leopard_g5_64, :leopard_64 (which is Intel) + if Hardware::CPU.type == :ppc + tag = "#{MacOS.cat}_#{Hardware::CPU.family}".to_sym + else + tag = MacOS.cat + end + MacOS.prefer_64_bit? ? "#{tag}_64".to_sym : tag + end + end + end + + class Collector + private + + alias_method :original_find_matching_tag, :find_matching_tag + def find_matching_tag(tag) + original_find_matching_tag(tag) || find_altivec_tag(tag) || find_or_later_tag(tag) + end + + # This allows generic Altivec PPC bottles to be supported in some + # formulae, while also allowing specific bottles in others; e.g., + # sometimes a formula has just :tiger_altivec, other times it has + # :tiger_g4, :tiger_g5, etc. + def find_altivec_tag(tag) + if tag.to_s =~ /(\w+)_(g4|g4e|g5)$/ + altivec_tag = "#{$1}_altivec".to_sym + altivec_tag if key?(altivec_tag) + end + end + + # Allows a bottle tag to specify a specific OS or later, + # so the same bottle can target multiple OSs. + # Not used in core, used in taps. + def find_or_later_tag(tag) + begin + tag_version = MacOS::Version.from_symbol(tag) + rescue ArgumentError + return + end + + keys.find do |key| + if key.to_s.end_with?("_or_later") + later_tag = key.to_s[/(\w+)_or_later$/, 1].to_sym + MacOS::Version.from_symbol(later_tag) <= tag_version + end + end + end + end + end +end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index a25a78f444..b8889225e0 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -2,7 +2,7 @@ require "formula_support" require "formula_lock" require "formula_pin" require "hardware" -require "bottles" +require "utils/bottles" require "build_environment" require "build_options" require "formulary" diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 4b8dcf202e..00678935d9 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -3,7 +3,7 @@ require "exceptions" require "formula" require "keg" require "tab" -require "bottles" +require "utils/bottles" require "caveats" require "cleaner" require "formula_cellar_checks" diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 28e79c68f8..1d31995c11 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -92,7 +92,7 @@ class Formulary class BottleLoader < FormulaLoader def initialize(bottle_name) @bottle_filename = Pathname(bottle_name).realpath - name, full_name = bottle_resolve_formula_names @bottle_filename + name, full_name = Utils::Bottles.resolve_formula_names @bottle_filename super name, Formulary.path(full_name) end @@ -100,7 +100,7 @@ class Formulary formula = super formula.local_bottle_path = @bottle_filename formula_version = formula.pkg_version - bottle_version = bottle_resolve_version(@bottle_filename) + bottle_version = Utils::Bottles.resolve_version(@bottle_filename) unless formula_version == bottle_version raise BottleVersionMismatchError.new(@bottle_filename, bottle_version, formula, formula_version) end diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index 6477dfd560..52885772cd 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -5,7 +5,7 @@ require "version" require "options" require "build_options" require "dependency_collector" -require "bottles" +require "utils/bottles" require "patch" require "compilers" @@ -80,7 +80,7 @@ class SoftwareSpec end def bottled? - bottle_specification.tag?(bottle_tag) && \ + bottle_specification.tag?(Utils::Bottles.tag) && \ (bottle_specification.compatible_cellar? || ARGV.force_bottle?) end @@ -254,7 +254,7 @@ class Bottle @resource.owner = formula @spec = spec - checksum, tag = spec.checksum_for(bottle_tag) + checksum, tag = spec.checksum_for(Utils::Bottles.tag) filename = Filename.create(formula, tag, spec.revision) @resource.url(build_url(spec.root_url, filename)) @@ -299,12 +299,12 @@ class BottleSpecification @revision = 0 @prefix = DEFAULT_PREFIX @cellar = DEFAULT_CELLAR - @collector = BottleCollector.new + @collector = Utils::Bottles::Collector.new end def root_url(var = nil) if var.nil? - @root_url ||= "#{DEFAULT_DOMAIN}/#{Bintray.repository(tap)}" + @root_url ||= "#{DEFAULT_DOMAIN}/#{Utils::Bottles::Bintray.repository(tap)}" else @root_url = var end diff --git a/Library/Homebrew/test/test_bottle_collector.rb b/Library/Homebrew/test/test_bottle_collector.rb index 2621d12720..fa356cb93e 100644 --- a/Library/Homebrew/test/test_bottle_collector.rb +++ b/Library/Homebrew/test/test_bottle_collector.rb @@ -1,9 +1,9 @@ require "testing_env" -require "bottles" +require "utils/bottles" class BottleCollectorTests < Homebrew::TestCase def setup - @collector = BottleCollector.new + @collector = Utils::Bottles::Collector.new end def checksum_for(tag) diff --git a/Library/Homebrew/test/test_bottle_tag.rb b/Library/Homebrew/test/test_bottle_tag.rb index 2bcbbf26d5..174c7d14ec 100644 --- a/Library/Homebrew/test/test_bottle_tag.rb +++ b/Library/Homebrew/test/test_bottle_tag.rb @@ -1,5 +1,5 @@ require "testing_env" -require "bottles" +require "utils/bottles" class BottleTagTests < Homebrew::TestCase def test_tag_tiger_ppc @@ -7,14 +7,14 @@ class BottleTagTests < Homebrew::TestCase Hardware::CPU.stubs(:type).returns(:ppc) Hardware::CPU.stubs(:family).returns(:foo) MacOS.stubs(:prefer_64_bit?).returns(false) - assert_equal :tiger_foo, bottle_tag + assert_equal :tiger_foo, Utils::Bottles.tag end def test_tag_tiger_intel MacOS.stubs(:version).returns(MacOS::Version.new("10.4")) Hardware::CPU.stubs(:type).returns(:intel) MacOS.stubs(:prefer_64_bit?).returns(false) - assert_equal :tiger, bottle_tag + assert_equal :tiger, Utils::Bottles.tag end def test_tag_tiger_ppc_64 @@ -22,7 +22,7 @@ class BottleTagTests < Homebrew::TestCase Hardware::CPU.stubs(:type).returns(:ppc) Hardware::CPU.stubs(:family).returns(:g5) MacOS.stubs(:prefer_64_bit?).returns(true) - assert_equal :tiger_g5_64, bottle_tag + assert_equal :tiger_g5_64, Utils::Bottles.tag end # Note that this will probably never be used @@ -30,14 +30,14 @@ class BottleTagTests < Homebrew::TestCase MacOS.stubs(:version).returns(MacOS::Version.new("10.4")) Hardware::CPU.stubs(:type).returns(:intel) MacOS.stubs(:prefer_64_bit?).returns(true) - assert_equal :tiger_64, bottle_tag + assert_equal :tiger_64, Utils::Bottles.tag end def test_tag_leopard_intel MacOS.stubs(:version).returns(MacOS::Version.new("10.5")) Hardware::CPU.stubs(:type).returns(:intel) MacOS.stubs(:prefer_64_bit?).returns(false) - assert_equal :leopard, bottle_tag + assert_equal :leopard, Utils::Bottles.tag end def test_tag_leopard_ppc_64 @@ -45,35 +45,35 @@ class BottleTagTests < Homebrew::TestCase Hardware::CPU.stubs(:type).returns(:ppc) Hardware::CPU.stubs(:family).returns(:g5) MacOS.stubs(:prefer_64_bit?).returns(true) - assert_equal :leopard_g5_64, bottle_tag + assert_equal :leopard_g5_64, Utils::Bottles.tag end def test_tag_leopard_intel_64 MacOS.stubs(:version).returns(MacOS::Version.new("10.5")) Hardware::CPU.stubs(:type).returns(:intel) MacOS.stubs(:prefer_64_bit?).returns(true) - assert_equal :leopard_64, bottle_tag + assert_equal :leopard_64, Utils::Bottles.tag end def test_tag_snow_leopard_32 MacOS.stubs(:version).returns(MacOS::Version.new("10.6")) Hardware::CPU.stubs(:is_64_bit?).returns(false) - assert_equal :snow_leopard_32, bottle_tag + assert_equal :snow_leopard_32, Utils::Bottles.tag end def test_tag_snow_leopard_64 MacOS.stubs(:version).returns(MacOS::Version.new("10.6")) Hardware::CPU.stubs(:is_64_bit?).returns(true) - assert_equal :snow_leopard, bottle_tag + assert_equal :snow_leopard, Utils::Bottles.tag end def test_tag_lion MacOS.stubs(:version).returns(MacOS::Version.new("10.7")) - assert_equal :lion, bottle_tag + assert_equal :lion, Utils::Bottles.tag end def test_tag_mountain_lion MacOS.stubs(:version).returns(MacOS::Version.new("10.8")) - assert_equal :mountain_lion, bottle_tag + assert_equal :mountain_lion, Utils::Bottles.tag end end diff --git a/Library/Homebrew/test/test_formulary.rb b/Library/Homebrew/test/test_formulary.rb index ec18ee0532..593e08cfa9 100644 --- a/Library/Homebrew/test/test_formulary.rb +++ b/Library/Homebrew/test/test_formulary.rb @@ -1,7 +1,7 @@ require "testing_env" require "formula" require "formula_installer" -require "bottles" +require "utils/bottles" class FormularyTest < Homebrew::TestCase def test_class_naming @@ -18,7 +18,7 @@ class FormularyFactoryTest < Homebrew::TestCase @name = "testball_bottle" @path = CoreTap.new.formula_dir/"#{@name}.rb" @bottle_dir = Pathname.new("#{File.expand_path("..", __FILE__)}/bottles") - @bottle = @bottle_dir/"testball_bottle-0.1.#{bottle_tag}.bottle.tar.gz" + @bottle = @bottle_dir/"testball_bottle-0.1.#{Utils::Bottles.tag}.bottle.tar.gz" @path.write <<-EOS.undent class #{Formulary.class_s(@name)} < Formula url "file://#{File.expand_path("..", __FILE__)}/tarballs/testball-0.1.tbz" @@ -27,7 +27,7 @@ class FormularyFactoryTest < Homebrew::TestCase bottle do cellar :any_skip_relocation root_url "file://#{@bottle_dir}" - sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => :#{bottle_tag} + sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => :#{Utils::Bottles.tag} end def install diff --git a/Library/Homebrew/test/testball_bottle.rb b/Library/Homebrew/test/testball_bottle.rb index 31e98364e9..5aa582fa8a 100644 --- a/Library/Homebrew/test/testball_bottle.rb +++ b/Library/Homebrew/test/testball_bottle.rb @@ -6,7 +6,7 @@ class TestballBottle < Formula stable.bottle do cellar :any_skip_relocation root_url "file://#{File.expand_path("..", __FILE__)}/bottles" - sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => bottle_tag + sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => Utils::Bottles.tag end cxxstdlib_check :skip end diff --git a/Library/Homebrew/utils/bottles.rb b/Library/Homebrew/utils/bottles.rb new file mode 100644 index 0000000000..6a05a7aeb1 --- /dev/null +++ b/Library/Homebrew/utils/bottles.rb @@ -0,0 +1,104 @@ +require "tab" +require "extend/ARGV" + +module Utils + class Bottles + class << self + def tag + @bottle_tag ||= "#{ENV["HOMEBREW_SYSTEM"]}-#{ENV["HOMEBREW_PROCESSOR"]}".downcase.to_sym + end + + def built_as?(f) + return false unless f.installed? + tab = Tab.for_keg(f.installed_prefix) + tab.built_as_bottle + end + + def file_outdated?(f, file) + filename = file.basename.to_s + return unless f.bottle && filename.match(Pathname::BOTTLE_EXTNAME_RX) + + bottle_ext = filename[native_regex, 1] + bottle_url_ext = f.bottle.url[native_regex, 1] + + bottle_ext && bottle_url_ext && bottle_ext != bottle_url_ext + end + + def native_regex + /(\.#{Regexp.escape(tag)}\.bottle\.(\d+\.)?tar\.gz)$/o + end + + def receipt_path(bottle_file) + Utils.popen_read("/usr/bin/tar", "-tzf", bottle_file, "*/*/INSTALL_RECEIPT.json").chomp + end + + def resolve_formula_names(bottle_file) + receipt_file_path = receipt_path bottle_file + receipt_file = Utils.popen_read("tar", "-xOzf", bottle_file, receipt_file_path) + name = receipt_file_path.split("/").first + tap = Tab.from_file_content(receipt_file, "#{bottle_file}/#{receipt_file_path}").tap + + if tap.nil? || tap.core_tap? + full_name = name + else + full_name = "#{tap}/#{name}" + end + + [name, full_name] + end + + def resolve_version(bottle_file) + PkgVersion.parse receipt_path(bottle_file).split("/")[1] + end + end + + class Bintray + def self.package(formula_name) + formula_name.to_s.tr("+", "x") + end + + def self.repository(tap = nil) + if tap.nil? || tap.core_tap? + "bottles" + else + "bottles-#{tap.repo}" + end + end + end + + class Collector + def initialize + @checksums = {} + end + + def fetch_checksum_for(tag) + tag = find_matching_tag(tag) + return self[tag], tag if tag + end + + def keys + @checksums.keys + end + + def [](key) + @checksums[key] + end + + def []=(key, value) + @checksums[key] = value + end + + def key?(key) + @checksums.key?(key) + end + + private + + def find_matching_tag(tag) + tag if key?(tag) + end + end + end +end + +require "extend/os/bottles" diff --git a/Library/brew.sh b/Library/brew.sh index 76cb2f9e98..5589bcc684 100644 --- a/Library/brew.sh +++ b/Library/brew.sh @@ -118,7 +118,9 @@ export HOMEBREW_LIBRARY export HOMEBREW_VERSION export HOMEBREW_CELLAR export HOMEBREW_RUBY_PATH +export HOMEBREW_SYSTEM export HOMEBREW_CURL +export HOMEBREW_PROCESSOR export HOMEBREW_PRODUCT export HOMEBREW_OS_VERSION export HOMEBREW_OSX_VERSION