diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 56965db1c1..6104050fc7 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -234,7 +234,7 @@ module Homebrew system "/usr/bin/sudo", "--non-interactive", "/usr/sbin/purge" end - def setup_tar_and_args!(args) + def setup_tar_and_args!(args, mtime) # Without --only-json-tab bottles are never reproducible default_tar_args = ["tar", [].freeze].freeze return default_tar_args unless args.only_json_tab? @@ -242,7 +242,7 @@ module Homebrew # Ensure tar is set up for reproducibility. # https://reproducible-builds.org/docs/archives/ gnutar_args = [ - "--format", "pax", "--owner", "0", "--group", "0", "--sort", "name", + "--format", "pax", "--owner", "0", "--group", "0", "--sort", "name", "--mtime=#{mtime}", # Set exthdr names to exclude PID (for GNU tar <1.33). Also don't store atime and ctime. "--pax-option", "globexthdr.name=/GlobalHead.%n,exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime" ].freeze @@ -409,28 +409,18 @@ module Homebrew tab.write end - keg.find do |file| - # Set the times for reproducible bottles. - if file.symlink? - # Need to make symlink permissions consistent on macOS and Linux - # TODO: Refactor and move to extend/os - File.lchmod 0777, file if OS.mac? # rubocop:disable Homebrew/MoveToExtendOS - File.lutime(tab.source_modified_time, tab.source_modified_time, file) - else - file.utime(tab.source_modified_time, tab.source_modified_time) - end - end + keg.consistent_reproducible_symlink_permissions! cd cellar do sudo_purge # Tar then gzip for reproducible bottles. - tar, tar_args = setup_tar_and_args!(args) + tar_mtime = tab.source_modified_time.strftime("%Y-%m-%d %H:%M:%S") + tar, tar_args = setup_tar_and_args!(args, tar_mtime) safe_system tar, "--create", "--numeric-owner", *tar_args, "--file", tar_path, "#{f.name}/#{f.pkg_version}" sudo_purge - # Set more times for reproducible bottles. - tar_path.utime(tab.source_modified_time, tab.source_modified_time) + # Set filename as it affects the tarball checksum. relocatable_tar_path = "#{f}-bottle.tar" mv tar_path, relocatable_tar_path # Use gzip, faster to compress than bzip2, faster to uncompress than bzip2 diff --git a/Library/Homebrew/extend/os/mac/keg.rb b/Library/Homebrew/extend/os/mac/keg.rb index 9aba39320a..6a47832a5c 100644 --- a/Library/Homebrew/extend/os/mac/keg.rb +++ b/Library/Homebrew/extend/os/mac/keg.rb @@ -1,4 +1,4 @@ -# typed: true +# typed: false # frozen_string_literal: true class Keg @@ -86,6 +86,8 @@ class Keg end end + undef prepare_debug_symbols + def prepare_debug_symbols binary_executable_or_library_files.each do |file| odebug "Extracting symbols #{file}" @@ -100,4 +102,14 @@ class Keg EOS end end + + undef consistent_reproducible_symlink_permissions! + + # Needed to make symlink permissions consistent on macOS and Linux for + # reproducible bottles. + def consistent_reproducible_symlink_permissions! + find do |file| + File.lchmod 0777, file if file.symlink? + end + end end diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index a12e8de395..a3a5579c53 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -485,6 +485,8 @@ class Keg def prepare_debug_symbols; end + def consistent_reproducible_symlink_permissions!; end + def remove_oldname_opt_record return unless oldname_opt_record return if oldname_opt_record.resolved_path != path