keg_relocate: cache files rewritten during brew bottle
`brew bottle` replaces instances of the Homebrew prefix, cellar, and repository with placeholders in all text files. Cache these files in INSTALL_RECEIPT.json so that we don't have to check every single text file for placeholders on install.
This commit is contained in:
		
							parent
							
								
									e6bce5ec27
								
							
						
					
					
						commit
						c46155aba4
					
				@ -187,12 +187,13 @@ 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,
 | 
			
		||||
          changed_files = keg.relocate_text_files prefix, Keg::PREFIX_PLACEHOLDER,
 | 
			
		||||
            cellar, Keg::CELLAR_PLACEHOLDER,
 | 
			
		||||
            repository, Keg::REPOSITORY_PLACEHOLDER
 | 
			
		||||
        end
 | 
			
		||||
@ -205,6 +206,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|
 | 
			
		||||
@ -268,7 +270,7 @@ module Homebrew
 | 
			
		||||
              Keg::CELLAR_PLACEHOLDER, cellar
 | 
			
		||||
            keg.relocate_text_files Keg::PREFIX_PLACEHOLDER, prefix,
 | 
			
		||||
              Keg::CELLAR_PLACEHOLDER, cellar,
 | 
			
		||||
              Keg::REPOSITORY_PLACEHOLDER, repository
 | 
			
		||||
              Keg::REPOSITORY_PLACEHOLDER, repository, changed_files
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
@ -762,13 +762,18 @@ class FormulaInstaller
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    keg = Keg.new(formula.prefix)
 | 
			
		||||
    tab_file = formula.prefix.join(Tab::FILENAME)
 | 
			
		||||
    # Skip the cache since the receipt will be rewritten
 | 
			
		||||
    orig_tab = Tab.from_file_content(tab_file.read, tab_file)
 | 
			
		||||
    changed_files = orig_tab.changed_files.map { |f| formula.prefix.join(f) }
 | 
			
		||||
 | 
			
		||||
    unless formula.bottle_specification.skip_relocation?
 | 
			
		||||
      keg.relocate_dynamic_linkage Keg::PREFIX_PLACEHOLDER, HOMEBREW_PREFIX.to_s,
 | 
			
		||||
        Keg::CELLAR_PLACEHOLDER, HOMEBREW_CELLAR.to_s
 | 
			
		||||
    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
 | 
			
		||||
      Keg::REPOSITORY_PLACEHOLDER, HOMEBREW_REPOSITORY.to_s, changed_files
 | 
			
		||||
 | 
			
		||||
    Pathname.glob("#{formula.bottle_prefix}/{etc,var}/**/*") do |path|
 | 
			
		||||
      path.extend(InstallRenamed)
 | 
			
		||||
 | 
			
		||||
@ -19,10 +19,11 @@ class Keg
 | 
			
		||||
    []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def relocate_text_files(old_prefix, new_prefix, old_cellar, new_cellar,
 | 
			
		||||
                          old_repository, new_repository)
 | 
			
		||||
    files = text_files | libtool_files
 | 
			
		||||
  def relocate_text_files(old_prefix, new_prefix, old_cellar, new_cellar, # rubocop:disable Metrics/ParameterLists
 | 
			
		||||
                          old_repository, new_repository, files = nil)
 | 
			
		||||
    files ||= text_files | libtool_files
 | 
			
		||||
 | 
			
		||||
    changed_files = []
 | 
			
		||||
    files.group_by { |f| f.stat.ino }.each_value do |first, *rest|
 | 
			
		||||
      s = first.open("rb", &:read)
 | 
			
		||||
      changed = s.gsub!(old_cellar, new_cellar)
 | 
			
		||||
@ -30,6 +31,7 @@ class Keg
 | 
			
		||||
      changed = s.gsub!(old_repository, new_repository) || changed
 | 
			
		||||
 | 
			
		||||
      next unless changed
 | 
			
		||||
      changed_files << first.relative_path_from(path)
 | 
			
		||||
 | 
			
		||||
      begin
 | 
			
		||||
        first.atomic_write(s)
 | 
			
		||||
@ -41,6 +43,7 @@ class Keg
 | 
			
		||||
        rest.each { |file| FileUtils.ln(first, file, force: true) }
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    changed_files
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def detect_cxx_stdlibs(_options = {})
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@ class Tab < OpenStruct
 | 
			
		||||
      "tabfile" => formula.prefix.join(FILENAME),
 | 
			
		||||
      "built_as_bottle" => build.bottle?,
 | 
			
		||||
      "poured_from_bottle" => false,
 | 
			
		||||
      "changed_files" => [],
 | 
			
		||||
      "time" => Time.now.to_i,
 | 
			
		||||
      "source_modified_time" => formula.source_modified_time.to_i,
 | 
			
		||||
      "HEAD" => HOMEBREW_REPOSITORY.git_head,
 | 
			
		||||
@ -61,6 +62,7 @@ class Tab < OpenStruct
 | 
			
		||||
    attributes = Utils::JSON.load(content)
 | 
			
		||||
    attributes["tabfile"] = path
 | 
			
		||||
    attributes["source_modified_time"] ||= 0
 | 
			
		||||
    attributes["changed_files"] ||= []
 | 
			
		||||
    attributes["source"] ||= {}
 | 
			
		||||
 | 
			
		||||
    tapped_from = attributes["tapped_from"]
 | 
			
		||||
@ -171,6 +173,7 @@ class Tab < OpenStruct
 | 
			
		||||
      "unused_options" => [],
 | 
			
		||||
      "built_as_bottle" => false,
 | 
			
		||||
      "poured_from_bottle" => false,
 | 
			
		||||
      "changed_files" => [],
 | 
			
		||||
      "time" => nil,
 | 
			
		||||
      "source_modified_time" => 0,
 | 
			
		||||
      "HEAD" => nil,
 | 
			
		||||
@ -303,6 +306,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.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_empty 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