aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorMike McQuaid2015-12-15 14:21:27 +0000
committerMike McQuaid2015-12-15 14:24:18 +0000
commit214c865167cb11c05841aef9d3ff25399e7f6b73 (patch)
tree49f83e29978543f656cbcbc3febb8d1b5482869f /Library
parente5ba31fcdcc4150e5aa8ecf110cfa502dd62a802 (diff)
downloadbrew-214c865167cb11c05841aef9d3ff25399e7f6b73.tar.bz2
bottle: make bottle checksums reproducible.
I've set all the variable data to versions that are dependent on the latest source file date and various modification dates also to the latest source file date. With this if you rerun `brew bottle` multiple times in a row you will see the same checksum even if you have `brew reinstall`ed (as long as upstream does not hardcode e.g. the build date). I debugged this with diffoscope and worked on this as part of the Athens 2015 reproducible builds workshop: https://reproducible-builds.org/events/athens2015/ Closes Homebrew/homebrew#46587. Signed-off-by: Mike McQuaid <mike@mikemcquaid.com>
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/cmd/bottle.rb27
-rw-r--r--Library/Homebrew/formula_installer.rb2
2 files changed, 28 insertions, 1 deletions
diff --git a/Library/Homebrew/cmd/bottle.rb b/Library/Homebrew/cmd/bottle.rb
index a543000bc..f642d458d 100644
--- a/Library/Homebrew/cmd/bottle.rb
+++ b/Library/Homebrew/cmd/bottle.rb
@@ -174,6 +174,9 @@ module Homebrew
filename = Bottle::Filename.create(f, bottle_tag, bottle_revision)
bottle_path = Pathname.pwd/filename
+ tar_filename = filename.to_s.sub(/.gz$/, "")
+ tar_path = Pathname.pwd/tar_filename
+
prefix = HOMEBREW_PREFIX.to_s
cellar = HOMEBREW_CELLAR.to_s
@@ -183,7 +186,13 @@ module Homebrew
relocatable = false
skip_relocation = false
+ formula_source_time = f.stable.stage do
+ Pathname.pwd.to_enum(:find).map(&:mtime).max
+ end
+
keg.lock do
+ original_tab = nil
+
begin
keg.relocate_install_names prefix, Keg::PREFIX_PLACEHOLDER,
cellar, Keg::CELLAR_PLACEHOLDER
@@ -192,10 +201,25 @@ module Homebrew
keg.delete_pyc_files!
+ tab = Tab.for_keg(keg)
+ original_tab = tab.dup
+ empty_tab = Tab.empty
+ tab["poured_from_bottle"] = empty_tab["poured_from_bottle"]
+ tab["HEAD"] = empty_tab["HEAD"]
+ tab["time"] = empty_tab["time"]
+ tab.write
+
+ keg.find {|k| File.utime(File.atime(k), formula_source_time, k) }
+
cd cellar do
+ safe_system "tar", "cf", tar_path, "#{f.name}/#{f.pkg_version}"
+ File.utime(File.atime(tar_path), formula_source_time, tar_path)
+ relocatable_tar_path = "#{f}-bottle.tar"
+ mv tar_path, relocatable_tar_path
# Use gzip, faster to compress than bzip2, faster to uncompress than bzip2
# or an uncompressed tarball (and more bandwidth friendly).
- safe_system "tar", "czf", bottle_path, "#{f.name}/#{f.pkg_version}"
+ safe_system "gzip", "-f", relocatable_tar_path
+ mv "#{relocatable_tar_path}.gz", bottle_path
end
if bottle_path.size > 1*1024*1024
@@ -222,6 +246,7 @@ module Homebrew
raise
ensure
ignore_interrupts do
+ original_tab.write
keg.relocate_install_names Keg::PREFIX_PLACEHOLDER, prefix,
Keg::CELLAR_PLACEHOLDER, cellar
end
diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb
index 0a483201f..8fae10137 100644
--- a/Library/Homebrew/formula_installer.rb
+++ b/Library/Homebrew/formula_installer.rb
@@ -741,6 +741,8 @@ class FormulaInstaller
tab.tap = formula.tap
tab.poured_from_bottle = true
+ tab.time = Time.now.to_i
+ tab.head = Homebrew.git_head
tab.write
end