Merge pull request #1253 from jawshooah/perf/relocate-text-files
keg_relocate: cache files rewritten during brew bottle
This commit is contained in:
commit
79e8cdd3ed
@ -187,14 +187,11 @@ module Homebrew
|
||||
|
||||
keg.lock do
|
||||
original_tab = nil
|
||||
changed_files = nil
|
||||
|
||||
begin
|
||||
unless ARGV.include? "--skip-relocation"
|
||||
keg.relocate_dynamic_linkage prefix, Keg::PREFIX_PLACEHOLDER,
|
||||
cellar, Keg::CELLAR_PLACEHOLDER
|
||||
keg.relocate_text_files prefix, Keg::PREFIX_PLACEHOLDER,
|
||||
cellar, Keg::CELLAR_PLACEHOLDER,
|
||||
repository, Keg::REPOSITORY_PLACEHOLDER
|
||||
changed_files = keg.replace_locations_with_placeholders
|
||||
end
|
||||
|
||||
keg.delete_pyc_files!
|
||||
@ -205,6 +202,7 @@ module Homebrew
|
||||
tab.poured_from_bottle = false
|
||||
tab.HEAD = nil
|
||||
tab.time = nil
|
||||
tab.changed_files = changed_files
|
||||
tab.write
|
||||
|
||||
keg.find do |file|
|
||||
@ -264,11 +262,7 @@ module Homebrew
|
||||
ignore_interrupts do
|
||||
original_tab.write if original_tab
|
||||
unless ARGV.include? "--skip-relocation"
|
||||
keg.relocate_dynamic_linkage Keg::PREFIX_PLACEHOLDER, prefix,
|
||||
Keg::CELLAR_PLACEHOLDER, cellar
|
||||
keg.relocate_text_files Keg::PREFIX_PLACEHOLDER, prefix,
|
||||
Keg::CELLAR_PLACEHOLDER, cellar,
|
||||
Keg::REPOSITORY_PLACEHOLDER, repository
|
||||
keg.replace_placeholders_with_locations changed_files
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -17,19 +17,19 @@ class Keg
|
||||
generic_fix_dynamic_linkage
|
||||
end
|
||||
|
||||
def relocate_dynamic_linkage(old_prefix, new_prefix, old_cellar, new_cellar)
|
||||
def relocate_dynamic_linkage(relocation)
|
||||
mach_o_files.each do |file|
|
||||
file.ensure_writable do
|
||||
if file.dylib?
|
||||
id = dylib_id_for(file).sub(old_prefix, new_prefix)
|
||||
id = dylib_id_for(file).sub(relocation.old_prefix, relocation.new_prefix)
|
||||
change_dylib_id(id, file)
|
||||
end
|
||||
|
||||
each_install_name_for(file) do |old_name|
|
||||
if old_name.start_with? old_cellar
|
||||
new_name = old_name.sub(old_cellar, new_cellar)
|
||||
elsif old_name.start_with? old_prefix
|
||||
new_name = old_name.sub(old_prefix, new_prefix)
|
||||
if old_name.start_with? relocation.old_cellar
|
||||
new_name = old_name.sub(relocation.old_cellar, relocation.new_cellar)
|
||||
elsif old_name.start_with? relocation.old_prefix
|
||||
new_name = old_name.sub(relocation.old_prefix, relocation.new_prefix)
|
||||
end
|
||||
|
||||
change_install_name(old_name, new_name, file) if new_name
|
||||
|
||||
@ -762,13 +762,12 @@ class FormulaInstaller
|
||||
end
|
||||
|
||||
keg = Keg.new(formula.prefix)
|
||||
|
||||
unless formula.bottle_specification.skip_relocation?
|
||||
keg.relocate_dynamic_linkage Keg::PREFIX_PLACEHOLDER, HOMEBREW_PREFIX.to_s,
|
||||
Keg::CELLAR_PLACEHOLDER, HOMEBREW_CELLAR.to_s
|
||||
tab = Tab.for_keg(keg)
|
||||
Tab.clear_cache
|
||||
keg.replace_placeholders_with_locations tab.changed_files
|
||||
end
|
||||
keg.relocate_text_files Keg::PREFIX_PLACEHOLDER, HOMEBREW_PREFIX.to_s,
|
||||
Keg::CELLAR_PLACEHOLDER, HOMEBREW_CELLAR.to_s,
|
||||
Keg::REPOSITORY_PLACEHOLDER, HOMEBREW_REPOSITORY.to_s
|
||||
|
||||
Pathname.glob("#{formula.bottle_prefix}/{etc,var}/**/*") do |path|
|
||||
path.extend(InstallRenamed)
|
||||
@ -776,7 +775,7 @@ class FormulaInstaller
|
||||
end
|
||||
FileUtils.rm_rf formula.bottle_prefix
|
||||
|
||||
tab = Tab.for_keg(formula.prefix)
|
||||
tab = Tab.for_keg(keg)
|
||||
|
||||
CxxStdlib.check_compatibility(
|
||||
formula, formula.recursive_dependencies,
|
||||
|
||||
@ -3,6 +3,14 @@ class Keg
|
||||
CELLAR_PLACEHOLDER = "@@HOMEBREW_CELLAR@@".freeze
|
||||
REPOSITORY_PLACEHOLDER = "@@HOMEBREW_REPOSITORY@@".freeze
|
||||
|
||||
Relocation = Struct.new(:old_prefix, :old_cellar, :old_repository,
|
||||
:new_prefix, :new_cellar, :new_repository) do
|
||||
# Use keyword args instead of positional args for initialization
|
||||
def initialize(**kwargs)
|
||||
super(*members.map { |k| kwargs[k] })
|
||||
end
|
||||
end
|
||||
|
||||
def fix_dynamic_linkage
|
||||
symlink_files.each do |file|
|
||||
link = file.readlink
|
||||
@ -15,21 +23,54 @@ class Keg
|
||||
end
|
||||
alias generic_fix_dynamic_linkage fix_dynamic_linkage
|
||||
|
||||
def relocate_dynamic_linkage(_old_prefix, _new_prefix, _old_cellar, _new_cellar)
|
||||
def relocate_dynamic_linkage(_relocation)
|
||||
[]
|
||||
end
|
||||
|
||||
def relocate_text_files(old_prefix, new_prefix, old_cellar, new_cellar,
|
||||
old_repository, new_repository)
|
||||
files = text_files | libtool_files
|
||||
def replace_locations_with_placeholders
|
||||
relocation = Relocation.new(
|
||||
old_prefix: HOMEBREW_PREFIX.to_s,
|
||||
old_cellar: HOMEBREW_CELLAR.to_s,
|
||||
old_repository: HOMEBREW_REPOSITORY.to_s,
|
||||
new_prefix: PREFIX_PLACEHOLDER,
|
||||
new_cellar: CELLAR_PLACEHOLDER,
|
||||
new_repository: REPOSITORY_PLACEHOLDER
|
||||
)
|
||||
relocate_dynamic_linkage(relocation)
|
||||
replace_text_in_files(relocation)
|
||||
end
|
||||
|
||||
files.group_by { |f| f.stat.ino }.each_value do |first, *rest|
|
||||
def replace_placeholders_with_locations(files)
|
||||
relocation = Relocation.new(
|
||||
old_prefix: PREFIX_PLACEHOLDER,
|
||||
old_cellar: CELLAR_PLACEHOLDER,
|
||||
old_repository: REPOSITORY_PLACEHOLDER,
|
||||
new_prefix: HOMEBREW_PREFIX.to_s,
|
||||
new_cellar: HOMEBREW_CELLAR.to_s,
|
||||
new_repository: HOMEBREW_REPOSITORY.to_s
|
||||
)
|
||||
relocate_dynamic_linkage(relocation)
|
||||
replace_text_in_files(relocation, files: files)
|
||||
end
|
||||
|
||||
def replace_text_in_files(relocation, files: nil)
|
||||
files ||= text_files | libtool_files
|
||||
|
||||
changed_files = []
|
||||
files.map(&path.method(:join)).group_by { |f| f.stat.ino }.each_value do |first, *rest|
|
||||
s = first.open("rb", &:read)
|
||||
changed = s.gsub!(old_cellar, new_cellar)
|
||||
changed = s.gsub!(old_prefix, new_prefix) || changed
|
||||
changed = s.gsub!(old_repository, new_repository) || changed
|
||||
|
||||
replacements = {
|
||||
relocation.old_prefix => relocation.new_prefix,
|
||||
relocation.old_cellar => relocation.new_cellar,
|
||||
relocation.old_repository => relocation.new_repository,
|
||||
}
|
||||
|
||||
regexp = Regexp.union(replacements.keys)
|
||||
changed = s.gsub!(regexp, replacements)
|
||||
|
||||
next unless changed
|
||||
changed_files << first.relative_path_from(path)
|
||||
|
||||
begin
|
||||
first.atomic_write(s)
|
||||
@ -41,6 +82,7 @@ class Keg
|
||||
rest.each { |file| FileUtils.ln(first, file, force: true) }
|
||||
end
|
||||
end
|
||||
changed_files
|
||||
end
|
||||
|
||||
def detect_cxx_stdlibs(_options = {})
|
||||
|
||||
@ -1,20 +1,24 @@
|
||||
class Metafiles
|
||||
require "set"
|
||||
|
||||
module Metafiles
|
||||
# https://github.com/github/markup#markups
|
||||
EXTENSIONS = %w[
|
||||
EXTENSIONS = Set.new %w[
|
||||
.adoc .asc .asciidoc .creole .html .markdown .md .mdown .mediawiki .mkdn
|
||||
.org .pod .rdoc .rst .rtf .textile .txt .wiki
|
||||
].freeze
|
||||
BASENAMES = %w[
|
||||
BASENAMES = Set.new %w[
|
||||
about authors changelog changes copying copyright history license licence
|
||||
news notes notice readme todo
|
||||
].freeze
|
||||
|
||||
def self.list?(file)
|
||||
module_function
|
||||
|
||||
def list?(file)
|
||||
return false if %w[.DS_Store INSTALL_RECEIPT.json].include?(file)
|
||||
!copy?(file)
|
||||
end
|
||||
|
||||
def self.copy?(file)
|
||||
def copy?(file)
|
||||
file = file.downcase
|
||||
ext = File.extname(file)
|
||||
file = File.basename(file, ext) if EXTENSIONS.include?(ext)
|
||||
|
||||
@ -303,6 +303,7 @@ class Tab < OpenStruct
|
||||
"unused_options" => unused_options.as_flags,
|
||||
"built_as_bottle" => built_as_bottle,
|
||||
"poured_from_bottle" => poured_from_bottle,
|
||||
"changed_files" => changed_files && changed_files.map(&:to_s),
|
||||
"time" => time,
|
||||
"source_modified_time" => source_modified_time.to_i,
|
||||
"HEAD" => self.HEAD,
|
||||
|
||||
4
Library/Homebrew/test/fixtures/receipt.json
vendored
4
Library/Homebrew/test/fixtures/receipt.json
vendored
@ -9,6 +9,10 @@
|
||||
],
|
||||
"built_as_bottle": false,
|
||||
"poured_from_bottle": true,
|
||||
"changed_files": [
|
||||
"INSTALL_RECEIPT.json",
|
||||
"bin/foo"
|
||||
],
|
||||
"time": 1403827774,
|
||||
"HEAD": "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
|
||||
"alias_path": "/usr/local/Library/Taps/homebrew/homebrew-core/Aliases/test-formula",
|
||||
|
||||
@ -11,6 +11,7 @@ class TabTests < Homebrew::TestCase
|
||||
"unused_options" => @unused.as_flags,
|
||||
"built_as_bottle" => false,
|
||||
"poured_from_bottle" => true,
|
||||
"changed_files" => [],
|
||||
"time" => nil,
|
||||
"source_modified_time" => 0,
|
||||
"HEAD" => TEST_SHA1,
|
||||
@ -33,6 +34,7 @@ class TabTests < Homebrew::TestCase
|
||||
tab = Tab.empty
|
||||
assert_empty tab.unused_options
|
||||
assert_empty tab.used_options
|
||||
assert_nil tab.changed_files
|
||||
refute_predicate tab, :built_as_bottle
|
||||
refute_predicate tab, :poured_from_bottle
|
||||
assert_predicate tab, :stable?
|
||||
@ -105,9 +107,11 @@ class TabTests < Homebrew::TestCase
|
||||
tab = Tab.from_file(path)
|
||||
source_path = "/usr/local/Library/Taps/hombrew/homebrew-core/Formula/foo.rb"
|
||||
runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }]
|
||||
changed_files = %w[INSTALL_RECEIPT.json bin/foo]
|
||||
|
||||
assert_equal @used.sort, tab.used_options.sort
|
||||
assert_equal @unused.sort, tab.unused_options.sort
|
||||
assert_equal changed_files, tab.changed_files
|
||||
refute_predicate tab, :built_as_bottle
|
||||
assert_predicate tab, :poured_from_bottle
|
||||
assert_predicate tab, :stable?
|
||||
@ -187,6 +191,7 @@ class TabTests < Homebrew::TestCase
|
||||
assert_equal @tab.unused_options.sort, tab.unused_options.sort
|
||||
assert_equal @tab.built_as_bottle, tab.built_as_bottle
|
||||
assert_equal @tab.poured_from_bottle, tab.poured_from_bottle
|
||||
assert_equal @tab.changed_files, tab.changed_files
|
||||
assert_equal @tab.tap, tab.tap
|
||||
assert_equal @tab.spec, tab.spec
|
||||
assert_equal @tab.time, tab.time
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user