Merge pull request #3176 from sjackman/bottle-formula

BottleLoader: Use the formula stored in the bottle
This commit is contained in:
Mike McQuaid 2017-09-29 13:59:52 +01:00 committed by GitHub
commit 296a44195b
9 changed files with 44 additions and 24 deletions

View File

@ -555,12 +555,12 @@ end
# raised when a single patch file is not found and apply hasn't been specified
class MissingApplyError < RuntimeError; end
class BottleVersionMismatchError < RuntimeError
def initialize(bottle_file, bottle_version, formula, formula_version)
class BottleFormulaUnavailableError < RuntimeError
def initialize(bottle_path, formula_path)
super <<-EOS.undent
Bottle version mismatch
Bottle: #{bottle_file} (#{bottle_version})
Formula: #{formula.full_name} (#{formula_version})
This bottle does not contain the formula file:
#{bottle_path}
#{formula_path}
EOS
end
end

View File

@ -84,8 +84,7 @@ class FormulaInstaller
return false if @pour_failed
bottle = formula.bottle
return false if !bottle && !formula.local_bottle_path
return false if !formula.bottled? && !formula.local_bottle_path
return true if force_bottle?
return false if build_from_source? || build_bottle? || interactive?
return false if ARGV.cc
@ -101,11 +100,11 @@ class FormulaInstaller
return false
end
unless bottle.compatible_cellar?
unless formula.bottled?
if install_bottle_options[:warn]
opoo <<-EOS.undent
Building #{formula.full_name} from source:
The bottle needs a #{bottle.cellar} Cellar (yours is #{HOMEBREW_CELLAR}).
The bottle needs a #{formula.bottle_specification.cellar} Cellar (yours is #{HOMEBREW_CELLAR}).
EOS
end
return false
@ -236,6 +235,15 @@ class FormulaInstaller
raise CannotInstallFormulaError, message
end
# Warn if a more recent version of this formula is available in the tap.
begin
if formula.pkg_version < (v = Formulary.factory(formula.full_name).pkg_version)
opoo "#{formula.full_name} #{v} is available and more recent than version #{formula.pkg_version}."
end
rescue FormulaUnavailableError
nil
end
check_conflicts
if !pour_bottle? && !formula.bottle_unneeded? && !DevelopmentTools.installed?
@ -309,7 +317,12 @@ class FormulaInstaller
clean
# Store the formula used to build the keg in the keg.
s = formula.path.read.gsub(/ bottle do.+?end\n\n?/m, "")
formula_contents = if formula.local_bottle_path
Utils::Bottles.formula_contents formula.local_bottle_path, name: formula.name
else
formula.path.read
end
s = formula_contents.gsub(/ bottle do.+?end\n\n?/m, "")
brew_prefix = formula.prefix/".brew"
brew_prefix.mkdir
Pathname(brew_prefix/"#{formula.name}.rb").atomic_write(s)

View File

@ -122,14 +122,10 @@ module Formulary
super name, Formulary.path(full_name)
end
def get_formula(spec, alias_path: nil)
formula = super
def get_formula(spec, **)
contents = Utils::Bottles.formula_contents @bottle_filename, name: name
formula = Formulary.from_contents name, @bottle_filename, contents, spec
formula.local_bottle_path = @bottle_filename
formula_version = formula.pkg_version
bottle_version = Utils::Bottles.resolve_version(@bottle_filename)
unless formula_version == bottle_version
raise BottleVersionMismatchError.new(@bottle_filename, bottle_version, formula, formula_version)
end
formula
end
end

View File

@ -8,7 +8,7 @@ describe Homebrew::Hooks::Bottles do
let(:formula) do
double(
bottle: nil,
bottled?: false,
local_bottle_path: nil,
bottle_disabled?: false,
some_random_method: true,

View File

@ -181,8 +181,8 @@ describe DuplicateResourceError do
its(:to_s) { is_expected.to eq("Resource <resource foo> is defined more than once") }
end
describe BottleVersionMismatchError do
subject { described_class.new("/foo.bottle.tar.gz", "1.0", formula, "1.1") }
describe BottleFormulaUnavailableError do
subject { described_class.new("/foo.bottle.tar.gz", "foo/1.0/.brew/foo.rb") }
let(:formula) { double(Formula, full_name: "foo") }
its(:to_s) { is_expected.to match(/Bottle version mismatch/) }
its(:to_s) { is_expected.to match(/This bottle does not contain the formula file/) }
end

View File

@ -14,7 +14,7 @@ describe Formulary do
bottle do
cellar :any_skip_relocation
root_url "file://#{bottle_dir}"
sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => :#{Utils::Bottles.tag}
sha256 "d48bbbe583dcfbfa608579724fc6f0328b3cd316935c6ea22f134610aaf2952f" => :#{Utils::Bottles.tag}
end
def install

View File

@ -6,7 +6,7 @@ class TestballBottle < Formula
stable.bottle do
cellar :any_skip_relocation
root_url "file://#{TEST_FIXTURE_DIR}/bottles"
sha256 "9abc8ce779067e26556002c4ca6b9427b9874d25f0cafa7028e05b5c5c410cb4" => Utils::Bottles.tag
sha256 "d48bbbe583dcfbfa608579724fc6f0328b3cd316935c6ea22f134610aaf2952f" => Utils::Bottles.tag
end
cxxstdlib_check :skip
end

View File

@ -29,9 +29,11 @@ module Utils
end
def receipt_path(bottle_file)
Utils.popen_read("tar", "-tzf", bottle_file).lines.map(&:chomp).find do |line|
path = Utils.popen_read("tar", "-tzf", bottle_file).lines.map(&:chomp).find do |line|
line =~ %r{.+/.+/INSTALL_RECEIPT.json}
end
raise "This bottle does not contain the file INSTALL_RECEIPT.json: #{bottle_file}" unless path
path
end
def resolve_formula_names(bottle_file)
@ -52,6 +54,15 @@ module Utils
def resolve_version(bottle_file)
PkgVersion.parse receipt_path(bottle_file).split("/")[1]
end
def formula_contents(bottle_file,
name: resolve_formula_names(bottle_file)[0])
bottle_version = resolve_version bottle_file
formula_path = "#{name}/#{bottle_version}/.brew/#{name}.rb"
contents = Utils.popen_read "tar", "-xOzf", bottle_file, formula_path
raise BottleFormulaUnavailableError.new(bottle_file, formula_path) unless $CHILD_STATUS.success?
contents
end
end
class Bintray